From: ishaangandhi Date: Tue, 24 Nov 2020 16:50:18 +0000 (-0500) Subject: Add dissector for ICMP Interface Identification Object X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/dbf0433fef377d3739e94b881cdd540c5f988a98 Add dissector for ICMP Interface Identification Object --- diff --git a/print-icmp.c b/print-icmp.c index fe90aff0..6642c990 100644 --- a/print-icmp.c +++ b/print-icmp.c @@ -276,6 +276,42 @@ static const struct tok icmp_multipart_ext_obj_values[] = { { 0, NULL} }; +/* rfc5837 */ +static const struct tok icmp_interface_identification_role_values[] = { + { 0, "the IP interface upon which a datagram arrived"}, + { 1, "the sub-IP component of an IP interface upon which a datagram arrived"}, + { 2, "the IP interface through which the datagram would have been forwarded had it been forwardable"}, + { 3, "the IP next hop to which the datagram would have been forwarded"}, + { 0, NULL } +}; + +/* +Interface IP Address Sub-Object +0 31 ++-------+-------+-------+-------+ +| AFI | Reserved | ++-------+-------+-------+-------+ +| IP Address .... +*/ +struct icmp_interface_identification_ipaddr_subobject_t { + nd_uint16_t afi; + nd_uint16_t reserved; + nd_uint32_t ip_addr; +}; + +/* +Interface Name Sub-Object +octet 0 1 63 + +--------+-----------................-----------------+ + | length | interface name octets 1-63 | + +--------+-----------................-----------------+ +*/ +struct icmp_interface_identification_ifname_subobject_t { + nd_uint8_t length; + nd_byte if_name[63]; +}; + + /* prototypes */ const char *icmp_tstamp_print(u_int); @@ -311,6 +347,10 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * const uint8_t *obj_tptr; uint32_t raw_label; const struct icmp_multipart_ext_object_header_t *icmp_multipart_ext_object_header; + u_int interface_role, if_index_flag, ipaddr_flag, name_flag, mtu_flag; + const uint8_t *offset; + const struct icmp_interface_identification_ipaddr_subobject_t *ipaddr_subobj; + const struct icmp_interface_identification_ifname_subobject_t *ifname_subobj; u_int hlen, mtu, obj_tlen, obj_class_num, obj_ctype; uint16_t dport; char buf[MAXHOSTNAMELEN + 100]; @@ -751,7 +791,7 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * obj_tlen-=sizeof(struct icmp_multipart_ext_object_header_t); switch (obj_class_num) { - case 1: + case MPLS_STACK_ENTRY_OBJECT_CLASS: switch(obj_ctype) { case 1: raw_label = GET_BE_U_4(obj_tptr); @@ -765,11 +805,64 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * } break; - /* - * FIXME those are the defined objects that lack a decoder - * you are welcome to contribute code ;-) - */ - case 2: + case INTERFACE_INFORMATION_OBJECT_CLASS: + /* + + Ctype in a INTERFACE_INFORMATION_OBJECT_CLASS object: + + Bit 0 1 2 3 4 5 6 7 + +-------+-------+-------+-------+-------+-------+-------+-------+ + | Interface Role| Rsvd1 | Rsvd2 |ifIndex| IPAddr| name | MTU | + +-------+-------+-------+-------+-------+-------+-------+-------+ + + */ + interface_role = (obj_ctype & 0xc0) >> 6; + if_index_flag = (obj_ctype & 0x8) >> 3; + ipaddr_flag = (obj_ctype & 0x4) >> 2; + name_flag = (obj_ctype & 0x2) >> 1; + mtu_flag = (obj_ctype & 0x1); + + ND_PRINT("\n\t\t This object describes %s", + tok2str(icmp_interface_identification_role_values,"an unknown interface role",interface_role)); + + offset = obj_tptr; + + if (if_index_flag) { + ND_PRINT("\n\t\t Interface Index: %u", GET_BE_U_4(offset)); + offset += 4; + } + + if (ipaddr_flag) { + ND_PRINT("\n\t\t IP Address sub-object: "); + ipaddr_subobj = (const struct icmp_interface_identification_ipaddr_subobject_t *) offset; + switch (GET_BE_U_2(ipaddr_subobj->afi)) { + case 1: + ND_PRINT("%s", GET_IPADDR_STRING(ipaddr_subobj->ip_addr)); + offset += 4; + break; + case 2: + ND_PRINT("%s", GET_IP6ADDR_STRING(ipaddr_subobj->ip_addr)); + offset += 16; + break; + default: + ND_PRINT("Unknown Address Family Identifier"); + return; + } + offset += 4; + } + + if (name_flag) { + ifname_subobj = (const struct icmp_interface_identification_ifname_subobject_t *) offset; + ND_PRINT("\n\t\t Interface Name: %.*s", GET_U_1(ifname_subobj->length), ifname_subobj->if_name); + offset += 1 + GET_U_1(ifname_subobj->length); + } + if (mtu_flag) { + ND_PRINT("\n\t\t MTU: %u", GET_BE_U_4(offset)); + offset += 4; + } + + break; + default: print_unknown_data(ndo, obj_tptr, "\n\t ", obj_tlen); break; diff --git a/tests/TESTLIST b/tests/TESTLIST index 05a326e4..8fa5d789 100644 --- a/tests/TESTLIST +++ b/tests/TESTLIST @@ -186,6 +186,9 @@ igmpv3-queries igmpv3-queries.pcap igmpv3-queries.out mtrace mtrace.pcap mtrace.out dvmrp mrinfo_query.pcap dvmrp.out +# ICMPv4 -- pcap from https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6632 +rfc5837 icmp-rfc5837.pcap icmp-rfc5837.out -v + # ICMPv6 icmpv6 icmpv6.pcap icmpv6.out -vv icmpv6_opt24-v icmpv6_opt24.pcap icmpv6_opt24-v.out -v diff --git a/tests/icmp-cksum-oobr-2.out b/tests/icmp-cksum-oobr-2.out index ce5fc141..c83905c4 100644 --- a/tests/icmp-cksum-oobr-2.out +++ b/tests/icmp-cksum-oobr-2.out @@ -2,10 +2,9 @@ 10.4.0.34 > 12.4.4.4: ICMP time exceeded in-transit, length 32988 (tos 0x0, ttl 1, id 42321, offset 0, flags [none], proto UDP (17), length 40) 12.4.4.4.42315 > 12.1.1.1.33440: [bad udp cksum 0x1000 -> 0xbad0!] UDP, length 12 - 0x0000: 0000 000f 0001 0000 0a0a 0a0a 3f54 6869 - 0x0010: 732d 6973 2d74 6865 2d6e 616d 652d 6f66 - 0x0020: 2d74 6865 2d49 6e74 6572 6661 6365 2d74 - 0x0030: 6861 742d 7765 2d61 7265 2d6c 6f6f 6b69 - 0x0040: 6e67 2d66 6f72 2d5b 3a2d 295d [|icmp] ICMP Multi-Part extension v2 Interface Identification Object (2), Class-Type: 14, length 80 + This object describes the IP interface upon which a datagram arrived + Interface Index: 15 + IP Address sub-object: 10.10.10.10 + Interface Name: This-is-the-name-of-the-Interface-that-we-are-looking-for-[:-)] [|icmp] diff --git a/tests/icmp-rfc5837.out b/tests/icmp-rfc5837.out new file mode 100644 index 00000000..bc6cd087 --- /dev/null +++ b/tests/icmp-rfc5837.out @@ -0,0 +1,10 @@ + 1 10:13:29.331681 IP (tos 0x0, ttl 254, id 59168, offset 0, flags [DF], proto ICMP (1), length 240) + 10.4.0.2 > 12.4.4.4: ICMP time exceeded in-transit, length 220 + IP (tos 0x0, ttl 1, id 42321, offset 0, flags [none], proto UDP (17), length 40) + 12.4.4.4.42315 > 12.1.1.1.33440: UDP, length 12 + ICMP Multi-Part extension v2, checksum 0x256c (correct), length 84 + Interface Identification Object (2), Class-Type: 14, length 80 + This object describes the IP interface upon which a datagram arrived + Interface Index: 15 + IP Address sub-object: 10.10.10.10 + Interface Name: This-is-the-name-of-the-Interface-that-we-are-looking-for-[:-)] diff --git a/tests/icmp-rfc5837.pcap b/tests/icmp-rfc5837.pcap new file mode 100644 index 00000000..5daa8e5a Binary files /dev/null and b/tests/icmp-rfc5837.pcap differ