]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-ip.c
CMake: Fix the comment about versions. [skip ci]
[tcpdump] / print-ip.c
index 23ba99c970075099b9e5a80a598967e2c4081b6e..a332bd7885fe4f77f84f74944068dafadab93d20 100644 (file)
@@ -21,9 +21,7 @@
 
 /* \summary: IP printer */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
-#endif
 
 #include "netdissect-stdinc.h"
 
@@ -318,7 +316,7 @@ static const struct tok ip_frag_values[] = {
 void
 ip_print(netdissect_options *ndo,
         const u_char *bp,
-        u_int length)
+        const u_int length)
 {
        const struct ip *ip;
        u_int off;
@@ -329,55 +327,42 @@ ip_print(netdissect_options *ndo,
        uint16_t sum, ip_sum;
        const char *p_name;
        int truncated = 0;
+       int presumed_tso = 0;
 
        ndo->ndo_protocol = "ip";
        ip = (const struct ip *)bp;
-       if (IP_V(ip) != 4) { /* print version and fail if != 4 */
-           if (IP_V(ip) == 6)
-             ND_PRINT("IP6, wrong link-layer encapsulation");
-           else
-             ND_PRINT("IP%u", IP_V(ip));
-           nd_print_invalid(ndo);
-           return;
-       }
-       if (!ndo->ndo_eflag)
-               ND_PRINT("IP ");
 
-       ND_TCHECK_SIZE(ip);
-       if (length < sizeof (struct ip)) {
-               ND_PRINT("truncated-ip %u", length);
-               return;
+       if (!ndo->ndo_eflag) {
+               nd_print_protocol_caps(ndo);
+               ND_PRINT(" ");
        }
+
+       ND_ICHECK_ZU(length, <, sizeof (struct ip));
+       ND_ICHECKMSG_U("version", IP_V(ip), !=, 4);
+
        hlen = IP_HL(ip) * 4;
-       if (hlen < sizeof (struct ip)) {
-               ND_PRINT("bad-hlen %u", hlen);
-               return;
-       }
+       ND_ICHECKMSG_ZU("header length", hlen, <, sizeof (struct ip));
 
        len = GET_BE_U_2(ip->ip_len);
-       if (length < len)
-               ND_PRINT("truncated-ip - %u bytes missing! ",
-                       len - length);
-       if (len < hlen) {
-#ifdef GUESS_TSO
-            if (len) {
-                ND_PRINT("bad-len %u", len);
-                return;
-            }
-            else {
-                /* we guess that it is a TSO send */
-                len = length;
-            }
-#else
-            ND_PRINT("bad-len %u", len);
-            return;
-#endif /* GUESS_TSO */
+       if (len > length) {
+               ND_PRINT("[total length %u > length %u]", len, length);
+               nd_print_invalid(ndo);
+               ND_PRINT(" ");
        }
+       if (len == 0) {
+               /* we guess that it is a TSO send */
+               len = length;
+               presumed_tso = 1;
+       } else
+               ND_ICHECKMSG_U("total length", len, <, hlen);
 
+       ND_TCHECK_SIZE(ip);
        /*
-        * Cut off the snapshot length to the end of the IP payload.
+        * Cut off the snapshot length to the end of the IP payload
+        * or the end of the data in which it's contained, whichever
+        * comes first.
         */
-       if (!nd_push_snaplen(ndo, bp, len)) {
+       if (!nd_push_snaplen(ndo, bp, ND_MIN(length, len))) {
                (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
                        "%s: can't push snaplen on buffer stack", __func__);
        }
@@ -426,9 +411,12 @@ ip_print(netdissect_options *ndo,
                          tok2str(ipproto_values, "unknown", ip_proto),
                          ip_proto);
 
-            ND_PRINT(", length %u", GET_BE_U_2(ip->ip_len));
+           if (presumed_tso)
+                ND_PRINT(", length %u [was 0, presumed TSO]", length);
+           else
+                ND_PRINT(", length %u", GET_BE_U_2(ip->ip_len));
 
-            if ((hlen - sizeof(struct ip)) > 0) {
+            if ((hlen > sizeof(struct ip))) {
                 ND_PRINT(", options (");
                 if (ip_optprint(ndo, (const u_char *)(ip + 1),
                     hlen - sizeof(struct ip)) == -1) {
@@ -513,6 +501,10 @@ ip_print(netdissect_options *ndo,
 
 trunc:
        nd_print_trunc(ndo);
+       return;
+
+invalid:
+       nd_print_invalid(ndo);
 }
 
 void