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