+
+ off = GET_BE_U_2(ip->ip_off);
+
+ ip_proto = GET_U_1(ip->ip_p);
+
+ if (ndo->ndo_vflag) {
+ ip_tos = GET_U_1(ip->ip_tos);
+ ND_PRINT("(tos 0x%x", ip_tos);
+ /* ECN bits */
+ switch (ip_tos & 0x03) {
+
+ case 0:
+ break;
+
+ case 1:
+ ND_PRINT(",ECT(1)");
+ break;
+
+ case 2:
+ ND_PRINT(",ECT(0)");
+ break;
+
+ case 3:
+ ND_PRINT(",CE");
+ break;
+ }
+
+ ip_ttl = GET_U_1(ip->ip_ttl);
+ if (ip_ttl >= 1)
+ ND_PRINT(", ttl %u", 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.
+ */
+ ND_PRINT(", id %u, offset %u, flags [%s], proto %s (%u)",
+ GET_BE_U_2(ip->ip_id),
+ (off & IP_OFFMASK) * 8,
+ bittok2str(ip_frag_values, "none", off & (IP_RES|IP_DF|IP_MF)),
+ tok2str(ipproto_values, "unknown", ip_proto),
+ ip_proto);
+
+ 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) {
+ ND_PRINT(", options (");
+ if (ip_optprint(ndo, (const u_char *)(ip + 1),
+ hlen - sizeof(struct ip)) == -1) {
+ ND_PRINT(" [truncated-option]");
+ truncated = 1;
+ }
+ ND_PRINT(")");
+ }
+
+ if (!ndo->ndo_Kflag && (const u_char *)ip + hlen <= ndo->ndo_snapend) {
+ vec[0].ptr = (const uint8_t *)(const void *)ip;
+ vec[0].len = hlen;
+ sum = in_cksum(vec, 1);
+ if (sum != 0) {
+ ip_sum = GET_BE_U_2(ip->ip_sum);
+ ND_PRINT(", bad cksum %x (->%x)!", ip_sum,
+ in_cksum_shouldbe(ip_sum, sum));
+ }
+ }
+
+ ND_PRINT(")\n ");
+ if (truncated) {
+ ND_PRINT("%s > %s: ",
+ GET_IPADDR_STRING(ip->ip_src),
+ GET_IPADDR_STRING(ip->ip_dst));
+ nd_print_trunc(ndo);
+ nd_pop_packet_info(ndo);
+ return;
+ }
+ }