]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-ip.c
Makefile.in: don't remove configure and config.h.in in make distclean.
[tcpdump] / print-ip.c
index 9e26d842459c9ec5f7dc794e7ac68de751bf12f7..23ba99c970075099b9e5a80a598967e2c4081b6e 100644 (file)
@@ -27,8 +27,6 @@
 
 #include "netdissect-stdinc.h"
 
-#include <string.h>
-
 #include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
@@ -66,13 +64,12 @@ ip_printroute(netdissect_options *ndo,
        }
        if ((length + 1) & 3)
                ND_PRINT(" [bad length %u]", length);
-       ND_TCHECK_1(cp + 2);
        ptr = GET_U_1(cp + 2) - 1;
        if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1)
                ND_PRINT(" [bad ptr %u]", GET_U_1(cp + 2));
 
        for (len = 3; len < length; len += 4) {
-               ND_TCHECK_4(cp + len);
+               ND_TCHECK_4(cp + len);  /* Needed to print the IP addresses */
                ND_PRINT(" %s", GET_IPADDR_STRING(cp + len));
                if (ptr > len)
                        ND_PRINT(",");
@@ -107,14 +104,12 @@ ip_finddst(netdissect_options *ndo,
        for (; length != 0; cp += len, length -= len) {
                int tt;
 
-               ND_TCHECK_1(cp);
                tt = GET_U_1(cp);
                if (tt == IPOPT_EOL)
                        break;
                else if (tt == IPOPT_NOP)
                        len = 1;
                else {
-                       ND_TCHECK_1(cp + 1);
                        len = GET_U_1(cp + 1);
                        if (len < 2)
                                break;
@@ -183,16 +178,13 @@ ip_printts(netdissect_options *ndo,
                return (0);
        }
        ND_PRINT(" TS{");
-       ND_TCHECK_1(cp + 3);
        hoplen = ((GET_U_1(cp + 3) & 0xF) != IPOPT_TS_TSONLY) ? 8 : 4;
        if ((length - 4) & (hoplen-1))
                ND_PRINT("[bad length %u]", length);
-       ND_TCHECK_1(cp + 2);
        ptr = GET_U_1(cp + 2) - 1;
        len = 0;
        if (ptr < 4 || ((ptr - 4) & (hoplen-1)) || ptr > length + 1)
                ND_PRINT("[bad ptr %u]", GET_U_1(cp + 2));
-       ND_TCHECK_1(cp + 3);
        switch (GET_U_1(cp + 3)&0xF) {
        case IPOPT_TS_TSONLY:
                ND_PRINT("TSONLY");
@@ -200,16 +192,7 @@ ip_printts(netdissect_options *ndo,
        case IPOPT_TS_TSANDADDR:
                ND_PRINT("TS+ADDR");
                break;
-       /*
-        * prespecified should really be 3, but some ones might send 2
-        * instead, and the IPOPT_TS_PRESPEC constant can apparently
-        * have both values, so we have to hard-code it here.
-        */
-
-       case 2:
-               ND_PRINT("PRESPEC2.0");
-               break;
-       case 3:                 /* IPOPT_TS_PRESPEC */
+       case IPOPT_TS_PRESPEC:
                ND_PRINT("PRESPEC");
                break;
        default:
@@ -257,7 +240,6 @@ ip_optprint(netdissect_options *ndo,
                ND_PRINT("%s", sep);
                sep = ",";
 
-               ND_TCHECK_1(cp);
                option_code = GET_U_1(cp);
 
                ND_PRINT("%s",
@@ -268,7 +250,6 @@ ip_optprint(netdissect_options *ndo,
                        option_len = 1;
 
                else {
-                       ND_TCHECK_1(cp + 1);
                        option_len = GET_U_1(cp + 1);
                        if (option_len < 2) {
                                ND_PRINT(" [bad length %u]", option_len);
@@ -396,7 +377,10 @@ ip_print(netdissect_options *ndo,
        /*
         * Cut off the snapshot length to the end of the IP payload.
         */
-       nd_push_snapend(ndo, bp + len);
+       if (!nd_push_snaplen(ndo, bp, len)) {
+               (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+                       "%s: can't push snaplen on buffer stack", __func__);
+       }
 
        len -= hlen;
 
@@ -490,8 +474,18 @@ ip_print(netdissect_options *ndo,
                                     GET_IPADDR_STRING(ip->ip_src),
                                     GET_IPADDR_STRING(ip->ip_dst));
                }
+               /*
+                * Do a bounds check before calling ip_demux_print().
+                * At least the header data is required.
+                */
+               if (!ND_TTEST_LEN((const u_char *)ip, hlen)) {
+                       ND_PRINT(" [remaining caplen(%u) < header length(%u)]",
+                                ND_BYTES_AVAILABLE_AFTER((const u_char *)ip),
+                                hlen);
+                       nd_trunc_longjmp(ndo);
+               }
                ip_demux_print(ndo, (const u_char *)ip + hlen, len, 4,
-                   off & IP_MF, GET_U_1(ip->ip_ttl), nh, bp);
+                              off & IP_MF, GET_U_1(ip->ip_ttl), nh, bp);
        } else {
                /*
                 * Ultra quiet now means that all this stuff should be
@@ -519,7 +513,6 @@ ip_print(netdissect_options *ndo,
 
 trunc:
        nd_print_trunc(ndo);
-       return;
 }
 
 void
@@ -531,7 +524,6 @@ ipN_print(netdissect_options *ndo, const u_char *bp, u_int length)
                return;
        }
 
-       ND_TCHECK_1(bp);
        switch (GET_U_1(bp) & 0xF0) {
        case 0x40:
                ip_print(ndo, bp, length);
@@ -543,9 +535,4 @@ ipN_print(netdissect_options *ndo, const u_char *bp, u_int length)
                ND_PRINT("unknown ip %u", (GET_U_1(bp) & 0xF0) >> 4);
                break;
        }
-       return;
-
-trunc:
-       nd_print_trunc(ndo);
-       return;
 }