]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-tcp.c
Process the flags even if parsing the full radiotap header fails.
[tcpdump] / print-tcp.c
index 7893f61da1ab978443d9c35f07b53617a82c5af9..1ef3961e8b2051e444c7b1f86742b2a32221aa1e 100644 (file)
@@ -156,37 +156,6 @@ static int tcp_cksum(register const struct ip *ip,
                         sp[0]+sp[1]+sp[2]+sp[3]+sp[4]+sp[5]);
 }
 
-#ifdef INET6
-static int tcp6_cksum(const struct ip6_hdr *ip6, const struct tcphdr *tp,
-                      u_int len)
-{
-        size_t i;
-        u_int32_t sum = 0;
-        union {
-                struct {
-                        struct in6_addr ph_src;
-                        struct in6_addr ph_dst;
-                        u_int32_t      ph_len;
-                        u_int8_t       ph_zero[3];
-                        u_int8_t       ph_nxt;
-                } ph;
-                u_int16_t pa[20];
-        } phu;
-
-        /* 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(len);
-        phu.ph.ph_nxt = IPPROTO_TCP;
-
-        for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++)
-                sum += phu.pa[i];
-
-        return in_cksum((u_short *)tp, len, sum);
-}
-#endif
-
 void
 tcp_print(register const u_char *bp, register u_int length,
          register const u_char *bp2, int fragmented)
@@ -325,7 +294,6 @@ tcp_print(register const u_char *bp, register u_int length,
                  * both directions).
                  */
 #ifdef INET6
-                memset(&tha, 0, sizeof(tha));
                 rev = 0;
                 if (ip6) {
                         src = &ip6->ip6_src;
@@ -346,6 +314,27 @@ tcp_print(register const u_char *bp, register u_int length,
                                 tha.port = sport << 16 | dport;
                         }
                 } else {
+                        /*
+                         * Zero out the tha structure; the src and dst
+                         * fields are big enough to hold an IPv6
+                         * address, but we only have IPv4 addresses
+                         * and thus must clear out the remaining 124
+                         * bits.
+                         *
+                         * XXX - should we just clear those bytes after
+                         * copying the IPv4 addresses, rather than
+                         * zeroing out the entire structure and then
+                         * overwriting some of the zeroes?
+                         *
+                         * XXX - this could fail if we see TCP packets
+                         * with an IPv6 address with the lower 124 bits
+                         * all zero and also see TCP packes with an
+                         * IPv4 address with the same 32 bits as the
+                         * upper 32 bits of the IPv6 address in question.
+                         * Can that happen?  Is it likely enough to be
+                         * an issue?
+                         */
+                        memset(&tha, 0, sizeof(tha));
                         src = &ip->ip_src;
                         dst = &ip->ip_dst;
                         if (sport > dport)
@@ -441,7 +430,7 @@ tcp_print(register const u_char *bp, register u_int length,
         if (IP_V(ip) == 6 && ip6->ip6_plen && vflag && !Kflag && !fragmented) {
                 u_int16_t sum,tcp_sum;
                 if (TTEST2(tp->th_sport, length)) {
-                        sum = tcp6_cksum(ip6, tp, length);
+                        sum = nextproto6_cksum(ip6, (u_short *)tp, length, IPPROTO_TCP);
                         (void)printf(", cksum 0x%04x",EXTRACT_16BITS(&tp->th_sum));
                         if (sum != 0) {
                                 tcp_sum = EXTRACT_16BITS(&tp->th_sum);
@@ -790,7 +779,7 @@ tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp,
                 ip6 = (struct ip6_hdr *)ip;
                 MD5_Update(&ctx, (char *)&ip6->ip6_src, sizeof(ip6->ip6_src));
                 MD5_Update(&ctx, (char *)&ip6->ip6_dst, sizeof(ip6->ip6_dst));
-                len32 = htonl(ntohs(ip6->ip6_plen));
+                len32 = htonl(EXTRACT_16BITS(&ip6->ip6_plen));
                 MD5_Update(&ctx, (char *)&len32, sizeof(len32));
                 nxt = 0;
                 MD5_Update(&ctx, (char *)&nxt, sizeof(nxt));