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 136struct 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*/ 147static struct inpcb* 148in6_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} 176int 177in6_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 371int 372in6_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 */ 439int 440in6_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 */ 501struct in6_addr * 502in6_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*/ 701int 702in6_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 715void 716in6_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 735void 736in6_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 inp->in6p_route.ro_rt = NULL; 764 } 765 /* Check and free IPv4 related resources in case of mapped addr */ 766 if (inp->inp_options) 767 (void)m_free(inp->inp_options); 768 ip_freemoptions(inp->inp_moptions); 769 inp->inp_moptions = NULL; 770 771 } 772} 773 774struct sockaddr * 775in6_sockaddr(port, addr_p) 776 in_port_t port; 777 struct in6_addr *addr_p; 778{ 779 struct sockaddr_in6 *sin6; 780 781 MALLOC(sin6, struct sockaddr_in6 *, sizeof *sin6, M_SONAME, M_WAITOK); 782 bzero(sin6, sizeof *sin6); 783 sin6->sin6_family = AF_INET6; 784 sin6->sin6_len = sizeof(*sin6); 785 sin6->sin6_port = port; 786 sin6->sin6_addr = *addr_p; 787 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) 788 sin6->sin6_scope_id = ntohs(sin6->sin6_addr.s6_addr16[1]); 789 else 790 sin6->sin6_scope_id = 0; /*XXX*/ 791 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) 792 sin6->sin6_addr.s6_addr16[1] = 0; 793 794 return (struct sockaddr *)sin6; 795} 796 797struct sockaddr * 798in6_v4mapsin6_sockaddr(port, addr_p) 799 in_port_t port; 800 struct in_addr *addr_p; 801{ 802 struct sockaddr_in sin; 803 struct sockaddr_in6 *sin6_p; 804 805 bzero(&sin, sizeof sin); 806 sin.sin_family = AF_INET; 807 sin.sin_len = sizeof(sin); 808 sin.sin_port = port; 809 sin.sin_addr = *addr_p; 810 811 MALLOC(sin6_p, struct sockaddr_in6 *, sizeof *sin6_p, M_SONAME, 812 M_WAITOK); 813 in6_sin_2_v4mapsin6(&sin, sin6_p); 814 815 return (struct sockaddr *)sin6_p; 816} 817 818/* 819 * The calling convention of in6_setsockaddr() and in6_setpeeraddr() was 820 * modified to match the pru_sockaddr() and pru_peeraddr() entry points 821 * in struct pr_usrreqs, so that protocols can just reference then directly 822 * without the need for a wrapper function. The socket must have a valid 823 * (i.e., non-nil) PCB, but it should be impossible to get an invalid one 824 * except through a kernel programming error, so it is acceptable to panic 825 * (or in this case trap) if the PCB is invalid. (Actually, we don't trap 826 * because there actually /is/ a programming error somewhere... XXX) 827 */ 828int 829in6_setsockaddr(so, nam) 830 struct socket *so; 831 struct sockaddr **nam; 832{ 833 struct inpcb *inp; 834 struct in6_addr addr; 835 in_port_t port; 836 837 inp = sotoinpcb(so); 838 if (!inp) { 839 return EINVAL; 840 } 841 port = inp->inp_lport; 842 addr = inp->in6p_laddr; 843 844 *nam = in6_sockaddr(port, &addr); 845 return 0; 846} 847 848int 849in6_setpeeraddr(so, nam) 850 struct socket *so; 851 struct sockaddr **nam; 852{ 853 struct inpcb *inp; 854 struct in6_addr addr; 855 in_port_t port; 856 857 inp = sotoinpcb(so); 858 if (!inp) { 859 return EINVAL; 860 } 861 port = inp->inp_fport; 862 addr = inp->in6p_faddr; 863 864 *nam = in6_sockaddr(port, &addr); 865 return 0; 866} 867 868int 869in6_mapped_sockaddr(struct socket *so, struct sockaddr **nam) 870{ 871 struct inpcb *inp = sotoinpcb(so); 872 int error; 873 874 if (inp == NULL) 875 return EINVAL; 876 if (inp->inp_vflag & INP_IPV4) { 877 error = in_setsockaddr(so, nam); 878 if (error == 0) 879 in6_sin_2_v4mapsin6_in_sock(nam); 880 } else 881 /* scope issues will be handled in in6_setsockaddr(). */ 882 error = in6_setsockaddr(so, nam); 883 884 return error; 885} 886 887int 888in6_mapped_peeraddr(struct socket *so, struct sockaddr **nam) 889{ 890 struct inpcb *inp = sotoinpcb(so); 891 int error; 892 893 if (inp == NULL) 894 return EINVAL; 895 if (inp->inp_vflag & INP_IPV4) { 896 error = in_setpeeraddr(so, nam); 897 if (error == 0) 898 in6_sin_2_v4mapsin6_in_sock(nam); 899 } else 900 /* scope issues will be handled in in6_setpeeraddr(). */ 901 error = in6_setpeeraddr(so, nam); 902 903 return error; 904} 905 906/* 907 * Pass some notification to all connections of a protocol 908 * associated with address dst. The local address and/or port numbers 909 * may be specified to limit the search. The "usual action" will be 910 * taken, depending on the ctlinput cmd. The caller must filter any 911 * cmds that are uninteresting (e.g., no error in the map). 912 * Call the protocol specific routine (if any) to report 913 * any errors for each matching socket. 914 * 915 * Must be called at splnet. 916 */ 917void 918in6_pcbnotify(pcbinfo, dst, fport_arg, src, lport_arg, cmd, notify) 919 struct inpcbinfo *pcbinfo; 920 struct sockaddr *dst; 921 const struct sockaddr *src; 922 u_int fport_arg, lport_arg; 923 int cmd; 924// struct inpcb *(*notify)(struct inpcb *, int); 925 void (*notify)(struct inpcb *, int); 926{ 927 struct inpcb *inp, *ninp; 928 struct sockaddr_in6 sa6_src, *sa6_dst; 929 u_short fport = fport_arg, lport = lport_arg; 930 u_int32_t flowinfo; 931 int errno; 932 struct inpcbhead *head = pcbinfo->listhead; 933 934 if ((unsigned)cmd > PRC_NCMDS || dst->sa_family != AF_INET6) 935 return; 936 937 sa6_dst = (struct sockaddr_in6 *)dst; 938 if (IN6_IS_ADDR_UNSPECIFIED(&sa6_dst->sin6_addr)) 939 return; 940 941 /* 942 * note that src can be NULL when we get notify by local fragmentation. 943 */ 944 sa6_src = (src == NULL) ? sa6_any : *(const struct sockaddr_in6 *)src; 945 flowinfo = sa6_src.sin6_flowinfo; 946 947 /* 948 * Redirects go to all references to the destination, 949 * and use in6_rtchange to invalidate the route cache. 950 * Dead host indications: also use in6_rtchange to invalidate 951 * the cache, and deliver the error to all the sockets. 952 * Otherwise, if we have knowledge of the local port and address, 953 * deliver only to that socket. 954 */ 955 if (PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) { 956 fport = 0; 957 lport = 0; 958 bzero((caddr_t)&sa6_src.sin6_addr, sizeof(sa6_src.sin6_addr)); 959 960 if (cmd != PRC_HOSTDEAD) 961 notify = in6_rtchange; 962 } 963 errno = inet6ctlerrmap[cmd]; 964 lck_rw_lock_shared(pcbinfo->mtx); 965 for (inp = LIST_FIRST(head); inp != NULL; inp = ninp) { 966 ninp = LIST_NEXT(inp, inp_list); 967 968 if ((inp->inp_vflag & INP_IPV6) == 0) 969 continue; 970 971 /* 972 * Detect if we should notify the error. If no source and 973 * destination ports are specifed, but non-zero flowinfo and 974 * local address match, notify the error. This is the case 975 * when the error is delivered with an encrypted buffer 976 * by ESP. Otherwise, just compare addresses and ports 977 * as usual. 978 */ 979 if (lport == 0 && fport == 0 && flowinfo && 980 inp->inp_socket != NULL && 981 flowinfo == (inp->in6p_flowinfo & IPV6_FLOWLABEL_MASK) && 982 IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, &sa6_src.sin6_addr)) 983 goto do_notify; 984 else if (!IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, 985 &sa6_dst->sin6_addr) || 986 inp->inp_socket == 0 || 987 (lport && inp->inp_lport != lport) || 988 (!IN6_IS_ADDR_UNSPECIFIED(&sa6_src.sin6_addr) && 989 !IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, 990 &sa6_src.sin6_addr)) || 991 (fport && inp->inp_fport != fport)) 992 continue; 993 994 995 do_notify: 996 if (notify) { 997 if (in_pcb_checkstate(inp, WNT_ACQUIRE, 0) == WNT_STOPUSING) 998 continue; 999 socket_lock(inp->inp_socket, 1); 1000 (*notify)(inp, errno); 1001 (void)in_pcb_checkstate(inp, WNT_RELEASE, 1); 1002 socket_unlock(inp->inp_socket, 1); 1003 } 1004 } 1005 lck_rw_done(pcbinfo->mtx); 1006} 1007 1008/* 1009 * Lookup a PCB based on the local address and port. 1010 */ 1011struct inpcb * 1012in6_pcblookup_local(pcbinfo, laddr, lport_arg, wild_okay) 1013 struct inpcbinfo *pcbinfo; 1014 struct in6_addr *laddr; 1015 u_int lport_arg; 1016 int wild_okay; 1017{ 1018 struct inpcb *inp; 1019 int matchwild = 3, wildcard; 1020 u_short lport = lport_arg; 1021 1022 if (!wild_okay) { 1023 struct inpcbhead *head; 1024 /* 1025 * Look for an unconnected (wildcard foreign addr) PCB that 1026 * matches the local address and port we're looking for. 1027 */ 1028 head = &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0, 1029 pcbinfo->hashmask)]; 1030 LIST_FOREACH(inp, head, inp_hash) { 1031 if ((inp->inp_vflag & INP_IPV6) == 0) 1032 continue; 1033 if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) && 1034 IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr) && 1035 inp->inp_lport == lport) { 1036 /* 1037 * Found. 1038 */ 1039 return (inp); 1040 } 1041 } 1042 /* 1043 * Not found. 1044 */ 1045 return (NULL); 1046 } else { 1047 struct inpcbporthead *porthash; 1048 struct inpcbport *phd; 1049 struct inpcb *match = NULL; 1050 /* 1051 * Best fit PCB lookup. 1052 * 1053 * First see if this local port is in use by looking on the 1054 * port hash list. 1055 */ 1056 porthash = &pcbinfo->porthashbase[INP_PCBPORTHASH(lport, 1057 pcbinfo->porthashmask)]; 1058 LIST_FOREACH(phd, porthash, phd_hash) { 1059 if (phd->phd_port == lport) 1060 break; 1061 } 1062 if (phd != NULL) { 1063 /* 1064 * Port is in use by one or more PCBs. Look for best 1065 * fit. 1066 */ 1067 LIST_FOREACH(inp, &phd->phd_pcblist, inp_portlist) { 1068 wildcard = 0; 1069 if ((inp->inp_vflag & INP_IPV6) == 0) 1070 continue; 1071 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) 1072 wildcard++; 1073 if (!IN6_IS_ADDR_UNSPECIFIED( 1074 &inp->in6p_laddr)) { 1075 if (IN6_IS_ADDR_UNSPECIFIED(laddr)) 1076 wildcard++; 1077 else if (!IN6_ARE_ADDR_EQUAL( 1078 &inp->in6p_laddr, laddr)) 1079 continue; 1080 } else { 1081 if (!IN6_IS_ADDR_UNSPECIFIED(laddr)) 1082 wildcard++; 1083 } 1084 if (wildcard < matchwild) { 1085 match = inp; 1086 matchwild = wildcard; 1087 if (matchwild == 0) { 1088 break; 1089 } 1090 } 1091 } 1092 } 1093 return (match); 1094 } 1095} 1096#ifndef APPLE 1097/* this is not used in Darwin */ 1098void 1099in6_pcbpurgeif0( 1100 struct in6pcb *head, 1101 struct ifnet *ifp) 1102{ 1103 struct in6pcb *in6p; 1104 struct ip6_moptions *im6o; 1105 struct in6_multi_mship *imm, *nimm; 1106 1107 for (in6p = head; in6p != NULL; in6p = LIST_NEXT(in6p, inp_list)) { 1108 im6o = in6p->in6p_moptions; 1109 if ((in6p->inp_vflag & INP_IPV6) && 1110 im6o) { 1111 /* 1112 * Unselect the outgoing interface if it is being 1113 * detached. 1114 */ 1115 if (im6o->im6o_multicast_ifp == ifp) 1116 im6o->im6o_multicast_ifp = NULL; 1117 1118 /* 1119 * Drop multicast group membership if we joined 1120 * through the interface being detached. 1121 * XXX controversial - is it really legal for kernel 1122 * to force this? 1123 */ 1124 for (imm = im6o->im6o_memberships.lh_first; 1125 imm != NULL; imm = nimm) { 1126 nimm = imm->i6mm_chain.le_next; 1127 if (imm->i6mm_maddr->in6m_ifp == ifp) { 1128 LIST_REMOVE(imm, i6mm_chain); 1129 in6_delmulti(imm->i6mm_maddr); 1130 FREE(imm, M_IPMADDR); 1131 } 1132 } 1133 } 1134 } 1135} 1136#endif 1137 1138/* 1139 * Check for alternatives when higher level complains 1140 * about service problems. For now, invalidate cached 1141 * routing information. If the route was created dynamically 1142 * (by a redirect), time to try a default gateway again. 1143 */ 1144void 1145in6_losing(in6p) 1146 struct inpcb *in6p; 1147{ 1148 struct rtentry *rt; 1149 struct rt_addrinfo info; 1150 1151 if ((rt = in6p->in6p_route.ro_rt) != NULL) { 1152 in6p->in6p_route.ro_rt = 0; 1153 bzero((caddr_t)&info, sizeof(info)); 1154 info.rti_info[RTAX_DST] = 1155 (struct sockaddr *)&in6p->in6p_route.ro_dst; 1156 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 1157 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 1158 lck_mtx_lock(rt_mtx); 1159 rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0); 1160 if (rt->rt_flags & RTF_DYNAMIC) 1161 (void)rtrequest_locked(RTM_DELETE, rt_key(rt), 1162 rt->rt_gateway, rt_mask(rt), rt->rt_flags, 1163 (struct rtentry **)0); 1164 else 1165 /* 1166 * A new route can be allocated 1167 * the next time output is attempted. 1168 */ 1169 rtfree_locked(rt); 1170 lck_mtx_unlock(rt_mtx); 1171 } 1172} 1173 1174/* 1175 * After a routing change, flush old routing 1176 * and allocate a (hopefully) better one. 1177 */ 1178void 1179in6_rtchange( 1180 struct inpcb *inp, 1181 __unused int errno) 1182{ 1183 if (inp->in6p_route.ro_rt) { 1184 rtfree(inp->in6p_route.ro_rt); 1185 inp->in6p_route.ro_rt = 0; 1186 /* 1187 * A new route can be allocated the next time 1188 * output is attempted. 1189 */ 1190 } 1191} 1192 1193/* 1194 * Lookup PCB in hash list. 1195 */ 1196struct inpcb * 1197in6_pcblookup_hash( 1198 struct inpcbinfo *pcbinfo, 1199 struct in6_addr *faddr, 1200 u_int fport_arg, 1201 struct in6_addr *laddr, 1202 u_int lport_arg, 1203 int wildcard, 1204 __unused struct ifnet *ifp) 1205{ 1206 struct inpcbhead *head; 1207 struct inpcb *inp; 1208 u_short fport = fport_arg, lport = lport_arg; 1209 int faith; 1210 1211#if defined(NFAITH) && NFAITH > 0 1212 faith = faithprefix(laddr); 1213#else 1214 faith = 0; 1215#endif 1216 1217 lck_rw_lock_shared(pcbinfo->mtx); 1218 1219 /* 1220 * First look for an exact match. 1221 */ 1222 head = &pcbinfo->hashbase[INP_PCBHASH(faddr->s6_addr32[3] /* XXX */, 1223 lport, fport, 1224 pcbinfo->hashmask)]; 1225 LIST_FOREACH(inp, head, inp_hash) { 1226 if ((inp->inp_vflag & INP_IPV6) == 0) 1227 continue; 1228 if (IN6_ARE_ADDR_EQUAL(&inp->in6p_faddr, faddr) && 1229 IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, laddr) && 1230 inp->inp_fport == fport && 1231 inp->inp_lport == lport) { 1232 /* 1233 * Found. Check if pcb is still valid 1234 */ 1235 if (in_pcb_checkstate(inp, WNT_ACQUIRE, 0) != WNT_STOPUSING) { 1236 lck_rw_done(pcbinfo->mtx); 1237 return (inp); 1238 } 1239 else { /* it's there but dead, say it isn't found */ 1240 lck_rw_done(pcbinfo->mtx); 1241 return(NULL); 1242 } 1243 } 1244 } 1245 if (wildcard) { 1246 struct inpcb *local_wild = NULL; 1247 1248 head = &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0, 1249 pcbinfo->hashmask)]; 1250 LIST_FOREACH(inp, head, inp_hash) { 1251 if ((inp->inp_vflag & INP_IPV6) == 0) 1252 continue; 1253 if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr) && 1254 inp->inp_lport == lport) { 1255 if (faith && (inp->inp_flags & INP_FAITH) == 0) 1256 continue; 1257 if (IN6_ARE_ADDR_EQUAL(&inp->in6p_laddr, 1258 laddr)) { 1259 if (in_pcb_checkstate(inp, WNT_ACQUIRE, 0) != WNT_STOPUSING) { 1260 lck_rw_done(pcbinfo->mtx); 1261 return (inp); 1262 } 1263 else { /* it's there but dead, say it isn't found */ 1264 lck_rw_done(pcbinfo->mtx); 1265 return(NULL); 1266 } 1267 } 1268 else if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr)) 1269 local_wild = inp; 1270 } 1271 } 1272 if (local_wild && in_pcb_checkstate(local_wild, WNT_ACQUIRE, 0) != WNT_STOPUSING) { 1273 lck_rw_done(pcbinfo->mtx); 1274 return (local_wild); 1275 } 1276 else { 1277 lck_rw_done(pcbinfo->mtx); 1278 return (NULL); 1279 } 1280 } 1281 1282 /* 1283 * Not found. 1284 */ 1285 lck_rw_done(pcbinfo->mtx); 1286 return (NULL); 1287} 1288 1289void 1290init_sin6(struct sockaddr_in6 *sin6, struct mbuf *m) 1291{ 1292 struct ip6_hdr *ip; 1293 1294 ip = mtod(m, struct ip6_hdr *); 1295 bzero(sin6, sizeof(*sin6)); 1296 sin6->sin6_len = sizeof(*sin6); 1297 sin6->sin6_family = AF_INET6; 1298 sin6->sin6_addr = ip->ip6_src; 1299 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) 1300 sin6->sin6_addr.s6_addr16[1] = 0; 1301 sin6->sin6_scope_id = 1302 (m->m_pkthdr.rcvif && IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) 1303 ? m->m_pkthdr.rcvif->if_index : 0; 1304 1305 return; 1306} 1307