+ break;
+
+ case IPPROTO_PGM:
+ pgm_print(ndo, ipds->cp, ipds->len, (const u_char *)ipds->ip);
+ break;
+
+ default:
+ if (ndo->ndo_nflag==0 && (proto = getprotobynumber(ipds->nh)) != NULL)
+ ND_PRINT((ndo, " %s", proto->p_name));
+ else
+ ND_PRINT((ndo, " ip-proto-%d", ipds->nh));
+ ND_PRINT((ndo, " %d", ipds->len));
+ break;
+ }
+}
+
+void
+ip_print_inner(netdissect_options *ndo,
+ const u_char *bp,
+ u_int length, u_int nh,
+ const u_char *bp2)
+{
+ struct ip_print_demux_state ipd;
+
+ ipd.ip = (const struct ip *)bp2;
+ ipd.cp = bp;
+ ipd.len = length;
+ ipd.off = 0;
+ ipd.nh = nh;
+ ipd.advance = 0;
+
+ ip_print_demux(ndo, &ipd);
+}
+
+
+/*
+ * print an IP datagram.
+ */
+void
+ip_print(netdissect_options *ndo,
+ const u_char *bp,
+ u_int length)
+{
+ struct ip_print_demux_state ipd;
+ struct ip_print_demux_state *ipds=&ipd;
+ const u_char *ipend;
+ u_int hlen;
+ struct cksum_vec vec[1];
+ uint16_t sum, ip_sum;
+ struct protoent *proto;
+
+ ipds->ip = (const struct ip *)bp;
+ ND_TCHECK(ipds->ip->ip_vhl);
+ if (IP_V(ipds->ip) != 4) { /* print version if != 4 */
+ if (IP_V(ipds->ip) == 6)
+ ND_PRINT((ndo, "IP6, wrong link-layer encapsulation "));
+ else
+ ND_PRINT((ndo, "IP%u ", IP_V(ipds->ip)));
+ }
+ else if (!ndo->ndo_eflag)
+ ND_PRINT((ndo, "IP "));
+
+ ND_TCHECK(*ipds->ip);
+ if (length < sizeof (struct ip)) {
+ ND_PRINT((ndo, "truncated-ip %u", length));
+ return;
+ }
+ hlen = IP_HL(ipds->ip) * 4;
+ if (hlen < sizeof (struct ip)) {
+ ND_PRINT((ndo, "bad-hlen %u", hlen));
+ return;
+ }
+
+ ipds->len = EXTRACT_16BITS(&ipds->ip->ip_len);
+ if (length < ipds->len)
+ ND_PRINT((ndo, "truncated-ip - %u bytes missing! ",
+ ipds->len - length));
+ if (ipds->len < hlen) {
+#ifdef GUESS_TSO
+ if (ipds->len) {
+ ND_PRINT((ndo, "bad-len %u", ipds->len));
+ return;
+ }
+ else {
+ /* we guess that it is a TSO send */
+ ipds->len = length;
+ }
+#else
+ ND_PRINT((ndo, "bad-len %u", ipds->len));
+ return;
+#endif /* GUESS_TSO */