#include "netdissect-stdinc.h"
-#include <string.h>
-
#include "netdissect.h"
#include "addrtoname.h"
#include "extract.h"
/*
* print the recorded route in an IP RR, LSRR or SSRR option.
*/
-static void
+static int
ip_printroute(netdissect_options *ndo,
const u_char *cp, u_int length)
{
if (length < 3) {
ND_PRINT(" [bad length %u]", length);
- return;
+ return (0);
}
if ((length + 1) & 3)
ND_PRINT(" [bad length %u]", length);
ND_PRINT(" [bad ptr %u]", GET_U_1(cp + 2));
for (len = 3; len < length; len += 4) {
+ ND_TCHECK_4(cp + len); /* Needed to print the IP addresses */
ND_PRINT(" %s", GET_IPADDR_STRING(cp + len));
if (ptr > len)
ND_PRINT(",");
}
+ return (0);
+
+trunc:
+ return (-1);
}
/*
case IPOPT_RR: /* fall through */
case IPOPT_SSRR:
case IPOPT_LSRR:
- ip_printroute(ndo, cp, option_len);
+ if (ip_printroute(ndo, cp, option_len) == -1)
+ goto trunc;
break;
case IPOPT_RA:
/*
* 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;
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
trunc:
nd_print_trunc(ndo);
- return;
}
void