const void *dst_addr;
const struct ip6_rthdr *dp;
const struct ip6_rthdr0 *dp0;
+ const struct ip6_srh *srh;
const u_char *p;
int i, len;
cp = (const u_char *)ip6;
advance = sizeof(struct ip6_hdr);
- nh = EXTRACT_U_1(ip6->ip6_nxt);
+ nh = GET_U_1(ip6->ip6_nxt);
dst_addr = (const void *)ip6->ip6_dst;
while (cp < ndo->ndo_snapend) {
* the first 8 octets.
*/
ND_TCHECK_2(cp);
- advance = (EXTRACT_U_1(cp + 1) + 1) << 3;
- nh = EXTRACT_U_1(cp);
+ advance = (GET_U_1(cp + 1) + 1) << 3;
+ nh = GET_U_1(cp);
break;
case IPPROTO_FRAGMENT:
*/
ND_TCHECK_1(cp);
advance = sizeof(struct ip6_frag);
- nh = EXTRACT_U_1(cp);
+ nh = GET_U_1(cp);
break;
case IPPROTO_ROUTING:
*/
dp = (const struct ip6_rthdr *)cp;
ND_TCHECK_SIZE(dp);
- len = EXTRACT_U_1(dp->ip6r_len);
- switch (EXTRACT_U_1(dp->ip6r_type)) {
+ len = GET_U_1(dp->ip6r_len);
+ switch (GET_U_1(dp->ip6r_type)) {
case IPV6_RTHDR_TYPE_0:
case IPV6_RTHDR_TYPE_2: /* Mobile IPv6 ID-20 */
p += 16;
}
break;
+ case IPV6_RTHDR_TYPE_4:
+ /* IPv6 Segment Routing Header (SRH) */
+ srh = (const struct ip6_srh *)dp;
+ if (len % 2 == 1)
+ goto trunc;
+ p = (const u_char *) srh->srh_segments;
+ /*
+ * The list of segments are encoded in the reverse order.
+ * Accordingly, the final DA is encoded in srh_segments[0]
+ */
+ ND_TCHECK_16(p);
+ dst_addr = (const void *)p;
+ break;
default:
break;
/*
* Compute a V6-style checksum by building a pseudoheader.
*/
-int
+uint16_t
nextproto6_cksum(netdissect_options *ndo,
const struct ip6_hdr *ip6, const uint8_t *data,
u_int len, u_int covlen, u_int next_proto)
/* pseudo-header */
memset(&ph, 0, sizeof(ph));
UNALIGNED_MEMCPY(&ph.ph_src, ip6->ip6_src, sizeof (struct in6_addr));
- nh = EXTRACT_U_1(ip6->ip6_nxt);
+ nh = GET_U_1(ip6->ip6_nxt);
switch (nh) {
case IPPROTO_HOPOPTS:
return;
}
- payload_len = EXTRACT_BE_U_2(ip6->ip6_plen);
+ payload_len = GET_BE_U_2(ip6->ip6_plen);
len = payload_len + sizeof(struct ip6_hdr);
if (length < len)
ND_PRINT("truncated-ip6 - %u bytes missing!",
len - length);
- nh = EXTRACT_U_1(ip6->ip6_nxt);
+ nh = GET_U_1(ip6->ip6_nxt);
if (ndo->ndo_vflag) {
- flow = EXTRACT_BE_U_4(ip6->ip6_flow);
+ flow = GET_BE_U_4(ip6->ip6_flow);
ND_PRINT("(");
#if 0
/* rfc1883 */
#endif
ND_PRINT("hlim %u, next-header %s (%u) payload length: %u) ",
- EXTRACT_U_1(ip6->ip6_hlim),
+ GET_U_1(ip6->ip6_hlim),
tok2str(ipproto_values,"unknown",nh),
nh,
payload_len);
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;
}
switch (nh) {
+
case IPPROTO_HOPOPTS:
advance = hbhopt_print(ndo, cp);
if (advance < 0)
return;
- nh = EXTRACT_U_1(cp);
+ nh = GET_U_1(cp);
break;
+
case IPPROTO_DSTOPTS:
advance = dstopt_print(ndo, cp);
if (advance < 0)
return;
- nh = EXTRACT_U_1(cp);
+ 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)
return;
- nh = EXTRACT_U_1(cp);
+ nh = GET_U_1(cp);
fragmented = 1;
break;
advance = mobility_print(ndo, cp, (const u_char *)ip6);
if (advance < 0)
return;
- nh = EXTRACT_U_1(cp);
+ nh = GET_U_1(cp);
return;
+
case IPPROTO_ROUTING:
ND_TCHECK_1(cp);
advance = rt6_print(ndo, cp, (const u_char *)ip6);
if (advance < 0)
return;
- nh = EXTRACT_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 = EXTRACT_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;
+ nh = GET_U_1(cp);
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;
}
+
+ /* ndo_protocol reassignment after xxx_print() calls */
+ ndo->ndo_protocol = "ip6";
}
return;
trunc:
- ND_PRINT("[|ip6]");
+ nd_print_trunc(ndo);
}