1 /* 2 * Copyright (c) 1982, 1986, 1991, 1993, 1995 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)in_pcb.c 8.4 (Berkeley) 5/24/95 34 * $FreeBSD$ 35 */ 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/malloc.h> 40 #include <sys/mbuf.h> 41 #include <sys/protosw.h> 42 #include <sys/socket.h> 43 #include <sys/socketvar.h> 44 #include <sys/proc.h> 45 #include <sys/jail.h> 46 #include <sys/kernel.h> 47 #include <sys/sysctl.h> 48 49 #include <machine/limits.h> 50 51 #include <vm/vm_zone.h> 52 53 #include <net/if.h> 54 #include <net/route.h> 55 56 #include <netinet/in.h> 57 #include <netinet/in_pcb.h> 58 #include <netinet/in_var.h> 59 #include <netinet/ip_var.h> 60 61 struct in_addr zeroin_addr; 62 63 static void in_pcbremlists __P((struct inpcb *)); 64 static void in_rtchange __P((struct inpcb *, int)); 65 66 /* 67 * These configure the range of local port addresses assigned to 68 * "unspecified" outgoing connections/packets/whatever. 69 */ 70 static int ipport_lowfirstauto = IPPORT_RESERVED - 1; /* 1023 */ 71 static int ipport_lowlastauto = IPPORT_RESERVEDSTART; /* 600 */ 72 static int ipport_firstauto = IPPORT_RESERVED; /* 1024 */ 73 static int ipport_lastauto = IPPORT_USERRESERVED; /* 5000 */ 74 static int ipport_hifirstauto = IPPORT_HIFIRSTAUTO; /* 49152 */ 75 static int ipport_hilastauto = IPPORT_HILASTAUTO; /* 65535 */ 76 77 #define RANGECHK(var, min, max) \ 78 if ((var) < (min)) { (var) = (min); } \ 79 else if ((var) > (max)) { (var) = (max); } 80 81 static int 82 sysctl_net_ipport_check SYSCTL_HANDLER_ARGS 83 { 84 int error = sysctl_handle_int(oidp, 85 oidp->oid_arg1, oidp->oid_arg2, req); 86 if (!error) { 87 RANGECHK(ipport_lowfirstauto, 1, IPPORT_RESERVED - 1); 88 RANGECHK(ipport_lowlastauto, 1, IPPORT_RESERVED - 1); 89 RANGECHK(ipport_firstauto, IPPORT_RESERVED, USHRT_MAX); 90 RANGECHK(ipport_lastauto, IPPORT_RESERVED, USHRT_MAX); 91 RANGECHK(ipport_hifirstauto, IPPORT_RESERVED, USHRT_MAX); 92 RANGECHK(ipport_hilastauto, IPPORT_RESERVED, USHRT_MAX); 93 } 94 return error; 95 } 96 97 #undef RANGECHK 98 99 SYSCTL_NODE(_net_inet_ip, IPPROTO_IP, portrange, CTLFLAG_RW, 0, "IP Ports"); 100 101 SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, lowfirst, CTLTYPE_INT|CTLFLAG_RW, 102 &ipport_lowfirstauto, 0, &sysctl_net_ipport_check, "I", ""); 103 SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, lowlast, CTLTYPE_INT|CTLFLAG_RW, 104 &ipport_lowlastauto, 0, &sysctl_net_ipport_check, "I", ""); 105 SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, first, CTLTYPE_INT|CTLFLAG_RW, 106 &ipport_firstauto, 0, &sysctl_net_ipport_check, "I", ""); 107 SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, last, CTLTYPE_INT|CTLFLAG_RW, 108 &ipport_lastauto, 0, &sysctl_net_ipport_check, "I", ""); 109 SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, hifirst, CTLTYPE_INT|CTLFLAG_RW, 110 &ipport_hifirstauto, 0, &sysctl_net_ipport_check, "I", ""); 111 SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, hilast, CTLTYPE_INT|CTLFLAG_RW, 112 &ipport_hilastauto, 0, &sysctl_net_ipport_check, "I", ""); 113 114 /* 115 * in_pcb.c: manage the Protocol Control Blocks. 116 * 117 * NOTE: It is assumed that most of these functions will be called at 118 * splnet(). XXX - There are, unfortunately, a few exceptions to this 119 * rule that should be fixed. 120 */ 121 122 /* 123 * Allocate a PCB and associate it with the socket. 124 */ 125 int 126 in_pcballoc(so, pcbinfo, p) 127 struct socket *so; 128 struct inpcbinfo *pcbinfo; 129 struct proc *p; 130 { 131 register struct inpcb *inp; 132 133 inp = zalloci(pcbinfo->ipi_zone); 134 if (inp == NULL) 135 return (ENOBUFS); 136 bzero((caddr_t)inp, sizeof(*inp)); 137 inp->inp_gencnt = ++pcbinfo->ipi_gencnt; 138 inp->inp_pcbinfo = pcbinfo; 139 inp->inp_socket = so; 140 LIST_INSERT_HEAD(pcbinfo->listhead, inp, inp_list); 141 pcbinfo->ipi_count++; 142 so->so_pcb = (caddr_t)inp; 143 return (0); 144 } 145 146 int 147 in_pcbbind(inp, nam, p) 148 register struct inpcb *inp; 149 struct sockaddr *nam; 150 struct proc *p; 151 { 152 register struct socket *so = inp->inp_socket; 153 unsigned short *lastport; 154 struct sockaddr_in *sin; 155 struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; 156 u_short lport = 0; 157 int wild = 0, reuseport = (so->so_options & SO_REUSEPORT); 158 int error, prison = 0; 159 160 if (TAILQ_EMPTY(&in_ifaddrhead)) /* XXX broken! */ 161 return (EADDRNOTAVAIL); 162 if (inp->inp_lport || inp->inp_laddr.s_addr != INADDR_ANY) 163 return (EINVAL); 164 if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0) 165 wild = 1; 166 if (nam) { 167 sin = (struct sockaddr_in *)nam; 168 if (nam->sa_len != sizeof (*sin)) 169 return (EINVAL); 170 #ifdef notdef 171 /* 172 * We should check the family, but old programs 173 * incorrectly fail to initialize it. 174 */ 175 if (sin->sin_family != AF_INET) 176 return (EAFNOSUPPORT); 177 #endif 178 if (prison_ip(p, 0, &sin->sin_addr.s_addr)) 179 return(EINVAL); 180 lport = sin->sin_port; 181 if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { 182 /* 183 * Treat SO_REUSEADDR as SO_REUSEPORT for multicast; 184 * allow complete duplication of binding if 185 * SO_REUSEPORT is set, or if SO_REUSEADDR is set 186 * and a multicast address is bound on both 187 * new and duplicated sockets. 188 */ 189 if (so->so_options & SO_REUSEADDR) 190 reuseport = SO_REUSEADDR|SO_REUSEPORT; 191 } else if (sin->sin_addr.s_addr != INADDR_ANY) { 192 sin->sin_port = 0; /* yech... */ 193 if (ifa_ifwithaddr((struct sockaddr *)sin) == 0) 194 return (EADDRNOTAVAIL); 195 } 196 if (lport) { 197 struct inpcb *t; 198 199 /* GROSS */ 200 if (ntohs(lport) < IPPORT_RESERVED && p && 201 suser_xxx(0, p, PRISON_ROOT)) 202 return (EACCES); 203 if (p && p->p_prison) 204 prison = 1; 205 if (so->so_cred->cr_uid != 0 && 206 !IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { 207 t = in_pcblookup_local(inp->inp_pcbinfo, 208 sin->sin_addr, lport, 209 prison ? 0 : INPLOOKUP_WILDCARD); 210 if (t && 211 (ntohl(sin->sin_addr.s_addr) != INADDR_ANY || 212 ntohl(t->inp_laddr.s_addr) != INADDR_ANY || 213 (t->inp_socket->so_options & 214 SO_REUSEPORT) == 0) && 215 (so->so_cred->cr_uid != 216 t->inp_socket->so_cred->cr_uid)) 217 return (EADDRINUSE); 218 } 219 t = in_pcblookup_local(pcbinfo, sin->sin_addr, 220 lport, prison ? 0 : wild); 221 if (t && (reuseport & t->inp_socket->so_options) == 0) 222 return (EADDRINUSE); 223 } 224 inp->inp_laddr = sin->sin_addr; 225 } 226 if (lport == 0) { 227 ushort first, last; 228 int count; 229 230 if (prison_ip(p, 0, &inp->inp_laddr.s_addr )) 231 return (EINVAL); 232 inp->inp_flags |= INP_ANONPORT; 233 234 if (inp->inp_flags & INP_HIGHPORT) { 235 first = ipport_hifirstauto; /* sysctl */ 236 last = ipport_hilastauto; 237 lastport = &pcbinfo->lasthi; 238 } else if (inp->inp_flags & INP_LOWPORT) { 239 if (p && (error = suser_xxx(0, p, PRISON_ROOT))) 240 return error; 241 first = ipport_lowfirstauto; /* 1023 */ 242 last = ipport_lowlastauto; /* 600 */ 243 lastport = &pcbinfo->lastlow; 244 } else { 245 first = ipport_firstauto; /* sysctl */ 246 last = ipport_lastauto; 247 lastport = &pcbinfo->lastport; 248 } 249 /* 250 * Simple check to ensure all ports are not used up causing 251 * a deadlock here. 252 * 253 * We split the two cases (up and down) so that the direction 254 * is not being tested on each round of the loop. 255 */ 256 if (first > last) { 257 /* 258 * counting down 259 */ 260 count = first - last; 261 262 do { 263 if (count-- < 0) { /* completely used? */ 264 /* 265 * Undo any address bind that may have 266 * occurred above. 267 */ 268 inp->inp_laddr.s_addr = INADDR_ANY; 269 return (EAGAIN); 270 } 271 --*lastport; 272 if (*lastport > first || *lastport < last) 273 *lastport = first; 274 lport = htons(*lastport); 275 } while (in_pcblookup_local(pcbinfo, 276 inp->inp_laddr, lport, wild)); 277 } else { 278 /* 279 * counting up 280 */ 281 count = last - first; 282 283 do { 284 if (count-- < 0) { /* completely used? */ 285 /* 286 * Undo any address bind that may have 287 * occurred above. 288 */ 289 inp->inp_laddr.s_addr = INADDR_ANY; 290 return (EAGAIN); 291 } 292 ++*lastport; 293 if (*lastport < first || *lastport > last) 294 *lastport = first; 295 lport = htons(*lastport); 296 } while (in_pcblookup_local(pcbinfo, 297 inp->inp_laddr, lport, wild)); 298 } 299 } 300 inp->inp_lport = lport; 301 if (in_pcbinshash(inp) != 0) { 302 inp->inp_laddr.s_addr = INADDR_ANY; 303 inp->inp_lport = 0; 304 return (EAGAIN); 305 } 306 return (0); 307 } 308 309 /* 310 * Transform old in_pcbconnect() into an inner subroutine for new 311 * in_pcbconnect(): Do some validity-checking on the remote 312 * address (in mbuf 'nam') and then determine local host address 313 * (i.e., which interface) to use to access that remote host. 314 * 315 * This preserves definition of in_pcbconnect(), while supporting a 316 * slightly different version for T/TCP. (This is more than 317 * a bit of a kludge, but cleaning up the internal interfaces would 318 * have forced minor changes in every protocol). 319 */ 320 321 int 322 in_pcbladdr(inp, nam, plocal_sin) 323 register struct inpcb *inp; 324 struct sockaddr *nam; 325 struct sockaddr_in **plocal_sin; 326 { 327 struct in_ifaddr *ia; 328 register struct sockaddr_in *sin = (struct sockaddr_in *)nam; 329 330 if (nam->sa_len != sizeof (*sin)) 331 return (EINVAL); 332 if (sin->sin_family != AF_INET) 333 return (EAFNOSUPPORT); 334 if (sin->sin_port == 0) 335 return (EADDRNOTAVAIL); 336 if (!TAILQ_EMPTY(&in_ifaddrhead)) { 337 /* 338 * If the destination address is INADDR_ANY, 339 * use the primary local address. 340 * If the supplied address is INADDR_BROADCAST, 341 * and the primary interface supports broadcast, 342 * choose the broadcast address for that interface. 343 */ 344 #define satosin(sa) ((struct sockaddr_in *)(sa)) 345 #define sintosa(sin) ((struct sockaddr *)(sin)) 346 #define ifatoia(ifa) ((struct in_ifaddr *)(ifa)) 347 if (sin->sin_addr.s_addr == INADDR_ANY) 348 sin->sin_addr = IA_SIN(in_ifaddrhead.tqh_first)->sin_addr; 349 else if (sin->sin_addr.s_addr == (u_long)INADDR_BROADCAST && 350 (in_ifaddrhead.tqh_first->ia_ifp->if_flags & IFF_BROADCAST)) 351 sin->sin_addr = satosin(&in_ifaddrhead.tqh_first->ia_broadaddr)->sin_addr; 352 } 353 if (inp->inp_laddr.s_addr == INADDR_ANY) { 354 register struct route *ro; 355 356 ia = (struct in_ifaddr *)0; 357 /* 358 * If route is known or can be allocated now, 359 * our src addr is taken from the i/f, else punt. 360 */ 361 ro = &inp->inp_route; 362 if (ro->ro_rt && 363 (satosin(&ro->ro_dst)->sin_addr.s_addr != 364 sin->sin_addr.s_addr || 365 inp->inp_socket->so_options & SO_DONTROUTE)) { 366 RTFREE(ro->ro_rt); 367 ro->ro_rt = (struct rtentry *)0; 368 } 369 if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/ 370 (ro->ro_rt == (struct rtentry *)0 || 371 ro->ro_rt->rt_ifp == (struct ifnet *)0)) { 372 /* No route yet, so try to acquire one */ 373 ro->ro_dst.sa_family = AF_INET; 374 ro->ro_dst.sa_len = sizeof(struct sockaddr_in); 375 ((struct sockaddr_in *) &ro->ro_dst)->sin_addr = 376 sin->sin_addr; 377 rtalloc(ro); 378 } 379 /* 380 * If we found a route, use the address 381 * corresponding to the outgoing interface 382 * unless it is the loopback (in case a route 383 * to our address on another net goes to loopback). 384 */ 385 if (ro->ro_rt && !(ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK)) 386 ia = ifatoia(ro->ro_rt->rt_ifa); 387 if (ia == 0) { 388 u_short fport = sin->sin_port; 389 390 sin->sin_port = 0; 391 ia = ifatoia(ifa_ifwithdstaddr(sintosa(sin))); 392 if (ia == 0) 393 ia = ifatoia(ifa_ifwithnet(sintosa(sin))); 394 sin->sin_port = fport; 395 if (ia == 0) 396 ia = in_ifaddrhead.tqh_first; 397 if (ia == 0) 398 return (EADDRNOTAVAIL); 399 } 400 /* 401 * If the destination address is multicast and an outgoing 402 * interface has been set as a multicast option, use the 403 * address of that interface as our source address. 404 */ 405 if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) && 406 inp->inp_moptions != NULL) { 407 struct ip_moptions *imo; 408 struct ifnet *ifp; 409 410 imo = inp->inp_moptions; 411 if (imo->imo_multicast_ifp != NULL) { 412 ifp = imo->imo_multicast_ifp; 413 for (ia = in_ifaddrhead.tqh_first; ia; 414 ia = ia->ia_link.tqe_next) 415 if (ia->ia_ifp == ifp) 416 break; 417 if (ia == 0) 418 return (EADDRNOTAVAIL); 419 } 420 } 421 /* 422 * Don't do pcblookup call here; return interface in plocal_sin 423 * and exit to caller, that will do the lookup. 424 */ 425 *plocal_sin = &ia->ia_addr; 426 427 } 428 return(0); 429 } 430 431 /* 432 * Outer subroutine: 433 * Connect from a socket to a specified address. 434 * Both address and port must be specified in argument sin. 435 * If don't have a local address for this socket yet, 436 * then pick one. 437 */ 438 int 439 in_pcbconnect(inp, nam, p) 440 register struct inpcb *inp; 441 struct sockaddr *nam; 442 struct proc *p; 443 { 444 struct sockaddr_in *ifaddr; 445 register struct sockaddr_in *sin = (struct sockaddr_in *)nam; 446 int error; 447 448 /* 449 * Call inner routine, to assign local interface address. 450 */ 451 if ((error = in_pcbladdr(inp, nam, &ifaddr)) != 0) 452 return(error); 453 454 if (in_pcblookup_hash(inp->inp_pcbinfo, sin->sin_addr, sin->sin_port, 455 inp->inp_laddr.s_addr ? inp->inp_laddr : ifaddr->sin_addr, 456 inp->inp_lport, 0) != NULL) { 457 return (EADDRINUSE); 458 } 459 if (inp->inp_laddr.s_addr == INADDR_ANY) { 460 if (inp->inp_lport == 0) { 461 error = in_pcbbind(inp, (struct sockaddr *)0, p); 462 if (error) 463 return (error); 464 } 465 inp->inp_laddr = ifaddr->sin_addr; 466 } 467 inp->inp_faddr = sin->sin_addr; 468 inp->inp_fport = sin->sin_port; 469 in_pcbrehash(inp); 470 return (0); 471 } 472 473 void 474 in_pcbdisconnect(inp) 475 struct inpcb *inp; 476 { 477 478 inp->inp_faddr.s_addr = INADDR_ANY; 479 inp->inp_fport = 0; 480 in_pcbrehash(inp); 481 if (inp->inp_socket->so_state & SS_NOFDREF) 482 in_pcbdetach(inp); 483 } 484 485 void 486 in_pcbdetach(inp) 487 struct inpcb *inp; 488 { 489 struct socket *so = inp->inp_socket; 490 struct inpcbinfo *ipi = inp->inp_pcbinfo; 491 492 inp->inp_gencnt = ++ipi->ipi_gencnt; 493 in_pcbremlists(inp); 494 so->so_pcb = 0; 495 sofree(so); 496 if (inp->inp_options) 497 (void)m_free(inp->inp_options); 498 if (inp->inp_route.ro_rt) 499 rtfree(inp->inp_route.ro_rt); 500 ip_freemoptions(inp->inp_moptions); 501 zfreei(ipi->ipi_zone, inp); 502 } 503 504 /* 505 * The calling convention of in_setsockaddr() and in_setpeeraddr() was 506 * modified to match the pru_sockaddr() and pru_peeraddr() entry points 507 * in struct pr_usrreqs, so that protocols can just reference then directly 508 * without the need for a wrapper function. The socket must have a valid 509 * (i.e., non-nil) PCB, but it should be impossible to get an invalid one 510 * except through a kernel programming error, so it is acceptable to panic 511 * (or in this case trap) if the PCB is invalid. (Actually, we don't trap 512 * because there actually /is/ a programming error somewhere... XXX) 513 */ 514 int 515 in_setsockaddr(so, nam) 516 struct socket *so; 517 struct sockaddr **nam; 518 { 519 int s; 520 register struct inpcb *inp; 521 register struct sockaddr_in *sin; 522 523 /* 524 * Do the malloc first in case it blocks. 525 */ 526 MALLOC(sin, struct sockaddr_in *, sizeof *sin, M_SONAME, M_WAITOK); 527 bzero(sin, sizeof *sin); 528 sin->sin_family = AF_INET; 529 sin->sin_len = sizeof(*sin); 530 531 s = splnet(); 532 inp = sotoinpcb(so); 533 if (!inp) { 534 splx(s); 535 free(sin, M_SONAME); 536 return EINVAL; 537 } 538 sin->sin_port = inp->inp_lport; 539 sin->sin_addr = inp->inp_laddr; 540 splx(s); 541 542 *nam = (struct sockaddr *)sin; 543 return 0; 544 } 545 546 int 547 in_setpeeraddr(so, nam) 548 struct socket *so; 549 struct sockaddr **nam; 550 { 551 int s; 552 struct inpcb *inp; 553 register struct sockaddr_in *sin; 554 555 /* 556 * Do the malloc first in case it blocks. 557 */ 558 MALLOC(sin, struct sockaddr_in *, sizeof *sin, M_SONAME, M_WAITOK); 559 bzero((caddr_t)sin, sizeof (*sin)); 560 sin->sin_family = AF_INET; 561 sin->sin_len = sizeof(*sin); 562 563 s = splnet(); 564 inp = sotoinpcb(so); 565 if (!inp) { 566 splx(s); 567 free(sin, M_SONAME); 568 return EINVAL; 569 } 570 sin->sin_port = inp->inp_fport; 571 sin->sin_addr = inp->inp_faddr; 572 splx(s); 573 574 *nam = (struct sockaddr *)sin; 575 return 0; 576 } 577 578 /* 579 * Pass some notification to all connections of a protocol 580 * associated with address dst. The local address and/or port numbers 581 * may be specified to limit the search. The "usual action" will be 582 * taken, depending on the ctlinput cmd. The caller must filter any 583 * cmds that are uninteresting (e.g., no error in the map). 584 * Call the protocol specific routine (if any) to report 585 * any errors for each matching socket. 586 */ 587 void 588 in_pcbnotify(head, dst, fport_arg, laddr, lport_arg, cmd, notify) 589 struct inpcbhead *head; 590 struct sockaddr *dst; 591 u_int fport_arg, lport_arg; 592 struct in_addr laddr; 593 int cmd; 594 void (*notify) __P((struct inpcb *, int)); 595 { 596 register struct inpcb *inp, *oinp; 597 struct in_addr faddr; 598 u_short fport = fport_arg, lport = lport_arg; 599 int errno, s; 600 601 if ((unsigned)cmd > PRC_NCMDS || dst->sa_family != AF_INET) 602 return; 603 faddr = ((struct sockaddr_in *)dst)->sin_addr; 604 if (faddr.s_addr == INADDR_ANY) 605 return; 606 607 /* 608 * Redirects go to all references to the destination, 609 * and use in_rtchange to invalidate the route cache. 610 * Dead host indications: notify all references to the destination. 611 * Otherwise, if we have knowledge of the local port and address, 612 * deliver only to that socket. 613 */ 614 if (PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) { 615 fport = 0; 616 lport = 0; 617 laddr.s_addr = 0; 618 if (cmd != PRC_HOSTDEAD) 619 notify = in_rtchange; 620 } 621 errno = inetctlerrmap[cmd]; 622 s = splnet(); 623 for (inp = head->lh_first; inp != NULL;) { 624 if (inp->inp_faddr.s_addr != faddr.s_addr || 625 inp->inp_socket == 0 || 626 (lport && inp->inp_lport != lport) || 627 (laddr.s_addr && inp->inp_laddr.s_addr != laddr.s_addr) || 628 (fport && inp->inp_fport != fport)) { 629 inp = inp->inp_list.le_next; 630 continue; 631 } 632 oinp = inp; 633 inp = inp->inp_list.le_next; 634 if (notify) 635 (*notify)(oinp, errno); 636 } 637 splx(s); 638 } 639 640 /* 641 * Check for alternatives when higher level complains 642 * about service problems. For now, invalidate cached 643 * routing information. If the route was created dynamically 644 * (by a redirect), time to try a default gateway again. 645 */ 646 void 647 in_losing(inp) 648 struct inpcb *inp; 649 { 650 register struct rtentry *rt; 651 struct rt_addrinfo info; 652 653 if ((rt = inp->inp_route.ro_rt)) { 654 inp->inp_route.ro_rt = 0; 655 bzero((caddr_t)&info, sizeof(info)); 656 info.rti_info[RTAX_DST] = 657 (struct sockaddr *)&inp->inp_route.ro_dst; 658 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 659 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 660 rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0); 661 if (rt->rt_flags & RTF_DYNAMIC) 662 (void) rtrequest(RTM_DELETE, rt_key(rt), 663 rt->rt_gateway, rt_mask(rt), rt->rt_flags, 664 (struct rtentry **)0); 665 else 666 /* 667 * A new route can be allocated 668 * the next time output is attempted. 669 */ 670 rtfree(rt); 671 } 672 } 673 674 /* 675 * After a routing change, flush old routing 676 * and allocate a (hopefully) better one. 677 */ 678 static void 679 in_rtchange(inp, errno) 680 register struct inpcb *inp; 681 int errno; 682 { 683 if (inp->inp_route.ro_rt) { 684 rtfree(inp->inp_route.ro_rt); 685 inp->inp_route.ro_rt = 0; 686 /* 687 * A new route can be allocated the next time 688 * output is attempted. 689 */ 690 } 691 } 692 693 /* 694 * Lookup a PCB based on the local address and port. 695 */ 696 struct inpcb * 697 in_pcblookup_local(pcbinfo, laddr, lport_arg, wild_okay) 698 struct inpcbinfo *pcbinfo; 699 struct in_addr laddr; 700 u_int lport_arg; 701 int wild_okay; 702 { 703 register struct inpcb *inp; 704 int matchwild = 3, wildcard; 705 u_short lport = lport_arg; 706 707 if (!wild_okay) { 708 struct inpcbhead *head; 709 /* 710 * Look for an unconnected (wildcard foreign addr) PCB that 711 * matches the local address and port we're looking for. 712 */ 713 head = &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0, pcbinfo->hashmask)]; 714 for (inp = head->lh_first; inp != NULL; inp = inp->inp_hash.le_next) { 715 if (inp->inp_faddr.s_addr == INADDR_ANY && 716 inp->inp_laddr.s_addr == laddr.s_addr && 717 inp->inp_lport == lport) { 718 /* 719 * Found. 720 */ 721 return (inp); 722 } 723 } 724 /* 725 * Not found. 726 */ 727 return (NULL); 728 } else { 729 struct inpcbporthead *porthash; 730 struct inpcbport *phd; 731 struct inpcb *match = NULL; 732 /* 733 * Best fit PCB lookup. 734 * 735 * First see if this local port is in use by looking on the 736 * port hash list. 737 */ 738 porthash = &pcbinfo->porthashbase[INP_PCBPORTHASH(lport, 739 pcbinfo->porthashmask)]; 740 for (phd = porthash->lh_first; phd != NULL; phd = phd->phd_hash.le_next) { 741 if (phd->phd_port == lport) 742 break; 743 } 744 if (phd != NULL) { 745 /* 746 * Port is in use by one or more PCBs. Look for best 747 * fit. 748 */ 749 for (inp = phd->phd_pcblist.lh_first; inp != NULL; 750 inp = inp->inp_portlist.le_next) { 751 wildcard = 0; 752 if (inp->inp_faddr.s_addr != INADDR_ANY) 753 wildcard++; 754 if (inp->inp_laddr.s_addr != INADDR_ANY) { 755 if (laddr.s_addr == INADDR_ANY) 756 wildcard++; 757 else if (inp->inp_laddr.s_addr != laddr.s_addr) 758 continue; 759 } else { 760 if (laddr.s_addr != INADDR_ANY) 761 wildcard++; 762 } 763 if (wildcard < matchwild) { 764 match = inp; 765 matchwild = wildcard; 766 if (matchwild == 0) { 767 break; 768 } 769 } 770 } 771 } 772 return (match); 773 } 774 } 775 776 /* 777 * Lookup PCB in hash list. 778 */ 779 struct inpcb * 780 in_pcblookup_hash(pcbinfo, faddr, fport_arg, laddr, lport_arg, wildcard) 781 struct inpcbinfo *pcbinfo; 782 struct in_addr faddr, laddr; 783 u_int fport_arg, lport_arg; 784 int wildcard; 785 { 786 struct inpcbhead *head; 787 register struct inpcb *inp; 788 u_short fport = fport_arg, lport = lport_arg; 789 790 /* 791 * First look for an exact match. 792 */ 793 head = &pcbinfo->hashbase[INP_PCBHASH(faddr.s_addr, lport, fport, pcbinfo->hashmask)]; 794 for (inp = head->lh_first; inp != NULL; inp = inp->inp_hash.le_next) { 795 if (inp->inp_faddr.s_addr == faddr.s_addr && 796 inp->inp_laddr.s_addr == laddr.s_addr && 797 inp->inp_fport == fport && 798 inp->inp_lport == lport) { 799 /* 800 * Found. 801 */ 802 return (inp); 803 } 804 } 805 if (wildcard) { 806 struct inpcb *local_wild = NULL; 807 808 head = &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0, pcbinfo->hashmask)]; 809 for (inp = head->lh_first; inp != NULL; inp = inp->inp_hash.le_next) { 810 if (inp->inp_faddr.s_addr == INADDR_ANY && 811 inp->inp_lport == lport) { 812 if (inp->inp_laddr.s_addr == laddr.s_addr) 813 return (inp); 814 else if (inp->inp_laddr.s_addr == INADDR_ANY) 815 local_wild = inp; 816 } 817 } 818 return (local_wild); 819 } 820 821 /* 822 * Not found. 823 */ 824 return (NULL); 825 } 826 827 /* 828 * Insert PCB onto various hash lists. 829 */ 830 int 831 in_pcbinshash(inp) 832 struct inpcb *inp; 833 { 834 struct inpcbhead *pcbhash; 835 struct inpcbporthead *pcbporthash; 836 struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; 837 struct inpcbport *phd; 838 839 pcbhash = &pcbinfo->hashbase[INP_PCBHASH(inp->inp_faddr.s_addr, 840 inp->inp_lport, inp->inp_fport, pcbinfo->hashmask)]; 841 842 pcbporthash = &pcbinfo->porthashbase[INP_PCBPORTHASH(inp->inp_lport, 843 pcbinfo->porthashmask)]; 844 845 /* 846 * Go through port list and look for a head for this lport. 847 */ 848 for (phd = pcbporthash->lh_first; phd != NULL; phd = phd->phd_hash.le_next) { 849 if (phd->phd_port == inp->inp_lport) 850 break; 851 } 852 /* 853 * If none exists, malloc one and tack it on. 854 */ 855 if (phd == NULL) { 856 MALLOC(phd, struct inpcbport *, sizeof(struct inpcbport), M_PCB, M_NOWAIT); 857 if (phd == NULL) { 858 return (ENOBUFS); /* XXX */ 859 } 860 phd->phd_port = inp->inp_lport; 861 LIST_INIT(&phd->phd_pcblist); 862 LIST_INSERT_HEAD(pcbporthash, phd, phd_hash); 863 } 864 inp->inp_phd = phd; 865 LIST_INSERT_HEAD(&phd->phd_pcblist, inp, inp_portlist); 866 LIST_INSERT_HEAD(pcbhash, inp, inp_hash); 867 return (0); 868 } 869 870 /* 871 * Move PCB to the proper hash bucket when { faddr, fport } have been 872 * changed. NOTE: This does not handle the case of the lport changing (the 873 * hashed port list would have to be updated as well), so the lport must 874 * not change after in_pcbinshash() has been called. 875 */ 876 void 877 in_pcbrehash(inp) 878 struct inpcb *inp; 879 { 880 struct inpcbhead *head; 881 882 head = &inp->inp_pcbinfo->hashbase[INP_PCBHASH(inp->inp_faddr.s_addr, 883 inp->inp_lport, inp->inp_fport, inp->inp_pcbinfo->hashmask)]; 884 885 LIST_REMOVE(inp, inp_hash); 886 LIST_INSERT_HEAD(head, inp, inp_hash); 887 } 888 889 /* 890 * Remove PCB from various lists. 891 */ 892 static void 893 in_pcbremlists(inp) 894 struct inpcb *inp; 895 { 896 inp->inp_gencnt = ++inp->inp_pcbinfo->ipi_gencnt; 897 if (inp->inp_lport) { 898 struct inpcbport *phd = inp->inp_phd; 899 900 LIST_REMOVE(inp, inp_hash); 901 LIST_REMOVE(inp, inp_portlist); 902 if (phd->phd_pcblist.lh_first == NULL) { 903 LIST_REMOVE(phd, phd_hash); 904 free(phd, M_PCB); 905 } 906 } 907 LIST_REMOVE(inp, inp_list); 908 inp->inp_pcbinfo->ipi_count--; 909 } 910 911 int 912 prison_xinpcb(struct proc *p, struct inpcb *inp) 913 { 914 if (!p->p_prison) 915 return (0); 916 if (ntohl(inp->inp_laddr.s_addr) == p->p_prison->pr_ip) 917 return (0); 918 return (1); 919 } 920