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