]> The Tcpdump Group git mirrors - tcpdump/commitdiff
ICMP: Update the snapend for some nested IP packets
authorFrancois-Xavier Le Bail <[email protected]>
Sun, 24 Jan 2021 09:52:50 +0000 (10:52 +0100)
committerFrancois-Xavier Le Bail <[email protected]>
Mon, 25 Jan 2021 10:17:37 +0000 (11:17 +0100)
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.

Moreover:
Reduce the scope of a variable.
Fix spaces

CHANGES
print-icmp.c

diff --git a/CHANGES b/CHANGES
index 75de7b715de0eeaff7a2ecf118b0e6a2f6355d0a..75ca60bc95afe6558831860d804e8731d4a709c2 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -15,6 +15,7 @@ Monthday, Month DD, YYYY by gharris and denis
       Introduce new ND_LCHECK*() macros to deduplicate more code.
       IEEE 802.11: Simplify handle_action().
       OpenFlow 1.0: Get snapend right for nested frames.
+      ICMP: Update the snapend for some nested IP packets.
 
 Monthday, Month DD, YYYY by gharris
   Summary for 4.99.1 tcpdump release (so far!)
index 955fba2307b4b6835be00ec4b112c57a3f0c8e44..b0e13f4c8239be1d410ae62be726c9804954f24b 100644 (file)
@@ -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;
@@ -651,12 +650,25 @@ icmp_print(netdissect_options *ndo, const u_char *bp, u_int plen, const u_char *
          * 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 */