Add support for parsing ICMP and ICMPv6 packets in packet parser

This commit is contained in:
luwenpeng
2024-04-22 16:38:24 +08:00
parent dd32f0f231
commit 8a41a79f06
4 changed files with 332 additions and 8 deletions

View File

@@ -2678,6 +2678,282 @@ TEST(PACKET, ETH_MPLS_MPLS_PWETHCW_ETH_ARP)
}
#endif
/******************************************************************************
* [Protocols in frame: eth:ethertype:ip:icmp:data]
******************************************************************************
*
* Frame 1: 98 bytes on wire (784 bits), 98 bytes captured (784 bits)
* Ethernet II, Src: EvocIntellig_36:51:46 (00:22:46:36:51:46), Dst: EvocIntellig_36:51:3c (00:22:46:36:51:3c)
* Destination: EvocIntellig_36:51:3c (00:22:46:36:51:3c)
* Source: EvocIntellig_36:51:46 (00:22:46:36:51:46)
* Type: IPv4 (0x0800)
* Internet Protocol Version 4, Src: 192.168.40.138, Dst: 192.168.40.134
* 0100 .... = Version: 4
* .... 0101 = Header Length: 20 bytes (5)
* Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
* 0000 00.. = Differentiated Services Codepoint: Default (0)
* .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
* Total Length: 84
* Identification: 0x22f6 (8950)
* 010. .... = Flags: 0x2, Don't fragment
* 0... .... = Reserved bit: Not set
* .1.. .... = Don't fragment: Set
* ..0. .... = More fragments: Not set
* ...0 0000 0000 0000 = Fragment Offset: 0
* Time to Live: 64
* Protocol: ICMP (1)
* Header Checksum: 0x4552 [correct]
* [Header checksum status: Good]
* [Calculated Checksum: 0x4552]
* Source Address: 192.168.40.138
* Destination Address: 192.168.40.134
* Internet Control Message Protocol
* Type: 8 (Echo (ping) request)
* Code: 0
* Checksum: 0xab05 [correct]
* [Checksum Status: Good]
* Identifier (BE): 24363 (0x5f2b)
* Identifier (LE): 11103 (0x2b5f)
* Sequence Number (BE): 1 (0x0001)
* Sequence Number (LE): 256 (0x0100)
* [Response frame: 2]
* Timestamp from icmp data: Jun 17, 2020 14:17:58.190124000 CST
* [Timestamp from icmp data (relative): -0.134576000 seconds]
* Data (40 bytes)
* Data: 101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
* [Length: 40]
*/
unsigned char data13[] = {
0x00, 0x22, 0x46, 0x36, 0x51, 0x3c, 0x00, 0x22, 0x46, 0x36, 0x51, 0x46, 0x08, 0x00, 0x45, 0x00, 0x00, 0x54, 0x22, 0xf6, 0x40, 0x00, 0x40, 0x01, 0x45, 0x52,
0xc0, 0xa8, 0x28, 0x8a, 0xc0, 0xa8, 0x28, 0x86, 0x08, 0x00, 0xab, 0x05, 0x5f, 0x2b, 0x00, 0x01, 0x96, 0xb5, 0xe9, 0x5e, 0x00, 0x00, 0x00, 0x00, 0xac, 0xe6,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37};
#if 1
TEST(PACKET, ETH_IP4_ICMP)
{
char buffer[256];
struct packet handler;
const char *payload = packet_parse(&handler, (const char *)data13, sizeof(data13));
EXPECT_TRUE(payload != nullptr);
EXPECT_TRUE((char *)payload - (char *)&data13 == 14 + 20 + 8);
packet_print(&handler);
/******************************************************
* packet_get_outermost/innermost_layer
******************************************************/
// LAYER_TYPE_ETHER
const struct packet_layer *outer_eth_record = packet_get_outermost_layer(&handler, LAYER_TYPE_ETHER);
const struct packet_layer *inner_eth_record = packet_get_innermost_layer(&handler, LAYER_TYPE_ETHER);
EXPECT_TRUE(outer_eth_record != nullptr);
EXPECT_TRUE(inner_eth_record != nullptr);
EXPECT_TRUE(outer_eth_record == inner_eth_record);
EXPECT_TRUE(outer_eth_record->hdr_offset == 0);
EXPECT_TRUE(outer_eth_record->hdr_len == 14);
EXPECT_TRUE(outer_eth_record->pld_len == 84);
// LAYER_TYPE_L2
const struct packet_layer *outer_l2_record = packet_get_outermost_layer(&handler, LAYER_TYPE_L2);
const struct packet_layer *inner_l2_record = packet_get_innermost_layer(&handler, LAYER_TYPE_L2);
EXPECT_TRUE(outer_l2_record != nullptr);
EXPECT_TRUE(inner_l2_record != nullptr);
EXPECT_TRUE(outer_l2_record == inner_l2_record);
EXPECT_TRUE(outer_l2_record == outer_eth_record);
// LAYER_TYPE_IPV4
const struct packet_layer *outer_ipv4_record = packet_get_outermost_layer(&handler, LAYER_TYPE_IPV4);
const struct packet_layer *inner_ipv4_record = packet_get_innermost_layer(&handler, LAYER_TYPE_IPV4);
EXPECT_TRUE(outer_ipv4_record != nullptr);
EXPECT_TRUE(inner_ipv4_record != nullptr);
EXPECT_TRUE(outer_ipv4_record == inner_ipv4_record);
EXPECT_TRUE(outer_ipv4_record->hdr_offset == 14);
EXPECT_TRUE(outer_ipv4_record->hdr_len == 20);
EXPECT_TRUE(outer_ipv4_record->pld_len == 64);
// LAYER_TYPE_L3
const struct packet_layer *outer_l3_record = packet_get_outermost_layer(&handler, LAYER_TYPE_L3);
const struct packet_layer *inner_l3_record = packet_get_innermost_layer(&handler, LAYER_TYPE_L3);
EXPECT_TRUE(outer_l3_record != nullptr);
EXPECT_TRUE(inner_l3_record != nullptr);
EXPECT_TRUE(outer_l3_record == inner_l3_record);
EXPECT_TRUE(outer_l3_record == outer_ipv4_record);
// LAYER_TYPE_ICMP
const struct packet_layer *outer_icmp_record = packet_get_outermost_layer(&handler, LAYER_TYPE_ICMP);
const struct packet_layer *inner_icmp_record = packet_get_innermost_layer(&handler, LAYER_TYPE_ICMP);
EXPECT_TRUE(outer_icmp_record != nullptr);
EXPECT_TRUE(inner_icmp_record != nullptr);
EXPECT_TRUE(outer_icmp_record == inner_icmp_record);
EXPECT_TRUE(outer_icmp_record->hdr_offset == 34);
EXPECT_TRUE(outer_icmp_record->hdr_len == 8);
EXPECT_TRUE(outer_icmp_record->pld_len == 56);
// LAYER_TYPE_L4
const struct packet_layer *outer_l4_record = packet_get_outermost_layer(&handler, LAYER_TYPE_L4);
const struct packet_layer *inner_l4_record = packet_get_innermost_layer(&handler, LAYER_TYPE_L4);
EXPECT_TRUE(outer_l4_record != nullptr);
EXPECT_TRUE(inner_l4_record != nullptr);
EXPECT_TRUE(outer_l4_record == inner_l4_record);
EXPECT_TRUE(outer_l4_record == outer_icmp_record);
/******************************************************
* packet_get_outermost/innermost_tuple2
******************************************************/
struct tuple2 outer_tuple2;
struct tuple2 inner_tuple2;
EXPECT_TRUE(packet_get_outermost_tuple2(&handler, &outer_tuple2) == 0);
EXPECT_TRUE(packet_get_innermost_tuple2(&handler, &inner_tuple2) == 0);
memset(buffer, 0, sizeof(buffer));
tuple2_to_str(&outer_tuple2, buffer, sizeof(buffer));
EXPECT_STREQ(buffer, "192.168.40.138 -> 192.168.40.134");
memset(buffer, 0, sizeof(buffer));
tuple2_to_str(&inner_tuple2, buffer, sizeof(buffer));
EXPECT_STREQ(buffer, "192.168.40.138 -> 192.168.40.134");
}
#endif
/******************************************************************************
* [Protocols in frame: eth:ethertype:ipv6:icmpv6:data]
******************************************************************************
*
* Frame 1: 114 bytes on wire (912 bits), 114 bytes captured (912 bits)
* Ethernet II, Src: c2:00:51:fa:00:00 (c2:00:51:fa:00:00), Dst: c2:01:51:fa:00:00 (c2:01:51:fa:00:00)
* Destination: c2:01:51:fa:00:00 (c2:01:51:fa:00:00)
* Source: c2:00:51:fa:00:00 (c2:00:51:fa:00:00)
* Type: IPv6 (0x86dd)
* Internet Protocol Version 6, Src: 2001:db8:0:12::1, Dst: 2001:db8:0:12::2
* 0110 .... = Version: 6
* .... 0000 0000 .... .... .... .... .... = Traffic Class: 0x00 (DSCP: CS0, ECN: Not-ECT)
* .... 0000 00.. .... .... .... .... .... = Differentiated Services Codepoint: Default (0)
* .... .... ..00 .... .... .... .... .... = Explicit Congestion Notification: Not ECN-Capable Transport (0)
* .... 0000 0000 0000 0000 0000 = Flow Label: 0x00000
* Payload Length: 60
* Next Header: ICMPv6 (58)
* Hop Limit: 64
* Source Address: 2001:db8:0:12::1
* Destination Address: 2001:db8:0:12::2
* Internet Control Message Protocol v6
* Type: Echo (ping) request (128)
* Code: 0
* Checksum: 0x863c [correct]
* [Checksum Status: Good]
* Identifier: 0x110d
* Sequence: 0
* [Response In: 2]
* Data (52 bytes)
* Data: 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233
* [Length: 52]
*/
unsigned char data14[] = {
0xc2, 0x01, 0x51, 0xfa, 0x00, 0x00, 0xc2, 0x00, 0x51, 0xfa, 0x00, 0x00, 0x86, 0xdd, 0x60, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3a, 0x40, 0x20, 0x01, 0x0d, 0xb8,
0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x80, 0x00, 0x86, 0x3c, 0x11, 0x0d, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33};
#if 1
TEST(PACKET, ETH_IP6_ICMP6)
{
char buffer[256];
struct packet handler;
const char *payload = packet_parse(&handler, (const char *)data14, sizeof(data14));
EXPECT_TRUE(payload != nullptr);
EXPECT_TRUE((char *)payload - (char *)&data14 == 14 + 40 + 8);
packet_print(&handler);
/******************************************************
* packet_get_outermost/innermost_layer
******************************************************/
// LAYER_TYPE_ETHER
const struct packet_layer *outer_eth_record = packet_get_outermost_layer(&handler, LAYER_TYPE_ETHER);
const struct packet_layer *inner_eth_record = packet_get_innermost_layer(&handler, LAYER_TYPE_ETHER);
EXPECT_TRUE(outer_eth_record != nullptr);
EXPECT_TRUE(inner_eth_record != nullptr);
EXPECT_TRUE(outer_eth_record == inner_eth_record);
EXPECT_TRUE(outer_eth_record->hdr_offset == 0);
EXPECT_TRUE(outer_eth_record->hdr_len == 14);
EXPECT_TRUE(outer_eth_record->pld_len == 100);
// LAYER_TYPE_L2
const struct packet_layer *outer_l2_record = packet_get_outermost_layer(&handler, LAYER_TYPE_L2);
const struct packet_layer *inner_l2_record = packet_get_innermost_layer(&handler, LAYER_TYPE_L2);
EXPECT_TRUE(outer_l2_record != nullptr);
EXPECT_TRUE(inner_l2_record != nullptr);
EXPECT_TRUE(outer_l2_record == inner_l2_record);
EXPECT_TRUE(outer_l2_record == outer_eth_record);
// LAYER_TYPE_IPV6
const struct packet_layer *outer_ipv6_record = packet_get_outermost_layer(&handler, LAYER_TYPE_IPV6);
const struct packet_layer *inner_ipv6_record = packet_get_innermost_layer(&handler, LAYER_TYPE_IPV6);
EXPECT_TRUE(outer_ipv6_record != nullptr);
EXPECT_TRUE(inner_ipv6_record != nullptr);
EXPECT_TRUE(outer_ipv6_record == inner_ipv6_record);
EXPECT_TRUE(outer_ipv6_record->hdr_offset == 14);
EXPECT_TRUE(outer_ipv6_record->hdr_len == 40);
EXPECT_TRUE(outer_ipv6_record->pld_len == 60);
// LAYER_TYPE_L3
const struct packet_layer *outer_l3_record = packet_get_outermost_layer(&handler, LAYER_TYPE_L3);
const struct packet_layer *inner_l3_record = packet_get_innermost_layer(&handler, LAYER_TYPE_L3);
EXPECT_TRUE(outer_l3_record != nullptr);
EXPECT_TRUE(inner_l3_record != nullptr);
EXPECT_TRUE(outer_l3_record == inner_l3_record);
EXPECT_TRUE(outer_l3_record == outer_ipv6_record);
// LAYER_TYPE_ICMP6
const struct packet_layer *outer_icmp6_record = packet_get_outermost_layer(&handler, LAYER_TYPE_ICMP6);
const struct packet_layer *inner_icmp6_record = packet_get_innermost_layer(&handler, LAYER_TYPE_ICMP6);
EXPECT_TRUE(outer_icmp6_record != nullptr);
EXPECT_TRUE(inner_icmp6_record != nullptr);
EXPECT_TRUE(outer_icmp6_record == inner_icmp6_record);
EXPECT_TRUE(outer_icmp6_record->hdr_offset == 54);
EXPECT_TRUE(outer_icmp6_record->hdr_len == 8);
EXPECT_TRUE(outer_icmp6_record->pld_len == 52);
// LAYER_TYPE_L4
const struct packet_layer *outer_l4_record = packet_get_outermost_layer(&handler, LAYER_TYPE_L4);
const struct packet_layer *inner_l4_record = packet_get_innermost_layer(&handler, LAYER_TYPE_L4);
EXPECT_TRUE(outer_l4_record != nullptr);
EXPECT_TRUE(inner_l4_record != nullptr);
EXPECT_TRUE(outer_l4_record == inner_l4_record);
EXPECT_TRUE(outer_l4_record == outer_icmp6_record);
/******************************************************
* packet_get_outermost/innermost_tuple2
******************************************************/
struct tuple2 outer_tuple2;
struct tuple2 inner_tuple2;
EXPECT_TRUE(packet_get_outermost_tuple2(&handler, &outer_tuple2) == 0);
EXPECT_TRUE(packet_get_innermost_tuple2(&handler, &inner_tuple2) == 0);
memset(buffer, 0, sizeof(buffer));
tuple2_to_str(&outer_tuple2, buffer, sizeof(buffer));
EXPECT_STREQ(buffer, "2001:db8:0:12::1 -> 2001:db8:0:12::2");
memset(buffer, 0, sizeof(buffer));
tuple2_to_str(&inner_tuple2, buffer, sizeof(buffer));
EXPECT_STREQ(buffer, "2001:db8:0:12::1 -> 2001:db8:0:12::2");
}
#endif
#if 1
TEST(PACKET, HASH_VALUE)
{