1 /* $OpenBSD: in_pcb.c,v 1.58 2001/12/06 02:21:48 itojun 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 so->so_pcb = 0; 547 sofree(so); 548 if (inp->inp_options) 549 (void)m_freem(inp->inp_options); 550 if (inp->inp_route.ro_rt) 551 rtfree(inp->inp_route.ro_rt); 552 #ifdef INET6 553 if (inp->inp_flags & INP_IPV6) 554 ip6_freemoptions(inp->inp_moptions6); 555 else 556 #endif 557 ip_freemoptions(inp->inp_moptions); 558 #ifdef IPSEC 559 /* XXX IPsec cleanup here */ 560 s = spltdb(); 561 if (inp->inp_tdb_in) 562 TAILQ_REMOVE(&inp->inp_tdb_in->tdb_inp_in, 563 inp, inp_tdb_in_next); 564 if (inp->inp_tdb_out) 565 TAILQ_REMOVE(&inp->inp_tdb_out->tdb_inp_out, inp, 566 inp_tdb_out_next); 567 if (inp->inp_ipsec_localid) 568 ipsp_reffree(inp->inp_ipsec_localid); 569 if (inp->inp_ipsec_remoteid) 570 ipsp_reffree(inp->inp_ipsec_remoteid); 571 if (inp->inp_ipsec_localcred) 572 ipsp_reffree(inp->inp_ipsec_localcred); 573 if (inp->inp_ipsec_remotecred) 574 ipsp_reffree(inp->inp_ipsec_remotecred); 575 if (inp->inp_ipsec_localauth) 576 ipsp_reffree(inp->inp_ipsec_localauth); 577 if (inp->inp_ipsec_remoteauth) 578 ipsp_reffree(inp->inp_ipsec_remoteauth); 579 splx(s); 580 #endif 581 s = splnet(); 582 LIST_REMOVE(inp, inp_hash); 583 CIRCLEQ_REMOVE(&inp->inp_table->inpt_queue, inp, inp_queue); 584 splx(s); 585 FREE(inp, M_PCB); 586 } 587 588 void 589 in_setsockaddr(inp, nam) 590 register struct inpcb *inp; 591 struct mbuf *nam; 592 { 593 register struct sockaddr_in *sin; 594 595 nam->m_len = sizeof (*sin); 596 sin = mtod(nam, struct sockaddr_in *); 597 bzero((caddr_t)sin, sizeof (*sin)); 598 sin->sin_family = AF_INET; 599 sin->sin_len = sizeof(*sin); 600 sin->sin_port = inp->inp_lport; 601 sin->sin_addr = inp->inp_laddr; 602 } 603 604 void 605 in_setpeeraddr(inp, nam) 606 struct inpcb *inp; 607 struct mbuf *nam; 608 { 609 register struct sockaddr_in *sin; 610 611 #ifdef INET6 612 if (sotopf(inp->inp_socket) == PF_INET6) { 613 in6_setpeeraddr(inp, nam); 614 return; 615 } 616 #endif /* INET6 */ 617 618 nam->m_len = sizeof (*sin); 619 sin = mtod(nam, struct sockaddr_in *); 620 bzero((caddr_t)sin, sizeof (*sin)); 621 sin->sin_family = AF_INET; 622 sin->sin_len = sizeof(*sin); 623 sin->sin_port = inp->inp_fport; 624 sin->sin_addr = inp->inp_faddr; 625 } 626 627 /* 628 * Pass some notification to all connections of a protocol 629 * associated with address dst. The local address and/or port numbers 630 * may be specified to limit the search. The "usual action" will be 631 * taken, depending on the ctlinput cmd. The caller must filter any 632 * cmds that are uninteresting (e.g., no error in the map). 633 * Call the protocol specific routine (if any) to report 634 * any errors for each matching socket. 635 * 636 * Must be called at splsoftnet. 637 */ 638 void 639 in_pcbnotify(table, dst, fport_arg, laddr, lport_arg, errno, notify) 640 struct inpcbtable *table; 641 struct sockaddr *dst; 642 u_int fport_arg, lport_arg; 643 struct in_addr laddr; 644 int errno; 645 void (*notify) __P((struct inpcb *, int)); 646 { 647 register struct inpcb *inp, *oinp; 648 struct in_addr faddr; 649 u_int16_t fport = fport_arg, lport = lport_arg; 650 651 #ifdef INET6 652 /* 653 * See in6_pcbnotify() for IPv6 codepath. By the time this 654 * gets called, the addresses passed are either definitely IPv4 or 655 * IPv6; *_pcbnotify() never gets called with v4-mapped v6 addresses. 656 */ 657 #endif /* INET6 */ 658 659 if (dst->sa_family != AF_INET) 660 return; 661 faddr = satosin(dst)->sin_addr; 662 if (faddr.s_addr == INADDR_ANY) 663 return; 664 665 for (inp = table->inpt_queue.cqh_first; 666 inp != (struct inpcb *)&table->inpt_queue;) { 667 #ifdef INET6 668 if (inp->inp_flags & INP_IPV6) { 669 inp = inp->inp_queue.cqe_next; 670 continue; 671 } 672 #endif 673 if (inp->inp_faddr.s_addr != faddr.s_addr || 674 inp->inp_socket == 0 || 675 inp->inp_fport != fport || 676 inp->inp_lport != lport || 677 inp->inp_laddr.s_addr != laddr.s_addr) { 678 inp = inp->inp_queue.cqe_next; 679 continue; 680 } 681 oinp = inp; 682 inp = inp->inp_queue.cqe_next; 683 if (notify) 684 (*notify)(oinp, errno); 685 } 686 } 687 688 void 689 in_pcbnotifyall(table, dst, errno, notify) 690 struct inpcbtable *table; 691 struct sockaddr *dst; 692 int errno; 693 void (*notify) __P((struct inpcb *, int)); 694 { 695 register struct inpcb *inp, *oinp; 696 struct in_addr faddr; 697 698 #ifdef INET6 699 /* 700 * See in6_pcbnotify() for IPv6 codepath. By the time this 701 * gets called, the addresses passed are either definitely IPv4 or 702 * IPv6; *_pcbnotify() never gets called with v4-mapped v6 addresses. 703 */ 704 #endif /* INET6 */ 705 706 if (dst->sa_family != AF_INET) 707 return; 708 faddr = satosin(dst)->sin_addr; 709 if (faddr.s_addr == INADDR_ANY) 710 return; 711 712 for (inp = table->inpt_queue.cqh_first; 713 inp != (struct inpcb *)&table->inpt_queue;) { 714 #ifdef INET6 715 if (inp->inp_flags & INP_IPV6) { 716 inp = inp->inp_queue.cqe_next; 717 continue; 718 } 719 #endif 720 if (inp->inp_faddr.s_addr != faddr.s_addr || 721 inp->inp_socket == 0) { 722 inp = inp->inp_queue.cqe_next; 723 continue; 724 } 725 oinp = inp; 726 inp = inp->inp_queue.cqe_next; 727 if (notify) 728 (*notify)(oinp, errno); 729 } 730 } 731 732 /* 733 * Check for alternatives when higher level complains 734 * about service problems. For now, invalidate cached 735 * routing information. If the route was created dynamically 736 * (by a redirect), time to try a default gateway again. 737 */ 738 void 739 in_losing(inp) 740 struct inpcb *inp; 741 { 742 register struct rtentry *rt; 743 struct rt_addrinfo info; 744 745 if ((rt = inp->inp_route.ro_rt)) { 746 inp->inp_route.ro_rt = 0; 747 bzero((caddr_t)&info, sizeof(info)); 748 info.rti_info[RTAX_DST] = &inp->inp_route.ro_dst; 749 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 750 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 751 rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0); 752 if (rt->rt_flags & RTF_DYNAMIC) 753 (void) rtrequest(RTM_DELETE, rt_key(rt), 754 rt->rt_gateway, rt_mask(rt), rt->rt_flags, 755 (struct rtentry **)0); 756 else 757 /* 758 * A new route can be allocated 759 * the next time output is attempted. 760 */ 761 rtfree(rt); 762 } 763 } 764 765 /* 766 * After a routing change, flush old routing 767 * and allocate a (hopefully) better one. 768 */ 769 void 770 in_rtchange(inp, errno) 771 register struct inpcb *inp; 772 int errno; 773 { 774 if (inp->inp_route.ro_rt) { 775 rtfree(inp->inp_route.ro_rt); 776 inp->inp_route.ro_rt = 0; 777 /* 778 * A new route can be allocated the next time 779 * output is attempted. 780 */ 781 } 782 } 783 784 struct inpcb * 785 in_pcblookup(table, faddrp, fport_arg, laddrp, lport_arg, flags) 786 struct inpcbtable *table; 787 void *faddrp, *laddrp; 788 u_int fport_arg, lport_arg; 789 int flags; 790 { 791 register struct inpcb *inp, *match = 0; 792 int matchwild = 3, wildcard; 793 u_int16_t fport = fport_arg, lport = lport_arg; 794 struct in_addr faddr = *(struct in_addr *)faddrp; 795 struct in_addr laddr = *(struct in_addr *)laddrp; 796 797 for (inp = table->inpt_queue.cqh_first; 798 inp != (struct inpcb *)&table->inpt_queue; 799 inp = inp->inp_queue.cqe_next) { 800 if (inp->inp_lport != lport) 801 continue; 802 wildcard = 0; 803 #ifdef INET6 804 if (flags & INPLOOKUP_IPV6) { 805 struct in6_addr *laddr6 = (struct in6_addr *)laddrp; 806 struct in6_addr *faddr6 = (struct in6_addr *)faddrp; 807 808 if (!(inp->inp_flags & INP_IPV6)) 809 continue; 810 811 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6)) { 812 if (IN6_IS_ADDR_UNSPECIFIED(laddr6)) 813 wildcard++; 814 else if (!IN6_ARE_ADDR_EQUAL(&inp->inp_laddr6, laddr6)) 815 continue; 816 } else { 817 if (!IN6_IS_ADDR_UNSPECIFIED(laddr6)) 818 wildcard++; 819 } 820 821 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) { 822 if (IN6_IS_ADDR_UNSPECIFIED(faddr6)) 823 wildcard++; 824 else if (!IN6_ARE_ADDR_EQUAL(&inp->inp_faddr6, 825 faddr6) || inp->inp_fport != fport) 826 continue; 827 } else { 828 if (!IN6_IS_ADDR_UNSPECIFIED(faddr6)) 829 wildcard++; 830 } 831 } else 832 #endif /* INET6 */ 833 { 834 #ifdef INET6 835 if (inp->inp_flags & INP_IPV6) 836 continue; 837 #endif /* INET6 */ 838 839 if (inp->inp_faddr.s_addr != INADDR_ANY) { 840 if (faddr.s_addr == INADDR_ANY) 841 wildcard++; 842 else if (inp->inp_faddr.s_addr != faddr.s_addr || 843 inp->inp_fport != fport) 844 continue; 845 } else { 846 if (faddr.s_addr != INADDR_ANY) 847 wildcard++; 848 } 849 if (inp->inp_laddr.s_addr != INADDR_ANY) { 850 if (laddr.s_addr == INADDR_ANY) 851 wildcard++; 852 else if (inp->inp_laddr.s_addr != laddr.s_addr) 853 continue; 854 } else { 855 if (laddr.s_addr != INADDR_ANY) 856 wildcard++; 857 } 858 } 859 if ((!wildcard || (flags & INPLOOKUP_WILDCARD)) && 860 wildcard < matchwild) { 861 match = inp; 862 if ((matchwild = wildcard) == 0) 863 break; 864 } 865 } 866 return (match); 867 } 868 869 struct rtentry * 870 in_pcbrtentry(inp) 871 struct inpcb *inp; 872 { 873 struct route *ro; 874 875 ro = &inp->inp_route; 876 877 /* 878 * No route yet, so try to acquire one. 879 */ 880 if (ro->ro_rt == NULL) { 881 #ifdef INET6 882 bzero(ro, sizeof(struct route_in6)); 883 #else 884 bzero(ro, sizeof(struct route)); 885 #endif 886 887 switch(sotopf(inp->inp_socket)) { 888 #ifdef INET6 889 case PF_INET6: 890 if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) 891 break; 892 ro->ro_dst.sa_family = AF_INET6; 893 ro->ro_dst.sa_len = sizeof(struct sockaddr_in6); 894 ((struct sockaddr_in6 *) &ro->ro_dst)->sin6_addr = 895 inp->inp_faddr6; 896 rtalloc(ro); 897 break; 898 #endif /* INET6 */ 899 case PF_INET: 900 if (inp->inp_faddr.s_addr == INADDR_ANY) 901 break; 902 ro->ro_dst.sa_family = AF_INET; 903 ro->ro_dst.sa_len = sizeof(ro->ro_dst); 904 satosin(&ro->ro_dst)->sin_addr = inp->inp_faddr; 905 rtalloc(ro); 906 break; 907 } 908 } 909 return (ro->ro_rt); 910 } 911 912 struct sockaddr_in * 913 in_selectsrc(sin, ro, soopts, mopts, errorp) 914 struct sockaddr_in *sin; 915 struct route *ro; 916 int soopts; 917 struct ip_moptions *mopts; 918 int *errorp; 919 { 920 struct sockaddr_in *sin2; 921 struct in_ifaddr *ia; 922 923 ia = (struct in_ifaddr *)0; 924 /* 925 * If route is known or can be allocated now, 926 * our src addr is taken from the i/f, else punt. 927 */ 928 if (ro->ro_rt && 929 (satosin(&ro->ro_dst)->sin_addr.s_addr != 930 sin->sin_addr.s_addr || 931 soopts & SO_DONTROUTE)) { 932 RTFREE(ro->ro_rt); 933 ro->ro_rt = (struct rtentry *)0; 934 } 935 if ((soopts & SO_DONTROUTE) == 0 && /*XXX*/ 936 (ro->ro_rt == (struct rtentry *)0 || 937 ro->ro_rt->rt_ifp == (struct ifnet *)0)) { 938 /* No route yet, so try to acquire one */ 939 ro->ro_dst.sa_family = AF_INET; 940 ro->ro_dst.sa_len = sizeof(struct sockaddr_in); 941 satosin(&ro->ro_dst)->sin_addr = sin->sin_addr; 942 rtalloc(ro); 943 944 /* 945 * It is important to bzero out the rest of the 946 * struct sockaddr_in when mixing v6 & v4! 947 */ 948 sin2 = (struct sockaddr_in *)&ro->ro_dst; 949 bzero(sin2->sin_zero, sizeof(sin2->sin_zero)); 950 } 951 /* 952 * If we found a route, use the address 953 * corresponding to the outgoing interface 954 * unless it is the loopback (in case a route 955 * to our address on another net goes to loopback). 956 */ 957 if (ro->ro_rt && !(ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK)) 958 ia = ifatoia(ro->ro_rt->rt_ifa); 959 if (ia == 0) { 960 u_int16_t fport = sin->sin_port; 961 962 sin->sin_port = 0; 963 ia = ifatoia(ifa_ifwithdstaddr(sintosa(sin))); 964 if (ia == 0) 965 ia = ifatoia(ifa_ifwithnet(sintosa(sin))); 966 sin->sin_port = fport; 967 if (ia == 0) 968 ia = in_ifaddr.tqh_first; 969 if (ia == 0) { 970 *errorp = EADDRNOTAVAIL; 971 return NULL; 972 } 973 } 974 /* 975 * If the destination address is multicast and an outgoing 976 * interface has been set as a multicast option, use the 977 * address of that interface as our source address. 978 */ 979 if (IN_MULTICAST(sin->sin_addr.s_addr) && mopts != NULL) { 980 struct ip_moptions *imo; 981 struct ifnet *ifp; 982 983 imo = mopts; 984 if (imo->imo_multicast_ifp != NULL) { 985 ifp = imo->imo_multicast_ifp; 986 for (ia = in_ifaddr.tqh_first; ia != 0; 987 ia = ia->ia_list.tqe_next) 988 if (ia->ia_ifp == ifp) 989 break; 990 if (ia == 0) { 991 *errorp = EADDRNOTAVAIL; 992 return NULL; 993 } 994 } 995 } 996 return satosin(&ia->ia_addr); 997 } 998 999 void 1000 in_pcbrehash(inp) 1001 struct inpcb *inp; 1002 { 1003 struct inpcbtable *table = inp->inp_table; 1004 int s; 1005 1006 s = splnet(); 1007 LIST_REMOVE(inp, inp_hash); 1008 #ifdef INET6 1009 if (inp->inp_flags & INP_IPV6) { 1010 LIST_INSERT_HEAD(IN6PCBHASH(table, &inp->inp_faddr6, 1011 inp->inp_fport, &inp->inp_laddr6, inp->inp_lport), 1012 inp, inp_hash); 1013 } else { 1014 #endif /* INET6 */ 1015 LIST_INSERT_HEAD(INPCBHASH(table, &inp->inp_faddr, 1016 inp->inp_fport, &inp->inp_laddr, inp->inp_lport), 1017 inp, inp_hash); 1018 #ifdef INET6 1019 } 1020 #endif /* INET6 */ 1021 splx(s); 1022 } 1023 1024 #ifdef DIAGNOSTIC 1025 int in_pcbnotifymiss = 0; 1026 #endif 1027 1028 struct inpcb * 1029 in_pcbhashlookup(table, faddr, fport_arg, laddr, lport_arg) 1030 struct inpcbtable *table; 1031 struct in_addr faddr, laddr; 1032 u_int fport_arg, lport_arg; 1033 { 1034 struct inpcbhead *head; 1035 register struct inpcb *inp; 1036 u_int16_t fport = fport_arg, lport = lport_arg; 1037 1038 head = INPCBHASH(table, &faddr, fport, &laddr, lport); 1039 for (inp = head->lh_first; inp != NULL; inp = inp->inp_hash.le_next) { 1040 #ifdef INET6 1041 if (inp->inp_flags & INP_IPV6) 1042 continue; /*XXX*/ 1043 #endif 1044 if (inp->inp_faddr.s_addr == faddr.s_addr && 1045 inp->inp_fport == fport && 1046 inp->inp_lport == lport && 1047 inp->inp_laddr.s_addr == laddr.s_addr) { 1048 /* 1049 * Move this PCB to the head of hash chain so that 1050 * repeated accesses are quicker. This is analogous to 1051 * the historic single-entry PCB cache. 1052 */ 1053 if (inp != head->lh_first) { 1054 LIST_REMOVE(inp, inp_hash); 1055 LIST_INSERT_HEAD(head, inp, inp_hash); 1056 } 1057 break; 1058 } 1059 } 1060 #ifdef DIAGNOSTIC 1061 if (inp == NULL && in_pcbnotifymiss) { 1062 printf("in_pcbhashlookup: faddr=%08x fport=%d laddr=%08x lport=%d\n", 1063 ntohl(faddr.s_addr), ntohs(fport), 1064 ntohl(laddr.s_addr), ntohs(lport)); 1065 } 1066 #endif 1067 return (inp); 1068 } 1069 1070 #ifdef INET6 1071 struct inpcb * 1072 in6_pcbhashlookup(table, faddr, fport_arg, laddr, lport_arg) 1073 struct inpcbtable *table; 1074 struct in6_addr *faddr, *laddr; 1075 u_int fport_arg, lport_arg; 1076 { 1077 struct inpcbhead *head; 1078 register struct inpcb *inp; 1079 u_int16_t fport = fport_arg, lport = lport_arg; 1080 1081 head = IN6PCBHASH(table, faddr, fport, laddr, lport); 1082 for (inp = head->lh_first; inp != NULL; inp = inp->inp_hash.le_next) { 1083 if (!(inp->inp_flags & INP_IPV6)) 1084 continue; 1085 if (IN6_ARE_ADDR_EQUAL(&inp->inp_faddr6, faddr) && 1086 inp->inp_fport == fport && inp->inp_lport == lport && 1087 IN6_ARE_ADDR_EQUAL(&inp->inp_laddr6, laddr)) { 1088 /* 1089 * Move this PCB to the head of hash chain so that 1090 * repeated accesses are quicker. This is analogous to 1091 * the historic single-entry PCB cache. 1092 */ 1093 if (inp != head->lh_first) { 1094 LIST_REMOVE(inp, inp_hash); 1095 LIST_INSERT_HEAD(head, inp, inp_hash); 1096 } 1097 break; 1098 } 1099 } 1100 #ifdef DIAGNOSTIC 1101 if (inp == NULL && in_pcbnotifymiss) { 1102 printf("in6_pcblookup_connect: faddr="); 1103 printf(" fport=%d laddr=", ntohs(fport)); 1104 printf(" lport=%d\n", ntohs(lport)); 1105 } 1106 #endif 1107 return (inp); 1108 } 1109 #endif /* INET6 */ 1110 1111 1112