]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-tcp.c
Fix the pointer tests in the non-ndoified TTEST2() macro as well.
[tcpdump] / print-tcp.c
index b34be32d8ac02bda5b387ba2ae0112300ca7aa49..e2559ecf64ca0335eabd3db96303d0570c44942e 100644 (file)
@@ -25,8 +25,8 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-"@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.131 2007-11-09 00:34:25 guy Exp $ (LBL)";
-  #else
+"@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.135 2008-11-09 23:35:03 mcr Exp $ (LBL)";
+#else
 __RCSID("$NetBSD: print-tcp.c,v 1.8 2007/07/24 11:53:48 drochner Exp $");
 #endif
 
@@ -58,10 +58,7 @@ __RCSID("$NetBSD: print-tcp.c,v 1.8 2007/07/24 11:53:48 drochner Exp $");
 
 #ifdef HAVE_LIBCRYPTO
 #include <openssl/md5.h>
-
-#define SIGNATURE_VALID                0
-#define SIGNATURE_INVALID      1
-#define CANT_CHECK_SIGNATURE   2
+#include <signature.h>
 
 static int tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp,
                                 const u_char *data, int length, const u_char *rcvsig);
@@ -124,6 +121,7 @@ struct tok tcp_option_values[] = {
         { TCPOPT_CCECHO, "" },
         { TCPOPT_SIGNATURE, "md5" },
         { TCPOPT_AUTH, "enhanced auth" },
+        { TCPOPT_UTO, "uto" },
         { 0, NULL }
 };
 
@@ -158,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)
@@ -200,6 +167,7 @@ tcp_print(register const u_char *bp, register u_int length,
         register char ch;
         u_int16_t sport, dport, win, urp;
         u_int32_t seq, ack, thseq, thack;
+        u_int utoval;
         int threv;
 #ifdef INET6
         register const struct ip6_hdr *ip6;
@@ -227,23 +195,39 @@ tcp_print(register const u_char *bp, register u_int length,
         hlen = TH_OFF(tp) * 4;
 
         /*
-         * If data present, header length valid, and NFS port used,
-         * assume NFS.
-         * Pass offset of data plus 4 bytes for RPC TCP msg length
-         * to NFS print routines.
-         */
-        if (!qflag && hlen >= sizeof(*tp) && hlen <= length) {
-                if ((u_char *)tp + 4 + sizeof(struct sunrpc_msg) <= snapend &&
-                    dport == NFS_PORT) {
-                        nfsreq_print((u_char *)tp + hlen + 4, length - hlen,
-                                     (u_char *)ip);
-                        return;
-                } else if ((u_char *)tp + 4 + sizeof(struct sunrpc_msg)
-                           <= snapend &&
-                           sport == NFS_PORT) {
-                        nfsreply_print((u_char *)tp + hlen + 4, length - hlen,
-                                       (u_char *)ip);
-                        return;
+        * If data present, header length valid, and NFS port used,
+        * assume NFS.
+        * Pass offset of data plus 4 bytes for RPC TCP msg length
+        * to NFS print routines.
+        */
+       if (!qflag && hlen >= sizeof(*tp) && hlen <= length &&
+           (length - hlen) >= 4) {
+               u_char *fraglenp;
+               u_int32_t fraglen;
+               register struct sunrpc_msg *rp;
+               enum sunrpc_msg_type direction;
+
+               fraglenp = (u_char *)tp + hlen;
+               if (TTEST2(*fraglenp, 4)) {
+                       fraglen = EXTRACT_32BITS(fraglenp) & 0x7FFFFFFF;
+                       if (fraglen > (length - hlen) - 4)
+                               fraglen = (length - hlen) - 4;
+                       rp = (struct sunrpc_msg *)(fraglenp + 4);
+                       if (TTEST(rp->rm_direction)) {
+                               direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction);
+                               if (dport == NFS_PORT &&
+                                   direction == SUNRPC_CALL) {
+                                       nfsreq_print((u_char *)rp, fraglen,
+                                           (u_char *)ip);
+                                       return;
+                               }
+                               if (sport == NFS_PORT &&
+                                   direction == SUNRPC_REPLY) {
+                                       nfsreply_print((u_char *)rp, fraglen,
+                                           (u_char *)ip);
+                                       return;
+                               }
+                       }
                 }
         }
 #ifdef INET6
@@ -426,7 +410,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);
@@ -439,7 +423,7 @@ tcp_print(register const u_char *bp, register u_int length,
 #endif
 
         length -= hlen;
-        if (vflag > 1 || flags & (TH_SYN | TH_FIN | TH_RST)) {
+        if (vflag > 1 || length > 0 || flags & (TH_SYN | TH_FIN | TH_RST)) {
                 (void)printf(", seq %u", seq);
 
                 if (length > 0) {
@@ -597,6 +581,18 @@ tcp_print(register const u_char *bp, register u_int length,
                                  */
                                 break;
 
+                        case TCPOPT_UTO:
+                                datalen = 2;
+                                LENCHECK(datalen);
+                                utoval = EXTRACT_16BITS(cp);
+                                (void)printf("0x%x", utoval);
+                                if (utoval & 0x0001)
+                                        utoval = (utoval >> 1) * 60;
+                                else
+                                        utoval >>= 1;
+                                (void)printf(" %u", utoval);
+                                break;
+
                         default:
                                 datalen = len - 2;
                                 for (i = 0; i < datalen; ++i) {
@@ -650,6 +646,8 @@ tcp_print(register const u_char *bp, register u_int length,
 #ifdef TCPDUMP_DO_SMB
         else if (sport == NETBIOS_SSN_PORT || dport == NETBIOS_SSN_PORT)
                 nbt_tcp_print(bp, length);
+       else if (sport == SMB_PORT || dport == SMB_PORT)
+               smb_tcp_print(bp, length);
 #endif
         else if (sport == BEEP_PORT || dport == BEEP_PORT)
                 beep_print(bp, length);
@@ -732,10 +730,17 @@ tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp,
         u_int8_t nxt;
 #endif
 
+       if (data + length > snapend) {
+               printf("snaplen too short, ");
+               return (CANT_CHECK_SIGNATURE);
+       }
+
         tp1 = *tp;
 
-        if (tcpmd5secret == NULL)
+        if (sigsecret == NULL) {
+               printf("shared secret not supplied with -M, ");
                 return (CANT_CHECK_SIGNATURE);
+        }
 
         MD5_Init(&ctx);
         /*
@@ -754,7 +759,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));
@@ -763,8 +768,14 @@ tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp,
                 nxt = IPPROTO_TCP;
                 MD5_Update(&ctx, (char *)&nxt, sizeof(nxt));
 #endif
-        } else
+        } else {
+#ifdef INET6
+               printf("IP version not 4 or 6, ");
+#else
+               printf("IP version not 4, ");
+#endif
                 return (CANT_CHECK_SIGNATURE);
+        }
 
         /*
          * Step 2: Update MD5 hash with TCP header, excluding options.
@@ -782,7 +793,7 @@ tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp,
         /*
          * Step 4: Update MD5 hash with shared secret.
          */
-        MD5_Update(&ctx, tcpmd5secret, strlen(tcpmd5secret));
+        MD5_Update(&ctx, sigsecret, strlen(sigsecret));
         MD5_Final(sig, &ctx);
 
         if (memcmp(rcvsig, sig, TCP_SIGLEN) == 0)