]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Cut off "snapend" at the length of the IPv4 or IPv6 payload, so we don't
authorguy <guy>
Wed, 19 Nov 2003 00:17:32 +0000 (00:17 +0000)
committerguy <guy>
Wed, 19 Nov 2003 00:17:32 +0000 (00:17 +0000)
run past the end of that payload.

Check that the IPv4 total length isn't less than the header length.

Use "%u", not "%d", to print unsigned values.

Properly update "len" in the header-processing loop for IPv6.

Doing so means we can trust the length passed to the TCP and UDP
dissectors when constructing the IPv6 pseudo-header; do so (but fix the
length we pass to the UDP-over-IPv6 checksum routine).

That length is unsigned; make the corresponding arguments to the TCP and
UDP checksum routines unsigned.

print-ip.c
print-ip6.c
print-tcp.c
print-udp.c

index 2d287d36263ccd4555d37ef89a991020208d5ce5..3be2a6888eaa8ae9f84a11400dac30e012f5f7e6 100644 (file)
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.130 2003-11-16 09:36:23 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.131 2003-11-19 00:17:32 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -358,6 +358,7 @@ ip_print(register const u_char *bp, register u_int length)
 {
        register const struct ip *ip;
        register u_int hlen, len, len0, off;
+       const u_char *ipend;
        register const u_char *cp;
        u_char nh;
        int advance;
@@ -383,14 +384,26 @@ ip_print(register const u_char *bp, register u_int length)
        }
        hlen = IP_HL(ip) * 4;
        if (hlen < sizeof (struct ip)) {
-               (void)printf("bad-hlen %d", hlen);
+               (void)printf("bad-hlen %u", hlen);
                return;
        }
 
        len = EXTRACT_16BITS(&ip->ip_len);
        if (length < len)
-               (void)printf("truncated-ip - %d bytes missing! ",
+               (void)printf("truncated-ip - %u bytes missing! ",
                        len - length);
+       if (len < hlen) {
+               (void)printf("bad-len %u", len);
+               return;
+       }
+
+       /*
+        * Cut off the snapshot length to the end of the IP payload.
+        */
+       ipend = bp + len;
+       if (ipend < snapend)
+               snapend = ipend;
+
        len -= hlen;
        len0 = len;
 
index 617ddeae4db9ed7c01eadb46851dc76b11aa345e..adfd8008e3cdd9318fbd1e8ba84eb03eee426615 100644 (file)
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-ip6.c,v 1.34 2003-11-16 09:36:24 guy Exp $";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-ip6.c,v 1.35 2003-11-19 00:17:32 guy Exp $";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -52,6 +52,7 @@ ip6_print(register const u_char *bp, register u_int length)
        register const struct ip6_hdr *ip6;
        register int advance;
        register u_int len;
+       const u_char *ipend;
        register const u_char *cp;
        int nh;
        int fragmented = 0;
@@ -64,17 +65,25 @@ ip6_print(register const u_char *bp, register u_int length)
                (void)printf("truncated-ip6 %d", length);
                return;
        }
-       advance = sizeof(struct ip6_hdr);
 
-       len = EXTRACT_16BITS(&ip6->ip6_plen);
-       if (length < len + advance)
+       len = EXTRACT_16BITS(&ip6->ip6_plen) + sizeof(struct ip6_hdr);
+       if (length < len)
                (void)printf("truncated-ip6 - %d bytes missing!",
-                       len + advance - length);
+                       len - length);
+
+       /*
+        * Cut off the snapshot length to the end of the IP payload.
+        */
+       ipend = bp + len;
+       if (ipend < snapend)
+               snapend = ipend;
 
        cp = (const u_char *)ip6;
