- return(rh->ip6r_nxt);
-}
-
-#if IP6_RTHDR0_ALLOWED
-/*
- * Type0 routing header processing
- *
- * RFC2292 backward compatibility warning: no support for strict/loose bitmap,
- * as it was dropped between RFC1883 and RFC2460.
- */
-static int
-ip6_rthdr0(m, ip6, rh0)
- struct mbuf *m;
- struct ip6_hdr *ip6;
- struct ip6_rthdr0 *rh0;
-{
- int addrs, index;
- struct in6_addr *nextaddr, tmpaddr;
-
- if (rh0->ip6r0_segleft == 0)
- return(0);
-
- if (rh0->ip6r0_len % 2
-#if COMPAT_RFC1883
- || rh0->ip6r0_len > 46
-#endif
- ) {
- /*
- * Type 0 routing header can't contain more than 23 addresses.
- * RFC 2462: this limitation was removed since stict/loose
- * bitmap field was deleted.
- */
- ip6stat.ip6s_badoptions++;
- icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
- (caddr_t)&rh0->ip6r0_len - (caddr_t)ip6);
- return(-1);
- }
-
- if ((addrs = rh0->ip6r0_len / 2) < rh0->ip6r0_segleft) {
- ip6stat.ip6s_badoptions++;
- icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
- (caddr_t)&rh0->ip6r0_segleft - (caddr_t)ip6);
- return(-1);
- }
-
- index = addrs - rh0->ip6r0_segleft;
- rh0->ip6r0_segleft--;
- /* note that ip6r0_addr does not exist in RFC2292bis */
- nextaddr = rh0->ip6r0_addr + index;
-
- /*
- * reject invalid addresses. be proactive about malicious use of
- * IPv4 mapped/compat address.
- * XXX need more checks?
- */
- if (IN6_IS_ADDR_MULTICAST(nextaddr) ||
- IN6_IS_ADDR_UNSPECIFIED(nextaddr) ||
- IN6_IS_ADDR_V4MAPPED(nextaddr) ||
- IN6_IS_ADDR_V4COMPAT(nextaddr)) {
- ip6stat.ip6s_badoptions++;
- m_freem(m);
- return(-1);
- }
- if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) ||
- IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst) ||
- IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst) ||
- IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) {
- ip6stat.ip6s_badoptions++;
- m_freem(m);
- return(-1);
- }
-
- /*
- * Swap the IPv6 destination address and nextaddr. Forward the packet.
- */
- tmpaddr = *nextaddr;
- *nextaddr = ip6->ip6_dst;
- if (IN6_IS_ADDR_LINKLOCAL(nextaddr))
- nextaddr->s6_addr16[1] = 0;
- ip6->ip6_dst = tmpaddr;
- if (IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_dst))
- ip6->ip6_dst.s6_addr16[1] = htons(m->m_pkthdr.rcvif->if_index);
-
-#if COMPAT_RFC1883
- if (rh0->ip6r0_slmap[index / 8] & (1 << (7 - (index % 8))))
- ip6_forward(m, IPV6_SRCRT_NEIGHBOR, 0);
- else
- ip6_forward(m, IPV6_SRCRT_NOTNEIGHBOR, 0);
-#else
- ip6_forward(m, 1, 0);
-#endif
-
- return(-1); /* m would be freed in ip6_forward() */