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
| 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: head/sys/netinet/in_pcb.c 86764 2001-11-22 04:50:44Z jlemon $
| 34 * $FreeBSD: head/sys/netinet/in_pcb.c 87275 2001-12-03 16:12:27Z rwatson $
|
35 */ 36 37#include "opt_ipsec.h" 38#include "opt_inet6.h" 39 40#include <sys/param.h> 41#include <sys/systm.h> 42#include <sys/malloc.h> 43#include <sys/mbuf.h> 44#include <sys/domain.h> 45#include <sys/protosw.h> 46#include <sys/socket.h> 47#include <sys/socketvar.h> 48#include <sys/proc.h> 49#include <sys/jail.h> 50#include <sys/kernel.h> 51#include <sys/sysctl.h> 52 53#include <machine/limits.h> 54 55#include <vm/vm_zone.h> 56 57#include <net/if.h> 58#include <net/if_types.h> 59#include <net/route.h> 60 61#include <netinet/in.h> 62#include <netinet/in_pcb.h> 63#include <netinet/in_var.h> 64#include <netinet/ip_var.h> 65#ifdef INET6 66#include <netinet/ip6.h> 67#include <netinet6/ip6_var.h> 68#endif /* INET6 */ 69 70#ifdef IPSEC 71#include <netinet6/ipsec.h> 72#include <netkey/key.h> 73#endif /* IPSEC */ 74 75struct in_addr zeroin_addr; 76 77/* 78 * These configure the range of local port addresses assigned to 79 * "unspecified" outgoing connections/packets/whatever. 80 */ 81int ipport_lowfirstauto = IPPORT_RESERVED - 1; /* 1023 */ 82int ipport_lowlastauto = IPPORT_RESERVEDSTART; /* 600 */ 83int ipport_firstauto = IPPORT_RESERVED; /* 1024 */ 84int ipport_lastauto = IPPORT_USERRESERVED; /* 5000 */ 85int ipport_hifirstauto = IPPORT_HIFIRSTAUTO; /* 49152 */ 86int ipport_hilastauto = IPPORT_HILASTAUTO; /* 65535 */ 87 88#define RANGECHK(var, min, max) \ 89 if ((var) < (min)) { (var) = (min); } \ 90 else if ((var) > (max)) { (var) = (max); } 91 92static int 93sysctl_net_ipport_check(SYSCTL_HANDLER_ARGS) 94{ 95 int error = sysctl_handle_int(oidp, 96 oidp->oid_arg1, oidp->oid_arg2, req); 97 if (!error) { 98 RANGECHK(ipport_lowfirstauto, 1, IPPORT_RESERVED - 1); 99 RANGECHK(ipport_lowlastauto, 1, IPPORT_RESERVED - 1); 100 RANGECHK(ipport_firstauto, IPPORT_RESERVED, USHRT_MAX); 101 RANGECHK(ipport_lastauto, IPPORT_RESERVED, USHRT_MAX); 102 RANGECHK(ipport_hifirstauto, IPPORT_RESERVED, USHRT_MAX); 103 RANGECHK(ipport_hilastauto, IPPORT_RESERVED, USHRT_MAX); 104 } 105 return error; 106} 107 108#undef RANGECHK 109 110SYSCTL_NODE(_net_inet_ip, IPPROTO_IP, portrange, CTLFLAG_RW, 0, "IP Ports"); 111 112SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, lowfirst, CTLTYPE_INT|CTLFLAG_RW, 113 &ipport_lowfirstauto, 0, &sysctl_net_ipport_check, "I", ""); 114SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, lowlast, CTLTYPE_INT|CTLFLAG_RW, 115 &ipport_lowlastauto, 0, &sysctl_net_ipport_check, "I", ""); 116SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, first, CTLTYPE_INT|CTLFLAG_RW, 117 &ipport_firstauto, 0, &sysctl_net_ipport_check, "I", ""); 118SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, last, CTLTYPE_INT|CTLFLAG_RW, 119 &ipport_lastauto, 0, &sysctl_net_ipport_check, "I", ""); 120SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, hifirst, CTLTYPE_INT|CTLFLAG_RW, 121 &ipport_hifirstauto, 0, &sysctl_net_ipport_check, "I", ""); 122SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, hilast, CTLTYPE_INT|CTLFLAG_RW, 123 &ipport_hilastauto, 0, &sysctl_net_ipport_check, "I", ""); 124 125/* 126 * in_pcb.c: manage the Protocol Control Blocks. 127 * 128 * NOTE: It is assumed that most of these functions will be called at 129 * splnet(). XXX - There are, unfortunately, a few exceptions to this 130 * rule that should be fixed. 131 */ 132 133/* 134 * Allocate a PCB and associate it with the socket. 135 */ 136int 137in_pcballoc(so, pcbinfo, td) 138 struct socket *so; 139 struct inpcbinfo *pcbinfo; 140 struct thread *td; 141{ 142 register struct inpcb *inp; 143#ifdef IPSEC 144 int error; 145#endif 146 147 inp = zalloc(pcbinfo->ipi_zone); 148 if (inp == NULL) 149 return (ENOBUFS); 150 bzero((caddr_t)inp, sizeof(*inp)); 151 inp->inp_gencnt = ++pcbinfo->ipi_gencnt; 152 inp->inp_pcbinfo = pcbinfo; 153 inp->inp_socket = so; 154#ifdef IPSEC 155 error = ipsec_init_policy(so, &inp->inp_sp); 156 if (error != 0) { 157 zfree(pcbinfo->ipi_zone, inp); 158 return error; 159 } 160#endif /*IPSEC*/ 161#if defined(INET6) 162 if (INP_SOCKAF(so) == AF_INET6 && !ip6_mapped_addr_on) 163 inp->inp_flags |= IN6P_IPV6_V6ONLY; 164#endif 165 LIST_INSERT_HEAD(pcbinfo->listhead, inp, inp_list); 166 pcbinfo->ipi_count++; 167 so->so_pcb = (caddr_t)inp; 168#ifdef INET6 169 if (ip6_auto_flowlabel) 170 inp->inp_flags |= IN6P_AUTOFLOWLABEL; 171#endif 172 return (0); 173} 174 175int 176in_pcbbind(inp, nam, td) 177 register struct inpcb *inp; 178 struct sockaddr *nam; 179 struct thread *td; 180{ 181 struct proc *p = td->td_proc; 182 register struct socket *so = inp->inp_socket; 183 unsigned short *lastport; 184 struct sockaddr_in *sin; 185 struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; 186 u_short lport = 0; 187 int wild = 0, reuseport = (so->so_options & SO_REUSEPORT); 188 int error, prison = 0; 189 190 if (TAILQ_EMPTY(&in_ifaddrhead)) /* XXX broken! */ 191 return (EADDRNOTAVAIL); 192 if (inp->inp_lport || inp->inp_laddr.s_addr != INADDR_ANY) 193 return (EINVAL); 194 if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0) 195 wild = 1; 196 if (nam) { 197 sin = (struct sockaddr_in *)nam; 198 if (nam->sa_len != sizeof (*sin)) 199 return (EINVAL); 200#ifdef notdef 201 /* 202 * We should check the family, but old programs 203 * incorrectly fail to initialize it. 204 */ 205 if (sin->sin_family != AF_INET) 206 return (EAFNOSUPPORT); 207#endif 208 if (sin->sin_addr.s_addr != INADDR_ANY) 209 if (prison_ip(p->p_ucred, 0, &sin->sin_addr.s_addr)) 210 return(EINVAL); 211 lport = sin->sin_port; 212 if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { 213 /* 214 * Treat SO_REUSEADDR as SO_REUSEPORT for multicast; 215 * allow complete duplication of binding if 216 * SO_REUSEPORT is set, or if SO_REUSEADDR is set 217 * and a multicast address is bound on both 218 * new and duplicated sockets. 219 */ 220 if (so->so_options & SO_REUSEADDR) 221 reuseport = SO_REUSEADDR|SO_REUSEPORT; 222 } else if (sin->sin_addr.s_addr != INADDR_ANY) { 223 sin->sin_port = 0; /* yech... */ 224 bzero(&sin->sin_zero, sizeof(sin->sin_zero)); 225 if (ifa_ifwithaddr((struct sockaddr *)sin) == 0) 226 return (EADDRNOTAVAIL); 227 } 228 if (lport) { 229 struct inpcb *t; 230 /* GROSS */ 231 if (ntohs(lport) < IPPORT_RESERVED && p && 232 suser_xxx(0, p, PRISON_ROOT)) 233 return (EACCES); 234 if (p && jailed(p->p_ucred)) 235 prison = 1; 236 if (so->so_cred->cr_uid != 0 && 237 !IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { 238 t = in_pcblookup_local(inp->inp_pcbinfo, 239 sin->sin_addr, lport, 240 prison ? 0 : INPLOOKUP_WILDCARD); 241 if (t && 242 (ntohl(sin->sin_addr.s_addr) != INADDR_ANY || 243 ntohl(t->inp_laddr.s_addr) != INADDR_ANY || 244 (t->inp_socket->so_options & 245 SO_REUSEPORT) == 0) && 246 (so->so_cred->cr_uid != 247 t->inp_socket->so_cred->cr_uid)) { 248#if defined(INET6) 249 if (ntohl(sin->sin_addr.s_addr) != 250 INADDR_ANY || 251 ntohl(t->inp_laddr.s_addr) != 252 INADDR_ANY || 253 INP_SOCKAF(so) == 254 INP_SOCKAF(t->inp_socket)) 255#endif /* defined(INET6) */ 256 return (EADDRINUSE); 257 } 258 } 259 if (prison && 260 prison_ip(p->p_ucred, 0, &sin->sin_addr.s_addr)) 261 return (EADDRNOTAVAIL); 262 t = in_pcblookup_local(pcbinfo, sin->sin_addr, 263 lport, prison ? 0 : wild); 264 if (t && 265 (reuseport & t->inp_socket->so_options) == 0) { 266#if defined(INET6) 267 if (ntohl(sin->sin_addr.s_addr) != 268 INADDR_ANY || 269 ntohl(t->inp_laddr.s_addr) != 270 INADDR_ANY || 271 INP_SOCKAF(so) == 272 INP_SOCKAF(t->inp_socket)) 273#endif /* defined(INET6) */ 274 return (EADDRINUSE); 275 } 276 } 277 inp->inp_laddr = sin->sin_addr; 278 } 279 if (lport == 0) { 280 ushort first, last; 281 int count; 282 283 if (inp->inp_laddr.s_addr != INADDR_ANY) 284 if (prison_ip(p->p_ucred, 0, &inp->inp_laddr.s_addr )) { 285 inp->inp_laddr.s_addr = INADDR_ANY; 286 return (EINVAL); 287 } 288 inp->inp_flags |= INP_ANONPORT; 289 290 if (inp->inp_flags & INP_HIGHPORT) { 291 first = ipport_hifirstauto; /* sysctl */ 292 last = ipport_hilastauto; 293 lastport = &pcbinfo->lasthi; 294 } else if (inp->inp_flags & INP_LOWPORT) { 295 if (p && (error = suser_xxx(0, p, PRISON_ROOT))) { 296 inp->inp_laddr.s_addr = INADDR_ANY; 297 return error; 298 } 299 first = ipport_lowfirstauto; /* 1023 */ 300 last = ipport_lowlastauto; /* 600 */ 301 lastport = &pcbinfo->lastlow; 302 } else { 303 first = ipport_firstauto; /* sysctl */ 304 last = ipport_lastauto; 305 lastport = &pcbinfo->lastport; 306 } 307 /* 308 * Simple check to ensure all ports are not used up causing 309 * a deadlock here. 310 * 311 * We split the two cases (up and down) so that the direction 312 * is not being tested on each round of the loop. 313 */ 314 if (first > last) { 315 /* 316 * counting down 317 */ 318 count = first - last; 319 320 do { 321 if (count-- < 0) { /* completely used? */ 322 inp->inp_laddr.s_addr = INADDR_ANY; 323 return (EADDRNOTAVAIL); 324 } 325 --*lastport; 326 if (*lastport > first || *lastport < last) 327 *lastport = first; 328 lport = htons(*lastport); 329 } while (in_pcblookup_local(pcbinfo, 330 inp->inp_laddr, lport, wild)); 331 } else { 332 /* 333 * counting up 334 */ 335 count = last - first; 336 337 do { 338 if (count-- < 0) { /* completely used? */ 339 /* 340 * Undo any address bind that may have 341 * occurred above. 342 */ 343 inp->inp_laddr.s_addr = INADDR_ANY; 344 return (EADDRNOTAVAIL); 345 } 346 ++*lastport; 347 if (*lastport < first || *lastport > last) 348 *lastport = first; 349 lport = htons(*lastport); 350 } while (in_pcblookup_local(pcbinfo, 351 inp->inp_laddr, lport, wild)); 352 } 353 } 354 inp->inp_lport = lport; 355 if (prison_ip(p->p_ucred, 0, &inp->inp_laddr.s_addr)) { 356 inp->inp_laddr.s_addr = INADDR_ANY; 357 inp->inp_lport = 0; 358 return(EINVAL); 359 } 360 if (in_pcbinshash(inp) != 0) { 361 inp->inp_laddr.s_addr = INADDR_ANY; 362 inp->inp_lport = 0; 363 return (EAGAIN); 364 } 365 return (0); 366} 367 368/* 369 * Transform old in_pcbconnect() into an inner subroutine for new 370 * in_pcbconnect(): Do some validity-checking on the remote 371 * address (in mbuf 'nam') and then determine local host address 372 * (i.e., which interface) to use to access that remote host. 373 * 374 * This preserves definition of in_pcbconnect(), while supporting a 375 * slightly different version for T/TCP. (This is more than 376 * a bit of a kludge, but cleaning up the internal interfaces would 377 * have forced minor changes in every protocol). 378 */ 379 380int 381in_pcbladdr(inp, nam, plocal_sin) 382 register struct inpcb *inp; 383 struct sockaddr *nam; 384 struct sockaddr_in **plocal_sin; 385{ 386 struct in_ifaddr *ia; 387 register struct sockaddr_in *sin = (struct sockaddr_in *)nam; 388 389 if (nam->sa_len != sizeof (*sin)) 390 return (EINVAL); 391 if (sin->sin_family != AF_INET) 392 return (EAFNOSUPPORT); 393 if (sin->sin_port == 0) 394 return (EADDRNOTAVAIL); 395 if (!TAILQ_EMPTY(&in_ifaddrhead)) { 396 /* 397 * If the destination address is INADDR_ANY, 398 * use the primary local address. 399 * If the supplied address is INADDR_BROADCAST, 400 * and the primary interface supports broadcast, 401 * choose the broadcast address for that interface. 402 */ 403 if (sin->sin_addr.s_addr == INADDR_ANY) 404 sin->sin_addr = IA_SIN(TAILQ_FIRST(&in_ifaddrhead))->sin_addr; 405 else if (sin->sin_addr.s_addr == (u_long)INADDR_BROADCAST && 406 (TAILQ_FIRST(&in_ifaddrhead)->ia_ifp->if_flags & IFF_BROADCAST)) 407 sin->sin_addr = satosin(&TAILQ_FIRST(&in_ifaddrhead)->ia_broadaddr)->sin_addr; 408 } 409 if (inp->inp_laddr.s_addr == INADDR_ANY) { 410 register struct route *ro; 411 412 ia = (struct in_ifaddr *)0; 413 /* 414 * If route is known or can be allocated now, 415 * our src addr is taken from the i/f, else punt. 416 */ 417 ro = &inp->inp_route; 418 if (ro->ro_rt && 419 (satosin(&ro->ro_dst)->sin_addr.s_addr != 420 sin->sin_addr.s_addr || 421 inp->inp_socket->so_options & SO_DONTROUTE)) { 422 RTFREE(ro->ro_rt); 423 ro->ro_rt = (struct rtentry *)0; 424 } 425 if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/ 426 (ro->ro_rt == (struct rtentry *)0 || 427 ro->ro_rt->rt_ifp == (struct ifnet *)0)) { 428 /* No route yet, so try to acquire one */ 429 ro->ro_dst.sa_family = AF_INET; 430 ro->ro_dst.sa_len = sizeof(struct sockaddr_in); 431 ((struct sockaddr_in *) &ro->ro_dst)->sin_addr = 432 sin->sin_addr; 433 rtalloc(ro); 434 } 435 /* 436 * If we found a route, use the address 437 * corresponding to the outgoing interface 438 * unless it is the loopback (in case a route 439 * to our address on another net goes to loopback). 440 */ 441 if (ro->ro_rt && !(ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK)) 442 ia = ifatoia(ro->ro_rt->rt_ifa); 443 if (ia == 0) { 444 u_short fport = sin->sin_port; 445 446 sin->sin_port = 0; 447 ia = ifatoia(ifa_ifwithdstaddr(sintosa(sin))); 448 if (ia == 0) 449 ia = ifatoia(ifa_ifwithnet(sintosa(sin))); 450 sin->sin_port = fport; 451 if (ia == 0) 452 ia = TAILQ_FIRST(&in_ifaddrhead); 453 if (ia == 0) 454 return (EADDRNOTAVAIL); 455 } 456 /* 457 * If the destination address is multicast and an outgoing 458 * interface has been set as a multicast option, use the 459 * address of that interface as our source address. 460 */ 461 if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) && 462 inp->inp_moptions != NULL) { 463 struct ip_moptions *imo; 464 struct ifnet *ifp; 465 466 imo = inp->inp_moptions; 467 if (imo->imo_multicast_ifp != NULL) { 468 ifp = imo->imo_multicast_ifp; 469 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) 470 if (ia->ia_ifp == ifp) 471 break; 472 if (ia == 0) 473 return (EADDRNOTAVAIL); 474 } 475 } 476 /* 477 * Don't do pcblookup call here; return interface in plocal_sin 478 * and exit to caller, that will do the lookup. 479 */ 480 *plocal_sin = &ia->ia_addr; 481 482 } 483 return(0); 484} 485 486/* 487 * Outer subroutine: 488 * Connect from a socket to a specified address. 489 * Both address and port must be specified in argument sin. 490 * If don't have a local address for this socket yet, 491 * then pick one. 492 */ 493int 494in_pcbconnect(inp, nam, td) 495 register struct inpcb *inp; 496 struct sockaddr *nam; 497 struct thread *td; 498{ 499 struct sockaddr_in *ifaddr; 500 struct sockaddr_in *sin = (struct sockaddr_in *)nam; 501 struct sockaddr_in sa; 502 struct ucred *cred; 503 int error; 504 505 cred = inp->inp_socket->so_cred; 506 if (inp->inp_laddr.s_addr == INADDR_ANY && jailed(cred)) { 507 bzero(&sa, sizeof (sa));
| 35 */ 36 37#include "opt_ipsec.h" 38#include "opt_inet6.h" 39 40#include <sys/param.h> 41#include <sys/systm.h> 42#include <sys/malloc.h> 43#include <sys/mbuf.h> 44#include <sys/domain.h> 45#include <sys/protosw.h> 46#include <sys/socket.h> 47#include <sys/socketvar.h> 48#include <sys/proc.h> 49#include <sys/jail.h> 50#include <sys/kernel.h> 51#include <sys/sysctl.h> 52 53#include <machine/limits.h> 54 55#include <vm/vm_zone.h> 56 57#include <net/if.h> 58#include <net/if_types.h> 59#include <net/route.h> 60 61#include <netinet/in.h> 62#include <netinet/in_pcb.h> 63#include <netinet/in_var.h> 64#include <netinet/ip_var.h> 65#ifdef INET6 66#include <netinet/ip6.h> 67#include <netinet6/ip6_var.h> 68#endif /* INET6 */ 69 70#ifdef IPSEC 71#include <netinet6/ipsec.h> 72#include <netkey/key.h> 73#endif /* IPSEC */ 74 75struct in_addr zeroin_addr; 76 77/* 78 * These configure the range of local port addresses assigned to 79 * "unspecified" outgoing connections/packets/whatever. 80 */ 81int ipport_lowfirstauto = IPPORT_RESERVED - 1; /* 1023 */ 82int ipport_lowlastauto = IPPORT_RESERVEDSTART; /* 600 */ 83int ipport_firstauto = IPPORT_RESERVED; /* 1024 */ 84int ipport_lastauto = IPPORT_USERRESERVED; /* 5000 */ 85int ipport_hifirstauto = IPPORT_HIFIRSTAUTO; /* 49152 */ 86int ipport_hilastauto = IPPORT_HILASTAUTO; /* 65535 */ 87 88#define RANGECHK(var, min, max) \ 89 if ((var) < (min)) { (var) = (min); } \ 90 else if ((var) > (max)) { (var) = (max); } 91 92static int 93sysctl_net_ipport_check(SYSCTL_HANDLER_ARGS) 94{ 95 int error = sysctl_handle_int(oidp, 96 oidp->oid_arg1, oidp->oid_arg2, req); 97 if (!error) { 98 RANGECHK(ipport_lowfirstauto, 1, IPPORT_RESERVED - 1); 99 RANGECHK(ipport_lowlastauto, 1, IPPORT_RESERVED - 1); 100 RANGECHK(ipport_firstauto, IPPORT_RESERVED, USHRT_MAX); 101 RANGECHK(ipport_lastauto, IPPORT_RESERVED, USHRT_MAX); 102 RANGECHK(ipport_hifirstauto, IPPORT_RESERVED, USHRT_MAX); 103 RANGECHK(ipport_hilastauto, IPPORT_RESERVED, USHRT_MAX); 104 } 105 return error; 106} 107 108#undef RANGECHK 109 110SYSCTL_NODE(_net_inet_ip, IPPROTO_IP, portrange, CTLFLAG_RW, 0, "IP Ports"); 111 112SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, lowfirst, CTLTYPE_INT|CTLFLAG_RW, 113 &ipport_lowfirstauto, 0, &sysctl_net_ipport_check, "I", ""); 114SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, lowlast, CTLTYPE_INT|CTLFLAG_RW, 115 &ipport_lowlastauto, 0, &sysctl_net_ipport_check, "I", ""); 116SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, first, CTLTYPE_INT|CTLFLAG_RW, 117 &ipport_firstauto, 0, &sysctl_net_ipport_check, "I", ""); 118SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, last, CTLTYPE_INT|CTLFLAG_RW, 119 &ipport_lastauto, 0, &sysctl_net_ipport_check, "I", ""); 120SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, hifirst, CTLTYPE_INT|CTLFLAG_RW, 121 &ipport_hifirstauto, 0, &sysctl_net_ipport_check, "I", ""); 122SYSCTL_PROC(_net_inet_ip_portrange, OID_AUTO, hilast, CTLTYPE_INT|CTLFLAG_RW, 123 &ipport_hilastauto, 0, &sysctl_net_ipport_check, "I", ""); 124 125/* 126 * in_pcb.c: manage the Protocol Control Blocks. 127 * 128 * NOTE: It is assumed that most of these functions will be called at 129 * splnet(). XXX - There are, unfortunately, a few exceptions to this 130 * rule that should be fixed. 131 */ 132 133/* 134 * Allocate a PCB and associate it with the socket. 135 */ 136int 137in_pcballoc(so, pcbinfo, td) 138 struct socket *so; 139 struct inpcbinfo *pcbinfo; 140 struct thread *td; 141{ 142 register struct inpcb *inp; 143#ifdef IPSEC 144 int error; 145#endif 146 147 inp = zalloc(pcbinfo->ipi_zone); 148 if (inp == NULL) 149 return (ENOBUFS); 150 bzero((caddr_t)inp, sizeof(*inp)); 151 inp->inp_gencnt = ++pcbinfo->ipi_gencnt; 152 inp->inp_pcbinfo = pcbinfo; 153 inp->inp_socket = so; 154#ifdef IPSEC 155 error = ipsec_init_policy(so, &inp->inp_sp); 156 if (error != 0) { 157 zfree(pcbinfo->ipi_zone, inp); 158 return error; 159 } 160#endif /*IPSEC*/ 161#if defined(INET6) 162 if (INP_SOCKAF(so) == AF_INET6 && !ip6_mapped_addr_on) 163 inp->inp_flags |= IN6P_IPV6_V6ONLY; 164#endif 165 LIST_INSERT_HEAD(pcbinfo->listhead, inp, inp_list); 166 pcbinfo->ipi_count++; 167 so->so_pcb = (caddr_t)inp; 168#ifdef INET6 169 if (ip6_auto_flowlabel) 170 inp->inp_flags |= IN6P_AUTOFLOWLABEL; 171#endif 172 return (0); 173} 174 175int 176in_pcbbind(inp, nam, td) 177 register struct inpcb *inp; 178 struct sockaddr *nam; 179 struct thread *td; 180{ 181 struct proc *p = td->td_proc; 182 register struct socket *so = inp->inp_socket; 183 unsigned short *lastport; 184 struct sockaddr_in *sin; 185 struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; 186 u_short lport = 0; 187 int wild = 0, reuseport = (so->so_options & SO_REUSEPORT); 188 int error, prison = 0; 189 190 if (TAILQ_EMPTY(&in_ifaddrhead)) /* XXX broken! */ 191 return (EADDRNOTAVAIL); 192 if (inp->inp_lport || inp->inp_laddr.s_addr != INADDR_ANY) 193 return (EINVAL); 194 if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0) 195 wild = 1; 196 if (nam) { 197 sin = (struct sockaddr_in *)nam; 198 if (nam->sa_len != sizeof (*sin)) 199 return (EINVAL); 200#ifdef notdef 201 /* 202 * We should check the family, but old programs 203 * incorrectly fail to initialize it. 204 */ 205 if (sin->sin_family != AF_INET) 206 return (EAFNOSUPPORT); 207#endif 208 if (sin->sin_addr.s_addr != INADDR_ANY) 209 if (prison_ip(p->p_ucred, 0, &sin->sin_addr.s_addr)) 210 return(EINVAL); 211 lport = sin->sin_port; 212 if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { 213 /* 214 * Treat SO_REUSEADDR as SO_REUSEPORT for multicast; 215 * allow complete duplication of binding if 216 * SO_REUSEPORT is set, or if SO_REUSEADDR is set 217 * and a multicast address is bound on both 218 * new and duplicated sockets. 219 */ 220 if (so->so_options & SO_REUSEADDR) 221 reuseport = SO_REUSEADDR|SO_REUSEPORT; 222 } else if (sin->sin_addr.s_addr != INADDR_ANY) { 223 sin->sin_port = 0; /* yech... */ 224 bzero(&sin->sin_zero, sizeof(sin->sin_zero)); 225 if (ifa_ifwithaddr((struct sockaddr *)sin) == 0) 226 return (EADDRNOTAVAIL); 227 } 228 if (lport) { 229 struct inpcb *t; 230 /* GROSS */ 231 if (ntohs(lport) < IPPORT_RESERVED && p && 232 suser_xxx(0, p, PRISON_ROOT)) 233 return (EACCES); 234 if (p && jailed(p->p_ucred)) 235 prison = 1; 236 if (so->so_cred->cr_uid != 0 && 237 !IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { 238 t = in_pcblookup_local(inp->inp_pcbinfo, 239 sin->sin_addr, lport, 240 prison ? 0 : INPLOOKUP_WILDCARD); 241 if (t && 242 (ntohl(sin->sin_addr.s_addr) != INADDR_ANY || 243 ntohl(t->inp_laddr.s_addr) != INADDR_ANY || 244 (t->inp_socket->so_options & 245 SO_REUSEPORT) == 0) && 246 (so->so_cred->cr_uid != 247 t->inp_socket->so_cred->cr_uid)) { 248#if defined(INET6) 249 if (ntohl(sin->sin_addr.s_addr) != 250 INADDR_ANY || 251 ntohl(t->inp_laddr.s_addr) != 252 INADDR_ANY || 253 INP_SOCKAF(so) == 254 INP_SOCKAF(t->inp_socket)) 255#endif /* defined(INET6) */ 256 return (EADDRINUSE); 257 } 258 } 259 if (prison && 260 prison_ip(p->p_ucred, 0, &sin->sin_addr.s_addr)) 261 return (EADDRNOTAVAIL); 262 t = in_pcblookup_local(pcbinfo, sin->sin_addr, 263 lport, prison ? 0 : wild); 264 if (t && 265 (reuseport & t->inp_socket->so_options) == 0) { 266#if defined(INET6) 267 if (ntohl(sin->sin_addr.s_addr) != 268 INADDR_ANY || 269 ntohl(t->inp_laddr.s_addr) != 270 INADDR_ANY || 271 INP_SOCKAF(so) == 272 INP_SOCKAF(t->inp_socket)) 273#endif /* defined(INET6) */ 274 return (EADDRINUSE); 275 } 276 } 277 inp->inp_laddr = sin->sin_addr; 278 } 279 if (lport == 0) { 280 ushort first, last; 281 int count; 282 283 if (inp->inp_laddr.s_addr != INADDR_ANY) 284 if (prison_ip(p->p_ucred, 0, &inp->inp_laddr.s_addr )) { 285 inp->inp_laddr.s_addr = INADDR_ANY; 286 return (EINVAL); 287 } 288 inp->inp_flags |= INP_ANONPORT; 289 290 if (inp->inp_flags & INP_HIGHPORT) { 291 first = ipport_hifirstauto; /* sysctl */ 292 last = ipport_hilastauto; 293 lastport = &pcbinfo->lasthi; 294 } else if (inp->inp_flags & INP_LOWPORT) { 295 if (p && (error = suser_xxx(0, p, PRISON_ROOT))) { 296 inp->inp_laddr.s_addr = INADDR_ANY; 297 return error; 298 } 299 first = ipport_lowfirstauto; /* 1023 */ 300 last = ipport_lowlastauto; /* 600 */ 301 lastport = &pcbinfo->lastlow; 302 } else { 303 first = ipport_firstauto; /* sysctl */ 304 last = ipport_lastauto; 305 lastport = &pcbinfo->lastport; 306 } 307 /* 308 * Simple check to ensure all ports are not used up causing 309 * a deadlock here. 310 * 311 * We split the two cases (up and down) so that the direction 312 * is not being tested on each round of the loop. 313 */ 314 if (first > last) { 315 /* 316 * counting down 317 */ 318 count = first - last; 319 320 do { 321 if (count-- < 0) { /* completely used? */ 322 inp->inp_laddr.s_addr = INADDR_ANY; 323 return (EADDRNOTAVAIL); 324 } 325 --*lastport; 326 if (*lastport > first || *lastport < last) 327 *lastport = first; 328 lport = htons(*lastport); 329 } while (in_pcblookup_local(pcbinfo, 330 inp->inp_laddr, lport, wild)); 331 } else { 332 /* 333 * counting up 334 */ 335 count = last - first; 336 337 do { 338 if (count-- < 0) { /* completely used? */ 339 /* 340 * Undo any address bind that may have 341 * occurred above. 342 */ 343 inp->inp_laddr.s_addr = INADDR_ANY; 344 return (EADDRNOTAVAIL); 345 } 346 ++*lastport; 347 if (*lastport < first || *lastport > last) 348 *lastport = first; 349 lport = htons(*lastport); 350 } while (in_pcblookup_local(pcbinfo, 351 inp->inp_laddr, lport, wild)); 352 } 353 } 354 inp->inp_lport = lport; 355 if (prison_ip(p->p_ucred, 0, &inp->inp_laddr.s_addr)) { 356 inp->inp_laddr.s_addr = INADDR_ANY; 357 inp->inp_lport = 0; 358 return(EINVAL); 359 } 360 if (in_pcbinshash(inp) != 0) { 361 inp->inp_laddr.s_addr = INADDR_ANY; 362 inp->inp_lport = 0; 363 return (EAGAIN); 364 } 365 return (0); 366} 367 368/* 369 * Transform old in_pcbconnect() into an inner subroutine for new 370 * in_pcbconnect(): Do some validity-checking on the remote 371 * address (in mbuf 'nam') and then determine local host address 372 * (i.e., which interface) to use to access that remote host. 373 * 374 * This preserves definition of in_pcbconnect(), while supporting a 375 * slightly different version for T/TCP. (This is more than 376 * a bit of a kludge, but cleaning up the internal interfaces would 377 * have forced minor changes in every protocol). 378 */ 379 380int 381in_pcbladdr(inp, nam, plocal_sin) 382 register struct inpcb *inp; 383 struct sockaddr *nam; 384 struct sockaddr_in **plocal_sin; 385{ 386 struct in_ifaddr *ia; 387 register struct sockaddr_in *sin = (struct sockaddr_in *)nam; 388 389 if (nam->sa_len != sizeof (*sin)) 390 return (EINVAL); 391 if (sin->sin_family != AF_INET) 392 return (EAFNOSUPPORT); 393 if (sin->sin_port == 0) 394 return (EADDRNOTAVAIL); 395 if (!TAILQ_EMPTY(&in_ifaddrhead)) { 396 /* 397 * If the destination address is INADDR_ANY, 398 * use the primary local address. 399 * If the supplied address is INADDR_BROADCAST, 400 * and the primary interface supports broadcast, 401 * choose the broadcast address for that interface. 402 */ 403 if (sin->sin_addr.s_addr == INADDR_ANY) 404 sin->sin_addr = IA_SIN(TAILQ_FIRST(&in_ifaddrhead))->sin_addr; 405 else if (sin->sin_addr.s_addr == (u_long)INADDR_BROADCAST && 406 (TAILQ_FIRST(&in_ifaddrhead)->ia_ifp->if_flags & IFF_BROADCAST)) 407 sin->sin_addr = satosin(&TAILQ_FIRST(&in_ifaddrhead)->ia_broadaddr)->sin_addr; 408 } 409 if (inp->inp_laddr.s_addr == INADDR_ANY) { 410 register struct route *ro; 411 412 ia = (struct in_ifaddr *)0; 413 /* 414 * If route is known or can be allocated now, 415 * our src addr is taken from the i/f, else punt. 416 */ 417 ro = &inp->inp_route; 418 if (ro->ro_rt && 419 (satosin(&ro->ro_dst)->sin_addr.s_addr != 420 sin->sin_addr.s_addr || 421 inp->inp_socket->so_options & SO_DONTROUTE)) { 422 RTFREE(ro->ro_rt); 423 ro->ro_rt = (struct rtentry *)0; 424 } 425 if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/ 426 (ro->ro_rt == (struct rtentry *)0 || 427 ro->ro_rt->rt_ifp == (struct ifnet *)0)) { 428 /* No route yet, so try to acquire one */ 429 ro->ro_dst.sa_family = AF_INET; 430 ro->ro_dst.sa_len = sizeof(struct sockaddr_in); 431 ((struct sockaddr_in *) &ro->ro_dst)->sin_addr = 432 sin->sin_addr; 433 rtalloc(ro); 434 } 435 /* 436 * If we found a route, use the address 437 * corresponding to the outgoing interface 438 * unless it is the loopback (in case a route 439 * to our address on another net goes to loopback). 440 */ 441 if (ro->ro_rt && !(ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK)) 442 ia = ifatoia(ro->ro_rt->rt_ifa); 443 if (ia == 0) { 444 u_short fport = sin->sin_port; 445 446 sin->sin_port = 0; 447 ia = ifatoia(ifa_ifwithdstaddr(sintosa(sin))); 448 if (ia == 0) 449 ia = ifatoia(ifa_ifwithnet(sintosa(sin))); 450 sin->sin_port = fport; 451 if (ia == 0) 452 ia = TAILQ_FIRST(&in_ifaddrhead); 453 if (ia == 0) 454 return (EADDRNOTAVAIL); 455 } 456 /* 457 * If the destination address is multicast and an outgoing 458 * interface has been set as a multicast option, use the 459 * address of that interface as our source address. 460 */ 461 if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) && 462 inp->inp_moptions != NULL) { 463 struct ip_moptions *imo; 464 struct ifnet *ifp; 465 466 imo = inp->inp_moptions; 467 if (imo->imo_multicast_ifp != NULL) { 468 ifp = imo->imo_multicast_ifp; 469 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) 470 if (ia->ia_ifp == ifp) 471 break; 472 if (ia == 0) 473 return (EADDRNOTAVAIL); 474 } 475 } 476 /* 477 * Don't do pcblookup call here; return interface in plocal_sin 478 * and exit to caller, that will do the lookup. 479 */ 480 *plocal_sin = &ia->ia_addr; 481 482 } 483 return(0); 484} 485 486/* 487 * Outer subroutine: 488 * Connect from a socket to a specified address. 489 * Both address and port must be specified in argument sin. 490 * If don't have a local address for this socket yet, 491 * then pick one. 492 */ 493int 494in_pcbconnect(inp, nam, td) 495 register struct inpcb *inp; 496 struct sockaddr *nam; 497 struct thread *td; 498{ 499 struct sockaddr_in *ifaddr; 500 struct sockaddr_in *sin = (struct sockaddr_in *)nam; 501 struct sockaddr_in sa; 502 struct ucred *cred; 503 int error; 504 505 cred = inp->inp_socket->so_cred; 506 if (inp->inp_laddr.s_addr == INADDR_ANY && jailed(cred)) { 507 bzero(&sa, sizeof (sa));
|
508 sa.sin_addr.s_addr = htonl(cred->cr_prison->pr_ip);
| 508 sa.sin_addr.s_addr = htonl(prison_getip(cred));
|
509 sa.sin_len=sizeof (sa); 510 sa.sin_family = AF_INET; 511 error = in_pcbbind(inp, (struct sockaddr *)&sa, td); 512 if (error) 513 return (error); 514 } 515 /* 516 * Call inner routine, to assign local interface address. 517 */ 518 if ((error = in_pcbladdr(inp, nam, &ifaddr)) != 0) 519 return(error); 520 521 if (in_pcblookup_hash(inp->inp_pcbinfo, sin->sin_addr, sin->sin_port, 522 inp->inp_laddr.s_addr ? inp->inp_laddr : ifaddr->sin_addr, 523 inp->inp_lport, 0, NULL) != NULL) { 524 return (EADDRINUSE); 525 } 526 if (inp->inp_laddr.s_addr == INADDR_ANY) { 527 if (inp->inp_lport == 0) { 528 error = in_pcbbind(inp, (struct sockaddr *)0, td); 529 if (error) 530 return (error); 531 } 532 inp->inp_laddr = ifaddr->sin_addr; 533 } 534 inp->inp_faddr = sin->sin_addr; 535 inp->inp_fport = sin->sin_port; 536 in_pcbrehash(inp); 537 return (0); 538} 539 540void 541in_pcbdisconnect(inp) 542 struct inpcb *inp; 543{ 544 545 inp->inp_faddr.s_addr = INADDR_ANY; 546 inp->inp_fport = 0; 547 in_pcbrehash(inp); 548 if (inp->inp_socket->so_state & SS_NOFDREF) 549 in_pcbdetach(inp); 550} 551 552void 553in_pcbdetach(inp) 554 struct inpcb *inp; 555{ 556 struct socket *so = inp->inp_socket; 557 struct inpcbinfo *ipi = inp->inp_pcbinfo; 558 559#ifdef IPSEC 560 ipsec4_delete_pcbpolicy(inp); 561#endif /*IPSEC*/ 562 inp->inp_gencnt = ++ipi->ipi_gencnt; 563 in_pcbremlists(inp); 564 so->so_pcb = 0; 565 sotryfree(so); 566 if (inp->inp_options) 567 (void)m_free(inp->inp_options); 568 if (inp->inp_route.ro_rt) 569 rtfree(inp->inp_route.ro_rt); 570 ip_freemoptions(inp->inp_moptions); 571 inp->inp_vflag = 0; 572 zfree(ipi->ipi_zone, inp); 573} 574 575/* 576 * The calling convention of in_setsockaddr() and in_setpeeraddr() was 577 * modified to match the pru_sockaddr() and pru_peeraddr() entry points 578 * in struct pr_usrreqs, so that protocols can just reference then directly 579 * without the need for a wrapper function. The socket must have a valid 580 * (i.e., non-nil) PCB, but it should be impossible to get an invalid one 581 * except through a kernel programming error, so it is acceptable to panic 582 * (or in this case trap) if the PCB is invalid. (Actually, we don't trap 583 * because there actually /is/ a programming error somewhere... XXX) 584 */ 585int 586in_setsockaddr(so, nam) 587 struct socket *so; 588 struct sockaddr **nam; 589{ 590 int s; 591 register struct inpcb *inp; 592 register struct sockaddr_in *sin; 593 594 /* 595 * Do the malloc first in case it blocks. 596 */ 597 MALLOC(sin, struct sockaddr_in *, sizeof *sin, M_SONAME, 598 M_WAITOK | M_ZERO); 599 sin->sin_family = AF_INET; 600 sin->sin_len = sizeof(*sin); 601 602 s = splnet(); 603 inp = sotoinpcb(so); 604 if (!inp) { 605 splx(s); 606 free(sin, M_SONAME); 607 return ECONNRESET; 608 } 609 sin->sin_port = inp->inp_lport; 610 sin->sin_addr = inp->inp_laddr; 611 splx(s); 612 613 *nam = (struct sockaddr *)sin; 614 return 0; 615} 616 617int 618in_setpeeraddr(so, nam) 619 struct socket *so; 620 struct sockaddr **nam; 621{ 622 int s; 623 struct inpcb *inp; 624 register struct sockaddr_in *sin; 625 626 /* 627 * Do the malloc first in case it blocks. 628 */ 629 MALLOC(sin, struct sockaddr_in *, sizeof *sin, M_SONAME, 630 M_WAITOK | M_ZERO); 631 sin->sin_family = AF_INET; 632 sin->sin_len = sizeof(*sin); 633 634 s = splnet(); 635 inp = sotoinpcb(so); 636 if (!inp) { 637 splx(s); 638 free(sin, M_SONAME); 639 return ECONNRESET; 640 } 641 sin->sin_port = inp->inp_fport; 642 sin->sin_addr = inp->inp_faddr; 643 splx(s); 644 645 *nam = (struct sockaddr *)sin; 646 return 0; 647} 648 649void 650in_pcbnotifyall(head, faddr, errno, notify) 651 struct inpcbhead *head; 652 struct in_addr faddr; 653 int errno; 654 void (*notify) __P((struct inpcb *, int)); 655{ 656 struct inpcb *inp, *ninp; 657 int s; 658 659 s = splnet(); 660 for (inp = LIST_FIRST(head); inp != NULL; inp = ninp) { 661 ninp = LIST_NEXT(inp, inp_list); 662#ifdef INET6 663 if ((inp->inp_vflag & INP_IPV4) == 0) 664 continue; 665#endif 666 if (inp->inp_faddr.s_addr != faddr.s_addr || 667 inp->inp_socket == NULL) 668 continue; 669 (*notify)(inp, errno); 670 } 671 splx(s); 672} 673 674void 675in_pcbpurgeif0(head, ifp) 676 struct inpcb *head; 677 struct ifnet *ifp; 678{ 679 struct inpcb *inp; 680 struct ip_moptions *imo; 681 int i, gap; 682 683 for (inp = head; inp != NULL; inp = LIST_NEXT(inp, inp_list)) { 684 imo = inp->inp_moptions; 685 if ((inp->inp_vflag & INP_IPV4) && 686 imo != NULL) { 687 /* 688 * Unselect the outgoing interface if it is being 689 * detached. 690 */ 691 if (imo->imo_multicast_ifp == ifp) 692 imo->imo_multicast_ifp = NULL; 693 694 /* 695 * Drop multicast group membership if we joined 696 * through the interface being detached. 697 */ 698 for (i = 0, gap = 0; i < imo->imo_num_memberships; 699 i++) { 700 if (imo->imo_membership[i]->inm_ifp == ifp) { 701 in_delmulti(imo->imo_membership[i]); 702 gap++; 703 } else if (gap != 0) 704 imo->imo_membership[i - gap] = 705 imo->imo_membership[i]; 706 } 707 imo->imo_num_memberships -= gap; 708 } 709 } 710} 711 712/* 713 * Check for alternatives when higher level complains 714 * about service problems. For now, invalidate cached 715 * routing information. If the route was created dynamically 716 * (by a redirect), time to try a default gateway again. 717 */ 718void 719in_losing(inp) 720 struct inpcb *inp; 721{ 722 register struct rtentry *rt; 723 struct rt_addrinfo info; 724 725 if ((rt = inp->inp_route.ro_rt)) { 726 bzero((caddr_t)&info, sizeof(info)); 727 info.rti_flags = rt->rt_flags; 728 info.rti_info[RTAX_DST] = rt_key(rt); 729 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 730 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 731 rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0); 732 if (rt->rt_flags & RTF_DYNAMIC) 733 (void) rtrequest1(RTM_DELETE, &info, NULL); 734 inp->inp_route.ro_rt = NULL; 735 rtfree(rt); 736 /* 737 * A new route can be allocated 738 * the next time output is attempted. 739 */ 740 } 741} 742 743/* 744 * After a routing change, flush old routing 745 * and allocate a (hopefully) better one. 746 */ 747void 748in_rtchange(inp, errno) 749 register struct inpcb *inp; 750 int errno; 751{ 752 if (inp->inp_route.ro_rt) { 753 rtfree(inp->inp_route.ro_rt); 754 inp->inp_route.ro_rt = 0; 755 /* 756 * A new route can be allocated the next time 757 * output is attempted. 758 */ 759 } 760} 761 762/* 763 * Lookup a PCB based on the local address and port. 764 */ 765struct inpcb * 766in_pcblookup_local(pcbinfo, laddr, lport_arg, wild_okay) 767 struct inpcbinfo *pcbinfo; 768 struct in_addr laddr; 769 u_int lport_arg; 770 int wild_okay; 771{ 772 register struct inpcb *inp; 773 int matchwild = 3, wildcard; 774 u_short lport = lport_arg; 775 776 if (!wild_okay) { 777 struct inpcbhead *head; 778 /* 779 * Look for an unconnected (wildcard foreign addr) PCB that 780 * matches the local address and port we're looking for. 781 */ 782 head = &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0, pcbinfo->hashmask)]; 783 LIST_FOREACH(inp, head, inp_hash) { 784#ifdef INET6 785 if ((inp->inp_vflag & INP_IPV4) == 0) 786 continue; 787#endif 788 if (inp->inp_faddr.s_addr == INADDR_ANY && 789 inp->inp_laddr.s_addr == laddr.s_addr && 790 inp->inp_lport == lport) { 791 /* 792 * Found. 793 */ 794 return (inp); 795 } 796 } 797 /* 798 * Not found. 799 */ 800 return (NULL); 801 } else { 802 struct inpcbporthead *porthash; 803 struct inpcbport *phd; 804 struct inpcb *match = NULL; 805 /* 806 * Best fit PCB lookup. 807 * 808 * First see if this local port is in use by looking on the 809 * port hash list. 810 */ 811 porthash = &pcbinfo->porthashbase[INP_PCBPORTHASH(lport, 812 pcbinfo->porthashmask)]; 813 LIST_FOREACH(phd, porthash, phd_hash) { 814 if (phd->phd_port == lport) 815 break; 816 } 817 if (phd != NULL) { 818 /* 819 * Port is in use by one or more PCBs. Look for best 820 * fit. 821 */ 822 LIST_FOREACH(inp, &phd->phd_pcblist, inp_portlist) { 823 wildcard = 0; 824#ifdef INET6 825 if ((inp->inp_vflag & INP_IPV4) == 0) 826 continue; 827#endif 828 if (inp->inp_faddr.s_addr != INADDR_ANY) 829 wildcard++; 830 if (inp->inp_laddr.s_addr != INADDR_ANY) { 831 if (laddr.s_addr == INADDR_ANY) 832 wildcard++; 833 else if (inp->inp_laddr.s_addr != laddr.s_addr) 834 continue; 835 } else { 836 if (laddr.s_addr != INADDR_ANY) 837 wildcard++; 838 } 839 if (wildcard < matchwild) { 840 match = inp; 841 matchwild = wildcard; 842 if (matchwild == 0) { 843 break; 844 } 845 } 846 } 847 } 848 return (match); 849 } 850} 851 852/* 853 * Lookup PCB in hash list. 854 */ 855struct inpcb * 856in_pcblookup_hash(pcbinfo, faddr, fport_arg, laddr, lport_arg, wildcard, 857 ifp) 858 struct inpcbinfo *pcbinfo; 859 struct in_addr faddr, laddr; 860 u_int fport_arg, lport_arg; 861 int wildcard; 862 struct ifnet *ifp; 863{ 864 struct inpcbhead *head; 865 register struct inpcb *inp; 866 u_short fport = fport_arg, lport = lport_arg; 867 868 /* 869 * First look for an exact match. 870 */ 871 head = &pcbinfo->hashbase[INP_PCBHASH(faddr.s_addr, lport, fport, pcbinfo->hashmask)]; 872 LIST_FOREACH(inp, head, inp_hash) { 873#ifdef INET6 874 if ((inp->inp_vflag & INP_IPV4) == 0) 875 continue; 876#endif 877 if (inp->inp_faddr.s_addr == faddr.s_addr && 878 inp->inp_laddr.s_addr == laddr.s_addr && 879 inp->inp_fport == fport && 880 inp->inp_lport == lport) { 881 /* 882 * Found. 883 */ 884 return (inp); 885 } 886 } 887 if (wildcard) { 888 struct inpcb *local_wild = NULL; 889#if defined(INET6) 890 struct inpcb *local_wild_mapped = NULL; 891#endif /* defined(INET6) */ 892 893 head = &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0, pcbinfo->hashmask)]; 894 LIST_FOREACH(inp, head, inp_hash) { 895#ifdef INET6 896 if ((inp->inp_vflag & INP_IPV4) == 0) 897 continue; 898#endif 899 if (inp->inp_faddr.s_addr == INADDR_ANY && 900 inp->inp_lport == lport) { 901 if (ifp && ifp->if_type == IFT_FAITH && 902 (inp->inp_flags & INP_FAITH) == 0) 903 continue; 904 if (inp->inp_laddr.s_addr == laddr.s_addr) 905 return (inp); 906 else if (inp->inp_laddr.s_addr == INADDR_ANY) { 907#if defined(INET6) 908 if (INP_CHECK_SOCKAF(inp->inp_socket, 909 AF_INET6)) 910 local_wild_mapped = inp; 911 else 912#endif /* defined(INET6) */ 913 local_wild = inp; 914 } 915 } 916 } 917#if defined(INET6) 918 if (local_wild == NULL) 919 return (local_wild_mapped); 920#endif /* defined(INET6) */ 921 return (local_wild); 922 } 923 924 /* 925 * Not found. 926 */ 927 return (NULL); 928} 929 930/* 931 * Insert PCB onto various hash lists. 932 */ 933int 934in_pcbinshash(inp) 935 struct inpcb *inp; 936{ 937 struct inpcbhead *pcbhash; 938 struct inpcbporthead *pcbporthash; 939 struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; 940 struct inpcbport *phd; 941 u_int32_t hashkey_faddr; 942 943#ifdef INET6 944 if (inp->inp_vflag & INP_IPV6) 945 hashkey_faddr = inp->in6p_faddr.s6_addr32[3] /* XXX */; 946 else 947#endif /* INET6 */ 948 hashkey_faddr = inp->inp_faddr.s_addr; 949 950 pcbhash = &pcbinfo->hashbase[INP_PCBHASH(hashkey_faddr, 951 inp->inp_lport, inp->inp_fport, pcbinfo->hashmask)]; 952 953 pcbporthash = &pcbinfo->porthashbase[INP_PCBPORTHASH(inp->inp_lport, 954 pcbinfo->porthashmask)]; 955 956 /* 957 * Go through port list and look for a head for this lport. 958 */ 959 LIST_FOREACH(phd, pcbporthash, phd_hash) { 960 if (phd->phd_port == inp->inp_lport) 961 break; 962 } 963 /* 964 * If none exists, malloc one and tack it on. 965 */ 966 if (phd == NULL) { 967 MALLOC(phd, struct inpcbport *, sizeof(struct inpcbport), M_PCB, M_NOWAIT); 968 if (phd == NULL) { 969 return (ENOBUFS); /* XXX */ 970 } 971 phd->phd_port = inp->inp_lport; 972 LIST_INIT(&phd->phd_pcblist); 973 LIST_INSERT_HEAD(pcbporthash, phd, phd_hash); 974 } 975 inp->inp_phd = phd; 976 LIST_INSERT_HEAD(&phd->phd_pcblist, inp, inp_portlist); 977 LIST_INSERT_HEAD(pcbhash, inp, inp_hash); 978 return (0); 979} 980 981/* 982 * Move PCB to the proper hash bucket when { faddr, fport } have been 983 * changed. NOTE: This does not handle the case of the lport changing (the 984 * hashed port list would have to be updated as well), so the lport must 985 * not change after in_pcbinshash() has been called. 986 */ 987void 988in_pcbrehash(inp) 989 struct inpcb *inp; 990{ 991 struct inpcbhead *head; 992 u_int32_t hashkey_faddr; 993 994#ifdef INET6 995 if (inp->inp_vflag & INP_IPV6) 996 hashkey_faddr = inp->in6p_faddr.s6_addr32[3] /* XXX */; 997 else 998#endif /* INET6 */ 999 hashkey_faddr = inp->inp_faddr.s_addr; 1000 1001 head = &inp->inp_pcbinfo->hashbase[INP_PCBHASH(hashkey_faddr, 1002 inp->inp_lport, inp->inp_fport, inp->inp_pcbinfo->hashmask)]; 1003 1004 LIST_REMOVE(inp, inp_hash); 1005 LIST_INSERT_HEAD(head, inp, inp_hash); 1006} 1007 1008/* 1009 * Remove PCB from various lists. 1010 */ 1011void 1012in_pcbremlists(inp) 1013 struct inpcb *inp; 1014{ 1015 inp->inp_gencnt = ++inp->inp_pcbinfo->ipi_gencnt; 1016 if (inp->inp_lport) { 1017 struct inpcbport *phd = inp->inp_phd; 1018 1019 LIST_REMOVE(inp, inp_hash); 1020 LIST_REMOVE(inp, inp_portlist); 1021 if (LIST_FIRST(&phd->phd_pcblist) == NULL) { 1022 LIST_REMOVE(phd, phd_hash); 1023 free(phd, M_PCB); 1024 } 1025 } 1026 LIST_REMOVE(inp, inp_list); 1027 inp->inp_pcbinfo->ipi_count--; 1028} 1029 1030int 1031prison_xinpcb(struct proc *p, struct inpcb *inp) 1032{ 1033 if (!jailed(p->p_ucred)) 1034 return (0);
| 509 sa.sin_len=sizeof (sa); 510 sa.sin_family = AF_INET; 511 error = in_pcbbind(inp, (struct sockaddr *)&sa, td); 512 if (error) 513 return (error); 514 } 515 /* 516 * Call inner routine, to assign local interface address. 517 */ 518 if ((error = in_pcbladdr(inp, nam, &ifaddr)) != 0) 519 return(error); 520 521 if (in_pcblookup_hash(inp->inp_pcbinfo, sin->sin_addr, sin->sin_port, 522 inp->inp_laddr.s_addr ? inp->inp_laddr : ifaddr->sin_addr, 523 inp->inp_lport, 0, NULL) != NULL) { 524 return (EADDRINUSE); 525 } 526 if (inp->inp_laddr.s_addr == INADDR_ANY) { 527 if (inp->inp_lport == 0) { 528 error = in_pcbbind(inp, (struct sockaddr *)0, td); 529 if (error) 530 return (error); 531 } 532 inp->inp_laddr = ifaddr->sin_addr; 533 } 534 inp->inp_faddr = sin->sin_addr; 535 inp->inp_fport = sin->sin_port; 536 in_pcbrehash(inp); 537 return (0); 538} 539 540void 541in_pcbdisconnect(inp) 542 struct inpcb *inp; 543{ 544 545 inp->inp_faddr.s_addr = INADDR_ANY; 546 inp->inp_fport = 0; 547 in_pcbrehash(inp); 548 if (inp->inp_socket->so_state & SS_NOFDREF) 549 in_pcbdetach(inp); 550} 551 552void 553in_pcbdetach(inp) 554 struct inpcb *inp; 555{ 556 struct socket *so = inp->inp_socket; 557 struct inpcbinfo *ipi = inp->inp_pcbinfo; 558 559#ifdef IPSEC 560 ipsec4_delete_pcbpolicy(inp); 561#endif /*IPSEC*/ 562 inp->inp_gencnt = ++ipi->ipi_gencnt; 563 in_pcbremlists(inp); 564 so->so_pcb = 0; 565 sotryfree(so); 566 if (inp->inp_options) 567 (void)m_free(inp->inp_options); 568 if (inp->inp_route.ro_rt) 569 rtfree(inp->inp_route.ro_rt); 570 ip_freemoptions(inp->inp_moptions); 571 inp->inp_vflag = 0; 572 zfree(ipi->ipi_zone, inp); 573} 574 575/* 576 * The calling convention of in_setsockaddr() and in_setpeeraddr() was 577 * modified to match the pru_sockaddr() and pru_peeraddr() entry points 578 * in struct pr_usrreqs, so that protocols can just reference then directly 579 * without the need for a wrapper function. The socket must have a valid 580 * (i.e., non-nil) PCB, but it should be impossible to get an invalid one 581 * except through a kernel programming error, so it is acceptable to panic 582 * (or in this case trap) if the PCB is invalid. (Actually, we don't trap 583 * because there actually /is/ a programming error somewhere... XXX) 584 */ 585int 586in_setsockaddr(so, nam) 587 struct socket *so; 588 struct sockaddr **nam; 589{ 590 int s; 591 register struct inpcb *inp; 592 register struct sockaddr_in *sin; 593 594 /* 595 * Do the malloc first in case it blocks. 596 */ 597 MALLOC(sin, struct sockaddr_in *, sizeof *sin, M_SONAME, 598 M_WAITOK | M_ZERO); 599 sin->sin_family = AF_INET; 600 sin->sin_len = sizeof(*sin); 601 602 s = splnet(); 603 inp = sotoinpcb(so); 604 if (!inp) { 605 splx(s); 606 free(sin, M_SONAME); 607 return ECONNRESET; 608 } 609 sin->sin_port = inp->inp_lport; 610 sin->sin_addr = inp->inp_laddr; 611 splx(s); 612 613 *nam = (struct sockaddr *)sin; 614 return 0; 615} 616 617int 618in_setpeeraddr(so, nam) 619 struct socket *so; 620 struct sockaddr **nam; 621{ 622 int s; 623 struct inpcb *inp; 624 register struct sockaddr_in *sin; 625 626 /* 627 * Do the malloc first in case it blocks. 628 */ 629 MALLOC(sin, struct sockaddr_in *, sizeof *sin, M_SONAME, 630 M_WAITOK | M_ZERO); 631 sin->sin_family = AF_INET; 632 sin->sin_len = sizeof(*sin); 633 634 s = splnet(); 635 inp = sotoinpcb(so); 636 if (!inp) { 637 splx(s); 638 free(sin, M_SONAME); 639 return ECONNRESET; 640 } 641 sin->sin_port = inp->inp_fport; 642 sin->sin_addr = inp->inp_faddr; 643 splx(s); 644 645 *nam = (struct sockaddr *)sin; 646 return 0; 647} 648 649void 650in_pcbnotifyall(head, faddr, errno, notify) 651 struct inpcbhead *head; 652 struct in_addr faddr; 653 int errno; 654 void (*notify) __P((struct inpcb *, int)); 655{ 656 struct inpcb *inp, *ninp; 657 int s; 658 659 s = splnet(); 660 for (inp = LIST_FIRST(head); inp != NULL; inp = ninp) { 661 ninp = LIST_NEXT(inp, inp_list); 662#ifdef INET6 663 if ((inp->inp_vflag & INP_IPV4) == 0) 664 continue; 665#endif 666 if (inp->inp_faddr.s_addr != faddr.s_addr || 667 inp->inp_socket == NULL) 668 continue; 669 (*notify)(inp, errno); 670 } 671 splx(s); 672} 673 674void 675in_pcbpurgeif0(head, ifp) 676 struct inpcb *head; 677 struct ifnet *ifp; 678{ 679 struct inpcb *inp; 680 struct ip_moptions *imo; 681 int i, gap; 682 683 for (inp = head; inp != NULL; inp = LIST_NEXT(inp, inp_list)) { 684 imo = inp->inp_moptions; 685 if ((inp->inp_vflag & INP_IPV4) && 686 imo != NULL) { 687 /* 688 * Unselect the outgoing interface if it is being 689 * detached. 690 */ 691 if (imo->imo_multicast_ifp == ifp) 692 imo->imo_multicast_ifp = NULL; 693 694 /* 695 * Drop multicast group membership if we joined 696 * through the interface being detached. 697 */ 698 for (i = 0, gap = 0; i < imo->imo_num_memberships; 699 i++) { 700 if (imo->imo_membership[i]->inm_ifp == ifp) { 701 in_delmulti(imo->imo_membership[i]); 702 gap++; 703 } else if (gap != 0) 704 imo->imo_membership[i - gap] = 705 imo->imo_membership[i]; 706 } 707 imo->imo_num_memberships -= gap; 708 } 709 } 710} 711 712/* 713 * Check for alternatives when higher level complains 714 * about service problems. For now, invalidate cached 715 * routing information. If the route was created dynamically 716 * (by a redirect), time to try a default gateway again. 717 */ 718void 719in_losing(inp) 720 struct inpcb *inp; 721{ 722 register struct rtentry *rt; 723 struct rt_addrinfo info; 724 725 if ((rt = inp->inp_route.ro_rt)) { 726 bzero((caddr_t)&info, sizeof(info)); 727 info.rti_flags = rt->rt_flags; 728 info.rti_info[RTAX_DST] = rt_key(rt); 729 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 730 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 731 rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0); 732 if (rt->rt_flags & RTF_DYNAMIC) 733 (void) rtrequest1(RTM_DELETE, &info, NULL); 734 inp->inp_route.ro_rt = NULL; 735 rtfree(rt); 736 /* 737 * A new route can be allocated 738 * the next time output is attempted. 739 */ 740 } 741} 742 743/* 744 * After a routing change, flush old routing 745 * and allocate a (hopefully) better one. 746 */ 747void 748in_rtchange(inp, errno) 749 register struct inpcb *inp; 750 int errno; 751{ 752 if (inp->inp_route.ro_rt) { 753 rtfree(inp->inp_route.ro_rt); 754 inp->inp_route.ro_rt = 0; 755 /* 756 * A new route can be allocated the next time 757 * output is attempted. 758 */ 759 } 760} 761 762/* 763 * Lookup a PCB based on the local address and port. 764 */ 765struct inpcb * 766in_pcblookup_local(pcbinfo, laddr, lport_arg, wild_okay) 767 struct inpcbinfo *pcbinfo; 768 struct in_addr laddr; 769 u_int lport_arg; 770 int wild_okay; 771{ 772 register struct inpcb *inp; 773 int matchwild = 3, wildcard; 774 u_short lport = lport_arg; 775 776 if (!wild_okay) { 777 struct inpcbhead *head; 778 /* 779 * Look for an unconnected (wildcard foreign addr) PCB that 780 * matches the local address and port we're looking for. 781 */ 782 head = &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0, pcbinfo->hashmask)]; 783 LIST_FOREACH(inp, head, inp_hash) { 784#ifdef INET6 785 if ((inp->inp_vflag & INP_IPV4) == 0) 786 continue; 787#endif 788 if (inp->inp_faddr.s_addr == INADDR_ANY && 789 inp->inp_laddr.s_addr == laddr.s_addr && 790 inp->inp_lport == lport) { 791 /* 792 * Found. 793 */ 794 return (inp); 795 } 796 } 797 /* 798 * Not found. 799 */ 800 return (NULL); 801 } else { 802 struct inpcbporthead *porthash; 803 struct inpcbport *phd; 804 struct inpcb *match = NULL; 805 /* 806 * Best fit PCB lookup. 807 * 808 * First see if this local port is in use by looking on the 809 * port hash list. 810 */ 811 porthash = &pcbinfo->porthashbase[INP_PCBPORTHASH(lport, 812 pcbinfo->porthashmask)]; 813 LIST_FOREACH(phd, porthash, phd_hash) { 814 if (phd->phd_port == lport) 815 break; 816 } 817 if (phd != NULL) { 818 /* 819 * Port is in use by one or more PCBs. Look for best 820 * fit. 821 */ 822 LIST_FOREACH(inp, &phd->phd_pcblist, inp_portlist) { 823 wildcard = 0; 824#ifdef INET6 825 if ((inp->inp_vflag & INP_IPV4) == 0) 826 continue; 827#endif 828 if (inp->inp_faddr.s_addr != INADDR_ANY) 829 wildcard++; 830 if (inp->inp_laddr.s_addr != INADDR_ANY) { 831 if (laddr.s_addr == INADDR_ANY) 832 wildcard++; 833 else if (inp->inp_laddr.s_addr != laddr.s_addr) 834 continue; 835 } else { 836 if (laddr.s_addr != INADDR_ANY) 837 wildcard++; 838 } 839 if (wildcard < matchwild) { 840 match = inp; 841 matchwild = wildcard; 842 if (matchwild == 0) { 843 break; 844 } 845 } 846 } 847 } 848 return (match); 849 } 850} 851 852/* 853 * Lookup PCB in hash list. 854 */ 855struct inpcb * 856in_pcblookup_hash(pcbinfo, faddr, fport_arg, laddr, lport_arg, wildcard, 857 ifp) 858 struct inpcbinfo *pcbinfo; 859 struct in_addr faddr, laddr; 860 u_int fport_arg, lport_arg; 861 int wildcard; 862 struct ifnet *ifp; 863{ 864 struct inpcbhead *head; 865 register struct inpcb *inp; 866 u_short fport = fport_arg, lport = lport_arg; 867 868 /* 869 * First look for an exact match. 870 */ 871 head = &pcbinfo->hashbase[INP_PCBHASH(faddr.s_addr, lport, fport, pcbinfo->hashmask)]; 872 LIST_FOREACH(inp, head, inp_hash) { 873#ifdef INET6 874 if ((inp->inp_vflag & INP_IPV4) == 0) 875 continue; 876#endif 877 if (inp->inp_faddr.s_addr == faddr.s_addr && 878 inp->inp_laddr.s_addr == laddr.s_addr && 879 inp->inp_fport == fport && 880 inp->inp_lport == lport) { 881 /* 882 * Found. 883 */ 884 return (inp); 885 } 886 } 887 if (wildcard) { 888 struct inpcb *local_wild = NULL; 889#if defined(INET6) 890 struct inpcb *local_wild_mapped = NULL; 891#endif /* defined(INET6) */ 892 893 head = &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0, pcbinfo->hashmask)]; 894 LIST_FOREACH(inp, head, inp_hash) { 895#ifdef INET6 896 if ((inp->inp_vflag & INP_IPV4) == 0) 897 continue; 898#endif 899 if (inp->inp_faddr.s_addr == INADDR_ANY && 900 inp->inp_lport == lport) { 901 if (ifp && ifp->if_type == IFT_FAITH && 902 (inp->inp_flags & INP_FAITH) == 0) 903 continue; 904 if (inp->inp_laddr.s_addr == laddr.s_addr) 905 return (inp); 906 else if (inp->inp_laddr.s_addr == INADDR_ANY) { 907#if defined(INET6) 908 if (INP_CHECK_SOCKAF(inp->inp_socket, 909 AF_INET6)) 910 local_wild_mapped = inp; 911 else 912#endif /* defined(INET6) */ 913 local_wild = inp; 914 } 915 } 916 } 917#if defined(INET6) 918 if (local_wild == NULL) 919 return (local_wild_mapped); 920#endif /* defined(INET6) */ 921 return (local_wild); 922 } 923 924 /* 925 * Not found. 926 */ 927 return (NULL); 928} 929 930/* 931 * Insert PCB onto various hash lists. 932 */ 933int 934in_pcbinshash(inp) 935 struct inpcb *inp; 936{ 937 struct inpcbhead *pcbhash; 938 struct inpcbporthead *pcbporthash; 939 struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; 940 struct inpcbport *phd; 941 u_int32_t hashkey_faddr; 942 943#ifdef INET6 944 if (inp->inp_vflag & INP_IPV6) 945 hashkey_faddr = inp->in6p_faddr.s6_addr32[3] /* XXX */; 946 else 947#endif /* INET6 */ 948 hashkey_faddr = inp->inp_faddr.s_addr; 949 950 pcbhash = &pcbinfo->hashbase[INP_PCBHASH(hashkey_faddr, 951 inp->inp_lport, inp->inp_fport, pcbinfo->hashmask)]; 952 953 pcbporthash = &pcbinfo->porthashbase[INP_PCBPORTHASH(inp->inp_lport, 954 pcbinfo->porthashmask)]; 955 956 /* 957 * Go through port list and look for a head for this lport. 958 */ 959 LIST_FOREACH(phd, pcbporthash, phd_hash) { 960 if (phd->phd_port == inp->inp_lport) 961 break; 962 } 963 /* 964 * If none exists, malloc one and tack it on. 965 */ 966 if (phd == NULL) { 967 MALLOC(phd, struct inpcbport *, sizeof(struct inpcbport), M_PCB, M_NOWAIT); 968 if (phd == NULL) { 969 return (ENOBUFS); /* XXX */ 970 } 971 phd->phd_port = inp->inp_lport; 972 LIST_INIT(&phd->phd_pcblist); 973 LIST_INSERT_HEAD(pcbporthash, phd, phd_hash); 974 } 975 inp->inp_phd = phd; 976 LIST_INSERT_HEAD(&phd->phd_pcblist, inp, inp_portlist); 977 LIST_INSERT_HEAD(pcbhash, inp, inp_hash); 978 return (0); 979} 980 981/* 982 * Move PCB to the proper hash bucket when { faddr, fport } have been 983 * changed. NOTE: This does not handle the case of the lport changing (the 984 * hashed port list would have to be updated as well), so the lport must 985 * not change after in_pcbinshash() has been called. 986 */ 987void 988in_pcbrehash(inp) 989 struct inpcb *inp; 990{ 991 struct inpcbhead *head; 992 u_int32_t hashkey_faddr; 993 994#ifdef INET6 995 if (inp->inp_vflag & INP_IPV6) 996 hashkey_faddr = inp->in6p_faddr.s6_addr32[3] /* XXX */; 997 else 998#endif /* INET6 */ 999 hashkey_faddr = inp->inp_faddr.s_addr; 1000 1001 head = &inp->inp_pcbinfo->hashbase[INP_PCBHASH(hashkey_faddr, 1002 inp->inp_lport, inp->inp_fport, inp->inp_pcbinfo->hashmask)]; 1003 1004 LIST_REMOVE(inp, inp_hash); 1005 LIST_INSERT_HEAD(head, inp, inp_hash); 1006} 1007 1008/* 1009 * Remove PCB from various lists. 1010 */ 1011void 1012in_pcbremlists(inp) 1013 struct inpcb *inp; 1014{ 1015 inp->inp_gencnt = ++inp->inp_pcbinfo->ipi_gencnt; 1016 if (inp->inp_lport) { 1017 struct inpcbport *phd = inp->inp_phd; 1018 1019 LIST_REMOVE(inp, inp_hash); 1020 LIST_REMOVE(inp, inp_portlist); 1021 if (LIST_FIRST(&phd->phd_pcblist) == NULL) { 1022 LIST_REMOVE(phd, phd_hash); 1023 free(phd, M_PCB); 1024 } 1025 } 1026 LIST_REMOVE(inp, inp_list); 1027 inp->inp_pcbinfo->ipi_count--; 1028} 1029 1030int 1031prison_xinpcb(struct proc *p, struct inpcb *inp) 1032{ 1033 if (!jailed(p->p_ucred)) 1034 return (0);
|
1035 if (ntohl(inp->inp_laddr.s_addr) == p->p_ucred->cr_prison->pr_ip)
| 1035 if (ntohl(inp->inp_laddr.s_addr) == prison_getip(p->p_ucred))
|
1036 return (0); 1037 return (1); 1038}
| 1036 return (0); 1037 return (1); 1038}
|