1 /* $OpenBSD: in_pcb.c,v 1.56 2001/07/05 16:45:54 jjbg Exp $ */ 2 /* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */ 3 4 /* 5 * Copyright (c) 1982, 1986, 1991, 1993 6 * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995 37 * 38 * NRL grants permission for redistribution and use in source and binary 39 * forms, with or without modification, of the software and documentation 40 * created at NRL provided that the following conditions are met: 41 * 42 * 1. Redistributions of source code must retain the above copyright 43 * notice, this list of conditions and the following disclaimer. 44 * 2. Redistributions in binary form must reproduce the above copyright 45 * notice, this list of conditions and the following disclaimer in the 46 * documentation and/or other materials provided with the distribution. 47 * 3. All advertising materials mentioning features or use of this software 48 * must display the following acknowledgements: 49 * This product includes software developed by the University of 50 * California, Berkeley and its contributors. 51 * This product includes software developed at the Information 52 * Technology Division, US Naval Research Laboratory. 53 * 4. Neither the name of the NRL nor the names of its contributors 54 * may be used to endorse or promote products derived from this software 55 * without specific prior written permission. 56 * 57 * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS 58 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 59 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 60 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NRL OR 61 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 62 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 63 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 64 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 65 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 66 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 67 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 68 * 69 * The views and conclusions contained in the software and documentation 70 * are those of the authors and should not be interpreted as representing 71 * official policies, either expressed or implied, of the US Naval 72 * Research Laboratory (NRL). 73 */ 74 75 #include <sys/param.h> 76 #include <sys/systm.h> 77 #include <sys/mbuf.h> 78 #include <sys/protosw.h> 79 #include <sys/socket.h> 80 #include <sys/socketvar.h> 81 #include <sys/proc.h> 82 #include <sys/domain.h> 83 84 #include <net/if.h> 85 #include <net/route.h> 86 87 #include <netinet/in.h> 88 #include <netinet/in_systm.h> 89 #include <netinet/ip.h> 90 #include <netinet/in_pcb.h> 91 #include <netinet/in_var.h> 92 #include <netinet/ip_var.h> 93 #include <dev/rndvar.h> 94 95 #ifdef INET6 96 #include <netinet6/ip6_var.h> 97 #endif /* INET6 */ 98 99 struct in_addr zeroin_addr; 100 101 extern int ipsec_auth_default_level; 102 extern int ipsec_esp_trans_default_level; 103 extern int ipsec_esp_network_default_level; 104 extern int ipsec_ipcomp_default_level; 105 106 /* 107 * These configure the range of local port addresses assigned to 108 * "unspecified" outgoing connections/packets/whatever. 109 */ 110 int ipport_firstauto = IPPORT_RESERVED; /* 1024 */ 111 int ipport_lastauto = IPPORT_USERRESERVED; /* 5000 */ 112 int ipport_hifirstauto = IPPORT_HIFIRSTAUTO; /* 40000 */ 113 int ipport_hilastauto = IPPORT_HILASTAUTO; /* 44999 */ 114 115 #define INPCBHASH(table, faddr, fport, laddr, lport) \ 116 &(table)->inpt_hashtbl[(ntohl((faddr)->s_addr) + \ 117 ntohs((fport)) + ntohs((lport))) & (table->inpt_hash)] 118 119 #define IN6PCBHASH(table, faddr, fport, laddr, lport) \ 120 &(table)->inpt_hashtbl[(ntohl((faddr)->s6_addr32[0] ^ \ 121 (faddr)->s6_addr32[3]) + ntohs((fport)) + ntohs((lport))) & \ 122 (table->inpt_hash)] 123 124 void 125 in_pcbinit(table, hashsize) 126 struct inpcbtable *table; 127 int hashsize; 128 { 129 130 CIRCLEQ_INIT(&table->inpt_queue); 131 table->inpt_hashtbl = hashinit(hashsize, M_PCB, M_WAITOK, &table->inpt_hash); 132 table->inpt_lastport = 0; 133 } 134 135 struct baddynamicports baddynamicports; 136 137 /* 138 * Check if the specified port is invalid for dynamic allocation. 139 */ 140 int 141 in_baddynamic(port, proto) 142 u_int16_t port; 143 u_int16_t proto; 144 { 145 146 if (port < IPPORT_RESERVED/2 || port >= IPPORT_RESERVED) 147 return(0); 148 149 switch (proto) { 150 case IPPROTO_TCP: 151 return (DP_ISSET(baddynamicports.tcp, port)); 152 case IPPROTO_UDP: 153 return (DP_ISSET(baddynamicports.udp, port)); 154 default: 155 return (0); 156 } 157 } 158 159 int 160 in_pcballoc(so, v) 161 struct socket *so; 162 void *v; 163 { 164 struct inpcbtable *table = v; 165 register struct inpcb *inp; 166 int s; 167 168 MALLOC(inp, struct inpcb *, sizeof(*inp), M_PCB, M_NOWAIT); 169 if (inp == NULL) 170 return (ENOBUFS); 171 bzero((caddr_t)inp, sizeof(*inp)); 172 inp->inp_table = table; 173 inp->inp_socket = so; 174 inp->inp_seclevel[SL_AUTH] = ipsec_auth_default_level; 175 inp->inp_seclevel[SL_ESP_TRANS] = ipsec_esp_trans_default_level; 176 inp->inp_seclevel[SL_ESP_NETWORK] = ipsec_esp_network_default_level; 177 inp->inp_seclevel[SL_IPCOMP] = ipsec_ipcomp_default_level; 178 s = splnet(); 179 CIRCLEQ_INSERT_HEAD(&table->inpt_queue, inp, inp_queue); 180 LIST_INSERT_HEAD(INPCBHASH(table, &inp->inp_faddr, inp->inp_fport, 181 &inp->inp_laddr, inp->inp_lport), inp, inp_hash); 182 splx(s); 183 so->so_pcb = inp; 184 inp->inp_hops = -1; 185 186 #ifdef INET6 187 /* 188 * Small change in this function to set the INP_IPV6 flag so routines 189 * outside pcb-specific routines don't need to use sotopf(), and all 190 * of it's pointer chasing, later. 191 */ 192 if (sotopf(so) == PF_INET6) 193 inp->inp_flags = INP_IPV6; 194 inp->in6p_cksum = -1; 195 #endif /* INET6 */ 196 return (0); 197 } 198 199 int 200 in_pcbbind(v, nam) 201 register void *v; 202 struct mbuf *nam; 203 { 204 register struct inpcb *inp = v; 205 register struct socket *so = inp->inp_socket; 206 register struct inpcbtable *table = inp->inp_table; 207 u_int16_t *lastport = &inp->inp_table->inpt_lastport; 208 register struct sockaddr_in *sin; 209 struct proc *p = curproc; /* XXX */ 210 u_int16_t lport = 0; 211 int wild = 0, reuseport = (so->so_options & SO_REUSEPORT); 212 int error; 213 214 #ifdef INET6 215 if (sotopf(so) == PF_INET6) 216 return in6_pcbbind(inp, nam); 217 #endif /* INET6 */ 218 219 if (in_ifaddr.tqh_first == 0) 220 return (EADDRNOTAVAIL); 221 if (inp->inp_lport || inp->inp_laddr.s_addr != INADDR_ANY) 222 return (EINVAL); 223 if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0 && 224 ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 || 225 (so->so_options & SO_ACCEPTCONN) == 0)) 226 wild = INPLOOKUP_WILDCARD; 227 if (nam) { 228 sin = mtod(nam, struct sockaddr_in *); 229 if (nam->m_len != sizeof (*sin)) 230 return (EINVAL); 231 #ifdef notdef 232 /* 233 * We should check the family, but old programs 234 * incorrectly fail to initialize it. 235 */ 236 if (sin->sin_family != AF_INET) 237 return (EAFNOSUPPORT); 238 #endif 239 lport = sin->sin_port; 240 if (IN_MULTICAST(sin->sin_addr.s_addr)) { 241 /* 242 * Treat SO_REUSEADDR as SO_REUSEPORT for multicast; 243 * allow complete duplication of binding if 244 * SO_REUSEPORT is set, or if SO_REUSEADDR is set 245 * and a multicast address is bound on both 246 * new and duplicated sockets. 247 */ 248 if (so->so_options & SO_REUSEADDR) 249 reuseport = SO_REUSEADDR|SO_REUSEPORT; 250 } else if (sin->sin_addr.s_addr != INADDR_ANY) { 251 sin->sin_port = 0; /* yech... */ 252 if (in_iawithaddr(sin->sin_addr, NULL) == 0) 253 return (EADDRNOTAVAIL); 254 } 255 if (lport) { 256 struct inpcb *t; 257 258 /* GROSS */ 259 if (ntohs(lport) < IPPORT_RESERVED && 260 (error = suser(p->p_ucred, &p->p_acflag))) 261 return (EACCES); 262 if (so->so_euid) { 263 t = in_pcblookup(table, &zeroin_addr, 0, 264 &sin->sin_addr, lport, INPLOOKUP_WILDCARD); 265 if (t && (so->so_euid != t->inp_socket->so_euid)) 266 return (EADDRINUSE); 267 } 268 t = in_pcblookup(table, &zeroin_addr, 0, 269 &sin->sin_addr, lport, wild); 270 if (t && (reuseport & t->inp_socket->so_options) == 0) 271 return (EADDRINUSE); 272 } 273 inp->inp_laddr = sin->sin_addr; 274 } 275 if (lport == 0) { 276 u_int16_t first, last, old = 0; 277 int count; 278 int loopcount = 0; 279 280 if (inp->inp_flags & INP_HIGHPORT) { 281 first = ipport_hifirstauto; /* sysctl */ 282 last = ipport_hilastauto; 283 } else if (inp->inp_flags & INP_LOWPORT) { 284 if ((error = suser(p->p_ucred, &p->p_acflag))) 285 return (EACCES); 286 first = IPPORT_RESERVED-1; /* 1023 */ 287 last = 600; /* not IPPORT_RESERVED/2 */ 288 } else { 289 first = ipport_firstauto; /* sysctl */ 290 last = ipport_lastauto; 291 } 292 293 /* 294 * Simple check to ensure all ports are not used up causing 295 * a deadlock here. 296 * 297 * We split the two cases (up and down) so that the direction 298 * is not being tested on each round of the loop. 299 */ 300 301 portloop: 302 if (first > last) { 303 /* 304 * counting down 305 */ 306 if (loopcount == 0) { /* only do this once. */ 307 old = first; 308 first -= (arc4random() % (first - last)); 309 } 310 count = first - last; 311 *lastport = first; /* restart each time */ 312 313 do { 314 if (count-- <= 0) { /* completely used? */ 315 if (loopcount == 0) { 316 last = old; 317 loopcount++; 318 goto portloop; 319 } 320 return (EADDRNOTAVAIL); 321 } 322 --*lastport; 323 if (*lastport > first || *lastport < last) 324 *lastport = first; 325 lport = htons(*lastport); 326 } while (in_baddynamic(*lastport, so->so_proto->pr_protocol) || 327 in_pcblookup(table, &zeroin_addr, 0, 328 &inp->inp_laddr, lport, wild)); 329 } else { 330 /* 331 * counting up 332 */ 333 if (loopcount == 0) { /* only do this once. */ 334 old = first; 335 first += (arc4random() % (last - first)); 336 } 337 count = last - first; 338 *lastport = first; /* restart each time */ 339 340 do { 341 if (count-- <= 0) { /* completely used? */ 342 if (loopcount == 0) { 343 first = old; 344 loopcount++; 345 goto portloop; 346 } 347 return (EADDRNOTAVAIL); 348 } 349 ++*lastport; 350 if (*lastport < first || *lastport > last) 351 *lastport = first; 352 lport = htons(*lastport); 353 } while (in_baddynamic(*lastport, so->so_proto->pr_protocol) || 354 in_pcblookup(table, &zeroin_addr, 0, 355 &inp->inp_laddr, lport, wild)); 356 } 357 } 358 inp->inp_lport = lport; 359 in_pcbrehash(inp); 360 return (0); 361 } 362 363 /* 364 * Connect from a socket to a specified address. 365 * Both address and port must be specified in argument sin. 366 * If don't have a local address for this socket yet, 367 * then pick one. 368 */ 369 int 370 in_pcbconnect(v, nam) 371 register void *v; 372 struct mbuf *nam; 373 { 374 register struct inpcb *inp = v; 375 struct sockaddr_in *ifaddr = NULL; 376 register struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *); 377 378 #ifdef INET6 379 if (sotopf(inp->inp_socket) == PF_INET6) 380 return (in6_pcbconnect(inp, nam)); 381 if ((inp->inp_flags & INP_IPV6) != 0) 382 panic("IPv6 pcb passed into in_pcbconnect"); 383 #endif /* INET6 */ 384 385 if (nam->m_len != sizeof (*sin)) 386 return (EINVAL); 387 if (sin->sin_family != AF_INET) 388 return (EAFNOSUPPORT); 389 if (sin->sin_port == 0) 390 return (EADDRNOTAVAIL); 391 if (in_ifaddr.tqh_first != 0) { 392 /* 393 * If the destination address is INADDR_ANY, 394 * use the primary local address. 395 * If the supplied address is INADDR_BROADCAST, 396 * and the primary interface supports broadcast, 397 * choose the broadcast address for that interface. 398 */ 399 if (sin->sin_addr.s_addr == INADDR_ANY) 400 sin->sin_addr = in_ifaddr.tqh_first->ia_addr.sin_addr; 401 else if (sin->sin_addr.s_addr == INADDR_BROADCAST && 402 (in_ifaddr.tqh_first->ia_ifp->if_flags & IFF_BROADCAST)) 403 sin->sin_addr = in_ifaddr.tqh_first->ia_broadaddr.sin_addr; 404 } 405 if (inp->inp_laddr.s_addr == INADDR_ANY) { 406 #if 0 407 register struct route *ro; 408 struct sockaddr_in *sin2; 409 struct in_ifaddr *ia; 410 411 ia = (struct in_ifaddr *)0; 412 /* 413 * If route is known or can be allocated now, 414 * our src addr is taken from the i/f, else punt. 415 */ 416 ro = &inp->inp_route; 417 if (ro->ro_rt && 418 (satosin(&ro->ro_dst)->sin_addr.s_addr != 419 sin->sin_addr.s_addr || 420 inp->inp_socket->so_options & SO_DONTROUTE)) { 421 RTFREE(ro->ro_rt); 422 ro->ro_rt = (struct rtentry *)0; 423 } 424 if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/ 425 (ro->ro_rt == (struct rtentry *)0 || 426 ro->ro_rt->rt_ifp == (struct ifnet *)0)) { 427 /* No route yet, so try to acquire one */ 428 ro->ro_dst.sa_family = AF_INET; 429 ro->ro_dst.sa_len = sizeof(struct sockaddr_in); 430 satosin(&ro->ro_dst)->sin_addr = sin->sin_addr; 431 rtalloc(ro); 432 433 /* 434 * It is important to bzero out the rest of the 435 * struct sockaddr_in when mixing v6 & v4! 436 */ 437 sin2 = (struct sockaddr_in *)&ro->ro_dst; 438 bzero(sin2->sin_zero, sizeof(sin2->sin_zero)); 439 } 440 /* 441 * If we found a route, use the address 442 * corresponding to the outgoing interface 443 * unless it is the loopback (in case a route 444 * to our address on another net goes to loopback). 445 */ 446 if (ro->ro_rt && !(ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK)) 447 ia = ifatoia(ro->ro_rt->rt_ifa); 448 if (ia == 0) { 449 u_int16_t fport = sin->sin_port; 450 451 sin->sin_port = 0; 452 ia = ifatoia(ifa_ifwithdstaddr(sintosa(sin))); 453 if (ia == 0) 454 ia = ifatoia(ifa_ifwithnet(sintosa(sin))); 455 sin->sin_port = fport; 456 if (ia == 0) 457 ia = in_ifaddr.tqh_first; 458 if (ia == 0) 459 return (EADDRNOTAVAIL); 460 } 461 /* 462 * If the destination address is multicast and an outgoing 463 * interface has been set as a multicast option, use the 464 * address of that interface as our source address. 465 */ 466 if (IN_MULTICAST(sin->sin_addr.s_addr) && 467 inp->inp_moptions != NULL) { 468 struct ip_moptions *imo; 469 struct ifnet *ifp; 470 471 imo = inp->inp_moptions; 472 if (imo->imo_multicast_ifp != NULL) { 473 ifp = imo->imo_multicast_ifp; 474 for (ia = in_ifaddr.tqh_first; ia != 0; 475 ia = ia->ia_list.tqe_next) 476 if (ia->ia_ifp == ifp) 477 break; 478 if (ia == 0) 479 return (EADDRNOTAVAIL); 480 } 481 } 482 ifaddr = satosin(&ia->ia_addr); 483 #else 484 int error; 485 ifaddr = in_selectsrc(sin, &inp->inp_route, 486 inp->inp_socket->so_options, inp->inp_moptions, &error); 487 if (ifaddr == NULL) { 488 if (error == 0) 489 error = EADDRNOTAVAIL; 490 return error; 491 } 492 #endif 493 } 494 if (in_pcbhashlookup(inp->inp_table, sin->sin_addr, sin->sin_port, 495 inp->inp_laddr.s_addr ? inp->inp_laddr : ifaddr->sin_addr, 496 inp->inp_lport) != 0) 497 return (EADDRINUSE); 498 if (inp->inp_laddr.s_addr == INADDR_ANY) { 499 if (inp->inp_lport == 0 && 500 in_pcbbind(inp, (struct mbuf *)0) == EADDRNOTAVAIL) 501 return (EADDRNOTAVAIL); 502 inp->inp_laddr = ifaddr->sin_addr; 503 } 504 inp->inp_faddr = sin->sin_addr; 505 inp->inp_fport = sin->sin_port; 506 in_pcbrehash(inp); 507 #ifdef IPSEC 508 /* XXX Find IPsec TDB */ 509 return (0); 510 #else 511 return (0); 512 #endif 513 } 514 515 void 516 in_pcbdisconnect(v) 517 void *v; 518 { 519 struct inpcb *inp = v; 520 521 switch (sotopf(inp->inp_socket)) { 522 #ifdef INET6 523 case PF_INET6: 524 inp->inp_faddr6 = in6addr_any; 525 break; 526 #endif 527 case PF_INET: 528 inp->inp_faddr.s_addr = INADDR_ANY; 529 break; 530 } 531 532 inp->inp_fport = 0; 533 in_pcbrehash(inp); 534 if (inp->inp_socket->so_state & SS_NOFDREF) 535 in_pcbdetach(inp); 536 } 537 538 void 539 in_pcbdetach(v) 540 void *v; 541 { 542 struct inpcb *inp = v; 543 struct socket *so = inp->inp_socket; 544 int s; 545 546 #if 0 /*KAME IPSEC*/ 547 if (so->so_pcb) { 548 KEYDEBUG(KEYDEBUG_KEY_STAMP, 549 printf("DP call free SO=%p from in_pcbdetach\n", so)); 550 key_freeso(so); 551 } 552 ipsec4_delete_pcbpolicy(inp); 553 #endif /*IPSEC*/ 554 so->so_pcb = 0; 555 sofree(so); 556 if (inp->inp_options) 557 (void)m_freem(inp->inp_options); 558 if (inp->inp_route.ro_rt) 559 rtfree(inp->inp_route.ro_rt); 560 #ifdef INET6 561 if (inp->inp_flags & INP_IPV6) 562 ip6_freemoptions(inp->inp_moptions6); 563 else 564 #endif 565 ip_freemoptions(inp->inp_moptions); 566 #ifdef IPSEC 567 /* XXX IPsec cleanup here */ 568 s = spltdb(); 569 if (inp->inp_tdb_in) 570 TAILQ_REMOVE(&inp->inp_tdb_in->tdb_inp_in, 571 inp, inp_tdb_in_next); 572 if (inp->inp_tdb_out) 573 TAILQ_REMOVE(&inp->inp_tdb_out->tdb_inp_out, inp, 574 inp_tdb_out_next); 575 if (inp->inp_ipsec_localid) 576 ipsp_reffree(inp->inp_ipsec_localid); 577 if (inp->inp_ipsec_remoteid) 578 ipsp_reffree(inp->inp_ipsec_remoteid); 579 if (inp->inp_ipsec_localcred) 580 ipsp_reffree(inp->inp_ipsec_localcred); 581 if (inp->inp_ipsec_remotecred) 582 ipsp_reffree(inp->inp_ipsec_remotecred); 583 if (inp->inp_ipsec_localauth) 584 ipsp_reffree(inp->inp_ipsec_localauth); 585 if (inp->inp_ipsec_remoteauth) 586 ipsp_reffree(inp->inp_ipsec_remoteauth); 587 splx(s); 588 #endif 589 s = splnet(); 590 LIST_REMOVE(inp, inp_hash); 591 CIRCLEQ_REMOVE(&inp->inp_table->inpt_queue, inp, inp_queue); 592 splx(s); 593 FREE(inp, M_PCB); 594 } 595 596 void 597 in_setsockaddr(inp, nam) 598 register struct inpcb *inp; 599 struct mbuf *nam; 600 { 601 register struct sockaddr_in *sin; 602 603 nam->m_len = sizeof (*sin); 604 sin = mtod(nam, struct sockaddr_in *); 605 bzero((caddr_t)sin, sizeof (*sin)); 606 sin->sin_family = AF_INET; 607 sin->sin_len = sizeof(*sin); 608 sin->sin_port = inp->inp_lport; 609 sin->sin_addr = inp->inp_laddr; 610 } 611 612 void 613 in_setpeeraddr(inp, nam) 614 struct inpcb *inp; 615 struct mbuf *nam; 616 { 617 register struct sockaddr_in *sin; 618 619 #ifdef INET6 620 if (sotopf(inp->inp_socket) == PF_INET6) { 621 in6_setpeeraddr(inp, nam); 622 return; 623 } 624 #endif /* INET6 */ 625 626 nam->m_len = sizeof (*sin); 627 sin = mtod(nam, struct sockaddr_in *); 628 bzero((caddr_t)sin, sizeof (*sin)); 629 sin->sin_family = AF_INET; 630 sin->sin_len = sizeof(*sin); 631 sin->sin_port = inp->inp_fport; 632 sin->sin_addr = inp->inp_faddr; 633 } 634 635 /* 636 * Pass some notification to all connections of a protocol 637 * associated with address dst. The local address and/or port numbers 638 * may be specified to limit the search. The "usual action" will be 639 * taken, depending on the ctlinput cmd. The caller must filter any 640 * cmds that are uninteresting (e.g., no error in the map). 641 * Call the protocol specific routine (if any) to report 642 * any errors for each matching socket. 643 * 644 * Must be called at splsoftnet. 645 */ 646 void 647 in_pcbnotify(table, dst, fport_arg, laddr, lport_arg, errno, notify) 648 struct inpcbtable *table; 649 struct sockaddr *dst; 650 u_int fport_arg, lport_arg; 651 struct in_addr laddr; 652 int errno; 653 void (*notify) __P((struct inpcb *, int)); 654 { 655 register struct inpcb *inp, *oinp; 656 struct in_addr faddr; 657 u_int16_t fport = fport_arg, lport = lport_arg; 658 659 #ifdef INET6 660 /* 661 * See in6_pcbnotify() for IPv6 codepath. By the time this 662 * gets called, the addresses passed are either definitely IPv4 or 663 * IPv6; *_pcbnotify() never gets called with v4-mapped v6 addresses. 664 */ 665 #endif /* INET6 */ 666 667 if (dst->sa_family != AF_INET) 668 return; 669 faddr = satosin(dst)->sin_addr; 670 if (faddr.s_addr == INADDR_ANY) 671 return; 672 673 for (inp = table->inpt_queue.cqh_first; 674 inp != (struct inpcb *)&table->inpt_queue;) { 675 #ifdef INET6 676 if (inp->inp_flags & INP_IPV6) { 677 inp = inp->inp_queue.cqe_next; 678 continue; 679 } 680 #endif 681 if (inp->inp_faddr.s_addr != faddr.s_addr || 682 inp->inp_socket == 0 || 683 inp->inp_fport != fport || 684 inp->inp_lport != lport || 685 inp->inp_laddr.s_addr != laddr.s_addr) { 686 inp = inp->inp_queue.cqe_next; 687 continue; 688 } 689 oinp = inp; 690 inp = inp->inp_queue.cqe_next; 691 if (notify) 692 (*notify)(oinp, errno); 693 } 694 } 695 696 void 697 in_pcbnotifyall(table, dst, errno, notify) 698 struct inpcbtable *table; 699 struct sockaddr *dst; 700 int errno; 701 void (*notify) __P((struct inpcb *, int)); 702 { 703 register struct inpcb *inp, *oinp; 704 struct in_addr faddr; 705 706 #ifdef INET6 707 /* 708 * See in6_pcbnotify() for IPv6 codepath. By the time this 709 * gets called, the addresses passed are either definitely IPv4 or 710 * IPv6; *_pcbnotify() never gets called with v4-mapped v6 addresses. 711 */ 712 #endif /* INET6 */ 713 714 if (dst->sa_family != AF_INET) 715 return; 716 faddr = satosin(dst)->sin_addr; 717 if (faddr.s_addr == INADDR_ANY) 718 return; 719 720 for (inp = table->inpt_queue.cqh_first; 721 inp != (struct inpcb *)&table->inpt_queue;) { 722 #ifdef INET6 723 if (inp->inp_flags & INP_IPV6) { 724 inp = inp->inp_queue.cqe_next; 725 continue; 726 } 727 #endif 728 if (inp->inp_faddr.s_addr != faddr.s_addr || 729 inp->inp_socket == 0) { 730 inp = inp->inp_queue.cqe_next; 731 continue; 732 } 733 oinp = inp; 734 inp = inp->inp_queue.cqe_next; 735 if (notify) 736 (*notify)(oinp, errno); 737 } 738 } 739 740 /* 741 * Check for alternatives when higher level complains 742 * about service problems. For now, invalidate cached 743 * routing information. If the route was created dynamically 744 * (by a redirect), time to try a default gateway again. 745 */ 746 void 747 in_losing(inp) 748 struct inpcb *inp; 749 { 750 register struct rtentry *rt; 751 struct rt_addrinfo info; 752 753 if ((rt = inp->inp_route.ro_rt)) { 754 inp->inp_route.ro_rt = 0; 755 bzero((caddr_t)&info, sizeof(info)); 756 info.rti_info[RTAX_DST] = &inp->inp_route.ro_dst; 757 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 758 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 759 rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0); 760 if (rt->rt_flags & RTF_DYNAMIC) 761 (void) rtrequest(RTM_DELETE, rt_key(rt), 762 rt->rt_gateway, rt_mask(rt), rt->rt_flags, 763 (struct rtentry **)0); 764 else 765 /* 766 * A new route can be allocated 767 * the next time output is attempted. 768 */ 769 rtfree(rt); 770 } 771 } 772 773 /* 774 * After a routing change, flush old routing 775 * and allocate a (hopefully) better one. 776 */ 777 void 778 in_rtchange(inp, errno) 779 register struct inpcb *inp; 780 int errno; 781 { 782 if (inp->inp_route.ro_rt) { 783 rtfree(inp->inp_route.ro_rt); 784 inp->inp_route.ro_rt = 0; 785 /* 786 * A new route can be allocated the next time 787 * output is attempted. 788 */ 789 } 790 } 791 792 struct inpcb * 793 in_pcblookup(table, faddrp, fport_arg, laddrp, lport_arg, flags) 794 struct inpcbtable *table; 795 void *faddrp, *laddrp; 796 u_int fport_arg, lport_arg; 797 int flags; 798 { 799 register struct inpcb *inp, *match = 0; 800 int matchwild = 3, wildcard; 801 u_int16_t fport = fport_arg, lport = lport_arg; 802 struct in_addr faddr = *(struct in_addr *)faddrp; 803 struct in_addr laddr = *(struct in_addr *)laddrp; 804 805 for (inp = table->inpt_queue.cqh_first; 806 inp != (struct inpcb *)&table->inpt_queue; 807 inp = inp->inp_queue.cqe_next) { 808 if (inp->inp_lport != lport) 809 continue; 810 wildcard = 0; 811 #ifdef INET6 812 if (flags & INPLOOKUP_IPV6) { 813 struct in6_addr *laddr6 = (struct in6_addr *)laddrp; 814 struct in6_addr *faddr6 = (struct in6_addr *)faddrp; 815 816 /* 817 * Always skip AF_INET sockets when looking 818 * for AF_INET6 addresses. The only problem 819 * with this comes if the PF_INET6 addresses 820 * are v4-mapped addresses. From what I've 821 * been able to see, none of the callers cause 822 * such a situation to occur. If such a 823 * situation DID occur, then it is possible to 824 * miss a matching PCB. 825 */ 826 if (!(inp->inp_flags & INP_IPV6)) 827 continue; 828 829 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6)) { 830 if (IN6_IS_ADDR_UNSPECIFIED(laddr6)) 831 wildcard++; 832 else if (!IN6_ARE_ADDR_EQUAL(&inp->inp_laddr6, laddr6)) 833 continue; 834 } else { 835 if (!IN6_IS_ADDR_UNSPECIFIED(laddr6)) 836 wildcard++; 837 } 838 839 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) { 840 if (IN6_IS_ADDR_UNSPECIFIED(faddr6)) 841 wildcard++; 842 else if (!IN6_ARE_ADDR_EQUAL(&inp->inp_faddr6, 843 faddr6) || inp->inp_fport != fport) 844 continue; 845 } else { 846 if (!IN6_IS_ADDR_UNSPECIFIED(faddr6)) 847 wildcard++; 848 } 849 } else 850 #endif /* INET6 */ 851 { 852 #ifdef INET6 853 if (inp->inp_flags & INP_IPV6) 854 continue; 855 #endif /* INET6 */ 856 857 if (inp->inp_faddr.s_addr != INADDR_ANY) { 858 if (faddr.s_addr == INADDR_ANY) 859 wildcard++; 860 else if (inp->inp_faddr.s_addr != faddr.s_addr || 861 inp->inp_fport != fport) 862 continue; 863 } else { 864 if (faddr.s_addr != INADDR_ANY) 865 wildcard++; 866 } 867 if (inp->inp_laddr.s_addr != INADDR_ANY) { 868 if (laddr.s_addr == INADDR_ANY) 869 wildcard++; 870 else if (inp->inp_laddr.s_addr != laddr.s_addr) 871 continue; 872 } else { 873 if (laddr.s_addr != INADDR_ANY) 874 wildcard++; 875 } 876 } 877 if ((!wildcard || (flags & INPLOOKUP_WILDCARD)) && 878 wildcard < matchwild) { 879 match = inp; 880 if ((matchwild = wildcard) == 0) 881 break; 882 } 883 } 884 return (match); 885 } 886 887 struct rtentry * 888 in_pcbrtentry(inp) 889 struct inpcb *inp; 890 { 891 struct route *ro; 892 893 ro = &inp->inp_route; 894 895 /* 896 * No route yet, so try to acquire one. 897 */ 898 if (ro->ro_rt == NULL) { 899 #ifdef INET6 900 bzero(ro, sizeof(struct route_in6)); 901 #else 902 bzero(ro, sizeof(struct route)); 903 #endif 904 905 switch(sotopf(inp->inp_socket)) { 906 #ifdef INET6 907 case PF_INET6: 908 if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) 909 break; 910 ro->ro_dst.sa_family = AF_INET6; 911 ro->ro_dst.sa_len = sizeof(struct sockaddr_in6); 912 ((struct sockaddr_in6 *) &ro->ro_dst)->sin6_addr = 913 inp->inp_faddr6; 914 rtalloc(ro); 915 break; 916 #endif /* INET6 */ 917 case PF_INET: 918 if (inp->inp_faddr.s_addr == INADDR_ANY) 919 break; 920 ro->ro_dst.sa_family = AF_INET; 921 ro->ro_dst.sa_len = sizeof(ro->ro_dst); 922 satosin(&ro->ro_dst)->sin_addr = inp->inp_faddr; 923 rtalloc(ro); 924 break; 925 } 926 } 927 return (ro->ro_rt); 928 } 929 930 struct sockaddr_in * 931 in_selectsrc(sin, ro, soopts, mopts, errorp) 932 struct sockaddr_in *sin; 933 struct route *ro; 934 int soopts; 935 struct ip_moptions *mopts; 936 int *errorp; 937 { 938 struct sockaddr_in *sin2; 939 struct in_ifaddr *ia; 940 941 ia = (struct in_ifaddr *)0; 942 /* 943 * If route is known or can be allocated now, 944 * our src addr is taken from the i/f, else punt. 945 */ 946 if (ro->ro_rt && 947 (satosin(&ro->ro_dst)->sin_addr.s_addr != 948 sin->sin_addr.s_addr || 949 soopts & SO_DONTROUTE)) { 950 RTFREE(ro->ro_rt); 951 ro->ro_rt = (struct rtentry *)0; 952 } 953 if ((soopts & SO_DONTROUTE) == 0 && /*XXX*/ 954 (ro->ro_rt == (struct rtentry *)0 || 955 ro->ro_rt->rt_ifp == (struct ifnet *)0)) { 956 /* No route yet, so try to acquire one */ 957 ro->ro_dst.sa_family = AF_INET; 958 ro->ro_dst.sa_len = sizeof(struct sockaddr_in); 959 satosin(&ro->ro_dst)->sin_addr = sin->sin_addr; 960 rtalloc(ro); 961 962 /* 963 * It is important to bzero out the rest of the 964 * struct sockaddr_in when mixing v6 & v4! 965 */ 966 sin2 = (struct sockaddr_in *)&ro->ro_dst; 967 bzero(sin2->sin_zero, sizeof(sin2->sin_zero)); 968 } 969 /* 970 * If we found a route, use the address 971 * corresponding to the outgoing interface 972 * unless it is the loopback (in case a route 973 * to our address on another net goes to loopback). 974 */ 975 if (ro->ro_rt && !(ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK)) 976 ia = ifatoia(ro->ro_rt->rt_ifa); 977 if (ia == 0) { 978 u_int16_t fport = sin->sin_port; 979 980 sin->sin_port = 0; 981 ia = ifatoia(ifa_ifwithdstaddr(sintosa(sin))); 982 if (ia == 0) 983 ia = ifatoia(ifa_ifwithnet(sintosa(sin))); 984 sin->sin_port = fport; 985 if (ia == 0) 986 ia = in_ifaddr.tqh_first; 987 if (ia == 0) { 988 *errorp = EADDRNOTAVAIL; 989 return NULL; 990 } 991 } 992 /* 993 * If the destination address is multicast and an outgoing 994 * interface has been set as a multicast option, use the 995 * address of that interface as our source address. 996 */ 997 if (IN_MULTICAST(sin->sin_addr.s_addr) && mopts != NULL) { 998 struct ip_moptions *imo; 999 struct ifnet *ifp; 1000 1001 imo = mopts; 1002 if (imo->imo_multicast_ifp != NULL) { 1003 ifp = imo->imo_multicast_ifp; 1004 for (ia = in_ifaddr.tqh_first; ia != 0; 1005 ia = ia->ia_list.tqe_next) 1006 if (ia->ia_ifp == ifp) 1007 break; 1008 if (ia == 0) { 1009 *errorp = EADDRNOTAVAIL; 1010 return NULL; 1011 } 1012 } 1013 } 1014 return satosin(&ia->ia_addr); 1015 } 1016 1017 void 1018 in_pcbrehash(inp) 1019 struct inpcb *inp; 1020 { 1021 struct inpcbtable *table = inp->inp_table; 1022 int s; 1023 1024 s = splnet(); 1025 LIST_REMOVE(inp, inp_hash); 1026 #ifdef INET6 1027 if (inp->inp_flags & INP_IPV6) { 1028 LIST_INSERT_HEAD(IN6PCBHASH(table, &inp->inp_faddr6, 1029 inp->inp_fport, &inp->inp_laddr6, inp->inp_lport), 1030 inp, inp_hash); 1031 } else { 1032 #endif /* INET6 */ 1033 LIST_INSERT_HEAD(INPCBHASH(table, &inp->inp_faddr, 1034 inp->inp_fport, &inp->inp_laddr, inp->inp_lport), 1035 inp, inp_hash); 1036 #ifdef INET6 1037 } 1038 #endif /* INET6 */ 1039 splx(s); 1040 } 1041 1042 #ifdef DIAGNOSTIC 1043 int in_pcbnotifymiss = 0; 1044 #endif 1045 1046 struct inpcb * 1047 in_pcbhashlookup(table, faddr, fport_arg, laddr, lport_arg) 1048 struct inpcbtable *table; 1049 struct in_addr faddr, laddr; 1050 u_int fport_arg, lport_arg; 1051 { 1052 struct inpcbhead *head; 1053 register struct inpcb *inp; 1054 u_int16_t fport = fport_arg, lport = lport_arg; 1055 1056 head = INPCBHASH(table, &faddr, fport, &laddr, lport); 1057 for (inp = head->lh_first; inp != NULL; inp = inp->inp_hash.le_next) { 1058 #ifdef INET6 1059 if (inp->inp_flags & INP_IPV6) 1060 continue; /*XXX*/ 1061 #endif 1062 if (inp->inp_faddr.s_addr == faddr.s_addr && 1063 inp->inp_fport == fport && 1064 inp->inp_lport == lport && 1065 inp->inp_laddr.s_addr == laddr.s_addr) { 1066 /* 1067 * Move this PCB to the head of hash chain so that 1068 * repeated accesses are quicker. This is analogous to 1069 * the historic single-entry PCB cache. 1070 */ 1071 if (inp != head->lh_first) { 1072 LIST_REMOVE(inp, inp_hash); 1073 LIST_INSERT_HEAD(head, inp, inp_hash); 1074 } 1075 break; 1076 } 1077 } 1078 #ifdef DIAGNOSTIC 1079 if (inp == NULL && in_pcbnotifymiss) { 1080 printf("in_pcbhashlookup: faddr=%08x fport=%d laddr=%08x lport=%d\n", 1081 ntohl(faddr.s_addr), ntohs(fport), 1082 ntohl(laddr.s_addr), ntohs(lport)); 1083 } 1084 #endif 1085 return (inp); 1086 } 1087 1088 #ifdef INET6 1089 struct inpcb * 1090 in6_pcbhashlookup(table, faddr, fport_arg, laddr, lport_arg) 1091 struct inpcbtable *table; 1092 struct in6_addr *faddr, *laddr; 1093 u_int fport_arg, lport_arg; 1094 { 1095 struct inpcbhead *head; 1096 register struct inpcb *inp; 1097 u_int16_t fport = fport_arg, lport = lport_arg; 1098 1099 head = IN6PCBHASH(table, faddr, fport, laddr, lport); 1100 for (inp = head->lh_first; inp != NULL; inp = inp->inp_hash.le_next) { 1101 if (!(inp->inp_flags & INP_IPV6)) 1102 continue; 1103 if (IN6_ARE_ADDR_EQUAL(&inp->inp_faddr6, faddr) && 1104 inp->inp_fport == fport && inp->inp_lport == lport && 1105 IN6_ARE_ADDR_EQUAL(&inp->inp_laddr6, laddr)) { 1106 /* 1107 * Move this PCB to the head of hash chain so that 1108 * repeated accesses are quicker. This is analogous to 1109 * the historic single-entry PCB cache. 1110 */ 1111 if (inp != head->lh_first) { 1112 LIST_REMOVE(inp, inp_hash); 1113 LIST_INSERT_HEAD(head, inp, inp_hash); 1114 } 1115 break; 1116 } 1117 } 1118 #ifdef DIAGNOSTIC 1119 if (inp == NULL && in_pcbnotifymiss) { 1120 printf("in6_pcblookup_connect: faddr="); 1121 printf(" fport=%d laddr=", ntohs(fport)); 1122 printf(" lport=%d\n", ntohs(lport)); 1123 } 1124 #endif 1125 return (inp); 1126 } 1127 #endif /* INET6 */ 1128 1129 1130