/* \summary: IP printer */
-#ifdef HAVE_CONFIG_H
#include <config.h>
-#endif
#include "netdissect-stdinc.h"
void
ip_print(netdissect_options *ndo,
const u_char *bp,
- u_int length)
+ const u_int length)
{
const struct ip *ip;
u_int off;
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;
ND_ICHECK_ZU(length, <, sizeof (struct ip));
ND_ICHECKMSG_U("version", IP_V(ip), !=, 4);
- ND_TCHECK_SIZE(ip);
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__);
}
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) {