+       advance = sizeof(struct ip6_hdr);
        nh = ip6->ip6_nxt;
        while (cp < snapend) {
                cp += advance;
+               len -= advance;
 
                if (cp == (const u_char *)(ip6 + 1) &&
                    nh != IPPROTO_TCP && nh != IPPROTO_UDP &&
index 44279215ddfb0125e6e1edd4cf9a15406f44bf7e..ccf8770665affe7520289a26ad1d64813398e359 100644 (file)
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.109 2003-11-16 09:36:39 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.110 2003-11-19 00:17:32 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -100,7 +100,7 @@ static struct tcp_seq_hash tcp_seq_hash[TSEQ_HASHSIZE];
 
 static int tcp_cksum(register const struct ip *ip,
                     register const struct tcphdr *tp,
-                    register int len)
+                    register u_int len)
 {
        union phu {
                struct phdr {
@@ -115,7 +115,7 @@ static int tcp_cksum(register const struct ip *ip,
        const u_int16_t *sp;
 
        /* pseudo-header.. */
-       phu.ph.len = htons(len);        /* XXX */
+       phu.ph.len = htons((u_int16_t)len);
        phu.ph.mbz = 0;
        phu.ph.proto = IPPROTO_TCP;
        memcpy(&phu.ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t));
@@ -131,9 +131,9 @@ static int tcp_cksum(register const struct ip *ip,
 
 #ifdef INET6
 static int tcp6_cksum(const struct ip6_hdr *ip6, const struct tcphdr *tp,
-       int len)
+       u_int len)
 {
-       size_t i, tlen;
+       size_t i;
        register const u_int16_t *sp;
        u_int32_t sum;
        union {
@@ -147,14 +147,11 @@ static int tcp6_cksum(const struct ip6_hdr *ip6, const struct tcphdr *tp,
                u_int16_t pa[20];
        } phu;
 
-       tlen = EXTRACT_16BITS(&ip6->ip6_plen) + sizeof(struct ip6_hdr) -
-           ((const char *)tp - (const char*)ip6);
-
        /* pseudo-header */
        memset(&phu, 0, sizeof(phu));
        phu.ph.ph_src = ip6->ip6_src;
        phu.ph.ph_dst = ip6->ip6_dst;
-       phu.ph.ph_len = htonl(tlen);
+       phu.ph.ph_len = htonl(len);
        phu.ph.ph_nxt = IPPROTO_TCP;
 
        sum = 0;
@@ -163,10 +160,10 @@ static int tcp6_cksum(const struct ip6_hdr *ip6, const struct tcphdr *tp,
 
        sp = (const u_int16_t *)tp;
 
-       for (i = 0; i < (tlen & ~1); i += 2)
+       for (i = 0; i < (len & ~1); i += 2)
                sum += *sp++;
 
-       if (tlen & 1)
+       if (len & 1)
                sum += htons((*(const u_int8_t *)sp) << 8);
 
        while (sum > 0xffff)
index 1f7816a6295a57fa0a725c365155e1bed979338d..1e620313fbd44743da3a7751f59c2bdb12c067c5 100644 (file)
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-udp.c,v 1.127 2003-11-18 23:26:38 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-udp.c,v 1.128 2003-11-19 00:17:33 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -285,7 +285,7 @@ rtcp_print(const u_char *hdr, const u_char *ep)
 
 static int udp_cksum(register const struct ip *ip,
                     register const struct udphdr *up,
-                    register int len)
+                    register u_int len)
 {
        union phu {
                struct phdr {
@@ -300,7 +300,7 @@ static int udp_cksum(register const struct ip *ip,
        register const u_int16_t *sp;
 
        /* pseudo-header.. */
-       phu.ph.len = htons(len);
+       phu.ph.len = htons((u_int16_t)len);
        phu.ph.mbz = 0;
        phu.ph.proto = IPPROTO_UDP;
        memcpy(&phu.ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t));
@@ -316,9 +316,9 @@ static int udp_cksum(register const struct ip *ip,
 
 #ifdef INET6
 static int udp6_cksum(const struct ip6_hdr *ip6, const struct udphdr *up,
-       int len)
+       u_int len)
 {
-       int i, tlen;
+       int i;
        register const u_int16_t *sp;
        u_int32_t sum;
        union {
@@ -332,14 +332,11 @@ static int udp6_cksum(const struct ip6_hdr *ip6, const struct udphdr *up,
                u_int16_t pa[20];
        } phu;
 
-       tlen = EXTRACT_16BITS(&ip6->ip6_plen) + sizeof(struct ip6_hdr) -
-           ((const char *)up - (const char*)ip6);
-
        /* pseudo-header */
        memset(&phu, 0, sizeof(phu));
        phu.ph.ph_src = ip6->ip6_src;
        phu.ph.ph_dst = ip6->ip6_dst;
-       phu.ph.ph_len = htonl(tlen);
+       phu.ph.ph_len = htonl(len);
        phu.ph.ph_nxt = IPPROTO_UDP;
 
        sum = 0;
@@ -348,10 +345,10 @@ static int udp6_cksum(const struct ip6_hdr *ip6, const struct udphdr *up,
 
        sp = (const u_int16_t *)up;
 
-       for (i = 0; i < (tlen & ~1); i += 2)
+       for (i = 0; i < (len & ~1); i += 2)
                sum += *sp++;
 
-       if (tlen & 1)
+       if (len & 1)
                sum += htons((*(const u_int8_t *)sp) << 8);
 
        while (sum > 0xffff)
@@ -588,7 +585,7 @@ udp_print(register const u_char *bp, u_int length,
                int sum = up->uh_sum;
                /* for IPv6, UDP checksum is mandatory */
                if (TTEST2(cp[0], length)) {
-                       sum = udp6_cksum(ip6, up, length);
+                       sum = udp6_cksum(ip6, up, length + sizeof(struct udphdr));
                        if (sum != 0)
                                (void)printf("[bad udp cksum %x!] ", sum);
                        else