]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Check for a TCP header length that's too short, report more information
authorguy <guy>
Thu, 8 Jul 2004 10:29:40 +0000 (10:29 +0000)
committerguy <guy>
Thu, 8 Jul 2004 10:29:40 +0000 (10:29 +0000)
if it's too long, and check for NFS only if the header length is OK.

print-tcp.c

index 6af150caa97b7f82d4b1d9b6d65a608a1dc2c6c8..82a714d311da1c3bab9cc6137ab0b5169b67717d 100644 (file)
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.107.2.3 2003-11-19 00:17:02 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.107.2.4 2004-07-08 10:29:40 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -212,11 +212,12 @@ tcp_print(register const u_char *bp, register u_int length,
        hlen = TH_OFF(tp) * 4;
 
        /*
        hlen = TH_OFF(tp) * 4;
 
        /*
-        * If data present and NFS port used, assume NFS.
+        * 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.
         */
         * Pass offset of data plus 4 bytes for RPC TCP msg length
         * to NFS print routines.
         */
-       if (!qflag) {
+       if (!qflag && hlen >= sizeof(*tp) && hlen <= length) {
                if ((u_char *)tp + 4 + sizeof(struct rpc_msg) <= snapend &&
                    dport == NFS_PORT) {
                        nfsreq_print((u_char *)tp + hlen + 4, length - hlen,
                if ((u_char *)tp + 4 + sizeof(struct rpc_msg) <= snapend &&
                    dport == NFS_PORT) {
                        nfsreq_print((u_char *)tp + hlen + 4, length - hlen,
@@ -257,6 +258,12 @@ tcp_print(register const u_char *bp, register u_int length,
                }
        }
 
                }
        }
 
+       if (hlen < sizeof(*tp)) {
+               (void)printf(" tcp %d [bad hdr length %u - too short, < %u]",
+                   length - hlen, hlen, sizeof(*tp));
+               return;
+       }
+
        TCHECK(*tp);
 
        seq = EXTRACT_32BITS(&tp->th_seq);
        TCHECK(*tp);
 
        seq = EXTRACT_32BITS(&tp->th_seq);
@@ -265,7 +272,11 @@ tcp_print(register const u_char *bp, register u_int length,
        urp = EXTRACT_16BITS(&tp->th_urp);
 
        if (qflag) {
        urp = EXTRACT_16BITS(&tp->th_urp);
 
        if (qflag) {
-               (void)printf("tcp %d", length - TH_OFF(tp) * 4);
+               (void)printf("tcp %d", length - hlen);
+               if (hlen > length) {
+                       (void)printf(" [bad hdr length %u - too long, > %u]",
+                           hlen, length);
+               }
                return;
        }
        if ((flags = tp->th_flags) & (TH_SYN|TH_FIN|TH_RST|TH_PUSH|
                return;
        }
        if ((flags = tp->th_flags) & (TH_SYN|TH_FIN|TH_RST|TH_PUSH|
@@ -391,7 +402,8 @@ tcp_print(register const u_char *bp, register u_int length,
                thseq = thack = threv = 0;
        }
        if (hlen > length) {
                thseq = thack = threv = 0;
        }
        if (hlen > length) {
-               (void)printf(" [bad hdr length]");
+               (void)printf(" [bad hdr length %u - too long, > %u]",
+                   hlen, length);
                return;
        }
 
                return;
        }