]> 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.
       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!)
 
 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 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;
        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)) {
          * 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;
                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));
                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 */
        }
 
        /* ndo_protocol reassignment after ip_print() call */