Skip to content

Commit 2dcc18a

Browse files
yuanchaoarvql
authored andcommitted
fix: the panic caused by parsing icmp6
1 parent e49962d commit 2dcc18a

2 files changed

Lines changed: 27 additions & 22 deletions

File tree

agent/crates/public/src/enums.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ pub enum HeaderType {
246246
Ipv4 = 0x20,
247247
Ipv4Icmp = 0x21,
248248
Ipv6 = 0x40,
249+
Ipv6Icmp = 0x41,
249250
Ipv4Tcp = 0x80,
250251
Ipv4Udp = 0x81,
251252
Ipv6Tcp = 0xb0,
@@ -267,8 +268,9 @@ impl HeaderType {
267268
Self::Ipv4 => 14 + 20, // 不包括DOT1Q + IPv4 option0,
268269
Self::Ipv4Icmp => 14 + 20 + 8, // 不包括DOT1Q + IPv4 option 0x21,
269270
Self::Ipv6 => 14 + 20, // 不包括DOT1Q + IPv6 option,IPv6大于IPv4的20个字节计算在m.l2L3OptSize里面0,
271+
Self::Ipv6Icmp => 14 + 20 + 8, // 不包括DOT1Q + IPv6 option,IPv6大于IPv4的20个字节计算在m.l2L3OptSize里面0,
270272
Self::Ipv4Tcp => 14 + 20 + 20, // 不包括DOT1Q + IPv4 option0x80,
271-
Self::Ipv4Udp => 14 + 20 + 8, // 不包括DOT1Q + IPv4 option0x81,
273+
Self::Ipv4Udp => 14 + 20 + 8, // 不包括DOT1Q + IPv4 option0x81,
272274
Self::Ipv6Tcp => 14 + 40 + 20, // 不包括DOT1Q + IPv6 option,IPv6大于40字节的option计算在m.l2L3OptSize里面0xb0,
273275
Self::Ipv6Udp => 14 + 40 + 8, // 不包括DOT1Q + IPv6 option,IPv6大于40字节的option计算在m.l2L3OptSize里面0xb1,
274276
Self::Invalid => unreachable!(),
@@ -282,6 +284,7 @@ impl HeaderType {
282284
Self::Ipv4 => 20,
283285
Self::Ipv4Icmp => 8,
284286
Self::Ipv6 => 20,
287+
Self::Ipv6Icmp => 8,
285288
Self::Ipv4Tcp => 20,
286289
Self::Ipv4Udp => 8,
287290
Self::Ipv6Tcp => 20,

agent/src/common/meta_packet.rs

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -940,33 +940,35 @@ impl<'a> MetaPacket<'a> {
940940
}
941941
}
942942
IpProtocol::ICMPV6 => {
943+
size_checker -= HeaderType::Ipv6Icmp.min_header_size() as isize;
944+
if size_checker < 0 {
945+
return Ok(());
946+
}
943947
let mut icmp_data = IcmpData::default();
944-
if size_checker > 0 {
945-
let icmpv6_type_index = ICMPV6_TYPE_OFFSET + self.l2_l3_opt_size as usize;
946-
icmp_data.icmp_type = packet[icmpv6_type_index];
947-
948-
match Icmpv6Type::new(packet[icmpv6_type_index]) {
949-
Icmpv6Types::NeighborAdvert => {
950-
self.nd_reply_or_arp_request = true;
951-
}
952-
Icmpv6Types::EchoRequest => {
953-
icmp_data.echo_id_seq = read_u32_be(&packet[icmpv6_type_index + 4..]);
954-
}
955-
Icmpv6Types::EchoReply => {
956-
icmp_data.echo_id_seq = read_u32_be(&packet[icmpv6_type_index + 4..]);
957-
self.lookup_key.direction = PacketDirection::ServerToClient;
958-
}
959-
_ => {}
948+
let icmpv6_type_index = ICMPV6_TYPE_OFFSET + self.l2_l3_opt_size as usize;
949+
icmp_data.icmp_type = packet[icmpv6_type_index];
950+
match Icmpv6Type::new(packet[icmpv6_type_index]) {
951+
Icmpv6Types::NeighborAdvert => {
952+
self.nd_reply_or_arp_request = true;
960953
}
961-
// 忽略link-local address并只考虑ND reply, i.e. neighbour advertisement
962-
if let IpAddr::V6(ip) = self.lookup_key.src_ip {
963-
self.nd_reply_or_arp_request =
964-
self.nd_reply_or_arp_request && !is_unicast_link_local(&ip);
954+
Icmpv6Types::EchoRequest => {
955+
icmp_data.echo_id_seq = read_u32_be(&packet[icmpv6_type_index + 4..]);
965956
}
957+
Icmpv6Types::EchoReply => {
958+
icmp_data.echo_id_seq = read_u32_be(&packet[icmpv6_type_index + 4..]);
959+
self.lookup_key.direction = PacketDirection::ServerToClient;
960+
}
961+
_ => {}
962+
}
963+
// 忽略link-local address并只考虑ND reply, i.e. neighbour advertisement
964+
if let IpAddr::V6(ip) = self.lookup_key.src_ip {
965+
self.nd_reply_or_arp_request =
966+
self.nd_reply_or_arp_request && !is_unicast_link_local(&ip);
966967
}
967-
self.protocol_data = ProtocolData::IcmpData(icmp_data);
968968
self.payload_len =
969969
(self.packet_len - (packet.len() - size_checker as usize) as u32) as u16;
970+
self.protocol_data = ProtocolData::IcmpData(icmp_data);
971+
self.header_type = HeaderType::Ipv6Icmp;
970972
return Ok(());
971973
}
972974
_ => {

0 commit comments

Comments
 (0)