summaryrefslogtreecommitdiff
path: root/print-ip6.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2019-03-27 19:58:26 -0700
committerGuy Harris <guy@alum.mit.edu>2019-03-27 19:58:26 -0700
commit202051bb55f5e99fb304c4b68cfb2a729fe2d55e (patch)
treea05c9dedb222085c1f4d5d59065a43f8f6a1f872 /print-ip6.c
parentb8964b5f43a1b3ec5d1a3a1ee6025d3d881354c9 (diff)
downloadtcpdump-202051bb55f5e99fb304c4b68cfb2a729fe2d55e.tar.gz
Put IPv4/IPv6 protocol demultiplexing into a common routine.
That means less duplication of functionality - and less chance that XXX-over-IPv4 will be handled but XXX-over-IPv6 won't be handled, or *vice versa*. (CARP and VRRP were being handled over IPv4 but not over IPv6; this fixes that.)
Diffstat (limited to 'print-ip6.c')
-rw-r--r--print-ip6.c91
1 files changed, 11 insertions, 80 deletions
diff --git a/print-ip6.c b/print-ip6.c
index 9802ce04..b6893cf3 100644
--- a/print-ip6.c
+++ b/print-ip6.c
@@ -281,6 +281,7 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
cp = (const u_char *)ip6;
advance = sizeof(struct ip6_hdr);
+ /* Process extension headers */
while (cp < ndo->ndo_snapend && advance > 0) {
if (len < (u_int)advance)
goto trunc;
@@ -295,18 +296,21 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
}
switch (nh) {
+
case IPPROTO_HOPOPTS:
advance = hbhopt_print(ndo, cp);
if (advance < 0)
return;
nh = GET_U_1(cp);
break;
+
case IPPROTO_DSTOPTS:
advance = dstopt_print(ndo, cp);
if (advance < 0)
return;
nh = GET_U_1(cp);
break;
+
case IPPROTO_FRAGMENT:
advance = frag6_print(ndo, cp, (const u_char *)ip6);
if (advance < 0 || ndo->ndo_snapend <= cp + advance)
@@ -330,6 +334,7 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
return;
nh = GET_U_1(cp);
return;
+
case IPPROTO_ROUTING:
ND_TCHECK_1(cp);
advance = rt6_print(ndo, cp, (const u_char *)ip6);
@@ -337,88 +342,14 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
return;
nh = GET_U_1(cp);
break;
- case IPPROTO_SCTP:
- sctp_print(ndo, cp, (const u_char *)ip6, len);
- return;
- case IPPROTO_DCCP:
- dccp_print(ndo, cp, (const u_char *)ip6, len);
- return;
- case IPPROTO_TCP:
- tcp_print(ndo, cp, len, (const u_char *)ip6, fragmented);
- return;
- case IPPROTO_UDP:
- udp_print(ndo, cp, len, (const u_char *)ip6, fragmented);
- return;
- case IPPROTO_ICMPV6:
- icmp6_print(ndo, cp, len, (const u_char *)ip6, fragmented);
- return;
- case IPPROTO_AH:
- advance = ah_print(ndo, cp);
- if (advance < 0)
- return;
- nh = GET_U_1(cp);
- break;
- case IPPROTO_ESP:
- {
- u_int enh, padlen;
- advance = esp_print(ndo, cp, len, (const u_char *)ip6, &enh, &padlen);
- if (advance < 0)
- return;
- nh = enh & 0xff;
- len -= padlen;
- break;
- }
- case IPPROTO_IPCOMP:
- {
- ipcomp_print(ndo, cp);
- /*
- * Either this has decompressed the payload and
- * printed it, in which case there's nothing more
- * to do, or it hasn't, in which case there's
- * nothing more to do.
- */
- advance = -1;
- break;
- }
-
- case IPPROTO_PIM:
- pim_print(ndo, cp, len, (const u_char *)ip6);
- return;
-
- case IPPROTO_OSPF:
- ospf6_print(ndo, cp, len);
- return;
-
- case IPPROTO_IPV6:
- ip6_print(ndo, cp, len);
- return;
-
- case IPPROTO_IPV4:
- ip_print(ndo, cp, len);
- return;
-
- case IPPROTO_PGM:
- pgm_print(ndo, cp, len, (const u_char *)ip6);
- return;
-
- case IPPROTO_GRE:
- gre_print(ndo, cp, len);
- return;
-
- case IPPROTO_RSVP:
- rsvp_print(ndo, cp, len);
- return;
-
- case IPPROTO_EIGRP:
- eigrp_print(ndo, cp, len);
- return;
-
- case IPPROTO_NONE:
- ND_PRINT("no next header");
- return;
default:
- ND_PRINT("ip-proto-%u %u", nh, len);
+ /*
+ * Not an extension header; hand off to the
+ * IP protocol demuxer.
+ */
+ ip_print_demux(ndo, cp, len, 6, fragmented,
+ GET_U_1(ip6->ip6_hlim), nh, bp);
return;
}