]> git.saurik.com Git - apple/xnu.git/blame_incremental - bsd/netinet6/in6_pcb.c
xnu-792.21.3.tar.gz
[apple/xnu.git] / bsd / netinet6 / in6_pcb.c
... / ...
CommitLineData
1/*
2 * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28/*
29 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
30 * All rights reserved.
31 *
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
34 * are met:
35 * 1. Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in the
39 * documentation and/or other materials provided with the distribution.
40 * 3. Neither the name of the project nor the names of its contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
43 *
44 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * SUCH DAMAGE.
55 *
56 */
57
58/*
59 * Copyright (c) 1982, 1986, 1991, 1993
60 * The Regents of the University of California. All rights reserved.
61 *
62 * Redistribution and use in source and binary forms, with or without
63 * modification, are permitted provided that the following conditions
64 * are met:
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 * 2. Redistributions in binary form must reproduce the above copyright
68 * notice, this list of conditions and the following disclaimer in the
69 * documentation and/or other materials provided with the distribution.
70 * 3. All advertising materials mentioning features or use of this software
71 * must display the following acknowledgement:
72 * This product includes software developed by the University of
73 * California, Berkeley and its contributors.
74 * 4. Neither the name of the University nor the names of its contributors
75 * may be used to endorse or promote products derived from this software
76 * without specific prior written permission.
77 *
78 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
79 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
80 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
81 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
82 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
83 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
84 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
85 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
86 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
87 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
88 * SUCH DAMAGE.
89 *
90 * @(#)in_pcb.c 8.2 (Berkeley) 1/4/94
91 */
92
93#include <sys/param.h>
94#include <sys/systm.h>
95#include <sys/malloc.h>
96#include <sys/mbuf.h>
97#include <sys/domain.h>
98#include <sys/protosw.h>
99#include <sys/socket.h>
100#include <sys/socketvar.h>
101#include <sys/sockio.h>
102#include <sys/errno.h>
103#include <sys/time.h>
104#include <sys/proc.h>
105
106#include <net/if.h>
107#include <net/if_types.h>
108#include <net/route.h>
109
110#include <netinet/in.h>
111#include <netinet/in_var.h>
112#include <netinet/in_systm.h>
113#include <netinet/ip6.h>
114#include <netinet/ip_var.h>
115#include <netinet6/ip6_var.h>
116#include <netinet6/nd6.h>
117#include <netinet/in_pcb.h>
118#include <netinet6/in6_pcb.h>
119#include <net/if_types.h>
120
121#include <kern/kern_types.h>
122#include <kern/zalloc.h>
123
124#include "faith.h"
125#if defined(NFAITH) && NFAITH > 0
126#include <net/if_faith.h>
127#endif
128
129#if IPSEC
130#include <netinet6/ipsec.h>
131#if INET6
132#include <netinet6/ipsec6.h>
133#endif
134#include <netinet6/ah.h>
135#if INET6
136#include <netinet6/ah6.h>
137#endif
138#include <netkey/key.h>
139extern lck_mtx_t *sadb_mutex;
140#endif /* IPSEC */
141
142struct in6_addr zeroin6_addr;
143
144int
145in6_pcbbind(
146 struct inpcb *inp,
147 struct sockaddr *nam,
148 struct proc *p)
149{
150 struct socket *so = inp->inp_socket;
151 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)NULL;
152 struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
153 u_short lport = 0;
154 int wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
155
156 if (!in6_ifaddrs) /* XXX broken! */
157 return (EADDRNOTAVAIL);
158 if (inp->inp_lport || !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
159 return(EINVAL);
160 if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0)
161 wild = 1;
162 socket_unlock(so, 0); /* keep reference */
163 lck_rw_lock_exclusive(pcbinfo->mtx);
164 if (nam) {
165 sin6 = (struct sockaddr_in6 *)nam;
166 if (nam->sa_len != sizeof(*sin6)) {
167 lck_rw_done(pcbinfo->mtx);
168 socket_lock(so, 0);
169 return(EINVAL);
170 }
171 /*
172 * family check.
173 */
174 if (nam->sa_family != AF_INET6) {
175 lck_rw_done(pcbinfo->mtx);
176 socket_lock(so, 0);
177 return(EAFNOSUPPORT);
178 }
179
180 /* KAME hack: embed scopeid */
181 if (in6_embedscope(&sin6->sin6_addr, sin6, inp, NULL) != 0) {
182 lck_rw_done(pcbinfo->mtx);
183 socket_lock(so, 0);
184 return EINVAL;
185 }
186 /* this must be cleared for ifa_ifwithaddr() */
187 sin6->sin6_scope_id = 0;
188
189 lport = sin6->sin6_port;
190 if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
191 /*
192 * Treat SO_REUSEADDR as SO_REUSEPORT for multicast;
193 * allow compepte duplication of binding if
194 * SO_REUSEPORT is set, or if SO_REUSEADDR is set
195 * and a multicast address is bound on both
196 * new and duplicated sockets.
197 */
198 if (so->so_options & SO_REUSEADDR)
199 reuseport = SO_REUSEADDR|SO_REUSEPORT;
200 } else if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
201 struct ifaddr *ia = NULL;
202
203 sin6->sin6_port = 0; /* yech... */
204 if ((ia = ifa_ifwithaddr((struct sockaddr *)sin6)) == 0) {
205 lck_rw_done(pcbinfo->mtx);
206 socket_lock(so, 0);
207 return(EADDRNOTAVAIL);
208 }
209
210 /*
211 * XXX: bind to an anycast address might accidentally
212 * cause sending a packet with anycast source address.
213 * We should allow to bind to a deprecated address, since
214 * the application dare to use it.
215 */
216 if (ia &&
217 ((struct in6_ifaddr *)ia)->ia6_flags &
218 (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY|IN6_IFF_DETACHED)) {
219 ifafree(ia);
220 lck_rw_done(pcbinfo->mtx);
221 socket_lock(so, 0);
222 return(EADDRNOTAVAIL);
223 }
224 ifafree(ia);
225 ia = NULL;
226 }
227 if (lport) {
228 struct inpcb *t;
229
230 /* GROSS */
231 if (ntohs(lport) < IPV6PORT_RESERVED && p &&
232 ((so->so_state & SS_PRIV) == 0)) {
233 lck_rw_done(pcbinfo->mtx);
234 socket_lock(so, 0);
235 return(EACCES);
236 }
237
238 if (so->so_uid &&
239 !IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
240 t = in6_pcblookup_local(pcbinfo,
241 &sin6->sin6_addr, lport,
242 INPLOOKUP_WILDCARD);
243 if (t &&
244 (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
245 !IN6_IS_ADDR_UNSPECIFIED(&t->in6p_laddr) ||
246 (t->inp_socket->so_options &
247 SO_REUSEPORT) == 0) &&
248 so->so_uid != t->inp_socket->so_uid) {
249 lck_rw_done(pcbinfo->mtx);
250 socket_lock(so, 0);
251 return (EADDRINUSE);
252 }
253 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 &&
254 IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
255 struct sockaddr_in sin;
256
257 in6_sin6_2_sin(&sin, sin6);
258 t = in_pcblookup_local(pcbinfo,
259 sin.sin_addr, lport,
260 INPLOOKUP_WILDCARD);
261 if (t &&
262 (so->so_uid !=
263 t->inp_socket->so_uid) &&
264 (ntohl(t->inp_laddr.s_addr) !=
265 INADDR_ANY ||
266 INP_SOCKAF(so) ==
267 INP_SOCKAF(t->inp_socket))) {
268
269 lck_rw_done(pcbinfo->mtx);
270 socket_lock(so, 0);
271 return (EADDRINUSE);
272 }
273 }
274 }
275 t = in6_pcblookup_local(pcbinfo, &sin6->sin6_addr,
276 lport, wild);
277 if (t && (reuseport & t->inp_socket->so_options) == 0) {
278 lck_rw_done(pcbinfo->mtx);
279 socket_lock(so, 0);
280 return(EADDRINUSE);
281 }
282 if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 &&
283 IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
284 struct sockaddr_in sin;
285
286 in6_sin6_2_sin(&sin, sin6);
287 t = in_pcblookup_local(pcbinfo, sin.sin_addr,
288 lport, wild);
289 if (t &&
290 (reuseport & t->inp_socket->so_options)
291 == 0 &&
292 (ntohl(t->inp_laddr.s_addr)
293 != INADDR_ANY ||
294 INP_SOCKAF(so) ==
295 INP_SOCKAF(t->inp_socket))) {
296 lck_rw_done(pcbinfo->mtx);
297 socket_lock(so, 0);
298 return (EADDRINUSE);
299 }
300 }
301 }
302 inp->in6p_laddr = sin6->sin6_addr;
303 }
304 socket_lock(so, 0);
305 if (lport == 0) {
306 int e;
307 if ((e = in6_pcbsetport(&inp->in6p_laddr, inp, p, 1)) != 0) {
308 lck_rw_done(pcbinfo->mtx);
309 return(e);
310 }
311 }
312 else {
313 inp->inp_lport = lport;
314 if (in_pcbinshash(inp, 1) != 0) {
315 inp->in6p_laddr = in6addr_any;
316 inp->inp_lport = 0;
317 lck_rw_done(pcbinfo->mtx);
318 return (EAGAIN);
319 }
320 }
321 lck_rw_done(pcbinfo->mtx);
322 return(0);
323}
324
325/*
326 * Transform old in6_pcbconnect() into an inner subroutine for new
327 * in6_pcbconnect(): Do some validity-checking on the remote
328 * address (in mbuf 'nam') and then determine local host address
329 * (i.e., which interface) to use to access that remote host.
330 *
331 * This preserves definition of in6_pcbconnect(), while supporting a
332 * slightly different version for T/TCP. (This is more than
333 * a bit of a kludge, but cleaning up the internal interfaces would
334 * have forced minor changes in every protocol).
335 */
336
337int
338in6_pcbladdr(
339 struct inpcb *inp,
340 struct sockaddr *nam,
341 struct in6_addr *plocal_addr6)
342{
343 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam;
344 struct in6_addr *addr6 = NULL;
345 struct in6_addr src_storage;
346
347 struct ifnet *ifp = NULL;
348 int error = 0;
349
350 if (nam->sa_len != sizeof (*sin6))
351 return (EINVAL);
352 if (sin6->sin6_family != AF_INET6)
353 return (EAFNOSUPPORT);
354 if (sin6->sin6_port == 0)
355 return (EADDRNOTAVAIL);
356
357 /* KAME hack: embed scopeid */
358 if (in6_embedscope(&sin6->sin6_addr, sin6, inp, &ifp) != 0)
359 return EINVAL;
360
361 if (in6_ifaddrs) {
362 /*
363 * If the destination address is UNSPECIFIED addr,
364 * use the loopback addr, e.g ::1.
365 */
366 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
367 sin6->sin6_addr = in6addr_loopback;
368 }
369 {
370 /*
371 * XXX: in6_selectsrc might replace the bound local address
372 * with the address specified by setsockopt(IPV6_PKTINFO).
373 * Is it the intended behavior?
374 */
375 addr6 = in6_selectsrc(sin6, inp->in6p_outputopts,
376 inp->in6p_moptions,
377 &inp->in6p_route,
378 &inp->in6p_laddr, &src_storage, &error);
379 if (addr6 == 0) {
380 if (error == 0)
381 error = EADDRNOTAVAIL;
382 return(error);
383 }
384 *plocal_addr6 = *addr6;
385 /*
386 * Don't do pcblookup call here; return interface in
387 * plocal_addr6
388 * and exit to caller, that will do the lookup.
389 */
390 }
391
392 if (inp->in6p_route.ro_rt)
393 ifp = inp->in6p_route.ro_rt->rt_ifp;
394
395 return(0);
396}
397
398/*
399 * Outer subroutine:
400 * Connect from a socket to a specified address.
401 * Both address and port must be specified in argument sin.
402 * If don't have a local address for this socket yet,
403 * then pick one.
404 */
405int
406in6_pcbconnect(inp, nam, p)
407 struct inpcb *inp;
408 struct sockaddr *nam;
409 struct proc *p;
410{
411 struct in6_addr addr6;
412 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam;
413 struct inpcb *pcb;
414 int error;
415
416 /*
417 * Call inner routine, to assign local interface address.
418 * in6_pcbladdr() may automatically fill in sin6_scope_id.
419 */
420 if ((error = in6_pcbladdr(inp, nam, &addr6)) != 0)
421 return(error);
422 socket_unlock(inp->inp_socket, 0);
423 pcb = in6_pcblookup_hash(inp->inp_pcbinfo, &sin6->sin6_addr,
424 sin6->sin6_port,
425 IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)
426 ? &addr6 : &inp->in6p_laddr,
427 inp->inp_lport, 0, NULL);
428 socket_lock(inp->inp_socket, 0);
429 if (pcb != NULL) {
430 in_pcb_checkstate(pcb, WNT_RELEASE, 0);
431 return (EADDRINUSE);
432 }
433 if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) {
434 if (inp->inp_lport == 0) {
435 error = in6_pcbbind(inp, (struct sockaddr *)0, p);
436 if (error)
437 return (error);
438 }
439 inp->in6p_laddr = addr6;
440 }
441 if (!lck_rw_try_lock_exclusive(inp->inp_pcbinfo->mtx)) {
442 /*lock inversion issue, mostly with udp multicast packets */
443 socket_unlock(inp->inp_socket, 0);
444 lck_rw_lock_exclusive(inp->inp_pcbinfo->mtx);
445 socket_lock(inp->inp_socket, 0);
446 }
447 inp->in6p_faddr = sin6->sin6_addr;
448 inp->inp_fport = sin6->sin6_port;
449 /* update flowinfo - draft-itojun-ipv6-flowlabel-api-00 */
450 inp->in6p_flowinfo &= ~IPV6_FLOWLABEL_MASK;
451 if (inp->in6p_flags & IN6P_AUTOFLOWLABEL)
452 inp->in6p_flowinfo |=
453 (htonl(ip6_flow_seq++) & IPV6_FLOWLABEL_MASK);
454
455 in_pcbrehash(inp);
456 lck_rw_done(inp->inp_pcbinfo->mtx);
457 return (0);
458}
459
460#if 0
461/*
462 * Return an IPv6 address, which is the most appropriate for given
463 * destination and user specified options.
464 * If necessary, this function lookups the routing table and return
465 * an entry to the caller for later use.
466 */
467struct in6_addr *
468in6_selectsrc(
469 struct sockaddr_in6 *dstsock,
470 struct ip6_pktopts *opts,
471 struct ip6_moptions *mopts,
472 struct route_in6 *ro,
473 struct in6_addr *laddr,
474 struct in6_addr *src_storage,
475 int *errorp)
476{
477 struct in6_addr *dst;
478 struct in6_ifaddr *ia6 = 0;
479 struct in6_pktinfo *pi = NULL;
480
481 dst = &dstsock->sin6_addr;
482 *errorp = 0;
483
484 /*
485 * If the source address is explicitly specified by the caller,
486 * use it.
487 */
488 if (opts && (pi = opts->ip6po_pktinfo) &&
489 !IN6_IS_ADDR_UNSPECIFIED(&pi->ipi6_addr))
490 return(&pi->ipi6_addr);
491
492 /*
493 * If the source address is not specified but the socket(if any)
494 * is already bound, use the bound address.
495 */
496 if (laddr && !IN6_IS_ADDR_UNSPECIFIED(laddr))
497 return(laddr);
498
499 /*
500 * If the caller doesn't specify the source address but
501 * the outgoing interface, use an address associated with
502 * the interface.
503 */
504 if (pi && pi->ipi6_ifindex) {
505 /* XXX boundary check is assumed to be already done. */
506 ia6 = in6_ifawithscope(ifindex2ifnet[pi->ipi6_ifindex],
507 dst);
508 if (ia6 == 0) {
509 *errorp = EADDRNOTAVAIL;
510 return(0);
511 }
512 *src_storage = satosin6(&ia6->ia_addr)->sin6_addr;
513 ifafree(&ia6->ia_ifa);
514 return(src_storage);
515 }
516
517 /*
518 * If the destination address is a link-local unicast address or
519 * a multicast address, and if the outgoing interface is specified
520 * by the sin6_scope_id filed, use an address associated with the
521 * interface.
522 * XXX: We're now trying to define more specific semantics of
523 * sin6_scope_id field, so this part will be rewritten in
524 * the near future.
525 */
526 if ((IN6_IS_ADDR_LINKLOCAL(dst) || IN6_IS_ADDR_MULTICAST(dst)) &&
527 dstsock->sin6_scope_id) {
528 /*
529 * I'm not sure if boundary check for scope_id is done
530 * somewhere...
531 */
532 if (dstsock->sin6_scope_id < 0 ||
533 if_index < dstsock->sin6_scope_id) {
534 *errorp = ENXIO; /* XXX: better error? */
535 return(0);
536 }
537 ia6 = in6_ifawithscope(ifindex2ifnet[dstsock->sin6_scope_id],
538 dst);
539 if (ia6 == 0) {
540 *errorp = EADDRNOTAVAIL;
541 return(0);
542 }
543 *src_storage = satosin6(&ia6->ia_addr)->sin6_addr;
544 ifafree(&ia6->ia_ifa);
545 return(src_storage);
546 }
547
548 /*
549 * If the destination address is a multicast address and
550 * the outgoing interface for the address is specified
551 * by the caller, use an address associated with the interface.
552 * There is a sanity check here; if the destination has node-local
553 * scope, the outgoing interfacde should be a loopback address.
554 * Even if the outgoing interface is not specified, we also
555 * choose a loopback interface as the outgoing interface.
556 */
557 if (IN6_IS_ADDR_MULTICAST(dst)) {
558 struct ifnet *ifp = mopts ? mopts->im6o_multicast_ifp : NULL;
559
560 if (ifp == NULL && IN6_IS_ADDR_MC_NODELOCAL(dst)) {
561 ifp = &loif[0];
562 }
563
564 if (ifp) {
565 ia6 = in6_ifawithscope(ifp, dst);
566 if (ia6 == 0) {
567 *errorp = EADDRNOTAVAIL;
568 return(0);
569 }
570 *src_storage = ia6->ia_addr.sin6_addr;
571 ifafree(&ia6->ia_ifa);
572 return(src_storage);
573 }
574 }
575
576 /*
577 * If the next hop address for the packet is specified
578 * by caller, use an address associated with the route
579 * to the next hop.
580 */
581 {
582 struct sockaddr_in6 *sin6_next;
583 struct rtentry *rt;
584
585 if (opts && opts->ip6po_nexthop) {
586 sin6_next = satosin6(opts->ip6po_nexthop);
587 rt = nd6_lookup(&sin6_next->sin6_addr, 1, NULL, 0);
588 if (rt) {
589 ia6 = in6_ifawithscope(rt->rt_ifp, dst);
590 if (ia6 == 0) {
591 ifaref(&rt->rt_ifa);
592 ia6 = ifatoia6(rt->rt_ifa);
593 }
594 }
595 if (ia6 == 0) {
596 *errorp = EADDRNOTAVAIL;
597 return(0);
598 }
599 *src_storage = satosin6(&ia6->ia_addr)->sin6_addr;
600 ifaref(&rt->rt_ifa);
601 return(src_storage);
602 }
603 }
604
605 /*
606 * If route is known or can be allocated now,
607 * our src addr is taken from the i/f, else punt.
608 */
609 if (ro) {
610 if (ro->ro_rt &&
611 !IN6_ARE_ADDR_EQUAL(&satosin6(&ro->ro_dst)->sin6_addr, dst)) {
612 rtfree(ro->ro_rt);
613 ro->ro_rt = (struct rtentry *)0;
614 }
615 if (ro->ro_rt == (struct rtentry *)0 ||
616 ro->ro_rt->rt_ifp == (struct ifnet *)0) {
617 struct sockaddr_in6 *dst6;
618
619 /* No route yet, so try to acquire one */
620 bzero(&ro->ro_dst, sizeof(struct sockaddr_in6));
621 dst6 = (struct sockaddr_in6 *)&ro->ro_dst;
622 dst6->sin6_family = AF_INET6;
623 dst6->sin6_len = sizeof(struct sockaddr_in6);
624 dst6->sin6_addr = *dst;
625 if (IN6_IS_ADDR_MULTICAST(dst)) {
626 ro->ro_rt = rtalloc1(&((struct route *)ro)
627 ->ro_dst, 0, 0UL);
628 } else {
629 rtalloc((struct route *)ro);
630 }
631 }
632
633 /*
634 * in_pcbconnect() checks out IFF_LOOPBACK to skip using
635 * the address. But we don't know why it does so.
636 * It is necessary to ensure the scope even for lo0
637 * so doesn't check out IFF_LOOPBACK.
638 */
639
640 if (ro->ro_rt) {
641 ia6 = in6_ifawithscope(ro->ro_rt->rt_ifa->ifa_ifp, dst);
642 if (ia6 == 0) { /* xxx scope error ?*/
643 ifaref(ro->ro_rt->rt_ifa);
644 ia6 = ifatoia6(ro->ro_rt->rt_ifa);
645 }
646 }
647 if (ia6 == 0) {
648 *errorp = EHOSTUNREACH; /* no route */
649 return(0);
650 }
651 *src_storage = satosin6(&ia6->ia_addr)->sin6_addr;
652 ifaref(&rt->rt_ifa);
653 return(src_storage);
654 }
655
656 *errorp = EADDRNOTAVAIL;
657 return(0);
658}
659
660/*
661 * Default hop limit selection. The precedence is as follows:
662 * 1. Hoplimit valued specified via ioctl.
663 * 2. (If the outgoing interface is detected) the current
664 * hop limit of the interface specified by router advertisement.
665 * 3. The system default hoplimit.
666*/
667int
668in6_selecthlim(
669 struct in6pcb *in6p,
670 struct ifnet *ifp)
671{
672 if (in6p && in6p->in6p_hops >= 0)
673 return(in6p->in6p_hops);
674 else if (ifp)
675 return(nd_ifinfo[ifp->if_index].chlim);
676 else
677 return(ip6_defhlim);
678}
679#endif
680
681void
682in6_pcbdisconnect(inp)
683 struct inpcb *inp;
684{
685 if (!lck_rw_try_lock_exclusive(inp->inp_pcbinfo->mtx)) {
686 /*lock inversion issue, mostly with udp multicast packets */
687 socket_unlock(inp->inp_socket, 0);
688 lck_rw_lock_exclusive(inp->inp_pcbinfo->mtx);
689 socket_lock(inp->inp_socket, 0);
690 }
691 bzero((caddr_t)&inp->in6p_faddr, sizeof(inp->in6p_faddr));
692 inp->inp_fport = 0;
693 /* clear flowinfo - draft-itojun-ipv6-flowlabel-api-00 */
694 inp->in6p_flowinfo &= ~IPV6_FLOWLABEL_MASK;
695 in_pcbrehash(inp);
696 lck_rw_done(inp->inp_pcbinfo->mtx);
697 if (inp->inp_socket->so_state & SS_NOFDREF)
698 in6_pcbdetach(inp);
699}
700
701void
702in6_pcbdetach(inp)
703 struct inpcb *inp;
704{
705 struct socket *so = inp->inp_socket;
706 struct inpcbinfo *ipi = inp->inp_pcbinfo;
707
708#if IPSEC
709 if (inp->in6p_sp != NULL) {
710 lck_mtx_lock(sadb_mutex);
711 ipsec6_delete_pcbpolicy(inp);
712 lck_mtx_unlock(sadb_mutex);
713 }
714#endif /* IPSEC */
715
716 if (in_pcb_checkstate(inp, WNT_STOPUSING, 1) != WNT_STOPUSING)
717 printf("in6_pcbdetach so=%x can't be marked dead ok\n", so);
718
719 inp->inp_state = INPCB_STATE_DEAD;
720
721 if ((so->so_flags & SOF_PCBCLEARING) == 0) {
722 inp->inp_vflag = 0;
723 so->so_flags |= SOF_PCBCLEARING;
724 inp->inp_gencnt = ++ipi->ipi_gencnt;
725 if (inp->in6p_options)
726 m_freem(inp->in6p_options);
727 ip6_freepcbopts(inp->in6p_outputopts);
728 ip6_freemoptions(inp->in6p_moptions);
729 if (inp->in6p_route.ro_rt)
730 rtfree(inp->in6p_route.ro_rt);
731 /* Check and free IPv4 related resources in case of mapped addr */
732 if (inp->inp_options)
733 (void)m_free(inp->inp_options);
734 ip_freemoptions(inp->inp_moptions);
735 inp->inp_moptions = NULL;
736
737 }
738}
739
740struct sockaddr *
741in6_sockaddr(port, addr_p)
742 in_port_t port;
743 struct in6_addr *addr_p;
744{
745 struct sockaddr_in6 *sin6;
746
747 MALLOC(sin6, struct sockaddr_in6 *, sizeof *sin6, M_SONAME, M_WAITOK);
748 bzero(sin6, sizeof *sin6);
749 sin6->sin6_family = AF_INET6;
750 sin6->sin6_len = sizeof(*sin6);
751 sin6->sin6_port = port;
752 sin6->sin6_addr = *addr_p;
753 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr))
754 sin6->sin6_scope_id = ntohs(sin6->sin6_addr.s6_addr16[1]);
755 else
756 sin6->sin6_scope_id = 0; /*XXX*/
757 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr))
758 sin6->sin6_addr.s6_addr16[1] = 0;
759
760 return (struct sockaddr *)sin6;
761}
762
763struct sockaddr *
764in6_v4mapsin6_sockaddr(port, addr_p)
765 in_port_t port;
766 struct in_addr *addr_p;
767{
768 struct sockaddr_in sin;
769 struct sockaddr_in6 *sin6_p;
770
771 bzero(&sin, sizeof sin);
772 sin.sin_family = AF_INET;
773 sin.sin_len = sizeof(sin);
774 sin.sin_port = port;
775 sin.sin_addr = *addr_p;
776
777 MALLOC(sin6_p, struct sockaddr_in6 *, sizeof *sin6_p, M_SONAME,
778 M_WAITOK);
779 in6_sin_2_v4mapsin6(&sin, sin6_p);
780
781 return (struct sockaddr *)sin6_p;
782}
783
784/*
785 * The calling convention of in6_setsockaddr() and in6_setpeeraddr() was
786 * modified to match the pru_sockaddr() and pru_peeraddr() entry points
787 * in struct pr_usrreqs, so that protocols can just reference then directly
788 * without the need for a wrapper function. The socket must have a valid
789 * (i.e., non-nil) PCB, but it should be impossible to get an invalid one
790 * except through a kernel programming error, so it is acceptable to panic
791 * (or in this case trap) if the PCB is invalid. (Actually, we don't trap
792 * because there actually /is/ a programming error somewhere... XXX)
793 */
794int
795in6_setsockaddr(so, nam)
796 struct socket *so;
797 struct sockaddr **nam;
798{
799 struct inpcb *inp;
800 struct in6_addr addr;
801 in_port_t port;
802
803 inp = sotoinpcb(so);
804 if (!inp) {
805 return EINVAL;
806 }
807 port = inp->inp_lport;
808 addr = inp->in6p_laddr;
809
810 *nam = in6_sockaddr(port, &addr);
811 return 0;
812}
813
814int
815in6_setpeeraddr(so, nam)
816 struct socket *so;
817 struct sockaddr **nam;
818{
819 struct inpcb *inp;
820 struct in6_addr addr;
821 in_port_t port;
822
823 inp = sotoinpcb(so);
824 if (!inp) {
825 return EINVAL;
826 }
827 port = inp->inp_fport;
828 addr = inp->in6p_faddr;
829
830 *nam = in6_sockaddr(port, &addr);
831 return 0;
832}
833
834int
835in6_mapped_sockaddr(struct socket *so, struct sockaddr **nam)
836{
837 struct inpcb *inp = sotoinpcb(so);
838 int error;
839
840 if (inp == NULL)
841 return EINVAL;
842 if (inp->inp_vflag & INP_IPV4) {
843 error = in_setsockaddr(so, nam);
844 if (error == 0)
845 in6_sin_2_v4mapsin6_in_sock(nam);
846 } else
847 /* scope issues will be handled in in6_setsockaddr(). */
848 error = in6_setsockaddr(so, nam);
849
850 return error;
851}
852
853int
854in6_mapped_peeraddr(struct socket *so, struct sockaddr **nam)
855{
856 struct inpcb *inp = sotoinpcb(so);
857 int error;
858
859 if (inp == NULL)
860 return EINVAL;
861 if (inp->inp_vflag & INP_IPV4) {
862 error = in_setpeeraddr(so, nam);
863 if (error == 0)
864 in6_sin_2_v4mapsin6_in_sock(nam);
865 } else
866 /* scope issues will be handled in in6_setpeeraddr(). */
867 error = in6_setpeeraddr(so, nam);
868
869 return error;
870}
871
872/*
873 * Pass some notification to all connections of a protocol
874 * associated with address dst. The local address and/or port numbers
875 * may be specified to limit the search. The "usual action" will be
876 * taken, depending on the ctlinput cmd. The caller must filter any
877 * cmds that are uninteresting (e.g., no error in the map).
878 * Call the protocol specific routine (if any) to report
879 * any errors for each matching socket.
880 *
881 * Must be called at splnet.
882 */
883void
884in6_pcbnotify(pcbinfo, dst, fport_arg, src, lport_arg, cmd, notify)
885 struct inpcbinfo *pcbinfo;
886 struct sockaddr *dst;
887 const struct sockaddr *src;
888 u_int fport_arg, lport_arg;
889 int cmd;
890// struct inpcb *(*notify)(struct inpcb *, int);
891 void (*notify)(struct inpcb *, int);
892{
893 struct inpcb *inp, *ninp;
894 struct sockaddr_in6 sa6_src, *sa6_dst;
895 u_short fport = fport_arg, lport = lport_arg;
896 u_int32_t flowinfo;
897 int errno;
898 struct inpcbhead *head = pcbinfo->listhead;
899
900 if ((unsigned)cmd > PRC_NCMDS || dst->sa_family != AF_INET6)
901 return;
902
903 sa6_dst = (struct sockaddr_in6 *)dst;
904 if (IN6_IS_ADDR_UNSPECIFIED(&sa6_dst->sin6_addr))
905 return;
906
907 /*
908 * note that src can be NULL when we get notify by local fragmentation.
909 */
910 sa6_src = (src == NULL) ? sa6_any : *(const struct sockaddr_in6 *)src;
911 flowinfo = sa6_src.sin6_flowinfo;
912
913 /*
914 * Redirects go to all references to the destination,
915 * and use in6_rtchange to invalidate the route cache.
916 * Dead host indications: also use in6_rtchange to invalidate
917 * the cache, and deliver the error to all the sockets.
918 * Otherwise, if we have knowledge of the local port and address,
919 * deliver only to that socket.
920 */
921 if (PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) {
922 fport = 0;
923 lport = 0;
924 bzero((caddr_t)&sa6_src.sin6_addr, sizeof(sa6_src.sin6_addr));
925
926 if (cmd != PRC_HOSTDEAD)
927 notify = in6_rtchange;
928 }
929 errno = inet6ctlerrmap[cmd];
930 lck_rw_lock_shared(pcbinfo->mtx);
931 for (inp = LIST_FIRST(head); inp != NULL; inp = ninp) {
932 ninp = LIST_NEXT(inp, inp_list);
933
934 if ((inp->inp_vflag & INP_IPV6) == 0)
935 continue;
936
937 /*
938 * Detect if we should notify the error. If no source and
939 * destination ports are specifed, but non-zero flowinfo and
940 * local address match, notify the error. This is the case
941 * when the error is delivered with an encrypted buffer
942 * by ESP. Otherwise, just compare addresses and ports
943 * as usual.
944 */
945 if (lport == 0 && fport == 0 && flowinfo &&
946 inp->inp_socket != NULL &&
947 flowinfo == (inp->in6p_flowinfo & IPV6_FLOWLABEL_MASK) &&
948 IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, &sa6_src.sin6_addr))
949 goto do_notify;
950 else if (!IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr,
951 &sa6_dst->sin6_addr) ||
952 inp->inp_socket == 0 ||
953 (lport && inp->inp_lport != lport) ||
954 (!IN6_IS_ADDR_UNSPECIFIED(&sa6_src.sin6_addr) &&
955 !IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr,
956 &sa6_src.sin6_addr)) ||
957 (fport && inp->inp_fport != fport))
958 continue;
959
960
961 do_notify:
962 if (notify) {
963 if (in_pcb_checkstate(inp, WNT_ACQUIRE, 0) == WNT_STOPUSING)
964 continue;
965 socket_lock(inp->inp_socket, 1);
966 (*notify)(inp, errno);
967 (void)in_pcb_checkstate(inp, WNT_RELEASE, 1);
968 socket_unlock(inp->inp_socket, 1);
969 }
970 }
971 lck_rw_done(pcbinfo->mtx);
972}
973
974/*
975 * Lookup a PCB based on the local address and port.
976 */
977struct inpcb *
978in6_pcblookup_local(pcbinfo, laddr, lport_arg, wild_okay)
979 struct inpcbinfo *pcbinfo;
980 struct in6_addr *laddr;
981 u_int lport_arg;
982 int wild_okay;
983{
984 struct inpcb *inp;
985 int matchwild = 3, wildcard;
986 u_short lport = lport_arg;
987
988 if (!wild_okay) {
989 struct inpcbhead *head;
990 /*
991 * Look for an unconnected (wildcard foreign addr) PCB that
992 * matches the local address and port we're looking for.
993 */
994 head = &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0,
995 pcbinfo->hashmask)];
996 LIST_FOREACH(inp, head, inp_hash) {
997 if ((inp->inp_vflag & INP_IPV6) == 0)
998 continue;
999 if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) &&
1000 IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr) &&
1001 inp->inp_lport == lport) {
1002 /*
1003 * Found.
1004 */
1005 return (inp);
1006 }
1007 }
1008 /*
1009 * Not found.
1010 */
1011 return (NULL);
1012 } else {
1013 struct inpcbporthead *porthash;
1014 struct inpcbport *phd;
1015 struct inpcb *match = NULL;
1016 /*
1017 * Best fit PCB lookup.
1018 *
1019 * First see if this local port is in use by looking on the
1020 * port hash list.
1021 */
1022 porthash = &pcbinfo->porthashbase[INP_PCBPORTHASH(lport,
1023 pcbinfo->porthashmask)];
1024 LIST_FOREACH(phd, porthash, phd_hash) {
1025 if (phd->phd_port == lport)
1026 break;
1027 }
1028 if (phd != NULL) {
1029 /*
1030 * Port is in use by one or more PCBs. Look for best
1031 * fit.
1032 */
1033 LIST_FOREACH(inp, &phd->phd_pcblist, inp_portlist) {
1034 wildcard = 0;
1035 if ((inp->inp_vflag & INP_IPV6) == 0)
1036 continue;
1037 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr))
1038 wildcard++;
1039 if (!IN6_IS_ADDR_UNSPECIFIED(
1040 &inp->in6p_laddr)) {
1041 if (IN6_IS_ADDR_UNSPECIFIED(laddr))
1042 wildcard++;
1043 else if (!IN6_ARE_ADDR_EQUAL(
1044 &inp->in6p_laddr, laddr))
1045 continue;
1046 } else {
1047 if (!IN6_IS_ADDR_UNSPECIFIED(laddr))
1048 wildcard++;
1049 }
1050 if (wildcard < matchwild) {
1051 match = inp;
1052 matchwild = wildcard;
1053 if (matchwild == 0) {
1054 break;
1055 }
1056 }
1057 }
1058 }
1059 return (match);
1060 }
1061}
1062#ifndef APPLE
1063/* this is not used in Darwin */
1064void
1065in6_pcbpurgeif0(
1066 struct in6pcb *head,
1067 struct ifnet *ifp)
1068{
1069 struct in6pcb *in6p;
1070 struct ip6_moptions *im6o;
1071 struct in6_multi_mship *imm, *nimm;
1072
1073 for (in6p = head; in6p != NULL; in6p = LIST_NEXT(in6p, inp_list)) {
1074 im6o = in6p->in6p_moptions;
1075 if ((in6p->inp_vflag & INP_IPV6) &&
1076 im6o) {
1077 /*
1078 * Unselect the outgoing interface if it is being
1079 * detached.
1080 */
1081 if (im6o->im6o_multicast_ifp == ifp)
1082 im6o->im6o_multicast_ifp = NULL;
1083
1084 /*
1085 * Drop multicast group membership if we joined
1086 * through the interface being detached.
1087 * XXX controversial - is it really legal for kernel
1088 * to force this?
1089 */
1090 for (imm = im6o->im6o_memberships.lh_first;
1091 imm != NULL; imm = nimm) {
1092 nimm = imm->i6mm_chain.le_next;
1093 if (imm->i6mm_maddr->in6m_ifp == ifp) {
1094 LIST_REMOVE(imm, i6mm_chain);
1095 in6_delmulti(imm->i6mm_maddr);
1096 FREE(imm, M_IPMADDR);
1097 }
1098 }
1099 }
1100 }
1101}
1102#endif
1103
1104/*
1105 * Check for alternatives when higher level complains
1106 * about service problems. For now, invalidate cached
1107 * routing information. If the route was created dynamically
1108 * (by a redirect), time to try a default gateway again.
1109 */
1110void
1111in6_losing(in6p)
1112 struct inpcb *in6p;
1113{
1114 struct rtentry *rt;
1115 struct rt_addrinfo info;
1116
1117 if ((rt = in6p->in6p_route.ro_rt) != NULL) {
1118 in6p->in6p_route.ro_rt = 0;
1119 bzero((caddr_t)&info, sizeof(info));
1120 info.rti_info[RTAX_DST] =
1121 (struct sockaddr *)&in6p->in6p_route.ro_dst;
1122 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
1123 info.rti_info[RTAX_NETMASK] = rt_mask(rt);
1124 lck_mtx_lock(rt_mtx);
1125 rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0);
1126 if (rt->rt_flags & RTF_DYNAMIC)
1127 (void)rtrequest_locked(RTM_DELETE, rt_key(rt),
1128 rt->rt_gateway, rt_mask(rt), rt->rt_flags,
1129 (struct rtentry **)0);
1130 else
1131 /*
1132 * A new route can be allocated
1133 * the next time output is attempted.
1134 */
1135 rtfree_locked(rt);
1136 lck_mtx_unlock(rt_mtx);
1137 }
1138}
1139
1140/*
1141 * After a routing change, flush old routing
1142 * and allocate a (hopefully) better one.
1143 */
1144void
1145in6_rtchange(
1146 struct inpcb *inp,
1147 int errno)
1148{
1149 if (inp->in6p_route.ro_rt) {
1150 rtfree(inp->in6p_route.ro_rt);
1151 inp->in6p_route.ro_rt = 0;
1152 /*
1153 * A new route can be allocated the next time
1154 * output is attempted.
1155 */
1156 }
1157}
1158
1159/*
1160 * Lookup PCB in hash list.
1161 */
1162struct inpcb *
1163in6_pcblookup_hash(
1164 struct inpcbinfo *pcbinfo,
1165 struct in6_addr *faddr,
1166 u_int fport_arg,
1167 struct in6_addr *laddr,
1168 u_int lport_arg,
1169 int wildcard,
1170 struct ifnet *ifp)
1171{
1172 struct inpcbhead *head;
1173 struct inpcb *inp;
1174 u_short fport = fport_arg, lport = lport_arg;
1175 int faith;
1176
1177#if defined(NFAITH) && NFAITH > 0
1178 faith = faithprefix(laddr);
1179#else
1180 faith = 0;
1181#endif
1182
1183 lck_rw_lock_shared(pcbinfo->mtx);
1184
1185 /*
1186 * First look for an exact match.
1187 */
1188 head = &pcbinfo->hashbase[INP_PCBHASH(faddr->s6_addr32[3] /* XXX */,
1189 lport, fport,
1190 pcbinfo->hashmask)];
1191 LIST_FOREACH(inp, head, inp_hash) {
1192 if ((inp->inp_vflag & INP_IPV6) == 0)
1193 continue;
1194 if (IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, faddr) &&
1195 IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr) &&
1196 inp->inp_fport == fport &&
1197 inp->inp_lport == lport) {
1198 /*
1199 * Found. Check if pcb is still valid
1200 */
1201 if (in_pcb_checkstate(inp, WNT_ACQUIRE, 0) != WNT_STOPUSING) {
1202 lck_rw_done(pcbinfo->mtx);
1203 return (inp);
1204 }
1205 else { /* it's there but dead, say it isn't found */
1206 lck_rw_done(pcbinfo->mtx);
1207 return(NULL);
1208 }
1209 }
1210 }
1211 if (wildcard) {
1212 struct inpcb *local_wild = NULL;
1213
1214 head = &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0,
1215 pcbinfo->hashmask)];
1216 LIST_FOREACH(inp, head, inp_hash) {
1217 if ((inp->inp_vflag & INP_IPV6) == 0)
1218 continue;
1219 if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) &&
1220 inp->inp_lport == lport) {
1221 if (faith && (inp->inp_flags & INP_FAITH) == 0)
1222 continue;
1223 if (IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr,
1224 laddr)) {
1225 if (in_pcb_checkstate(inp, WNT_ACQUIRE, 0) != WNT_STOPUSING) {
1226 lck_rw_done(pcbinfo->mtx);
1227 return (inp);
1228 }
1229 else { /* it's there but dead, say it isn't found */
1230 lck_rw_done(pcbinfo->mtx);
1231 return(NULL);
1232 }
1233 }
1234 else if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr))
1235 local_wild = inp;
1236 }
1237 }
1238 if (local_wild && in_pcb_checkstate(local_wild, WNT_ACQUIRE, 0) != WNT_STOPUSING) {
1239 lck_rw_done(pcbinfo->mtx);
1240 return (local_wild);
1241 }
1242 else {
1243 lck_rw_done(pcbinfo->mtx);
1244 return (NULL);
1245 }
1246 }
1247
1248 /*
1249 * Not found.
1250 */
1251 lck_rw_done(pcbinfo->mtx);
1252 return (NULL);
1253}
1254
1255void
1256init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m)
1257{
1258 struct ip6_hdr *ip;
1259
1260 ip = mtod(m, struct ip6_hdr *);
1261 bzero(sin6, sizeof(*sin6));
1262 sin6->sin6_len = sizeof(*sin6);
1263 sin6->sin6_family = AF_INET6;
1264 sin6->sin6_addr = ip->ip6_src;
1265 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr))
1266 sin6->sin6_addr.s6_addr16[1] = 0;
1267 sin6->sin6_scope_id =
1268 (m->m_pkthdr.rcvif && IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr))
1269 ? m->m_pkthdr.rcvif->if_index : 0;
1270
1271 return;
1272}