X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/aad6ac30ce7904f688226dbc61021ca4f907274f..d1e77f9887bf21eecdbbd14b5c1a7d16ec12ce58:/print-icmp.c diff --git a/print-icmp.c b/print-icmp.c index 59b56c6a..77539225 100644 --- a/print-icmp.c +++ b/print-icmp.c @@ -92,7 +92,7 @@ struct icmp { /* * Lower bounds on packet lengths for various types. * For the error advice packets must first insure that the - * packet is large enought to contain the returned ip header. + * packet is large enough to contain the returned ip header. * Only then can we do the check to see if 64 bits of packet * data have been returned, since we need to check the returned * ip header length. @@ -226,7 +226,7 @@ struct id_rdiscovery { * The Destination Unreachable, Time Exceeded * and Parameter Problem messages are slightly changed as per * the above draft. A new Length field gets added to give - * the caller an idea about the length of the piggypacked + * the caller an idea about the length of the piggybacked * IP packet before the MPLS extension header starts. * * The Length field represents length of the padded "original datagram" @@ -305,7 +305,6 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * const struct udphdr *ouh; const uint8_t *obj_tptr; uint32_t raw_label; - const u_char *snapend_save; const struct icmp_mpls_ext_object_header_t *icmp_mpls_ext_object_header; u_int hlen, mtu, obj_tlen, obj_class_num, obj_ctype; uint16_t dport; @@ -324,7 +323,6 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * case ICMP_ECHO: case ICMP_ECHOREPLY: - ND_TCHECK_2(dp->icmp_seq); (void)snprintf(buf, sizeof(buf), "echo %s, id %u, seq %u", icmp_type == ICMP_ECHO ? "request" : "reply", @@ -348,7 +346,6 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * break; case ICMP_UNREACH_PROTOCOL: - ND_TCHECK_1(dp->icmp_ip.ip_p); (void)snprintf(buf, sizeof(buf), "%s protocol %u unreachable", GET_IPADDR_STRING(dp->icmp_ip.ip_dst), @@ -595,7 +592,6 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * (void)snprintf(buf, sizeof(buf), "parameter problem - code %u", icmp_code); else { - ND_TCHECK_1(dp->icmp_pptr); (void)snprintf(buf, sizeof(buf), "parameter problem - octet %u", GET_U_1(dp->icmp_pptr)); @@ -608,7 +604,6 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * break; case ICMP_TSTAMP: - ND_TCHECK_2(dp->icmp_seq); (void)snprintf(buf, sizeof(buf), "time stamp query id %u seq %u", GET_BE_U_2(dp->icmp_id), @@ -652,15 +647,28 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char * /* * print the remnants of the IP packet. - * save the snaplength as this may get overidden in the IP printer. + * save the snaplength as this may get overridden in the IP printer. */ if (ndo->ndo_vflag >= 1 && ICMP_ERRTYPE(icmp_type)) { + const u_char *snapend_save; + bp += 8; ND_PRINT("\n\t"); ip = (const struct ip *)bp; - snapend_save = ndo->ndo_snapend; + snapend_save = ndo->ndo_snapend; + /* + * Update the snapend because extensions (MPLS, ...) may be + * present after the IP packet. In this case the current + * (outer) packet's snapend is not what ip_print() needs to + * decode an IP packet nested in the middle of an ICMP payload. + * + * This prevents that, in ip_print(), for the nested IP packet, + * the remaining length < remaining caplen. + */ + ndo->ndo_snapend = ND_MIN(bp + GET_BE_U_2(ip->ip_len), + ndo->ndo_snapend); ip_print(ndo, bp, GET_BE_U_2(ip->ip_len)); - ndo->ndo_snapend = snapend_save; + ndo->ndo_snapend = snapend_save; } /* ndo_protocol reassignment after ip_print() call */