- struct ip6_rthdr0 *rh0;
- struct in6_addr *addr;
- struct sockaddr_in6 sa;
-
- rh = (struct ip6_rthdr *)
- (mtod(exthdrs.ip6e_rthdr, struct ip6_rthdr *));
- switch (rh->ip6r_type) {
- case IPV6_RTHDR_TYPE_0:
- rh0 = (struct ip6_rthdr0 *)rh;
- addr = (struct in6_addr *)(void *)(rh0 + 1);
-
- /*
- * construct a sockaddr_in6 form of
- * the first hop.
- *
- * XXX: we may not have enough
- * information about its scope zone;
- * there is no standard API to pass
- * the information from the
- * application.
- */
- bzero(&sa, sizeof (sa));
- sa.sin6_family = AF_INET6;
- sa.sin6_len = sizeof (sa);
- sa.sin6_addr = addr[0];
- if ((error = sa6_embedscope(&sa,
- ip6_use_defzone)) != 0) {
- goto bad;
- }
- ip6->ip6_dst = sa.sin6_addr;
- bcopy(&addr[1], &addr[0], sizeof (struct in6_addr) *
- (rh0->ip6r0_segleft - 1));
- addr[rh0->ip6r0_segleft - 1] = finaldst;
- /* XXX */
- in6_clearscope(addr + rh0->ip6r0_segleft - 1);
- break;
- default: /* is it possible? */
- error = EINVAL;
- goto bad;
- }