#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.116 2002-10-18 04:40:03 itojun Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.125 2003-05-21 08:39:57 hannes Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
return shouldbe;
}
+#ifndef IP_MF
+#define IP_MF 0x2000
+#endif /* IP_MF */
+#ifndef IP_DF
+#define IP_DF 0x4000
+#endif /* IP_DF */
+#define IP_RES 0x8000
+
+static struct tok ip_frag_values[] = {
+ { IP_MF, "+" },
+ { IP_DF, "DF" },
+ { IP_RES, "rsvd" }, /* The RFC3514 evil ;-) bit */
+ { 0, NULL }
+};
+
/*
* print an IP datagram.
*/
u_char nh;
int advance;
struct protoent *proto;
+ u_int16_t sum, ip_sum;
+ const char *sep = "";
+
+ printf("IP%s ", (((*bp >> 4) & 0xf) == 4) ? "" : "%u", (*bp >> 4) & 0xf); /* print version if != 4 */
ip = (const struct ip *)bp;
if ((u_char *)(ip + 1) > snapend) {
return;
}
- len = ntohs(ip->ip_len);
+ len = EXTRACT_16BITS(&ip->ip_len);
if (length < len)
(void)printf("truncated-ip - %d bytes missing! ",
len - length);
len -= hlen;
len0 = len;
- printf("IP ");
-
- off = ntohs(ip->ip_off);
+ off = EXTRACT_16BITS(&ip->ip_off);
if (vflag) {
(void)printf("(tos 0x%x", (int)ip->ip_tos);
}
if (ip->ip_ttl >= 1)
- (void)printf(", ttl %d", (int)ip->ip_ttl);
+ (void)printf(", ttl %3u", ip->ip_ttl);
+
+ /*
+ * for the firewall guys, print id, offset.
+ * On all but the last stick a "+" in the flags portion.
+ * For unfragmented datagrams, note the don't fragment flag.
+ */
+
+ (void)printf(", id %u, offset %u, flags [%s]",
+ EXTRACT_16BITS(&ip->ip_id),
+ (off & 0x1fff) * 8,
+ bittok2str(ip_frag_values, "none", off & 0xe000 ));
- if ((off & 0x3fff) == 0)
- (void)printf(", id %d", (int)ntohs(ip->ip_id));
- (void)printf(", len %d) ", (int)ntohs(ip->ip_len));
+ (void)printf(", length: %u", EXTRACT_16BITS(&ip->ip_len));
+
+ if ((hlen - sizeof(struct ip)) > 0) {
+ (void)printf(", optlength: %u (", hlen - (u_int)sizeof(struct ip));
+ ip_optprint((u_char *)(ip + 1), hlen - sizeof(struct ip));
+ printf(" )");
+ }
+
+ if ((u_char *)ip + hlen <= snapend) {
+ sum = in_cksum((const u_short *)ip, hlen, 0);
+ if (sum != 0) {
+ ip_sum = EXTRACT_16BITS(&ip->ip_sum);
+ (void)printf("%sbad cksum %x (->%x)!", sep,
+ ip_sum,
+ in_cksum_shouldbe(ip_sum, sum));
+ sep = ", ";
+ }
+ }
+
+ printf(") ");
}
/*
break;
case IPPROTO_ICMP:
- icmp_print(cp, len, (const u_char *)ip);
+ /* pass on the MF bit plus the offset to detect fragments */
+ icmp_print(cp, len, (const u_char *)ip, (off & 0x3fff));
break;
#ifndef IPPROTO_IGRP
printf(" %d", len);
break;
}
+ } else {
+ /* Ultra quiet now means that all this stuff should be suppressed */
+ if (qflag > 1) return;
+
+ /*
+ * if this isn't the first frag, we're missing the
+ * next level protocol header. print the ip addr
+ * and the protocol.
+ */
+ if (off & 0x1fff) {
+ (void)printf("%s > %s:", ipaddr_string(&ip->ip_src),
+ ipaddr_string(&ip->ip_dst));
+ if ((proto = getprotobynumber(ip->ip_p)) != NULL)
+ (void)printf(" %s", proto->p_name);
+ else
+ (void)printf(" ip-proto-%d", ip->ip_p);
+ }
}
-
- /* Ultra quiet now means that all this stuff should be suppressed */
- /* res 3-Nov-98 */
- if (qflag > 1) return;
-
-
- /*
- * for fragmented datagrams, print id:size@offset. On all
- * but the last stick a "+". For unfragmented datagrams, note
- * the don't fragment flag.
- */
- len = len0; /* get the original length */
- if (off & 0x3fff) {
- /*
- * if this isn't the first frag, we're missing the
- * next level protocol header. print the ip addr
- * and the protocol.
- */
- if (off & 0x1fff) {
- (void)printf("%s > %s:", ipaddr_string(&ip->ip_src),
- ipaddr_string(&ip->ip_dst));
- if ((proto = getprotobynumber(ip->ip_p)) != NULL)
- (void)printf(" %s", proto->p_name);
- else
- (void)printf(" ip-proto-%d", ip->ip_p);
- }
-#ifndef IP_MF
-#define IP_MF 0x2000
-#endif /* IP_MF */
-#ifndef IP_DF
-#define IP_DF 0x4000
-#endif /* IP_DF */
- (void)printf(" (frag %d:%u@%d%s)", ntohs(ip->ip_id), len,
- (off & 0x1fff) * 8,
- (off & IP_MF)? "+" : "");
-
- } else if (off & IP_DF)
- (void)printf(" (DF)");
-
- if (vflag) {
- u_int16_t sum, ip_sum;
- const char *sep = "";
-
- if ((u_char *)ip + hlen <= snapend) {
- sum = in_cksum((const u_short *)ip, hlen, 0);
- if (sum != 0) {
- ip_sum = ntohs(ip->ip_sum);
- (void)printf("%sbad cksum %x (->%x)!", sep,
- ip_sum,
- in_cksum_shouldbe(ip_sum, sum));
- sep = ", ";
- }
- }
- if ((hlen -= sizeof(struct ip)) > 0) {
- (void)printf("%soptlen=%d", sep, hlen);
- ip_optprint((u_char *)(ip + 1), hlen);
- }
- }
-
}
void