1 /* $NetBSD: in6_pcb.c,v 1.150 2016/09/29 12:19:47 roy Exp $ */ 2 /* $KAME: in6_pcb.c,v 1.84 2001/02/08 18:02:08 itojun 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 * Copyright (c) 1982, 1986, 1991, 1993 35 * The Regents of the University of California. All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 3. Neither the name of the University nor the names of its contributors 46 * may be used to endorse or promote products derived from this software 47 * without specific prior written permission. 48 * 49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 * SUCH DAMAGE. 60 * 61 * @(#)in_pcb.c 8.2 (Berkeley) 1/4/94 62 */ 63 64 #include <sys/cdefs.h> 65 __KERNEL_RCSID(0, "$NetBSD: in6_pcb.c,v 1.150 2016/09/29 12:19:47 roy Exp $"); 66 67 #ifdef _KERNEL_OPT 68 #include "opt_inet.h" 69 #include "opt_ipsec.h" 70 #endif 71 72 #include <sys/param.h> 73 #include <sys/systm.h> 74 #include <sys/mbuf.h> 75 #include <sys/protosw.h> 76 #include <sys/socket.h> 77 #include <sys/socketvar.h> 78 #include <sys/ioctl.h> 79 #include <sys/errno.h> 80 #include <sys/time.h> 81 #include <sys/proc.h> 82 #include <sys/kauth.h> 83 #include <sys/domain.h> 84 #include <sys/once.h> 85 86 #include <net/if.h> 87 #include <net/route.h> 88 89 #include <netinet/in.h> 90 #include <netinet/in_var.h> 91 #include <netinet/in_systm.h> 92 #include <netinet/ip.h> 93 #include <netinet/in_pcb.h> 94 #include <netinet/ip6.h> 95 #include <netinet/portalgo.h> 96 #include <netinet6/ip6_var.h> 97 #include <netinet6/in6_pcb.h> 98 #include <netinet6/scope6_var.h> 99 #include <netinet6/nd6.h> 100 101 #include "faith.h" 102 103 #ifdef IPSEC 104 #include <netipsec/ipsec.h> 105 #include <netipsec/ipsec6.h> 106 #include <netipsec/key.h> 107 #endif /* IPSEC */ 108 109 #include <netinet/tcp_vtw.h> 110 111 const struct in6_addr zeroin6_addr; 112 113 #define IN6PCBHASH_PORT(table, lport) \ 114 &(table)->inpt_porthashtbl[ntohs(lport) & (table)->inpt_porthash] 115 #define IN6PCBHASH_BIND(table, laddr, lport) \ 116 &(table)->inpt_bindhashtbl[ \ 117 (((laddr)->s6_addr32[0] ^ (laddr)->s6_addr32[1] ^ \ 118 (laddr)->s6_addr32[2] ^ (laddr)->s6_addr32[3]) + ntohs(lport)) & \ 119 (table)->inpt_bindhash] 120 #define IN6PCBHASH_CONNECT(table, faddr, fport, laddr, lport) \ 121 &(table)->inpt_bindhashtbl[ \ 122 ((((faddr)->s6_addr32[0] ^ (faddr)->s6_addr32[1] ^ \ 123 (faddr)->s6_addr32[2] ^ (faddr)->s6_addr32[3]) + ntohs(fport)) + \ 124 (((laddr)->s6_addr32[0] ^ (laddr)->s6_addr32[1] ^ \ 125 (laddr)->s6_addr32[2] ^ (laddr)->s6_addr32[3]) + \ 126 ntohs(lport))) & (table)->inpt_bindhash] 127 128 int ip6_anonportmin = IPV6PORT_ANONMIN; 129 int ip6_anonportmax = IPV6PORT_ANONMAX; 130 int ip6_lowportmin = IPV6PORT_RESERVEDMIN; 131 int ip6_lowportmax = IPV6PORT_RESERVEDMAX; 132 133 static struct pool in6pcb_pool; 134 135 static int 136 in6pcb_poolinit(void) 137 { 138 139 pool_init(&in6pcb_pool, sizeof(struct in6pcb), 0, 0, 0, "in6pcbpl", 140 NULL, IPL_SOFTNET); 141 return 0; 142 } 143 144 void 145 in6_pcbinit(struct inpcbtable *table, int bindhashsize, int connecthashsize) 146 { 147 static ONCE_DECL(control); 148 149 in_pcbinit(table, bindhashsize, connecthashsize); 150 table->inpt_lastport = (u_int16_t)ip6_anonportmax; 151 152 RUN_ONCE(&control, in6pcb_poolinit); 153 } 154 155 int 156 in6_pcballoc(struct socket *so, void *v) 157 { 158 struct inpcbtable *table = v; 159 struct in6pcb *in6p; 160 int s; 161 162 s = splnet(); 163 in6p = pool_get(&in6pcb_pool, PR_NOWAIT); 164 splx(s); 165 if (in6p == NULL) 166 return (ENOBUFS); 167 memset((void *)in6p, 0, sizeof(*in6p)); 168 in6p->in6p_af = AF_INET6; 169 in6p->in6p_table = table; 170 in6p->in6p_socket = so; 171 in6p->in6p_hops = -1; /* use kernel default */ 172 in6p->in6p_icmp6filt = NULL; 173 in6p->in6p_portalgo = PORTALGO_DEFAULT; 174 in6p->in6p_bindportonsend = false; 175 #if defined(IPSEC) 176 if (ipsec_enabled) { 177 int error = ipsec_init_pcbpolicy(so, &in6p->in6p_sp); 178 if (error != 0) { 179 s = splnet(); 180 pool_put(&in6pcb_pool, in6p); 181 splx(s); 182 return error; 183 } 184 } 185 #endif /* IPSEC */ 186 s = splnet(); 187 TAILQ_INSERT_HEAD(&table->inpt_queue, (struct inpcb_hdr*)in6p, 188 inph_queue); 189 LIST_INSERT_HEAD(IN6PCBHASH_PORT(table, in6p->in6p_lport), 190 &in6p->in6p_head, inph_lhash); 191 in6_pcbstate(in6p, IN6P_ATTACHED); 192 splx(s); 193 if (ip6_v6only) 194 in6p->in6p_flags |= IN6P_IPV6_V6ONLY; 195 so->so_pcb = (void *)in6p; 196 return (0); 197 } 198 199 /* 200 * Bind address from sin6 to in6p. 201 */ 202 static int 203 in6_pcbbind_addr(struct in6pcb *in6p, struct sockaddr_in6 *sin6, struct lwp *l) 204 { 205 int error; 206 int s; 207 208 /* 209 * We should check the family, but old programs 210 * incorrectly fail to intialize it. 211 */ 212 if (sin6->sin6_family != AF_INET6) 213 return (EAFNOSUPPORT); 214 215 #ifndef INET 216 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) 217 return (EADDRNOTAVAIL); 218 #endif 219 220 if ((error = sa6_embedscope(sin6, ip6_use_defzone)) != 0) 221 return (error); 222 223 s = pserialize_read_enter(); 224 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 225 if ((in6p->in6p_flags & IN6P_IPV6_V6ONLY) != 0) { 226 error = EINVAL; 227 goto out; 228 } 229 if (sin6->sin6_addr.s6_addr32[3]) { 230 struct sockaddr_in sin; 231 232 memset(&sin, 0, sizeof(sin)); 233 sin.sin_len = sizeof(sin); 234 sin.sin_family = AF_INET; 235 bcopy(&sin6->sin6_addr.s6_addr32[3], 236 &sin.sin_addr, sizeof(sin.sin_addr)); 237 if (!IN_MULTICAST(sin.sin_addr.s_addr)) { 238 struct ifaddr *ifa; 239 ifa = ifa_ifwithaddr((struct sockaddr *)&sin); 240 if (ifa == NULL) { 241 error = EADDRNOTAVAIL; 242 goto out; 243 } 244 } 245 } 246 } else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) { 247 // succeed 248 } else if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 249 struct ifaddr *ifa = NULL; 250 251 if ((in6p->in6p_flags & IN6P_FAITH) == 0) { 252 ifa = ifa_ifwithaddr(sin6tosa(sin6)); 253 if (ifa == NULL) { 254 error = EADDRNOTAVAIL; 255 goto out; 256 } 257 } 258 259 /* 260 * bind to an anycast address might accidentally 261 * cause sending a packet with an anycast source 262 * address, so we forbid it. 263 * 264 * We should allow to bind to a deprecated address, 265 * since the application dare to use it. 266 * But, can we assume that they are careful enough 267 * to check if the address is deprecated or not? 268 * Maybe, as a safeguard, we should have a setsockopt 269 * flag to control the bind(2) behavior against 270 * deprecated addresses (default: forbid bind(2)). 271 */ 272 if (ifa && 273 ifatoia6(ifa)->ia6_flags & 274 (IN6_IFF_ANYCAST | IN6_IFF_DUPLICATED)) { 275 error = EADDRNOTAVAIL; 276 goto out; 277 } 278 } 279 in6p->in6p_laddr = sin6->sin6_addr; 280 error = 0; 281 out: 282 pserialize_read_exit(s); 283 return error; 284 } 285 286 /* 287 * Bind port from sin6 to in6p. 288 */ 289 static int 290 in6_pcbbind_port(struct in6pcb *in6p, struct sockaddr_in6 *sin6, struct lwp *l) 291 { 292 struct inpcbtable *table = in6p->in6p_table; 293 struct socket *so = in6p->in6p_socket; 294 int wild = 0, reuseport = (so->so_options & SO_REUSEPORT); 295 int error; 296 297 if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0 && 298 ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 || 299 (so->so_options & SO_ACCEPTCONN) == 0)) 300 wild = 1; 301 302 if (sin6->sin6_port != 0) { 303 enum kauth_network_req req; 304 305 #ifndef IPNOPRIVPORTS 306 if (ntohs(sin6->sin6_port) < IPV6PORT_RESERVED) 307 req = KAUTH_REQ_NETWORK_BIND_PRIVPORT; 308 else 309 #endif /* IPNOPRIVPORTS */ 310 req = KAUTH_REQ_NETWORK_BIND_PORT; 311 312 error = kauth_authorize_network(l->l_cred, KAUTH_NETWORK_BIND, 313 req, so, sin6, NULL); 314 if (error) 315 return (EACCES); 316 } 317 318 if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) { 319 /* 320 * Treat SO_REUSEADDR as SO_REUSEPORT for multicast; 321 * allow compepte duplication of binding if 322 * SO_REUSEPORT is set, or if SO_REUSEADDR is set 323 * and a multicast address is bound on both 324 * new and duplicated sockets. 325 */ 326 if (so->so_options & (SO_REUSEADDR | SO_REUSEPORT)) 327 reuseport = SO_REUSEADDR|SO_REUSEPORT; 328 } 329 330 if (sin6->sin6_port != 0) { 331 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 332 #ifdef INET 333 struct inpcb *t; 334 struct vestigial_inpcb vestige; 335 336 t = in_pcblookup_port(table, 337 *(struct in_addr *)&sin6->sin6_addr.s6_addr32[3], 338 sin6->sin6_port, wild, &vestige); 339 if (t && (reuseport & t->inp_socket->so_options) == 0) 340 return (EADDRINUSE); 341 if (!t 342 && vestige.valid 343 && !(reuseport && vestige.reuse_port)) 344 return EADDRINUSE; 345 #else 346 return (EADDRNOTAVAIL); 347 #endif 348 } 349 350 { 351 struct in6pcb *t; 352 struct vestigial_inpcb vestige; 353 354 t = in6_pcblookup_port(table, &sin6->sin6_addr, 355 sin6->sin6_port, wild, &vestige); 356 if (t && (reuseport & t->in6p_socket->so_options) == 0) 357 return (EADDRINUSE); 358 if (!t 359 && vestige.valid 360 && !(reuseport && vestige.reuse_port)) 361 return EADDRINUSE; 362 } 363 } 364 365 if (sin6->sin6_port == 0) { 366 int e; 367 e = in6_pcbsetport(sin6, in6p, l); 368 if (e != 0) 369 return (e); 370 } else { 371 in6p->in6p_lport = sin6->sin6_port; 372 in6_pcbstate(in6p, IN6P_BOUND); 373 } 374 375 LIST_REMOVE(&in6p->in6p_head, inph_lhash); 376 LIST_INSERT_HEAD(IN6PCBHASH_PORT(table, in6p->in6p_lport), 377 &in6p->in6p_head, inph_lhash); 378 379 return (0); 380 } 381 382 int 383 in6_pcbbind(void *v, struct sockaddr_in6 *sin6, struct lwp *l) 384 { 385 struct in6pcb *in6p = v; 386 struct sockaddr_in6 lsin6; 387 int error; 388 389 if (in6p->in6p_af != AF_INET6) 390 return (EINVAL); 391 392 /* 393 * If we already have a local port or a local address it means we're 394 * bounded. 395 */ 396 if (in6p->in6p_lport || !(IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr) || 397 (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_laddr) && 398 in6p->in6p_laddr.s6_addr32[3] == 0))) 399 return (EINVAL); 400 401 if (NULL != sin6) { 402 /* We were provided a sockaddr_in6 to use. */ 403 if (sin6->sin6_len != sizeof(*sin6)) 404 return (EINVAL); 405 } else { 406 /* We always bind to *something*, even if it's "anything". */ 407 lsin6 = *((const struct sockaddr_in6 *) 408 in6p->in6p_socket->so_proto->pr_domain->dom_sa_any); 409 sin6 = &lsin6; 410 } 411 412 /* Bind address. */ 413 error = in6_pcbbind_addr(in6p, sin6, l); 414 if (error) 415 return (error); 416 417 /* Bind port. */ 418 error = in6_pcbbind_port(in6p, sin6, l); 419 if (error) { 420 /* 421 * Reset the address here to "any" so we don't "leak" the 422 * in6pcb. 423 */ 424 in6p->in6p_laddr = in6addr_any; 425 426 return (error); 427 } 428 429 430 #if 0 431 in6p->in6p_flowinfo = 0; /* XXX */ 432 #endif 433 return (0); 434 } 435 436 /* 437 * Connect from a socket to a specified address. 438 * Both address and port must be specified in argument sin6. 439 * If don't have a local address for this socket yet, 440 * then pick one. 441 */ 442 int 443 in6_pcbconnect(void *v, struct sockaddr_in6 *sin6, struct lwp *l) 444 { 445 struct in6pcb *in6p = v; 446 struct in6_addr *in6a = NULL; 447 struct ifnet *ifp = NULL; /* outgoing interface */ 448 int error = 0; 449 int scope_ambiguous = 0; 450 #ifdef INET 451 struct in6_addr mapped; 452 #endif 453 struct sockaddr_in6 tmp; 454 struct vestigial_inpcb vestige; 455 struct psref psref; 456 int bound; 457 458 (void)&in6a; /* XXX fool gcc */ 459 460 if (in6p->in6p_af != AF_INET6) 461 return (EINVAL); 462 463 if (sin6->sin6_len != sizeof(*sin6)) 464 return (EINVAL); 465 if (sin6->sin6_family != AF_INET6) 466 return (EAFNOSUPPORT); 467 if (sin6->sin6_port == 0) 468 return (EADDRNOTAVAIL); 469 470 if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr) && 471 in6p->in6p_socket->so_type == SOCK_STREAM) 472 return EADDRNOTAVAIL; 473 474 if (sin6->sin6_scope_id == 0 && !ip6_use_defzone) 475 scope_ambiguous = 1; 476 if ((error = sa6_embedscope(sin6, ip6_use_defzone)) != 0) 477 return(error); 478 479 /* sanity check for mapped address case */ 480 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 481 if ((in6p->in6p_flags & IN6P_IPV6_V6ONLY) != 0) 482 return EINVAL; 483 if (IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) 484 in6p->in6p_laddr.s6_addr16[5] = htons(0xffff); 485 if (!IN6_IS_ADDR_V4MAPPED(&in6p->in6p_laddr)) 486 return EINVAL; 487 } else 488 { 489 if (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_laddr)) 490 return EINVAL; 491 } 492 493 /* protect *sin6 from overwrites */ 494 tmp = *sin6; 495 sin6 = &tmp; 496 497 bound = curlwp_bind(); 498 /* Source address selection. */ 499 if (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_laddr) && 500 in6p->in6p_laddr.s6_addr32[3] == 0) { 501 #ifdef INET 502 struct sockaddr_in sin; 503 struct in_ifaddr *ia4; 504 struct psref _psref; 505 506 memset(&sin, 0, sizeof(sin)); 507 sin.sin_len = sizeof(sin); 508 sin.sin_family = AF_INET; 509 memcpy(&sin.sin_addr, &sin6->sin6_addr.s6_addr32[3], 510 sizeof(sin.sin_addr)); 511 ia4 = in_selectsrc(&sin, &in6p->in6p_route, 512 in6p->in6p_socket->so_options, NULL, &error, &_psref); 513 if (ia4 == NULL) { 514 if (error == 0) 515 error = EADDRNOTAVAIL; 516 return (error); 517 } 518 memset(&mapped, 0, sizeof(mapped)); 519 mapped.s6_addr16[5] = htons(0xffff); 520 memcpy(&mapped.s6_addr32[3], &IA_SIN(ia4)->sin_addr, 521 sizeof(IA_SIN(ia4)->sin_addr)); 522 ia4_release(ia4, &_psref); 523 in6a = &mapped; 524 #else 525 return EADDRNOTAVAIL; 526 #endif 527 } else { 528 /* 529 * XXX: in6_selectsrc might replace the bound local address 530 * with the address specified by setsockopt(IPV6_PKTINFO). 531 * Is it the intended behavior? 532 */ 533 in6a = in6_selectsrc(sin6, in6p->in6p_outputopts, 534 in6p->in6p_moptions, 535 &in6p->in6p_route, 536 &in6p->in6p_laddr, &ifp, &psref, &error); 537 if (ifp && scope_ambiguous && 538 (error = in6_setscope(&sin6->sin6_addr, ifp, NULL)) != 0) { 539 if_put(ifp, &psref); 540 curlwp_bindx(bound); 541 return(error); 542 } 543 544 if (in6a == NULL) { 545 if_put(ifp, &psref); 546 curlwp_bindx(bound); 547 if (error == 0) 548 error = EADDRNOTAVAIL; 549 return (error); 550 } 551 } 552 553 if (ifp != NULL) { 554 in6p->in6p_ip6.ip6_hlim = (u_int8_t)in6_selecthlim(in6p, ifp); 555 if_put(ifp, &psref); 556 } else 557 in6p->in6p_ip6.ip6_hlim = (u_int8_t)in6_selecthlim_rt(in6p); 558 curlwp_bindx(bound); 559 560 if (in6_pcblookup_connect(in6p->in6p_table, &sin6->sin6_addr, 561 sin6->sin6_port, 562 IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr) ? in6a : &in6p->in6p_laddr, 563 in6p->in6p_lport, 0, &vestige) 564 || vestige.valid) 565 return (EADDRINUSE); 566 if (IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr) || 567 (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_laddr) && 568 in6p->in6p_laddr.s6_addr32[3] == 0)) 569 { 570 if (in6p->in6p_lport == 0) { 571 error = in6_pcbbind(in6p, NULL, l); 572 if (error != 0) 573 return error; 574 } 575 in6p->in6p_laddr = *in6a; 576 } 577 in6p->in6p_faddr = sin6->sin6_addr; 578 in6p->in6p_fport = sin6->sin6_port; 579 580 /* Late bind, if needed */ 581 if (in6p->in6p_bindportonsend) { 582 struct sockaddr_in6 lsin = *((const struct sockaddr_in6 *) 583 in6p->in6p_socket->so_proto->pr_domain->dom_sa_any); 584 lsin.sin6_addr = in6p->in6p_laddr; 585 lsin.sin6_port = 0; 586 587 if ((error = in6_pcbbind_port(in6p, &lsin, l)) != 0) 588 return error; 589 } 590 591 in6_pcbstate(in6p, IN6P_CONNECTED); 592 in6p->in6p_flowinfo &= ~IPV6_FLOWLABEL_MASK; 593 if (ip6_auto_flowlabel) 594 in6p->in6p_flowinfo |= 595 (htonl(ip6_randomflowlabel()) & IPV6_FLOWLABEL_MASK); 596 #if defined(IPSEC) 597 if (ipsec_enabled && in6p->in6p_socket->so_type == SOCK_STREAM) 598 ipsec_pcbconn(in6p->in6p_sp); 599 #endif 600 return (0); 601 } 602 603 void 604 in6_pcbdisconnect(struct in6pcb *in6p) 605 { 606 memset((void *)&in6p->in6p_faddr, 0, sizeof(in6p->in6p_faddr)); 607 in6p->in6p_fport = 0; 608 in6_pcbstate(in6p, IN6P_BOUND); 609 in6p->in6p_flowinfo &= ~IPV6_FLOWLABEL_MASK; 610 #if defined(IPSEC) 611 if (ipsec_enabled) 612 ipsec_pcbdisconn(in6p->in6p_sp); 613 #endif 614 if (in6p->in6p_socket->so_state & SS_NOFDREF) 615 in6_pcbdetach(in6p); 616 } 617 618 void 619 in6_pcbdetach(struct in6pcb *in6p) 620 { 621 struct socket *so = in6p->in6p_socket; 622 int s; 623 624 if (in6p->in6p_af != AF_INET6) 625 return; 626 627 #if defined(IPSEC) 628 if (ipsec_enabled) 629 ipsec6_delete_pcbpolicy(in6p); 630 #endif 631 so->so_pcb = NULL; 632 633 s = splnet(); 634 in6_pcbstate(in6p, IN6P_ATTACHED); 635 LIST_REMOVE(&in6p->in6p_head, inph_lhash); 636 TAILQ_REMOVE(&in6p->in6p_table->inpt_queue, &in6p->in6p_head, 637 inph_queue); 638 splx(s); 639 640 if (in6p->in6p_options) { 641 m_freem(in6p->in6p_options); 642 } 643 if (in6p->in6p_outputopts != NULL) { 644 ip6_clearpktopts(in6p->in6p_outputopts, -1); 645 free(in6p->in6p_outputopts, M_IP6OPT); 646 } 647 rtcache_free(&in6p->in6p_route); 648 ip6_freemoptions(in6p->in6p_moptions); 649 ip_freemoptions(in6p->in6p_v4moptions); 650 sofree(so); /* drops the socket's lock */ 651 652 pool_put(&in6pcb_pool, in6p); 653 mutex_enter(softnet_lock); /* reacquire it */ 654 } 655 656 void 657 in6_setsockaddr(struct in6pcb *in6p, struct sockaddr_in6 *sin6) 658 { 659 660 if (in6p->in6p_af != AF_INET6) 661 return; 662 663 sockaddr_in6_init(sin6, &in6p->in6p_laddr, in6p->in6p_lport, 0, 0); 664 (void)sa6_recoverscope(sin6); /* XXX: should catch errors */ 665 } 666 667 void 668 in6_setpeeraddr(struct in6pcb *in6p, struct sockaddr_in6 *sin6) 669 { 670 671 if (in6p->in6p_af != AF_INET6) 672 return; 673 674 sockaddr_in6_init(sin6, &in6p->in6p_faddr, in6p->in6p_fport, 0, 0); 675 (void)sa6_recoverscope(sin6); /* XXX: should catch errors */ 676 } 677 678 /* 679 * Pass some notification to all connections of a protocol 680 * associated with address dst. The local address and/or port numbers 681 * may be specified to limit the search. The "usual action" will be 682 * taken, depending on the ctlinput cmd. The caller must filter any 683 * cmds that are uninteresting (e.g., no error in the map). 684 * Call the protocol specific routine (if any) to report 685 * any errors for each matching socket. 686 * 687 * Must be called at splsoftnet. 688 * 689 * Note: src (4th arg) carries the flowlabel value on the original IPv6 690 * header, in sin6_flowinfo member. 691 */ 692 int 693 in6_pcbnotify(struct inpcbtable *table, const struct sockaddr *dst, 694 u_int fport_arg, const struct sockaddr *src, u_int lport_arg, int cmd, 695 void *cmdarg, void (*notify)(struct in6pcb *, int)) 696 { 697 struct rtentry *rt; 698 struct inpcb_hdr *inph, *ninph; 699 struct sockaddr_in6 sa6_src; 700 const struct sockaddr_in6 *sa6_dst; 701 u_int16_t fport = fport_arg, lport = lport_arg; 702 int errno; 703 int nmatch = 0; 704 u_int32_t flowinfo; 705 706 if ((unsigned)cmd >= PRC_NCMDS || dst->sa_family != AF_INET6) 707 return 0; 708 709 sa6_dst = (const struct sockaddr_in6 *)dst; 710 if (IN6_IS_ADDR_UNSPECIFIED(&sa6_dst->sin6_addr)) 711 return 0; 712 713 /* 714 * note that src can be NULL when we get notify by local fragmentation. 715 */ 716 sa6_src = (src == NULL) ? sa6_any : *(const struct sockaddr_in6 *)src; 717 flowinfo = sa6_src.sin6_flowinfo; 718 719 /* 720 * Redirects go to all references to the destination, 721 * and use in6_rtchange to invalidate the route cache. 722 * Dead host indications: also use in6_rtchange to invalidate 723 * the cache, and deliver the error to all the sockets. 724 * Otherwise, if we have knowledge of the local port and address, 725 * deliver only to that socket. 726 */ 727 if (PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) { 728 fport = 0; 729 lport = 0; 730 memset((void *)&sa6_src.sin6_addr, 0, sizeof(sa6_src.sin6_addr)); 731 732 if (cmd != PRC_HOSTDEAD) 733 notify = in6_rtchange; 734 } 735 736 errno = inet6ctlerrmap[cmd]; 737 TAILQ_FOREACH_SAFE(inph, &table->inpt_queue, inph_queue, ninph) { 738 struct in6pcb *in6p = (struct in6pcb *)inph; 739 if (in6p->in6p_af != AF_INET6) 740 continue; 741 742 /* 743 * Under the following condition, notify of redirects 744 * to the pcb, without making address matches against inpcb. 745 * - redirect notification is arrived. 746 * - the inpcb is unconnected. 747 * - the inpcb is caching !RTF_HOST routing entry. 748 * - the ICMPv6 notification is from the gateway cached in the 749 * inpcb. i.e. ICMPv6 notification is from nexthop gateway 750 * the inpcb used very recently. 751 * 752 * This is to improve interaction between netbsd/openbsd 753 * redirect handling code, and inpcb route cache code. 754 * without the clause, !RTF_HOST routing entry (which carries 755 * gateway used by inpcb right before the ICMPv6 redirect) 756 * will be cached forever in unconnected inpcb. 757 * 758 * There still is a question regarding to what is TRT: 759 * - On bsdi/freebsd, RTF_HOST (cloned) routing entry will be 760 * generated on packet output. inpcb will always cache 761 * RTF_HOST routing entry so there's no need for the clause 762 * (ICMPv6 redirect will update RTF_HOST routing entry, 763 * and inpcb is caching it already). 764 * However, bsdi/freebsd are vulnerable to local DoS attacks 765 * due to the cloned routing entries. 766 * - Specwise, "destination cache" is mentioned in RFC2461. 767 * Jinmei says that it implies bsdi/freebsd behavior, itojun 768 * is not really convinced. 769 * - Having hiwat/lowat on # of cloned host route (redirect/ 770 * pmtud) may be a good idea. netbsd/openbsd has it. see 771 * icmp6_mtudisc_update(). 772 */ 773 if ((PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) && 774 IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr) && 775 (rt = rtcache_validate(&in6p->in6p_route)) != NULL && 776 !(rt->rt_flags & RTF_HOST)) { 777 const struct sockaddr_in6 *dst6; 778 779 dst6 = (const struct sockaddr_in6 *) 780 rtcache_getdst(&in6p->in6p_route); 781 if (dst6 == NULL) 782 ; 783 else if (IN6_ARE_ADDR_EQUAL(&dst6->sin6_addr, 784 &sa6_dst->sin6_addr)) 785 goto do_notify; 786 } 787 788 /* 789 * If the error designates a new path MTU for a destination 790 * and the application (associated with this socket) wanted to 791 * know the value, notify. Note that we notify for all 792 * disconnected sockets if the corresponding application 793 * wanted. This is because some UDP applications keep sending 794 * sockets disconnected. 795 * XXX: should we avoid to notify the value to TCP sockets? 796 */ 797 if (cmd == PRC_MSGSIZE && (in6p->in6p_flags & IN6P_MTU) != 0 && 798 (IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) || 799 IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &sa6_dst->sin6_addr))) { 800 ip6_notify_pmtu(in6p, (const struct sockaddr_in6 *)dst, 801 (u_int32_t *)cmdarg); 802 } 803 804 /* 805 * Detect if we should notify the error. If no source and 806 * destination ports are specified, but non-zero flowinfo and 807 * local address match, notify the error. This is the case 808 * when the error is delivered with an encrypted buffer 809 * by ESP. Otherwise, just compare addresses and ports 810 * as usual. 811 */ 812 if (lport == 0 && fport == 0 && flowinfo && 813 in6p->in6p_socket != NULL && 814 flowinfo == (in6p->in6p_flowinfo & IPV6_FLOWLABEL_MASK) && 815 IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &sa6_src.sin6_addr)) 816 goto do_notify; 817 else if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, 818 &sa6_dst->sin6_addr) || 819 in6p->in6p_socket == NULL || 820 (lport && in6p->in6p_lport != lport) || 821 (!IN6_IS_ADDR_UNSPECIFIED(&sa6_src.sin6_addr) && 822 !IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, 823 &sa6_src.sin6_addr)) || 824 (fport && in6p->in6p_fport != fport)) 825 continue; 826 827 do_notify: 828 if (notify) 829 (*notify)(in6p, errno); 830 nmatch++; 831 } 832 return nmatch; 833 } 834 835 void 836 in6_pcbpurgeif0(struct inpcbtable *table, struct ifnet *ifp) 837 { 838 struct inpcb_hdr *inph, *ninph; 839 struct ip6_moptions *im6o; 840 struct in6_multi_mship *imm, *nimm; 841 842 KASSERT(ifp != NULL); 843 844 TAILQ_FOREACH_SAFE(inph, &table->inpt_queue, inph_queue, ninph) { 845 struct in6pcb *in6p = (struct in6pcb *)inph; 846 if (in6p->in6p_af != AF_INET6) 847 continue; 848 849 im6o = in6p->in6p_moptions; 850 if (im6o) { 851 /* 852 * Unselect the outgoing interface if it is being 853 * detached. 854 */ 855 if (im6o->im6o_multicast_if_index == ifp->if_index) 856 im6o->im6o_multicast_if_index = 0; 857 858 /* 859 * Drop multicast group membership if we joined 860 * through the interface being detached. 861 * XXX controversial - is it really legal for kernel 862 * to force this? 863 */ 864 for (imm = im6o->im6o_memberships.lh_first; 865 imm != NULL; imm = nimm) { 866 nimm = imm->i6mm_chain.le_next; 867 if (imm->i6mm_maddr->in6m_ifp == ifp) { 868 LIST_REMOVE(imm, i6mm_chain); 869 in6_leavegroup(imm); 870 } 871 } 872 } 873 in_purgeifmcast(in6p->in6p_v4moptions, ifp); 874 } 875 } 876 877 void 878 in6_pcbpurgeif(struct inpcbtable *table, struct ifnet *ifp) 879 { 880 struct rtentry *rt; 881 struct inpcb_hdr *inph, *ninph; 882 883 TAILQ_FOREACH_SAFE(inph, &table->inpt_queue, inph_queue, ninph) { 884 struct in6pcb *in6p = (struct in6pcb *)inph; 885 if (in6p->in6p_af != AF_INET6) 886 continue; 887 if ((rt = rtcache_validate(&in6p->in6p_route)) != NULL && 888 rt->rt_ifp == ifp) 889 in6_rtchange(in6p, 0); 890 } 891 } 892 893 /* 894 * Check for alternatives when higher level complains 895 * about service problems. For now, invalidate cached 896 * routing information. If the route was created dynamically 897 * (by a redirect), time to try a default gateway again. 898 */ 899 void 900 in6_losing(struct in6pcb *in6p) 901 { 902 struct rtentry *rt; 903 struct rt_addrinfo info; 904 905 if (in6p->in6p_af != AF_INET6) 906 return; 907 908 if ((rt = rtcache_validate(&in6p->in6p_route)) == NULL) 909 return; 910 911 memset(&info, 0, sizeof(info)); 912 info.rti_info[RTAX_DST] = rtcache_getdst(&in6p->in6p_route); 913 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 914 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 915 rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0); 916 if (rt->rt_flags & RTF_DYNAMIC) { 917 (void)rtrequest(RTM_DELETE, rt_getkey(rt), 918 rt->rt_gateway, rt_mask(rt), rt->rt_flags, NULL); 919 } 920 /* 921 * A new route can be allocated 922 * the next time output is attempted. 923 */ 924 rtcache_free(&in6p->in6p_route); 925 } 926 927 /* 928 * After a routing change, flush old routing. A new route can be 929 * allocated the next time output is attempted. 930 */ 931 void 932 in6_rtchange(struct in6pcb *in6p, int errno) 933 { 934 if (in6p->in6p_af != AF_INET6) 935 return; 936 937 rtcache_free(&in6p->in6p_route); 938 /* 939 * A new route can be allocated the next time 940 * output is attempted. 941 */ 942 } 943 944 struct in6pcb * 945 in6_pcblookup_port(struct inpcbtable *table, struct in6_addr *laddr6, 946 u_int lport_arg, int lookup_wildcard, struct vestigial_inpcb *vp) 947 { 948 struct inpcbhead *head; 949 struct inpcb_hdr *inph; 950 struct in6pcb *in6p, *match = NULL; 951 int matchwild = 3, wildcard; 952 u_int16_t lport = lport_arg; 953 954 if (vp) 955 vp->valid = 0; 956 957 head = IN6PCBHASH_PORT(table, lport); 958 LIST_FOREACH(inph, head, inph_lhash) { 959 in6p = (struct in6pcb *)inph; 960 if (in6p->in6p_af != AF_INET6) 961 continue; 962 963 if (in6p->in6p_lport != lport) 964 continue; 965 wildcard = 0; 966 if (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_faddr)) { 967 if ((in6p->in6p_flags & IN6P_IPV6_V6ONLY) != 0) 968 continue; 969 } 970 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) 971 wildcard++; 972 if (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_laddr)) { 973 if ((in6p->in6p_flags & IN6P_IPV6_V6ONLY) != 0) 974 continue; 975 if (!IN6_IS_ADDR_V4MAPPED(laddr6)) 976 continue; 977 978 /* duplicate of IPv4 logic */ 979 wildcard = 0; 980 if (IN6_IS_ADDR_V4MAPPED(&in6p->in6p_faddr) && 981 in6p->in6p_faddr.s6_addr32[3]) 982 wildcard++; 983 if (!in6p->in6p_laddr.s6_addr32[3]) { 984 if (laddr6->s6_addr32[3]) 985 wildcard++; 986 } else { 987 if (!laddr6->s6_addr32[3]) 988 wildcard++; 989 else { 990 if (in6p->in6p_laddr.s6_addr32[3] != 991 laddr6->s6_addr32[3]) 992 continue; 993 } 994 } 995 } else if (IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) { 996 if (IN6_IS_ADDR_V4MAPPED(laddr6)) { 997 if ((in6p->in6p_flags & IN6P_IPV6_V6ONLY) != 0) 998 continue; 999 } 1000 if (!IN6_IS_ADDR_UNSPECIFIED(laddr6)) 1001 wildcard++; 1002 } else { 1003 if (IN6_IS_ADDR_V4MAPPED(laddr6)) { 1004 if ((in6p->in6p_flags & IN6P_IPV6_V6ONLY) != 0) 1005 continue; 1006 } 1007 if (IN6_IS_ADDR_UNSPECIFIED(laddr6)) 1008 wildcard++; 1009 else { 1010 if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, 1011 laddr6)) 1012 continue; 1013 } 1014 } 1015 if (wildcard && !lookup_wildcard) 1016 continue; 1017 if (wildcard < matchwild) { 1018 match = in6p; 1019 matchwild = wildcard; 1020 if (matchwild == 0) 1021 break; 1022 } 1023 } 1024 if (match && matchwild == 0) 1025 return match; 1026 1027 if (vp && table->vestige && table->vestige->init_ports6) { 1028 struct vestigial_inpcb better; 1029 void *state; 1030 1031 state = (*table->vestige->init_ports6)(laddr6, 1032 lport_arg, 1033 lookup_wildcard); 1034 while (table->vestige 1035 && (*table->vestige->next_port6)(state, vp)) { 1036 1037 if (vp->lport != lport) 1038 continue; 1039 wildcard = 0; 1040 if (!IN6_IS_ADDR_UNSPECIFIED(&vp->faddr.v6)) 1041 wildcard++; 1042 if (IN6_IS_ADDR_UNSPECIFIED(&vp->laddr.v6)) { 1043 if (!IN6_IS_ADDR_UNSPECIFIED(laddr6)) 1044 wildcard++; 1045 } else { 1046 if (IN6_IS_ADDR_V4MAPPED(laddr6)) { 1047 if (vp->v6only) 1048 continue; 1049 } 1050 if (IN6_IS_ADDR_UNSPECIFIED(laddr6)) 1051 wildcard++; 1052 else { 1053 if (!IN6_ARE_ADDR_EQUAL(&vp->laddr.v6, laddr6)) 1054 continue; 1055 } 1056 } 1057 if (wildcard && !lookup_wildcard) 1058 continue; 1059 if (wildcard < matchwild) { 1060 better = *vp; 1061 match = (void*)&better; 1062 1063 matchwild = wildcard; 1064 if (matchwild == 0) 1065 break; 1066 } 1067 } 1068 1069 if (match) { 1070 if (match != (void*)&better) 1071 return match; 1072 else { 1073 *vp = better; 1074 return 0; 1075 } 1076 } 1077 } 1078 return (match); 1079 } 1080 1081 /* 1082 * WARNING: return value (rtentry) could be IPv4 one if in6pcb is connected to 1083 * IPv4 mapped address. 1084 */ 1085 struct rtentry * 1086 in6_pcbrtentry(struct in6pcb *in6p) 1087 { 1088 struct rtentry *rt; 1089 struct route *ro; 1090 union { 1091 const struct sockaddr *sa; 1092 const struct sockaddr_in6 *sa6; 1093 #ifdef INET 1094 const struct sockaddr_in *sa4; 1095 #endif 1096 } cdst; 1097 1098 ro = &in6p->in6p_route; 1099 1100 if (in6p->in6p_af != AF_INET6) 1101 return (NULL); 1102 1103 cdst.sa = rtcache_getdst(ro); 1104 if (cdst.sa == NULL) 1105 ; 1106 #ifdef INET 1107 else if (cdst.sa->sa_family == AF_INET) { 1108 KASSERT(IN6_IS_ADDR_V4MAPPED(&in6p->in6p_faddr)); 1109 if (cdst.sa4->sin_addr.s_addr != in6p->in6p_faddr.s6_addr32[3]) 1110 rtcache_free(ro); 1111 } 1112 #endif 1113 else { 1114 if (!IN6_ARE_ADDR_EQUAL(&cdst.sa6->sin6_addr, 1115 &in6p->in6p_faddr)) 1116 rtcache_free(ro); 1117 } 1118 if ((rt = rtcache_validate(ro)) == NULL) 1119 rt = rtcache_update(ro, 1); 1120 #ifdef INET 1121 if (rt == NULL && IN6_IS_ADDR_V4MAPPED(&in6p->in6p_faddr)) { 1122 union { 1123 struct sockaddr dst; 1124 struct sockaddr_in dst4; 1125 } u; 1126 struct in_addr addr; 1127 1128 addr.s_addr = in6p->in6p_faddr.s6_addr32[3]; 1129 1130 sockaddr_in_init(&u.dst4, &addr, 0); 1131 if (rtcache_setdst(ro, &u.dst) != 0) 1132 return NULL; 1133 1134 rt = rtcache_init(ro); 1135 } else 1136 #endif 1137 if (rt == NULL && !IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) { 1138 union { 1139 struct sockaddr dst; 1140 struct sockaddr_in6 dst6; 1141 } u; 1142 1143 sockaddr_in6_init(&u.dst6, &in6p->in6p_faddr, 0, 0, 0); 1144 if (rtcache_setdst(ro, &u.dst) != 0) 1145 return NULL; 1146 1147 rt = rtcache_init(ro); 1148 } 1149 return rt; 1150 } 1151 1152 struct in6pcb * 1153 in6_pcblookup_connect(struct inpcbtable *table, const struct in6_addr *faddr6, 1154 u_int fport_arg, const struct in6_addr *laddr6, u_int lport_arg, 1155 int faith, 1156 struct vestigial_inpcb *vp) 1157 { 1158 struct inpcbhead *head; 1159 struct inpcb_hdr *inph; 1160 struct in6pcb *in6p; 1161 u_int16_t fport = fport_arg, lport = lport_arg; 1162 1163 if (vp) 1164 vp->valid = 0; 1165 1166 head = IN6PCBHASH_CONNECT(table, faddr6, fport, laddr6, lport); 1167 LIST_FOREACH(inph, head, inph_hash) { 1168 in6p = (struct in6pcb *)inph; 1169 if (in6p->in6p_af != AF_INET6) 1170 continue; 1171 1172 /* find exact match on both source and dest */ 1173 if (in6p->in6p_fport != fport) 1174 continue; 1175 if (in6p->in6p_lport != lport) 1176 continue; 1177 if (IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) 1178 continue; 1179 if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, faddr6)) 1180 continue; 1181 if (IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) 1182 continue; 1183 if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, laddr6)) 1184 continue; 1185 if ((IN6_IS_ADDR_V4MAPPED(laddr6) || 1186 IN6_IS_ADDR_V4MAPPED(faddr6)) && 1187 (in6p->in6p_flags & IN6P_IPV6_V6ONLY)) 1188 continue; 1189 return in6p; 1190 } 1191 if (vp && table->vestige) { 1192 if ((*table->vestige->lookup6)(faddr6, fport_arg, 1193 laddr6, lport_arg, vp)) 1194 return NULL; 1195 } 1196 1197 return NULL; 1198 } 1199 1200 struct in6pcb * 1201 in6_pcblookup_bind(struct inpcbtable *table, const struct in6_addr *laddr6, 1202 u_int lport_arg, int faith) 1203 { 1204 struct inpcbhead *head; 1205 struct inpcb_hdr *inph; 1206 struct in6pcb *in6p; 1207 u_int16_t lport = lport_arg; 1208 #ifdef INET 1209 struct in6_addr zero_mapped; 1210 #endif 1211 1212 head = IN6PCBHASH_BIND(table, laddr6, lport); 1213 LIST_FOREACH(inph, head, inph_hash) { 1214 in6p = (struct in6pcb *)inph; 1215 if (in6p->in6p_af != AF_INET6) 1216 continue; 1217 1218 if (faith && (in6p->in6p_flags & IN6P_FAITH) == 0) 1219 continue; 1220 if (in6p->in6p_fport != 0) 1221 continue; 1222 if (in6p->in6p_lport != lport) 1223 continue; 1224 if (IN6_IS_ADDR_V4MAPPED(laddr6) && 1225 (in6p->in6p_flags & IN6P_IPV6_V6ONLY) != 0) 1226 continue; 1227 if (IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, laddr6)) 1228 goto out; 1229 } 1230 #ifdef INET 1231 if (IN6_IS_ADDR_V4MAPPED(laddr6)) { 1232 memset(&zero_mapped, 0, sizeof(zero_mapped)); 1233 zero_mapped.s6_addr16[5] = 0xffff; 1234 head = IN6PCBHASH_BIND(table, &zero_mapped, lport); 1235 LIST_FOREACH(inph, head, inph_hash) { 1236 in6p = (struct in6pcb *)inph; 1237 if (in6p->in6p_af != AF_INET6) 1238 continue; 1239 1240 if (faith && (in6p->in6p_flags & IN6P_FAITH) == 0) 1241 continue; 1242 if (in6p->in6p_fport != 0) 1243 continue; 1244 if (in6p->in6p_lport != lport) 1245 continue; 1246 if ((in6p->in6p_flags & IN6P_IPV6_V6ONLY) != 0) 1247 continue; 1248 if (IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &zero_mapped)) 1249 goto out; 1250 } 1251 } 1252 #endif 1253 head = IN6PCBHASH_BIND(table, &zeroin6_addr, lport); 1254 LIST_FOREACH(inph, head, inph_hash) { 1255 in6p = (struct in6pcb *)inph; 1256 if (in6p->in6p_af != AF_INET6) 1257 continue; 1258 1259 if (faith && (in6p->in6p_flags & IN6P_FAITH) == 0) 1260 continue; 1261 if (in6p->in6p_fport != 0) 1262 continue; 1263 if (in6p->in6p_lport != lport) 1264 continue; 1265 if (IN6_IS_ADDR_V4MAPPED(laddr6) && 1266 (in6p->in6p_flags & IN6P_IPV6_V6ONLY) != 0) 1267 continue; 1268 if (IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr, &zeroin6_addr)) 1269 goto out; 1270 } 1271 return (NULL); 1272 1273 out: 1274 inph = &in6p->in6p_head; 1275 if (inph != LIST_FIRST(head)) { 1276 LIST_REMOVE(inph, inph_hash); 1277 LIST_INSERT_HEAD(head, inph, inph_hash); 1278 } 1279 return in6p; 1280 } 1281 1282 void 1283 in6_pcbstate(struct in6pcb *in6p, int state) 1284 { 1285 1286 if (in6p->in6p_af != AF_INET6) 1287 return; 1288 1289 if (in6p->in6p_state > IN6P_ATTACHED) 1290 LIST_REMOVE(&in6p->in6p_head, inph_hash); 1291 1292 switch (state) { 1293 case IN6P_BOUND: 1294 LIST_INSERT_HEAD(IN6PCBHASH_BIND(in6p->in6p_table, 1295 &in6p->in6p_laddr, in6p->in6p_lport), &in6p->in6p_head, 1296 inph_hash); 1297 break; 1298 case IN6P_CONNECTED: 1299 LIST_INSERT_HEAD(IN6PCBHASH_CONNECT(in6p->in6p_table, 1300 &in6p->in6p_faddr, in6p->in6p_fport, 1301 &in6p->in6p_laddr, in6p->in6p_lport), &in6p->in6p_head, 1302 inph_hash); 1303 break; 1304 } 1305 1306 in6p->in6p_state = state; 1307 } 1308