X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/69cb46af9119e8b5554bcc4bf1bf36f39cb82131..7029d15f148ef24bb7c6668bc640f5470d085e5a:/print-icmp.c?ds=inline diff --git a/print-icmp.c b/print-icmp.c index 1c92d032..366094ef 100644 --- a/print-icmp.c +++ b/print-icmp.c @@ -19,18 +19,20 @@ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ +/* \summary: Internet Control Message Protocol (ICMP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" -#include "extract.h" /* must come after interface.h */ +#include "extract.h" #include "ip.h" #include "udp.h" @@ -386,14 +388,14 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * (void)snprintf(buf, sizeof(buf), "%s tcp port %s unreachable", ipaddr_string(ndo, &oip->ip_dst), - tcpport_string(dport)); + tcpport_string(ndo, dport)); break; case IPPROTO_UDP: (void)snprintf(buf, sizeof(buf), "%s udp port %s unreachable", ipaddr_string(ndo, &oip->ip_dst), - udpport_string(dport)); + udpport_string(ndo, dport)); break; default: @@ -479,7 +481,7 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * " [size %d]", size); break; } - idp = (struct id_rdiscovery *)&dp->icmp_data; + idp = (const struct id_rdiscovery *)&dp->icmp_data; while (num-- > 0) { ND_TCHECK(*idp); (void)snprintf(cp, sizeof(buf) - (cp - buf), " {%s %u}", @@ -556,7 +558,7 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * ND_PRINT((ndo, "ICMP %s, length %u", str, plen)); if (ndo->ndo_vflag && !fragmented) { /* don't attempt checksumming if this is a frag */ uint16_t sum, icmp_sum; - struct cksum_vec vec[1]; + if (ND_TTEST2(*bp, plen)) { vec[0].ptr = (const uint8_t *)(const void *)dp; vec[0].len = plen; @@ -578,8 +580,8 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * bp += 8; ND_PRINT((ndo, "\n\t")); ip = (const struct ip *)bp; - ndo->ndo_snaplen = ndo->ndo_snapend - bp; snapend_save = ndo->ndo_snapend; + ND_TCHECK_16BITS(&ip->ip_len); ip_print(ndo, bp, EXTRACT_16BITS(&ip->ip_len)); ndo->ndo_snapend = snapend_save; } @@ -597,8 +599,9 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * * 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) { - vec[0].ptr = (const uint8_t *)(void *)&ext_dp->icmp_ext_version_res; + if (!ext_dp->icmp_length && + ND_TTEST2(ext_dp->icmp_ext_version_res, plen - ICMP_EXTD_MINLEN)) { + vec[0].ptr = (const uint8_t *)(const void *)&ext_dp->icmp_ext_version_res; vec[0].len = plen - ICMP_EXTD_MINLEN; if (in_cksum(vec, 1)) { return; @@ -618,12 +621,14 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * } hlen = plen - ICMP_EXTD_MINLEN; - vec[0].ptr = (const uint8_t *)(void *)&ext_dp->icmp_ext_version_res; - vec[0].len = hlen; - ND_PRINT((ndo, ", checksum 0x%04x (%scorrect), length %u", - EXTRACT_16BITS(ext_dp->icmp_ext_checksum), - in_cksum(vec, 1) ? "in" : "", - hlen)); + if (ND_TTEST2(ext_dp->icmp_ext_version_res, hlen)) { + vec[0].ptr = (const uint8_t *)(const void *)&ext_dp->icmp_ext_version_res; + vec[0].len = hlen; + ND_PRINT((ndo, ", checksum 0x%04x (%scorrect), length %u", + EXTRACT_16BITS(ext_dp->icmp_ext_checksum), + in_cksum(vec, 1) ? "in" : "", + hlen)); + } hlen -= 4; /* subtract common header size */ obj_tptr = (const uint8_t *)ext_dp->icmp_ext_data;