From: hannes Date: Tue, 12 Dec 2006 14:31:51 +0000 (+0000) Subject: apply some heuristics to detect MPLS ICMP extension headers because X-Git-Tag: tcpdump-4.0.0~182 X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/92d23114231c836c1c12d503679ab545100fa8d2 apply some heuristics to detect MPLS ICMP extension headers because not all implementations correctly set the length field in the ICMP header as per draft-bonica-internet-icmp-08. if the length field is not set then simply check the checksum. --- diff --git a/print-icmp.c b/print-icmp.c index a6c08110..d9b8c8ee 100644 --- a/print-icmp.c +++ b/print-icmp.c @@ -21,7 +21,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-icmp.c,v 1.84 2006-12-12 10:48:43 hannes Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-icmp.c,v 1.85 2006-12-12 14:31:51 hannes Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -589,13 +589,24 @@ icmp_print(const u_char *bp, u_int plen, const u_char *bp2, int fragmented) } /* - * Check if the extended ICMP header indicates that there is - * MPLS extension header present for the "interesting" ICMP types. + * Attempt to decode the MPLS extensions only for some ICMP types. */ - if (vflag >= 1 && plen > ICMP_EXTD_MINLEN && - ext_dp->icmp_length && ICMP_MPLS_EXT_TYPE(dp->icmp_type)) { + if (vflag >= 1 && plen > ICMP_EXTD_MINLEN && ICMP_MPLS_EXT_TYPE(dp->icmp_type)) { TCHECK(*ext_dp); + + /* + * Check first if the mpls extension header shows a non-zero length. + * If the length field is not set then silently verify the checksum + * to check if an extension header is present. This is expedient, + * however not all implementations set the length field proper. + */ + if (!ext_dp->icmp_length && + in_cksum((const u_short *)&ext_dp->icmp_ext_version_res, + plen - ICMP_EXTD_MINLEN, 0)) { + return; + } + printf("\n\tMPLS extension v%u", ICMP_MPLS_EXT_EXTRACT_VERSION(*(ext_dp->icmp_ext_version_res))); @@ -609,8 +620,10 @@ icmp_print(const u_char *bp, u_int plen, const u_char *bp2, int fragmented) } hlen = plen - ICMP_EXTD_MINLEN; - printf(", checksum 0x%04x (unverified), length %u", /* FIXME */ + printf(", checksum 0x%04x (%scorrect), length %u", EXTRACT_16BITS(ext_dp->icmp_ext_checksum), + in_cksum((const u_short *)&ext_dp->icmp_ext_version_res, + plen - ICMP_EXTD_MINLEN, 0) ? "in" : "", hlen); hlen -= 4; /* subtract common header size */