-struct ip_print_demux_state {
- const struct ip *ip;
- const u_char *cp;
- u_int len, off;
- u_char nh;
- int advance;
-};
-
-static void
-ip_print_demux(netdissect_options *ndo,
- struct ip_print_demux_state *ipds)
-{
- struct protoent *proto;
- struct cksum_vec vec[1];
-
-again:
- switch (ipds->nh) {
-
- case IPPROTO_AH:
- ipds->nh = *ipds->cp;
- ipds->advance = ah_print(ndo, ipds->cp);
- if (ipds->advance <= 0)
- break;
- ipds->cp += ipds->advance;
- ipds->len -= ipds->advance;
- goto again;
-
- case IPPROTO_ESP:
- {
- int enh, padlen;
- ipds->advance = esp_print(ndo, ipds->cp, ipds->len,
- (const u_char *)ipds->ip,
- &enh, &padlen);
- if (ipds->advance <= 0)
- break;
- ipds->cp += ipds->advance;
- ipds->len -= ipds->advance + padlen;
- ipds->nh = enh & 0xff;
- goto again;
- }
-
- case IPPROTO_IPCOMP:
- {
- int enh;
- ipds->advance = ipcomp_print(ndo, ipds->cp, &enh);
- if (ipds->advance <= 0)
- break;
- ipds->cp += ipds->advance;
- ipds->len -= ipds->advance;
- ipds->nh = enh & 0xff;
- goto again;
- }
-
- case IPPROTO_SCTP:
- sctp_print(ndo, ipds->cp, (const u_char *)ipds->ip, ipds->len);
- break;
-
- case IPPROTO_DCCP:
- dccp_print(ndo, ipds->cp, (const u_char *)ipds->ip, ipds->len);
- break;
-
- case IPPROTO_TCP:
- /* pass on the MF bit plus the offset to detect fragments */
- tcp_print(ndo, ipds->cp, ipds->len, (const u_char *)ipds->ip,
- ipds->off & (IP_MF|IP_OFFMASK));
- break;
-
- case IPPROTO_UDP:
- /* pass on the MF bit plus the offset to detect fragments */
- udp_print(ndo, ipds->cp, ipds->len, (const u_char *)ipds->ip,
- ipds->off & (IP_MF|IP_OFFMASK));
- break;
-
- case IPPROTO_ICMP:
- /* pass on the MF bit plus the offset to detect fragments */
- icmp_print(ndo, ipds->cp, ipds->len, (const u_char *)ipds->ip,
- ipds->off & (IP_MF|IP_OFFMASK));
- break;
-
- case IPPROTO_PIGP:
- /*
- * XXX - the current IANA protocol number assignments
- * page lists 9 as "any private interior gateway
- * (used by Cisco for their IGRP)" and 88 as
- * "EIGRP" from Cisco.
- *
- * Recent BSD <netinet/in.h> headers define
- * IP_PROTO_PIGP as 9 and IP_PROTO_IGRP as 88.
- * We define IP_PROTO_PIGP as 9 and
- * IP_PROTO_EIGRP as 88; those names better
- * match was the current protocol number
- * assignments say.
- */
- igrp_print(ndo, ipds->cp, ipds->len);
- break;
-
- case IPPROTO_EIGRP:
- eigrp_print(ndo, ipds->cp, ipds->len);
- break;
-
- case IPPROTO_ND:
- ND_PRINT((ndo, " nd %d", ipds->len));
- break;
-
- case IPPROTO_EGP:
- egp_print(ndo, ipds->cp, ipds->len);
- break;
-
- case IPPROTO_OSPF:
- ospf_print(ndo, ipds->cp, ipds->len, (const u_char *)ipds->ip);
- break;
-
- case IPPROTO_IGMP:
- igmp_print(ndo, ipds->cp, ipds->len);
- break;
-
- case IPPROTO_IPV4:
- /* DVMRP multicast tunnel (ip-in-ip encapsulation) */
- ip_print(ndo, ipds->cp, ipds->len);
- if (! ndo->ndo_vflag) {
- ND_PRINT((ndo, " (ipip-proto-4)"));
- return;
- }
- break;
-
- case IPPROTO_IPV6:
- /* ip6-in-ip encapsulation */
- ip6_print(ndo, ipds->cp, ipds->len);
- break;
-
- case IPPROTO_RSVP:
- rsvp_print(ndo, ipds->cp, ipds->len);
- break;
-
- case IPPROTO_GRE:
- /* do it */
- gre_print(ndo, ipds->cp, ipds->len);
- break;
-
- case IPPROTO_MOBILE:
- mobile_print(ndo, ipds->cp, ipds->len);
- break;
-
- case IPPROTO_PIM:
- vec[0].ptr = ipds->cp;
- vec[0].len = ipds->len;
- pim_print(ndo, ipds->cp, ipds->len, in_cksum(vec, 1));
- break;
-
- case IPPROTO_VRRP:
- if (ndo->ndo_packettype == PT_CARP) {
- if (ndo->ndo_vflag)
- ND_PRINT((ndo, "carp %s > %s: ",
- ipaddr_string(ndo, &ipds->ip->ip_src),
- ipaddr_string(ndo, &ipds->ip->ip_dst)));
- carp_print(ndo, ipds->cp, ipds->len, ipds->ip->ip_ttl);
- } else {
- if (ndo->ndo_vflag)
- ND_PRINT((ndo, "vrrp %s > %s: ",
- ipaddr_string(ndo, &ipds->ip->ip_src),
- ipaddr_string(ndo, &ipds->ip->ip_dst)));
- vrrp_print(ndo, ipds->cp, ipds->len,
- (const u_char *)ipds->ip, ipds->ip->ip_ttl);
- }
- 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);
-}
-