]> 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 a701fede62d5b0bfa844b27a31ed2551497372f0..23ba99c970075099b9e5a80a598967e2c4081b6e 100644 (file)
@@ -27,8 +27,6 @@
 
 #include "netdissect-stdinc.h"
 
-#include <string.h>
-
 #include "netdissect.h"
 #include "addrtoname.h"
 #include "extract.h"
@@ -66,14 +64,13 @@ 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_PRINT(" %s", ipaddr_string(ndo, 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;
@@ -141,13 +136,13 @@ trunc:
 uint16_t
 nextproto4_cksum(netdissect_options *ndo,
                  const struct ip *ip, const uint8_t *data,
-                 u_int len, u_int covlen, u_int next_proto)
+                 u_int len, u_int covlen, uint8_t next_proto)
 {
        struct phdr {
                uint32_t src;
                uint32_t dst;
-               u_char mbz;
-               u_char proto;
+               uint8_t mbz;
+               uint8_t proto;
                uint16_t len;
        } ph;
        struct cksum_vec vec[2];
@@ -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:
@@ -223,7 +206,7 @@ ip_printts(netdissect_options *ndo,
                        type = " ^ ";
                ND_TCHECK_LEN(cp + len, hoplen);
                ND_PRINT("%s%u@%s", type, GET_BE_U_4(cp + len + hoplen - 4),
-                         hoplen!=8 ? "" : ipaddr_string(ndo, cp + len));
+                         hoplen!=8 ? "" : GET_IPADDR_STRING(cp + len));
                type = " ";
        }
 
@@ -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);
@@ -340,7 +321,6 @@ ip_print(netdissect_options *ndo,
         u_int length)
 {
        const struct ip *ip;
-       const u_char *ipend;
        u_int off;
        u_int hlen;
        u_int len;
@@ -397,9 +377,10 @@ ip_print(netdissect_options *ndo,
        /*
         * Cut off the snapshot length to the end of the IP payload.
         */
-       ipend = bp + len;
-       if (ipend < ndo->ndo_snapend)
-               ndo->ndo_snapend = ipend;
+       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;
 
@@ -471,9 +452,11 @@ ip_print(netdissect_options *ndo,
            ND_PRINT(")\n    ");
            if (truncated) {
                ND_PRINT("%s > %s: ",
-                        ipaddr_string(ndo, ip->ip_src),
-                        ipaddr_string(ndo, ip->ip_dst));
-               goto trunc;
+                        GET_IPADDR_STRING(ip->ip_src),
+                        GET_IPADDR_STRING(ip->ip_dst));
+               nd_print_trunc(ndo);
+               nd_pop_packet_info(ndo);
+               return;
            }
        }
 
@@ -483,53 +466,64 @@ ip_print(netdissect_options *ndo,
         * fragments.
         */
        if ((off & IP_OFFMASK) == 0) {
-               u_int nh = GET_U_1(ip->ip_p);
+               uint8_t nh = GET_U_1(ip->ip_p);
 
                if (nh != IPPROTO_TCP && nh != IPPROTO_UDP &&
                    nh != IPPROTO_SCTP && nh != IPPROTO_DCCP) {
                        ND_PRINT("%s > %s: ",
-                                    ipaddr_string(ndo, ip->ip_src),
-                                    ipaddr_string(ndo, ip->ip_dst));
+                                    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_print_demux(ndo, (const u_char *)ip + hlen, len, 4,
-                   off & IP_MF, GET_U_1(ip->ip_ttl), nh, bp);
+               ip_demux_print(ndo, (const u_char *)ip + hlen, len, 4,
+                              off & IP_MF, GET_U_1(ip->ip_ttl), nh, bp);
        } else {
                /*
                 * Ultra quiet now means that all this stuff should be
                 * suppressed.
                 */
-               if (ndo->ndo_qflag > 1)
+               if (ndo->ndo_qflag > 1) {
+                       nd_pop_packet_info(ndo);
                        return;
+               }
 
                /*
                 * This isn't the first frag, so we're missing the
                 * next level protocol header.  print the ip addr
                 * and the protocol.
                 */
-               ND_PRINT("%s > %s:", ipaddr_string(ndo, ip->ip_src),
-                         ipaddr_string(ndo, ip->ip_dst));
+               ND_PRINT("%s > %s:", GET_IPADDR_STRING(ip->ip_src),
+                         GET_IPADDR_STRING(ip->ip_dst));
                if (!ndo->ndo_nflag && (p_name = netdb_protoname(ip_proto)) != NULL)
                        ND_PRINT(" %s", p_name);
                else
                        ND_PRINT(" ip-proto-%u", ip_proto);
        }
+       nd_pop_packet_info(ndo);
        return;
 
 trunc:
        nd_print_trunc(ndo);
-       return;
 }
 
 void
 ipN_print(netdissect_options *ndo, const u_char *bp, u_int length)
 {
-       ndo->ndo_protocol = "ipN";
+       ndo->ndo_protocol = "ipn";
        if (length < 1) {
                ND_PRINT("truncated-ip %u", length);
                return;
        }
 
-       ND_TCHECK_1(bp);
        switch (GET_U_1(bp) & 0xF0) {
        case 0x40:
                ip_print(ndo, bp, length);
@@ -541,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;
 }