1 1.202 ozaki /* $NetBSD: in_pcb.c,v 1.202 2022/11/04 09:05:41 ozaki-r Exp $ */ 2 1.59 itojun 3 1.59 itojun /* 4 1.59 itojun * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 1.59 itojun * All rights reserved. 6 1.78 itojun * 7 1.59 itojun * Redistribution and use in source and binary forms, with or without 8 1.59 itojun * modification, are permitted provided that the following conditions 9 1.59 itojun * are met: 10 1.59 itojun * 1. Redistributions of source code must retain the above copyright 11 1.59 itojun * notice, this list of conditions and the following disclaimer. 12 1.59 itojun * 2. Redistributions in binary form must reproduce the above copyright 13 1.59 itojun * notice, this list of conditions and the following disclaimer in the 14 1.59 itojun * documentation and/or other materials provided with the distribution. 15 1.59 itojun * 3. Neither the name of the project nor the names of its contributors 16 1.59 itojun * may be used to endorse or promote products derived from this software 17 1.59 itojun * without specific prior written permission. 18 1.78 itojun * 19 1.59 itojun * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 20 1.59 itojun * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.59 itojun * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.59 itojun * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 1.59 itojun * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 1.59 itojun * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 1.59 itojun * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 1.59 itojun * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.59 itojun * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 1.59 itojun * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 1.59 itojun * SUCH DAMAGE. 30 1.59 itojun */ 31 1.57 thorpej 32 1.57 thorpej /*- 33 1.138 dyoung * Copyright (c) 1998, 2011 The NetBSD Foundation, Inc. 34 1.57 thorpej * All rights reserved. 35 1.57 thorpej * 36 1.57 thorpej * This code is derived from software contributed to The NetBSD Foundation 37 1.138 dyoung * by Coyote Point Systems, Inc. 38 1.138 dyoung * This code is derived from software contributed to The NetBSD Foundation 39 1.57 thorpej * by Public Access Networks Corporation ("Panix"). It was developed under 40 1.57 thorpej * contract to Panix by Eric Haszlakiewicz and Thor Lancelot Simon. 41 1.57 thorpej * 42 1.57 thorpej * Redistribution and use in source and binary forms, with or without 43 1.57 thorpej * modification, are permitted provided that the following conditions 44 1.57 thorpej * are met: 45 1.57 thorpej * 1. Redistributions of source code must retain the above copyright 46 1.57 thorpej * notice, this list of conditions and the following disclaimer. 47 1.57 thorpej * 2. Redistributions in binary form must reproduce the above copyright 48 1.57 thorpej * notice, this list of conditions and the following disclaimer in the 49 1.57 thorpej * documentation and/or other materials provided with the distribution. 50 1.57 thorpej * 51 1.57 thorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 52 1.57 thorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 53 1.57 thorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 54 1.57 thorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 55 1.57 thorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 56 1.57 thorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 57 1.57 thorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 58 1.57 thorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 59 1.57 thorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 60 1.57 thorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 61 1.57 thorpej * POSSIBILITY OF SUCH DAMAGE. 62 1.57 thorpej */ 63 1.11 cgd 64 1.1 cgd /* 65 1.44 thorpej * Copyright (c) 1982, 1986, 1991, 1993, 1995 66 1.10 mycroft * The Regents of the University of California. All rights reserved. 67 1.1 cgd * 68 1.1 cgd * Redistribution and use in source and binary forms, with or without 69 1.1 cgd * modification, are permitted provided that the following conditions 70 1.1 cgd * are met: 71 1.1 cgd * 1. Redistributions of source code must retain the above copyright 72 1.1 cgd * notice, this list of conditions and the following disclaimer. 73 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 74 1.1 cgd * notice, this list of conditions and the following disclaimer in the 75 1.1 cgd * documentation and/or other materials provided with the distribution. 76 1.86 agc * 3. Neither the name of the University nor the names of its contributors 77 1.1 cgd * may be used to endorse or promote products derived from this software 78 1.1 cgd * without specific prior written permission. 79 1.1 cgd * 80 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 81 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 82 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 83 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 84 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 85 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 86 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 87 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 88 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 89 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 90 1.1 cgd * SUCH DAMAGE. 91 1.1 cgd * 92 1.44 thorpej * @(#)in_pcb.c 8.4 (Berkeley) 5/24/95 93 1.1 cgd */ 94 1.73 lukem 95 1.73 lukem #include <sys/cdefs.h> 96 1.202 ozaki __KERNEL_RCSID(0, "$NetBSD: in_pcb.c,v 1.202 2022/11/04 09:05:41 ozaki-r Exp $"); 97 1.60 thorpej 98 1.162 pooka #ifdef _KERNEL_OPT 99 1.88 itojun #include "opt_inet.h" 100 1.60 thorpej #include "opt_ipsec.h" 101 1.162 pooka #endif 102 1.1 cgd 103 1.7 mycroft #include <sys/param.h> 104 1.7 mycroft #include <sys/systm.h> 105 1.7 mycroft #include <sys/mbuf.h> 106 1.7 mycroft #include <sys/socket.h> 107 1.7 mycroft #include <sys/socketvar.h> 108 1.7 mycroft #include <sys/ioctl.h> 109 1.10 mycroft #include <sys/errno.h> 110 1.10 mycroft #include <sys/time.h> 111 1.128 pooka #include <sys/once.h> 112 1.52 thorpej #include <sys/pool.h> 113 1.10 mycroft #include <sys/proc.h> 114 1.102 elad #include <sys/kauth.h> 115 1.129 pooka #include <sys/uidinfo.h> 116 1.132 elad #include <sys/domain.h> 117 1.1 cgd 118 1.7 mycroft #include <net/if.h> 119 1.7 mycroft #include <net/route.h> 120 1.1 cgd 121 1.7 mycroft #include <netinet/in.h> 122 1.7 mycroft #include <netinet/in_systm.h> 123 1.7 mycroft #include <netinet/ip.h> 124 1.7 mycroft #include <netinet/in_pcb.h> 125 1.7 mycroft #include <netinet/in_var.h> 126 1.7 mycroft #include <netinet/ip_var.h> 127 1.143 christos #include <netinet/portalgo.h> 128 1.1 cgd 129 1.88 itojun #ifdef INET6 130 1.88 itojun #include <netinet/ip6.h> 131 1.88 itojun #include <netinet6/ip6_var.h> 132 1.88 itojun #include <netinet6/in6_pcb.h> 133 1.88 itojun #endif 134 1.88 itojun 135 1.145 christos #ifdef IPSEC 136 1.87 jonathan #include <netipsec/ipsec.h> 137 1.87 jonathan #include <netipsec/key.h> 138 1.59 itojun #endif /* IPSEC */ 139 1.59 itojun 140 1.138 dyoung #include <netinet/tcp_vtw.h> 141 1.138 dyoung 142 1.1 cgd struct in_addr zeroin_addr; 143 1.1 cgd 144 1.90 provos #define INPCBHASH_PORT(table, lport) \ 145 1.92 itojun &(table)->inpt_porthashtbl[ntohs(lport) & (table)->inpt_porthash] 146 1.33 mycroft #define INPCBHASH_BIND(table, laddr, lport) \ 147 1.33 mycroft &(table)->inpt_bindhashtbl[ \ 148 1.33 mycroft ((ntohl((laddr).s_addr) + ntohs(lport))) & (table)->inpt_bindhash] 149 1.33 mycroft #define INPCBHASH_CONNECT(table, faddr, fport, laddr, lport) \ 150 1.33 mycroft &(table)->inpt_connecthashtbl[ \ 151 1.33 mycroft ((ntohl((faddr).s_addr) + ntohs(fport)) + \ 152 1.33 mycroft (ntohl((laddr).s_addr) + ntohs(lport))) & (table)->inpt_connecthash] 153 1.33 mycroft 154 1.43 lukem int anonportmin = IPPORT_ANONMIN; 155 1.43 lukem int anonportmax = IPPORT_ANONMAX; 156 1.67 tron int lowportmin = IPPORT_RESERVEDMIN; 157 1.67 tron int lowportmax = IPPORT_RESERVEDMAX; 158 1.43 lukem 159 1.197 ozaki static pool_cache_t in4pcb_pool_cache; 160 1.194 ozaki #ifdef INET6 161 1.197 ozaki static pool_cache_t in6pcb_pool_cache; 162 1.194 ozaki #endif 163 1.128 pooka 164 1.128 pooka static int 165 1.128 pooka inpcb_poolinit(void) 166 1.128 pooka { 167 1.128 pooka 168 1.197 ozaki in4pcb_pool_cache = pool_cache_init(sizeof(struct in4pcb), coherency_unit, 169 1.197 ozaki 0, 0, "in4pcbpl", NULL, IPL_NET, NULL, NULL, NULL); 170 1.194 ozaki #ifdef INET6 171 1.197 ozaki in6pcb_pool_cache = pool_cache_init(sizeof(struct in6pcb), coherency_unit, 172 1.197 ozaki 0, 0, "in6pcbpl", NULL, IPL_NET, NULL, NULL, NULL); 173 1.194 ozaki #endif 174 1.128 pooka return 0; 175 1.128 pooka } 176 1.52 thorpej 177 1.18 mycroft void 178 1.195 ozaki inpcb_init(struct inpcbtable *table, int bindhashsize, int connecthashsize) 179 1.18 mycroft { 180 1.128 pooka static ONCE_DECL(control); 181 1.18 mycroft 182 1.146 christos TAILQ_INIT(&table->inpt_queue); 183 1.125 ad table->inpt_porthashtbl = hashinit(bindhashsize, HASH_LIST, true, 184 1.125 ad &table->inpt_porthash); 185 1.125 ad table->inpt_bindhashtbl = hashinit(bindhashsize, HASH_LIST, true, 186 1.125 ad &table->inpt_bindhash); 187 1.125 ad table->inpt_connecthashtbl = hashinit(connecthashsize, HASH_LIST, true, 188 1.125 ad &table->inpt_connecthash); 189 1.47 lukem table->inpt_lastlow = IPPORT_RESERVEDMAX; 190 1.198 ozaki table->inpt_lastport = (in_port_t)anonportmax; 191 1.128 pooka 192 1.128 pooka RUN_ONCE(&control, inpcb_poolinit); 193 1.18 mycroft } 194 1.18 mycroft 195 1.202 ozaki /* 196 1.202 ozaki * inpcb_create: construct a new PCB and associated with a given socket. 197 1.202 ozaki * Sets the PCB state to INP_ATTACHED and makes PCB globally visible. 198 1.202 ozaki */ 199 1.10 mycroft int 200 1.195 ozaki inpcb_create(struct socket *so, void *v) 201 1.1 cgd { 202 1.25 christos struct inpcbtable *table = v; 203 1.64 augustss struct inpcb *inp; 204 1.24 mycroft int s; 205 1.1 cgd 206 1.194 ozaki #ifdef INET6 207 1.192 ozaki KASSERT(soaf(so) == AF_INET || soaf(so) == AF_INET6); 208 1.177 ozaki 209 1.193 ozaki if (soaf(so) == AF_INET) 210 1.197 ozaki inp = pool_cache_get(in4pcb_pool_cache, PR_NOWAIT); 211 1.193 ozaki else 212 1.197 ozaki inp = pool_cache_get(in6pcb_pool_cache, PR_NOWAIT); 213 1.194 ozaki #else 214 1.194 ozaki KASSERT(soaf(so) == AF_INET); 215 1.197 ozaki inp = pool_cache_get(in4pcb_pool_cache, PR_NOWAIT); 216 1.194 ozaki #endif 217 1.10 mycroft if (inp == NULL) 218 1.200 ozaki return ENOBUFS; 219 1.197 ozaki if (soaf(so) == AF_INET) 220 1.197 ozaki memset(inp, 0, sizeof(struct in4pcb)); 221 1.197 ozaki #ifdef INET6 222 1.197 ozaki else 223 1.197 ozaki memset(inp, 0, sizeof(struct in6pcb)); 224 1.197 ozaki #endif 225 1.192 ozaki inp->inp_af = soaf(so); 226 1.18 mycroft inp->inp_table = table; 227 1.1 cgd inp->inp_socket = so; 228 1.143 christos inp->inp_portalgo = PORTALGO_DEFAULT; 229 1.139 christos inp->inp_bindportonsend = false; 230 1.193 ozaki 231 1.193 ozaki if (inp->inp_af == AF_INET) { 232 1.193 ozaki in4p_errormtu(inp) = -1; 233 1.193 ozaki in4p_prefsrcip(inp).s_addr = INADDR_ANY; 234 1.193 ozaki } 235 1.192 ozaki #ifdef INET6 236 1.193 ozaki else { 237 1.193 ozaki in6p_hops6(inp) = -1; /* use kernel default */ 238 1.193 ozaki if (ip6_v6only) 239 1.193 ozaki inp->inp_flags |= IN6P_IPV6_V6ONLY; 240 1.193 ozaki } 241 1.192 ozaki #endif 242 1.145 christos #if defined(IPSEC) 243 1.148 christos if (ipsec_enabled) { 244 1.148 christos int error = ipsec_init_pcbpolicy(so, &inp->inp_sp); 245 1.148 christos if (error != 0) { 246 1.194 ozaki #ifdef INET6 247 1.193 ozaki if (inp->inp_af == AF_INET) 248 1.197 ozaki pool_cache_put(in4pcb_pool_cache, inp); 249 1.193 ozaki else 250 1.197 ozaki pool_cache_put(in6pcb_pool_cache, inp); 251 1.194 ozaki #else 252 1.194 ozaki KASSERT(inp->inp_af == AF_INET); 253 1.197 ozaki pool_cache_put(in4pcb_pool_cache, inp); 254 1.194 ozaki #endif 255 1.148 christos return error; 256 1.148 christos } 257 1.192 ozaki inp->inp_sp->sp_inp = inp; 258 1.70 itojun } 259 1.70 itojun #endif 260 1.33 mycroft so->so_pcb = inp; 261 1.175 ozaki s = splsoftnet(); 262 1.192 ozaki TAILQ_INSERT_HEAD(&table->inpt_queue, inp, inp_queue); 263 1.192 ozaki LIST_INSERT_HEAD(INPCBHASH_PORT(table, inp->inp_lport), inp, 264 1.192 ozaki inp_lhash); 265 1.195 ozaki inpcb_set_state(inp, INP_ATTACHED); 266 1.24 mycroft splx(s); 267 1.200 ozaki return 0; 268 1.1 cgd } 269 1.8 mycroft 270 1.132 elad static int 271 1.195 ozaki inpcb_set_port(struct sockaddr_in *sin, struct inpcb *inp, kauth_cred_t cred) 272 1.1 cgd { 273 1.132 elad struct inpcbtable *table = inp->inp_table; 274 1.64 augustss struct socket *so = inp->inp_socket; 275 1.198 ozaki in_port_t *lastport; 276 1.198 ozaki in_port_t lport = 0; 277 1.134 elad enum kauth_network_req req; 278 1.134 elad int error; 279 1.1 cgd 280 1.132 elad if (inp->inp_flags & INP_LOWPORT) { 281 1.132 elad #ifndef IPNOPRIVPORTS 282 1.134 elad req = KAUTH_REQ_NETWORK_BIND_PRIVPORT; 283 1.134 elad #else 284 1.134 elad req = KAUTH_REQ_NETWORK_BIND_PORT; 285 1.132 elad #endif 286 1.134 elad 287 1.132 elad lastport = &table->inpt_lastlow; 288 1.132 elad } else { 289 1.134 elad req = KAUTH_REQ_NETWORK_BIND_PORT; 290 1.134 elad 291 1.132 elad lastport = &table->inpt_lastport; 292 1.132 elad } 293 1.134 elad 294 1.134 elad /* XXX-kauth: KAUTH_REQ_NETWORK_BIND_AUTOASSIGN_{,PRIV}PORT */ 295 1.134 elad error = kauth_authorize_network(cred, KAUTH_NETWORK_BIND, req, so, sin, 296 1.134 elad NULL); 297 1.134 elad if (error) 298 1.200 ozaki return EACCES; 299 1.134 elad 300 1.139 christos /* 301 1.139 christos * Use RFC6056 randomized port selection 302 1.139 christos */ 303 1.192 ozaki error = portalgo_randport(&lport, inp, cred); 304 1.139 christos if (error) 305 1.139 christos return error; 306 1.132 elad 307 1.132 elad inp->inp_flags |= INP_ANONPORT; 308 1.132 elad *lastport = lport; 309 1.132 elad lport = htons(lport); 310 1.132 elad inp->inp_lport = lport; 311 1.195 ozaki inpcb_set_state(inp, INP_BOUND); 312 1.132 elad 313 1.200 ozaki return 0; 314 1.132 elad } 315 1.88 itojun 316 1.179 ryo int 317 1.195 ozaki inpcb_bindableaddr(const struct inpcb *inp, struct sockaddr_in *sin, 318 1.185 christos kauth_cred_t cred) 319 1.132 elad { 320 1.168 ozaki int error = EADDRNOTAVAIL; 321 1.168 ozaki struct ifaddr *ifa = NULL; 322 1.168 ozaki int s; 323 1.168 ozaki 324 1.28 mycroft if (sin->sin_family != AF_INET) 325 1.200 ozaki return EAFNOSUPPORT; 326 1.132 elad 327 1.168 ozaki s = pserialize_read_enter(); 328 1.136 elad if (IN_MULTICAST(sin->sin_addr.s_addr)) { 329 1.195 ozaki /* Always succeed; port reuse handled in inpcb_bind_port(). */ 330 1.136 elad } else if (!in_nullhost(sin->sin_addr)) { 331 1.168 ozaki struct in_ifaddr *ia; 332 1.132 elad 333 1.166 ozaki ia = in_get_ia(sin->sin_addr); 334 1.132 elad /* check for broadcast addresses */ 335 1.168 ozaki if (ia == NULL) { 336 1.168 ozaki ifa = ifa_ifwithaddr(sintosa(sin)); 337 1.168 ozaki if (ifa != NULL) 338 1.168 ozaki ia = ifatoia(ifa); 339 1.185 christos else if ((inp->inp_flags & INP_BINDANY) != 0) { 340 1.185 christos error = 0; 341 1.185 christos goto error; 342 1.185 christos } 343 1.168 ozaki } 344 1.132 elad if (ia == NULL) 345 1.168 ozaki goto error; 346 1.170 roy if (ia->ia4_flags & IN_IFF_DUPLICATED) 347 1.168 ozaki goto error; 348 1.132 elad } 349 1.179 ryo error = 0; 350 1.179 ryo error: 351 1.168 ozaki pserialize_read_exit(s); 352 1.179 ryo return error; 353 1.179 ryo } 354 1.132 elad 355 1.179 ryo static int 356 1.195 ozaki inpcb_bind_addr(struct inpcb *inp, struct sockaddr_in *sin, kauth_cred_t cred) 357 1.179 ryo { 358 1.179 ryo int error; 359 1.132 elad 360 1.195 ozaki error = inpcb_bindableaddr(inp, sin, cred); 361 1.179 ryo if (error == 0) 362 1.193 ozaki in4p_laddr(inp) = sin->sin_addr; 363 1.168 ozaki return error; 364 1.132 elad } 365 1.132 elad 366 1.132 elad static int 367 1.195 ozaki inpcb_bind_port(struct inpcb *inp, struct sockaddr_in *sin, kauth_cred_t cred) 368 1.132 elad { 369 1.132 elad struct inpcbtable *table = inp->inp_table; 370 1.132 elad struct socket *so = inp->inp_socket; 371 1.132 elad int reuseport = (so->so_options & SO_REUSEPORT); 372 1.133 elad int wild = 0, error; 373 1.132 elad 374 1.28 mycroft if (IN_MULTICAST(sin->sin_addr.s_addr)) { 375 1.10 mycroft /* 376 1.28 mycroft * Treat SO_REUSEADDR as SO_REUSEPORT for multicast; 377 1.28 mycroft * allow complete duplication of binding if 378 1.28 mycroft * SO_REUSEPORT is set, or if SO_REUSEADDR is set 379 1.28 mycroft * and a multicast address is bound on both 380 1.28 mycroft * new and duplicated sockets. 381 1.10 mycroft */ 382 1.155 seanb if (so->so_options & (SO_REUSEADDR | SO_REUSEPORT)) 383 1.28 mycroft reuseport = SO_REUSEADDR|SO_REUSEPORT; 384 1.132 elad } 385 1.132 elad 386 1.132 elad if (sin->sin_port == 0) { 387 1.195 ozaki error = inpcb_set_port(sin, inp, cred); 388 1.132 elad if (error) 389 1.200 ozaki return error; 390 1.132 elad } else { 391 1.28 mycroft struct inpcb *t; 392 1.138 dyoung vestigial_inpcb_t vestige; 393 1.88 itojun #ifdef INET6 394 1.192 ozaki struct inpcb *t6; 395 1.88 itojun struct in6_addr mapped; 396 1.88 itojun #endif 397 1.133 elad enum kauth_network_req req; 398 1.132 elad 399 1.132 elad if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0) 400 1.132 elad wild = 1; 401 1.132 elad 402 1.31 perry #ifndef IPNOPRIVPORTS 403 1.133 elad if (ntohs(sin->sin_port) < IPPORT_RESERVED) 404 1.133 elad req = KAUTH_REQ_NETWORK_BIND_PRIVPORT; 405 1.133 elad else 406 1.133 elad #endif /* !IPNOPRIVPORTS */ 407 1.133 elad req = KAUTH_REQ_NETWORK_BIND_PORT; 408 1.133 elad 409 1.133 elad error = kauth_authorize_network(cred, KAUTH_NETWORK_BIND, req, 410 1.133 elad so, sin, NULL); 411 1.133 elad if (error) 412 1.200 ozaki return EACCES; 413 1.133 elad 414 1.88 itojun #ifdef INET6 415 1.163 rtr in6_in_2_v4mapin6(&sin->sin_addr, &mapped); 416 1.196 ozaki t6 = in6pcb_lookup_local(table, &mapped, sin->sin_port, wild, &vestige); 417 1.192 ozaki if (t6 && (reuseport & t6->inp_socket->so_options) == 0) 418 1.200 ozaki return EADDRINUSE; 419 1.138 dyoung if (!t6 && vestige.valid) { 420 1.138 dyoung if (!!reuseport != !!vestige.reuse_port) { 421 1.138 dyoung return EADDRINUSE; 422 1.138 dyoung } 423 1.138 dyoung } 424 1.88 itojun #endif 425 1.133 elad 426 1.133 elad /* XXX-kauth */ 427 1.99 christos if (so->so_uidinfo->ui_uid && !IN_MULTICAST(sin->sin_addr.s_addr)) { 428 1.195 ozaki t = inpcb_lookup_local(table, sin->sin_addr, sin->sin_port, 1, &vestige); 429 1.133 elad /* 430 1.133 elad * XXX: investigate ramifications of loosening this 431 1.133 elad * restriction so that as long as both ports have 432 1.133 elad * SO_REUSEPORT allow the bind 433 1.133 elad */ 434 1.58 lukem if (t && 435 1.58 lukem (!in_nullhost(sin->sin_addr) || 436 1.193 ozaki !in_nullhost(in4p_laddr(t)) || 437 1.58 lukem (t->inp_socket->so_options & SO_REUSEPORT) == 0) 438 1.99 christos && (so->so_uidinfo->ui_uid != t->inp_socket->so_uidinfo->ui_uid)) { 439 1.200 ozaki return EADDRINUSE; 440 1.58 lukem } 441 1.138 dyoung if (!t && vestige.valid) { 442 1.138 dyoung if ((!in_nullhost(sin->sin_addr) 443 1.138 dyoung || !in_nullhost(vestige.laddr.v4) 444 1.138 dyoung || !vestige.reuse_port) 445 1.138 dyoung && so->so_uidinfo->ui_uid != vestige.uid) { 446 1.138 dyoung return EADDRINUSE; 447 1.138 dyoung } 448 1.138 dyoung } 449 1.58 lukem } 450 1.195 ozaki t = inpcb_lookup_local(table, sin->sin_addr, sin->sin_port, wild, &vestige); 451 1.28 mycroft if (t && (reuseport & t->inp_socket->so_options) == 0) 452 1.200 ozaki return EADDRINUSE; 453 1.138 dyoung if (!t 454 1.138 dyoung && vestige.valid 455 1.138 dyoung && !(reuseport && vestige.reuse_port)) 456 1.138 dyoung return EADDRINUSE; 457 1.132 elad 458 1.132 elad inp->inp_lport = sin->sin_port; 459 1.195 ozaki inpcb_set_state(inp, INP_BOUND); 460 1.1 cgd } 461 1.45 lukem 462 1.192 ozaki LIST_REMOVE(inp, inp_lhash); 463 1.192 ozaki LIST_INSERT_HEAD(INPCBHASH_PORT(table, inp->inp_lport), inp, 464 1.192 ozaki inp_lhash); 465 1.132 elad 466 1.200 ozaki return 0; 467 1.132 elad } 468 1.132 elad 469 1.202 ozaki /* 470 1.202 ozaki * inpcb_bind: assign a local IP address and port number to the PCB. 471 1.202 ozaki * 472 1.202 ozaki * If the address is not a wildcard, verify that it corresponds to a 473 1.202 ozaki * local interface. If a port is specified and it is privileged, then 474 1.202 ozaki * check the permission. Check whether the address or port is in use, 475 1.202 ozaki * and if so, whether we can re-use them. 476 1.202 ozaki */ 477 1.132 elad int 478 1.195 ozaki inpcb_bind(void *v, struct sockaddr_in *sin, struct lwp *l) 479 1.132 elad { 480 1.132 elad struct inpcb *inp = v; 481 1.134 elad struct sockaddr_in lsin; 482 1.132 elad int error; 483 1.132 elad 484 1.132 elad if (inp->inp_af != AF_INET) 485 1.200 ozaki return EINVAL; 486 1.132 elad 487 1.193 ozaki if (inp->inp_lport || !in_nullhost(in4p_laddr(inp))) 488 1.200 ozaki return EINVAL; 489 1.132 elad 490 1.156 rtr if (NULL != sin) { 491 1.156 rtr if (sin->sin_len != sizeof(*sin)) 492 1.200 ozaki return EINVAL; 493 1.132 elad } else { 494 1.134 elad lsin = *((const struct sockaddr_in *) 495 1.134 elad inp->inp_socket->so_proto->pr_domain->dom_sa_any); 496 1.134 elad sin = &lsin; 497 1.132 elad } 498 1.132 elad 499 1.132 elad /* Bind address. */ 500 1.195 ozaki error = inpcb_bind_addr(inp, sin, l->l_cred); 501 1.132 elad if (error) 502 1.200 ozaki return error; 503 1.132 elad 504 1.132 elad /* Bind port. */ 505 1.195 ozaki error = inpcb_bind_port(inp, sin, l->l_cred); 506 1.132 elad if (error) { 507 1.193 ozaki in4p_laddr(inp).s_addr = INADDR_ANY; 508 1.132 elad 509 1.200 ozaki return error; 510 1.132 elad } 511 1.132 elad 512 1.200 ozaki return 0; 513 1.1 cgd } 514 1.1 cgd 515 1.1 cgd /* 516 1.202 ozaki * inpcb_connect: connect from a socket to a specified address, i.e., 517 1.202 ozaki * assign a foreign IP address and port number to the PCB. 518 1.202 ozaki * 519 1.202 ozaki * Both address and port must be specified in the name argument. 520 1.202 ozaki * If there is no local address for this socket yet, then pick one. 521 1.1 cgd */ 522 1.10 mycroft int 523 1.195 ozaki inpcb_connect(void *v, struct sockaddr_in *sin, struct lwp *l) 524 1.1 cgd { 525 1.64 augustss struct inpcb *inp = v; 526 1.138 dyoung vestigial_inpcb_t vestige; 527 1.40 thorpej int error; 528 1.167 ozaki struct in_addr laddr; 529 1.1 cgd 530 1.88 itojun if (inp->inp_af != AF_INET) 531 1.200 ozaki return EINVAL; 532 1.88 itojun 533 1.158 rtr if (sin->sin_len != sizeof (*sin)) 534 1.200 ozaki return EINVAL; 535 1.1 cgd if (sin->sin_family != AF_INET) 536 1.200 ozaki return EAFNOSUPPORT; 537 1.1 cgd if (sin->sin_port == 0) 538 1.200 ozaki return EADDRNOTAVAIL; 539 1.144 christos 540 1.144 christos if (IN_MULTICAST(sin->sin_addr.s_addr) && 541 1.144 christos inp->inp_socket->so_type == SOCK_STREAM) 542 1.144 christos return EADDRNOTAVAIL; 543 1.144 christos 544 1.165 ozaki if (!IN_ADDRLIST_READER_EMPTY()) { 545 1.1 cgd /* 546 1.1 cgd * If the destination address is INADDR_ANY, 547 1.49 tls * use any local address (likely loopback). 548 1.1 cgd * If the supplied address is INADDR_BROADCAST, 549 1.49 tls * use the broadcast address of an interface 550 1.49 tls * which supports broadcast. (loopback does not) 551 1.1 cgd */ 552 1.49 tls 553 1.72 matt if (in_nullhost(sin->sin_addr)) { 554 1.165 ozaki /* XXX racy */ 555 1.72 matt sin->sin_addr = 556 1.165 ozaki IN_ADDRLIST_READER_FIRST()->ia_addr.sin_addr; 557 1.72 matt } else if (sin->sin_addr.s_addr == INADDR_BROADCAST) { 558 1.167 ozaki struct in_ifaddr *ia; 559 1.168 ozaki int s = pserialize_read_enter(); 560 1.165 ozaki IN_ADDRLIST_READER_FOREACH(ia) { 561 1.72 matt if (ia->ia_ifp->if_flags & IFF_BROADCAST) { 562 1.72 matt sin->sin_addr = 563 1.72 matt ia->ia_broadaddr.sin_addr; 564 1.72 matt break; 565 1.72 matt } 566 1.49 tls } 567 1.168 ozaki pserialize_read_exit(s); 568 1.72 matt } 569 1.1 cgd } 570 1.32 mycroft /* 571 1.32 mycroft * If we haven't bound which network number to use as ours, 572 1.32 mycroft * we will use the number of the outgoing interface. 573 1.32 mycroft * This depends on having done a routing lookup, which 574 1.32 mycroft * we will probably have to do anyway, so we might 575 1.32 mycroft * as well do it now. On the other hand if we are 576 1.32 mycroft * sending to multiple destinations we may have already 577 1.32 mycroft * done the lookup, so see if we can use the route 578 1.32 mycroft * from before. In any case, we only 579 1.32 mycroft * chose a port number once, even if sending to multiple 580 1.32 mycroft * destinations. 581 1.32 mycroft */ 582 1.193 ozaki if (in_nullhost(in4p_laddr(inp))) { 583 1.100 christos int xerror; 584 1.168 ozaki struct in_ifaddr *ia, *_ia; 585 1.168 ozaki int s; 586 1.168 ozaki struct psref psref; 587 1.168 ozaki int bound; 588 1.168 ozaki 589 1.168 ozaki bound = curlwp_bind(); 590 1.168 ozaki ia = in_selectsrc(sin, &inp->inp_route, 591 1.168 ozaki inp->inp_socket->so_options, inp->inp_moptions, &xerror, 592 1.168 ozaki &psref); 593 1.168 ozaki if (ia == NULL) { 594 1.168 ozaki curlwp_bindx(bound); 595 1.100 christos if (xerror == 0) 596 1.100 christos xerror = EADDRNOTAVAIL; 597 1.100 christos return xerror; 598 1.59 itojun } 599 1.168 ozaki s = pserialize_read_enter(); 600 1.168 ozaki _ia = in_get_ia(IA_SIN(ia)->sin_addr); 601 1.185 christos if (_ia == NULL && (inp->inp_flags & INP_BINDANY) == 0) { 602 1.168 ozaki pserialize_read_exit(s); 603 1.168 ozaki ia4_release(ia, &psref); 604 1.168 ozaki curlwp_bindx(bound); 605 1.200 ozaki return EADDRNOTAVAIL; 606 1.168 ozaki } 607 1.168 ozaki pserialize_read_exit(s); 608 1.168 ozaki laddr = IA_SIN(ia)->sin_addr; 609 1.168 ozaki ia4_release(ia, &psref); 610 1.168 ozaki curlwp_bindx(bound); 611 1.167 ozaki } else 612 1.193 ozaki laddr = in4p_laddr(inp); 613 1.195 ozaki if (inpcb_lookup(inp->inp_table, sin->sin_addr, sin->sin_port, 614 1.168 ozaki laddr, inp->inp_lport, &vestige) != NULL || 615 1.168 ozaki vestige.valid) { 616 1.200 ozaki return EADDRINUSE; 617 1.168 ozaki } 618 1.193 ozaki if (in_nullhost(in4p_laddr(inp))) { 619 1.40 thorpej if (inp->inp_lport == 0) { 620 1.195 ozaki error = inpcb_bind(inp, NULL, l); 621 1.40 thorpej /* 622 1.40 thorpej * This used to ignore the return value 623 1.40 thorpej * completely, but we need to check for 624 1.40 thorpej * ephemeral port shortage. 625 1.101 dsl * And attempts to request low ports if not root. 626 1.40 thorpej */ 627 1.101 dsl if (error != 0) 628 1.200 ozaki return error; 629 1.40 thorpej } 630 1.193 ozaki in4p_laddr(inp) = laddr; 631 1.1 cgd } 632 1.193 ozaki in4p_faddr(inp) = sin->sin_addr; 633 1.1 cgd inp->inp_fport = sin->sin_port; 634 1.139 christos 635 1.201 ozaki /* Late bind, if needed */ 636 1.139 christos if (inp->inp_bindportonsend) { 637 1.201 ozaki struct sockaddr_in lsin = *((const struct sockaddr_in *) 638 1.139 christos inp->inp_socket->so_proto->pr_domain->dom_sa_any); 639 1.193 ozaki lsin.sin_addr = in4p_laddr(inp); 640 1.139 christos lsin.sin_port = 0; 641 1.139 christos 642 1.195 ozaki if ((error = inpcb_bind_port(inp, &lsin, l->l_cred)) != 0) 643 1.201 ozaki return error; 644 1.139 christos } 645 1.139 christos 646 1.195 ozaki inpcb_set_state(inp, INP_CONNECTED); 647 1.145 christos #if defined(IPSEC) 648 1.148 christos if (ipsec_enabled && inp->inp_socket->so_type == SOCK_STREAM) 649 1.71 itojun ipsec_pcbconn(inp->inp_sp); 650 1.71 itojun #endif 651 1.200 ozaki return 0; 652 1.1 cgd } 653 1.1 cgd 654 1.202 ozaki /* 655 1.202 ozaki * inpcb_disconnect: remove any foreign IP/port association. 656 1.202 ozaki * 657 1.202 ozaki * Note: destroys the PCB if socket was closed. 658 1.202 ozaki */ 659 1.25 christos void 660 1.195 ozaki inpcb_disconnect(void *v) 661 1.1 cgd { 662 1.25 christos struct inpcb *inp = v; 663 1.1 cgd 664 1.88 itojun if (inp->inp_af != AF_INET) 665 1.88 itojun return; 666 1.88 itojun 667 1.193 ozaki in4p_faddr(inp) = zeroin_addr; 668 1.1 cgd inp->inp_fport = 0; 669 1.195 ozaki inpcb_set_state(inp, INP_BOUND); 670 1.145 christos #if defined(IPSEC) 671 1.148 christos if (ipsec_enabled) 672 1.148 christos ipsec_pcbdisconn(inp->inp_sp); 673 1.71 itojun #endif 674 1.93 itojun if (inp->inp_socket->so_state & SS_NOFDREF) 675 1.195 ozaki inpcb_destroy(inp); 676 1.1 cgd } 677 1.1 cgd 678 1.202 ozaki /* 679 1.202 ozaki * inpcb_destroy: destroy PCB as well as the associated socket. 680 1.202 ozaki */ 681 1.25 christos void 682 1.195 ozaki inpcb_destroy(void *v) 683 1.1 cgd { 684 1.25 christos struct inpcb *inp = v; 685 1.1 cgd struct socket *so = inp->inp_socket; 686 1.24 mycroft int s; 687 1.1 cgd 688 1.192 ozaki KASSERT(inp->inp_af == AF_INET || inp->inp_af == AF_INET6); 689 1.88 itojun 690 1.145 christos #if defined(IPSEC) 691 1.148 christos if (ipsec_enabled) 692 1.182 maxv ipsec_delete_pcbpolicy(inp); 693 1.150 rmind #endif 694 1.150 rmind so->so_pcb = NULL; 695 1.150 rmind 696 1.175 ozaki s = splsoftnet(); 697 1.195 ozaki inpcb_set_state(inp, INP_ATTACHED); 698 1.192 ozaki LIST_REMOVE(inp, inp_lhash); 699 1.192 ozaki TAILQ_REMOVE(&inp->inp_table->inpt_queue, inp, inp_queue); 700 1.24 mycroft splx(s); 701 1.150 rmind 702 1.150 rmind if (inp->inp_options) { 703 1.150 rmind m_free(inp->inp_options); 704 1.150 rmind } 705 1.150 rmind rtcache_free(&inp->inp_route); 706 1.152 rmind ip_freemoptions(inp->inp_moptions); 707 1.194 ozaki #ifdef INET6 708 1.193 ozaki if (inp->inp_af == AF_INET6) { 709 1.193 ozaki if (in6p_outputopts(inp) != NULL) { 710 1.193 ozaki ip6_clearpktopts(in6p_outputopts(inp), -1); 711 1.193 ozaki free(in6p_outputopts(inp), M_IP6OPT); 712 1.193 ozaki } 713 1.193 ozaki ip6_freemoptions(in6p_moptions(inp)); 714 1.193 ozaki } 715 1.194 ozaki #endif 716 1.127 spz sofree(so); /* drops the socket's lock */ 717 1.150 rmind 718 1.194 ozaki #ifdef INET6 719 1.193 ozaki if (inp->inp_af == AF_INET) 720 1.197 ozaki pool_cache_put(in4pcb_pool_cache, inp); 721 1.193 ozaki else 722 1.197 ozaki pool_cache_put(in6pcb_pool_cache, inp); 723 1.194 ozaki #else 724 1.194 ozaki KASSERT(inp->inp_af == AF_INET); 725 1.197 ozaki pool_cache_put(in4pcb_pool_cache, inp); 726 1.194 ozaki #endif 727 1.126 matt mutex_enter(softnet_lock); /* reacquire the softnet_lock */ 728 1.1 cgd } 729 1.1 cgd 730 1.202 ozaki /* 731 1.202 ozaki * inpcb_fetch_sockaddr: fetch the local IP address and port number. 732 1.202 ozaki */ 733 1.25 christos void 734 1.195 ozaki inpcb_fetch_sockaddr(struct inpcb *inp, struct sockaddr_in *sin) 735 1.1 cgd { 736 1.78 itojun 737 1.88 itojun if (inp->inp_af != AF_INET) 738 1.88 itojun return; 739 1.88 itojun 740 1.193 ozaki sockaddr_in_init(sin, &in4p_laddr(inp), inp->inp_lport); 741 1.1 cgd } 742 1.1 cgd 743 1.202 ozaki /* 744 1.202 ozaki * inpcb_fetch_peeraddr: fetch the foreign IP address and port number. 745 1.202 ozaki */ 746 1.25 christos void 747 1.195 ozaki inpcb_fetch_peeraddr(struct inpcb *inp, struct sockaddr_in *sin) 748 1.1 cgd { 749 1.78 itojun 750 1.88 itojun if (inp->inp_af != AF_INET) 751 1.88 itojun return; 752 1.88 itojun 753 1.193 ozaki sockaddr_in_init(sin, &in4p_faddr(inp), inp->inp_fport); 754 1.1 cgd } 755 1.1 cgd 756 1.1 cgd /* 757 1.202 ozaki * inpcb_notify: pass some notification to all connections of a protocol 758 1.202 ozaki * associated with destination address. The local address and/or port 759 1.202 ozaki * numbers may be specified to limit the search. The "usual action" will 760 1.202 ozaki * be taken, depending on the command. 761 1.202 ozaki * 762 1.202 ozaki * The caller must filter any commands that are not interesting (e.g., 763 1.202 ozaki * no error in the map). Call the protocol specific routine (if any) to 764 1.202 ozaki * report any errors for each matching socket. 765 1.1 cgd * 766 1.22 mycroft * Must be called at splsoftnet. 767 1.1 cgd */ 768 1.37 thorpej int 769 1.195 ozaki inpcb_notify(struct inpcbtable *table, struct in_addr faddr, u_int fport_arg, 770 1.98 perry struct in_addr laddr, u_int lport_arg, int errno, 771 1.98 perry void (*notify)(struct inpcb *, int)) 772 1.1 cgd { 773 1.33 mycroft struct inpcbhead *head; 774 1.188 knakahar struct inpcb *inp; 775 1.198 ozaki in_port_t fport = fport_arg, lport = lport_arg; 776 1.37 thorpej int nmatch; 777 1.1 cgd 778 1.199 ozaki if (in_nullhost(faddr) || notify == NULL) 779 1.200 ozaki return 0; 780 1.1 cgd 781 1.37 thorpej nmatch = 0; 782 1.33 mycroft head = INPCBHASH_CONNECT(table, faddr, fport, laddr, lport); 783 1.192 ozaki LIST_FOREACH(inp, head, inp_hash) { 784 1.88 itojun if (inp->inp_af != AF_INET) 785 1.88 itojun continue; 786 1.188 knakahar 787 1.193 ozaki if (in_hosteq(in4p_faddr(inp), faddr) && 788 1.33 mycroft inp->inp_fport == fport && 789 1.33 mycroft inp->inp_lport == lport && 790 1.193 ozaki in_hosteq(in4p_laddr(inp), laddr)) { 791 1.33 mycroft (*notify)(inp, errno); 792 1.37 thorpej nmatch++; 793 1.37 thorpej } 794 1.1 cgd } 795 1.200 ozaki return nmatch; 796 1.18 mycroft } 797 1.18 mycroft 798 1.20 mycroft void 799 1.195 ozaki inpcb_notifyall(struct inpcbtable *table, struct in_addr faddr, int errno, 800 1.98 perry void (*notify)(struct inpcb *, int)) 801 1.18 mycroft { 802 1.192 ozaki struct inpcb *inp; 803 1.18 mycroft 804 1.199 ozaki if (in_nullhost(faddr) || notify == NULL) 805 1.18 mycroft return; 806 1.18 mycroft 807 1.192 ozaki TAILQ_FOREACH(inp, &table->inpt_queue, inp_queue) { 808 1.88 itojun if (inp->inp_af != AF_INET) 809 1.88 itojun continue; 810 1.193 ozaki if (in_hosteq(in4p_faddr(inp), faddr)) 811 1.33 mycroft (*notify)(inp, errno); 812 1.63 thorpej } 813 1.63 thorpej } 814 1.63 thorpej 815 1.63 thorpej void 816 1.154 seanb in_purgeifmcast(struct ip_moptions *imo, struct ifnet *ifp) 817 1.154 seanb { 818 1.154 seanb int i, gap; 819 1.154 seanb 820 1.176 ozaki /* The owner of imo should be protected by solock */ 821 1.164 ozaki KASSERT(ifp != NULL); 822 1.164 ozaki 823 1.154 seanb if (imo == NULL) 824 1.154 seanb return; 825 1.154 seanb 826 1.154 seanb /* 827 1.154 seanb * Unselect the outgoing interface if it is being 828 1.154 seanb * detached. 829 1.154 seanb */ 830 1.164 ozaki if (imo->imo_multicast_if_index == ifp->if_index) 831 1.164 ozaki imo->imo_multicast_if_index = 0; 832 1.154 seanb 833 1.154 seanb /* 834 1.154 seanb * Drop multicast group membership if we joined 835 1.154 seanb * through the interface being detached. 836 1.154 seanb */ 837 1.154 seanb for (i = 0, gap = 0; i < imo->imo_num_memberships; i++) { 838 1.154 seanb if (imo->imo_membership[i]->inm_ifp == ifp) { 839 1.154 seanb in_delmulti(imo->imo_membership[i]); 840 1.154 seanb gap++; 841 1.154 seanb } else if (gap != 0) 842 1.154 seanb imo->imo_membership[i - gap] = imo->imo_membership[i]; 843 1.154 seanb } 844 1.154 seanb imo->imo_num_memberships -= gap; 845 1.154 seanb } 846 1.154 seanb 847 1.154 seanb void 848 1.195 ozaki inpcb_purgeif0(struct inpcbtable *table, struct ifnet *ifp) 849 1.63 thorpej { 850 1.192 ozaki struct inpcb *inp; 851 1.63 thorpej 852 1.192 ozaki TAILQ_FOREACH(inp, &table->inpt_queue, inp_queue) { 853 1.176 ozaki bool need_unlock = false; 854 1.176 ozaki 855 1.88 itojun if (inp->inp_af != AF_INET) 856 1.88 itojun continue; 857 1.176 ozaki 858 1.176 ozaki /* The caller holds either one of inps' lock */ 859 1.176 ozaki if (!inp_locked(inp)) { 860 1.176 ozaki inp_lock(inp); 861 1.176 ozaki need_unlock = true; 862 1.176 ozaki } 863 1.176 ozaki 864 1.154 seanb in_purgeifmcast(inp->inp_moptions, ifp); 865 1.176 ozaki 866 1.176 ozaki if (need_unlock) 867 1.176 ozaki inp_unlock(inp); 868 1.69 itojun } 869 1.69 itojun } 870 1.69 itojun 871 1.69 itojun void 872 1.195 ozaki inpcb_purgeif(struct inpcbtable *table, struct ifnet *ifp) 873 1.69 itojun { 874 1.121 dyoung struct rtentry *rt; 875 1.192 ozaki struct inpcb *inp; 876 1.69 itojun 877 1.192 ozaki TAILQ_FOREACH(inp, &table->inpt_queue, inp_queue) { 878 1.88 itojun if (inp->inp_af != AF_INET) 879 1.88 itojun continue; 880 1.122 dyoung if ((rt = rtcache_validate(&inp->inp_route)) != NULL && 881 1.171 ozaki rt->rt_ifp == ifp) { 882 1.171 ozaki rtcache_unref(rt, &inp->inp_route); 883 1.195 ozaki inpcb_rtchange(inp, 0); 884 1.171 ozaki } else 885 1.171 ozaki rtcache_unref(rt, &inp->inp_route); 886 1.1 cgd } 887 1.1 cgd } 888 1.1 cgd 889 1.1 cgd /* 890 1.202 ozaki * inpcb_losing: check for alternatives when higher level complains about 891 1.202 ozaki * service problems. For now, invalidate cached routing information. 892 1.202 ozaki * If the route was created dynamically (by a redirect), time to try a 893 1.202 ozaki * default gateway again. 894 1.1 cgd */ 895 1.25 christos void 896 1.195 ozaki inpcb_losing(struct inpcb *inp) 897 1.1 cgd { 898 1.64 augustss struct rtentry *rt; 899 1.10 mycroft struct rt_addrinfo info; 900 1.1 cgd 901 1.88 itojun if (inp->inp_af != AF_INET) 902 1.88 itojun return; 903 1.88 itojun 904 1.122 dyoung if ((rt = rtcache_validate(&inp->inp_route)) == NULL) 905 1.122 dyoung return; 906 1.122 dyoung 907 1.122 dyoung memset(&info, 0, sizeof(info)); 908 1.122 dyoung info.rti_info[RTAX_DST] = rtcache_getdst(&inp->inp_route); 909 1.122 dyoung info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 910 1.122 dyoung info.rti_info[RTAX_NETMASK] = rt_mask(rt); 911 1.122 dyoung rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0); 912 1.171 ozaki if (rt->rt_flags & RTF_DYNAMIC) { 913 1.171 ozaki int error; 914 1.171 ozaki struct rtentry *nrt; 915 1.171 ozaki 916 1.171 ozaki error = rtrequest(RTM_DELETE, rt_getkey(rt), 917 1.171 ozaki rt->rt_gateway, rt_mask(rt), rt->rt_flags, &nrt); 918 1.171 ozaki rtcache_unref(rt, &inp->inp_route); 919 1.190 knakahar if (error == 0) { 920 1.190 knakahar rt_newmsg_dynamic(RTM_DELETE, nrt); 921 1.172 ozaki rt_free(nrt); 922 1.190 knakahar } 923 1.171 ozaki } else 924 1.171 ozaki rtcache_unref(rt, &inp->inp_route); 925 1.122 dyoung /* 926 1.122 dyoung * A new route can be allocated 927 1.122 dyoung * the next time output is attempted. 928 1.122 dyoung */ 929 1.122 dyoung rtcache_free(&inp->inp_route); 930 1.1 cgd } 931 1.1 cgd 932 1.1 cgd /* 933 1.202 ozaki * inpcb_rtchange: after a routing change, flush old routing. 934 1.202 ozaki * A new route can be allocated the next time output is attempted. 935 1.1 cgd */ 936 1.10 mycroft void 937 1.195 ozaki inpcb_rtchange(struct inpcb *inp, int errno) 938 1.1 cgd { 939 1.32 mycroft 940 1.88 itojun if (inp->inp_af != AF_INET) 941 1.88 itojun return; 942 1.88 itojun 943 1.112 joerg rtcache_free(&inp->inp_route); 944 1.112 joerg 945 1.49 tls /* XXX SHOULD NOTIFY HIGHER-LEVEL PROTOCOLS */ 946 1.1 cgd } 947 1.1 cgd 948 1.202 ozaki /* 949 1.202 ozaki * inpcb_lookup_local: find a PCB by looking at the local port and matching 950 1.202 ozaki * the local address or resolving the wildcards. Primarily used to detect 951 1.202 ozaki * when the local address is already in use. 952 1.202 ozaki */ 953 1.1 cgd struct inpcb * 954 1.195 ozaki inpcb_lookup_local(struct inpcbtable *table, struct in_addr laddr, 955 1.138 dyoung u_int lport_arg, int lookup_wildcard, vestigial_inpcb_t *vp) 956 1.1 cgd { 957 1.90 provos struct inpcbhead *head; 958 1.192 ozaki struct inpcb *inp; 959 1.142 yamt struct inpcb *match = NULL; 960 1.142 yamt int matchwild = 3; 961 1.142 yamt int wildcard; 962 1.198 ozaki in_port_t lport = lport_arg; 963 1.1 cgd 964 1.138 dyoung if (vp) 965 1.138 dyoung vp->valid = 0; 966 1.138 dyoung 967 1.90 provos head = INPCBHASH_PORT(table, lport); 968 1.192 ozaki LIST_FOREACH(inp, head, inp_lhash) { 969 1.88 itojun if (inp->inp_af != AF_INET) 970 1.88 itojun continue; 971 1.1 cgd if (inp->inp_lport != lport) 972 1.1 cgd continue; 973 1.142 yamt /* 974 1.142 yamt * check if inp's faddr and laddr match with ours. 975 1.142 yamt * our faddr is considered null. 976 1.142 yamt * count the number of wildcard matches. (0 - 2) 977 1.142 yamt * 978 1.142 yamt * null null match 979 1.142 yamt * A null wildcard match 980 1.142 yamt * null B wildcard match 981 1.142 yamt * A B non match 982 1.142 yamt * A A match 983 1.142 yamt */ 984 1.1 cgd wildcard = 0; 985 1.193 ozaki if (!in_nullhost(in4p_faddr(inp))) 986 1.33 mycroft wildcard++; 987 1.193 ozaki if (in_nullhost(in4p_laddr(inp))) { 988 1.32 mycroft if (!in_nullhost(laddr)) 989 1.1 cgd wildcard++; 990 1.1 cgd } else { 991 1.32 mycroft if (in_nullhost(laddr)) 992 1.1 cgd wildcard++; 993 1.32 mycroft else { 994 1.193 ozaki if (!in_hosteq(in4p_laddr(inp), laddr)) 995 1.32 mycroft continue; 996 1.32 mycroft } 997 1.1 cgd } 998 1.54 lukem if (wildcard && !lookup_wildcard) 999 1.1 cgd continue; 1000 1.142 yamt /* 1001 1.142 yamt * prefer an address with less wildcards. 1002 1.142 yamt */ 1003 1.1 cgd if (wildcard < matchwild) { 1004 1.1 cgd match = inp; 1005 1.1 cgd matchwild = wildcard; 1006 1.1 cgd if (matchwild == 0) 1007 1.1 cgd break; 1008 1.1 cgd } 1009 1.1 cgd } 1010 1.138 dyoung if (match && matchwild == 0) 1011 1.138 dyoung return match; 1012 1.138 dyoung 1013 1.138 dyoung if (vp && table->vestige) { 1014 1.138 dyoung void *state = (*table->vestige->init_ports4)(laddr, lport_arg, lookup_wildcard); 1015 1.138 dyoung vestigial_inpcb_t better; 1016 1.191 ryo bool has_better = false; 1017 1.138 dyoung 1018 1.138 dyoung while (table->vestige 1019 1.138 dyoung && (*table->vestige->next_port4)(state, vp)) { 1020 1.138 dyoung 1021 1.138 dyoung if (vp->lport != lport) 1022 1.138 dyoung continue; 1023 1.138 dyoung wildcard = 0; 1024 1.138 dyoung if (!in_nullhost(vp->faddr.v4)) 1025 1.138 dyoung wildcard++; 1026 1.138 dyoung if (in_nullhost(vp->laddr.v4)) { 1027 1.138 dyoung if (!in_nullhost(laddr)) 1028 1.138 dyoung wildcard++; 1029 1.138 dyoung } else { 1030 1.138 dyoung if (in_nullhost(laddr)) 1031 1.138 dyoung wildcard++; 1032 1.138 dyoung else { 1033 1.138 dyoung if (!in_hosteq(vp->laddr.v4, laddr)) 1034 1.138 dyoung continue; 1035 1.138 dyoung } 1036 1.138 dyoung } 1037 1.138 dyoung if (wildcard && !lookup_wildcard) 1038 1.138 dyoung continue; 1039 1.138 dyoung if (wildcard < matchwild) { 1040 1.138 dyoung better = *vp; 1041 1.191 ryo has_better = true; 1042 1.138 dyoung 1043 1.138 dyoung matchwild = wildcard; 1044 1.138 dyoung if (matchwild == 0) 1045 1.138 dyoung break; 1046 1.138 dyoung } 1047 1.138 dyoung } 1048 1.138 dyoung 1049 1.191 ryo if (has_better) { 1050 1.191 ryo *vp = better; 1051 1.191 ryo return 0; 1052 1.138 dyoung } 1053 1.138 dyoung } 1054 1.138 dyoung 1055 1.200 ozaki return match; 1056 1.24 mycroft } 1057 1.24 mycroft 1058 1.24 mycroft #ifdef DIAGNOSTIC 1059 1.195 ozaki int inpcb_notifymiss = 0; 1060 1.24 mycroft #endif 1061 1.24 mycroft 1062 1.202 ozaki /* 1063 1.202 ozaki * inpcb_lookup: perform a full 4-tuple PCB lookup. 1064 1.202 ozaki */ 1065 1.24 mycroft struct inpcb * 1066 1.195 ozaki inpcb_lookup(struct inpcbtable *table, 1067 1.98 perry struct in_addr faddr, u_int fport_arg, 1068 1.138 dyoung struct in_addr laddr, u_int lport_arg, 1069 1.138 dyoung vestigial_inpcb_t *vp) 1070 1.24 mycroft { 1071 1.24 mycroft struct inpcbhead *head; 1072 1.64 augustss struct inpcb *inp; 1073 1.198 ozaki in_port_t fport = fport_arg, lport = lport_arg; 1074 1.24 mycroft 1075 1.138 dyoung if (vp) 1076 1.138 dyoung vp->valid = 0; 1077 1.138 dyoung 1078 1.33 mycroft head = INPCBHASH_CONNECT(table, faddr, fport, laddr, lport); 1079 1.192 ozaki LIST_FOREACH(inp, head, inp_hash) { 1080 1.88 itojun if (inp->inp_af != AF_INET) 1081 1.88 itojun continue; 1082 1.88 itojun 1083 1.193 ozaki if (in_hosteq(in4p_faddr(inp), faddr) && 1084 1.33 mycroft inp->inp_fport == fport && 1085 1.33 mycroft inp->inp_lport == lport && 1086 1.193 ozaki in_hosteq(in4p_laddr(inp), laddr)) 1087 1.33 mycroft goto out; 1088 1.24 mycroft } 1089 1.138 dyoung if (vp && table->vestige) { 1090 1.138 dyoung if ((*table->vestige->lookup4)(faddr, fport_arg, 1091 1.138 dyoung laddr, lport_arg, vp)) 1092 1.138 dyoung return 0; 1093 1.138 dyoung } 1094 1.138 dyoung 1095 1.24 mycroft #ifdef DIAGNOSTIC 1096 1.195 ozaki if (inpcb_notifymiss) { 1097 1.195 ozaki printf("inpcb_lookup: faddr=%08x fport=%d laddr=%08x lport=%d\n", 1098 1.24 mycroft ntohl(faddr.s_addr), ntohs(fport), 1099 1.24 mycroft ntohl(laddr.s_addr), ntohs(lport)); 1100 1.24 mycroft } 1101 1.24 mycroft #endif 1102 1.200 ozaki return 0; 1103 1.33 mycroft 1104 1.33 mycroft out: 1105 1.33 mycroft /* Move this PCB to the head of hash chain. */ 1106 1.192 ozaki if (inp != LIST_FIRST(head)) { 1107 1.192 ozaki LIST_REMOVE(inp, inp_hash); 1108 1.192 ozaki LIST_INSERT_HEAD(head, inp, inp_hash); 1109 1.33 mycroft } 1110 1.200 ozaki return inp; 1111 1.33 mycroft } 1112 1.33 mycroft 1113 1.202 ozaki /* 1114 1.202 ozaki * inpcb_lookup_bound: find a PCB by looking at the local address and port. 1115 1.202 ozaki * Primarily used to find the listening (i.e., already bound) socket. 1116 1.202 ozaki */ 1117 1.33 mycroft struct inpcb * 1118 1.195 ozaki inpcb_lookup_bound(struct inpcbtable *table, 1119 1.98 perry struct in_addr laddr, u_int lport_arg) 1120 1.33 mycroft { 1121 1.33 mycroft struct inpcbhead *head; 1122 1.64 augustss struct inpcb *inp; 1123 1.198 ozaki in_port_t lport = lport_arg; 1124 1.33 mycroft 1125 1.33 mycroft head = INPCBHASH_BIND(table, laddr, lport); 1126 1.192 ozaki LIST_FOREACH(inp, head, inp_hash) { 1127 1.88 itojun if (inp->inp_af != AF_INET) 1128 1.88 itojun continue; 1129 1.88 itojun 1130 1.33 mycroft if (inp->inp_lport == lport && 1131 1.193 ozaki in_hosteq(in4p_laddr(inp), laddr)) 1132 1.33 mycroft goto out; 1133 1.33 mycroft } 1134 1.33 mycroft head = INPCBHASH_BIND(table, zeroin_addr, lport); 1135 1.192 ozaki LIST_FOREACH(inp, head, inp_hash) { 1136 1.88 itojun if (inp->inp_af != AF_INET) 1137 1.88 itojun continue; 1138 1.88 itojun 1139 1.33 mycroft if (inp->inp_lport == lport && 1140 1.193 ozaki in_hosteq(in4p_laddr(inp), zeroin_addr)) 1141 1.33 mycroft goto out; 1142 1.33 mycroft } 1143 1.33 mycroft #ifdef DIAGNOSTIC 1144 1.195 ozaki if (inpcb_notifymiss) { 1145 1.195 ozaki printf("inpcb_lookup_bound: laddr=%08x lport=%d\n", 1146 1.33 mycroft ntohl(laddr.s_addr), ntohs(lport)); 1147 1.33 mycroft } 1148 1.33 mycroft #endif 1149 1.200 ozaki return 0; 1150 1.33 mycroft 1151 1.33 mycroft out: 1152 1.33 mycroft /* Move this PCB to the head of hash chain. */ 1153 1.192 ozaki if (inp != LIST_FIRST(head)) { 1154 1.192 ozaki LIST_REMOVE(inp, inp_hash); 1155 1.192 ozaki LIST_INSERT_HEAD(head, inp, inp_hash); 1156 1.33 mycroft } 1157 1.200 ozaki return inp; 1158 1.33 mycroft } 1159 1.33 mycroft 1160 1.33 mycroft void 1161 1.195 ozaki inpcb_set_state(struct inpcb *inp, int state) 1162 1.33 mycroft { 1163 1.33 mycroft 1164 1.194 ozaki #ifdef INET6 1165 1.192 ozaki if (inp->inp_af == AF_INET6) { 1166 1.196 ozaki in6pcb_set_state(inp, state); 1167 1.88 itojun return; 1168 1.192 ozaki } 1169 1.194 ozaki #else 1170 1.194 ozaki if (inp->inp_af != AF_INET) 1171 1.194 ozaki return; 1172 1.194 ozaki #endif 1173 1.88 itojun 1174 1.33 mycroft if (inp->inp_state > INP_ATTACHED) 1175 1.192 ozaki LIST_REMOVE(inp, inp_hash); 1176 1.33 mycroft 1177 1.33 mycroft switch (state) { 1178 1.33 mycroft case INP_BOUND: 1179 1.33 mycroft LIST_INSERT_HEAD(INPCBHASH_BIND(inp->inp_table, 1180 1.193 ozaki in4p_laddr(inp), inp->inp_lport), inp, 1181 1.192 ozaki inp_hash); 1182 1.33 mycroft break; 1183 1.33 mycroft case INP_CONNECTED: 1184 1.33 mycroft LIST_INSERT_HEAD(INPCBHASH_CONNECT(inp->inp_table, 1185 1.193 ozaki in4p_faddr(inp), inp->inp_fport, 1186 1.193 ozaki in4p_laddr(inp), inp->inp_lport), inp, 1187 1.192 ozaki inp_hash); 1188 1.33 mycroft break; 1189 1.33 mycroft } 1190 1.33 mycroft 1191 1.33 mycroft inp->inp_state = state; 1192 1.38 thorpej } 1193 1.38 thorpej 1194 1.38 thorpej struct rtentry * 1195 1.195 ozaki inpcb_rtentry(struct inpcb *inp) 1196 1.38 thorpej { 1197 1.38 thorpej struct route *ro; 1198 1.117 dyoung union { 1199 1.117 dyoung struct sockaddr dst; 1200 1.117 dyoung struct sockaddr_in dst4; 1201 1.117 dyoung } u; 1202 1.88 itojun 1203 1.194 ozaki #ifdef INET6 1204 1.192 ozaki if (inp->inp_af == AF_INET6) 1205 1.196 ozaki return in6pcb_rtentry(inp); 1206 1.194 ozaki #endif 1207 1.88 itojun if (inp->inp_af != AF_INET) 1208 1.200 ozaki return NULL; 1209 1.38 thorpej 1210 1.38 thorpej ro = &inp->inp_route; 1211 1.38 thorpej 1212 1.193 ozaki sockaddr_in_init(&u.dst4, &in4p_faddr(inp), 0); 1213 1.117 dyoung return rtcache_lookup(ro, &u.dst); 1214 1.59 itojun } 1215 1.171 ozaki 1216 1.171 ozaki void 1217 1.195 ozaki inpcb_rtentry_unref(struct rtentry *rt, struct inpcb *inp) 1218 1.171 ozaki { 1219 1.171 ozaki 1220 1.171 ozaki rtcache_unref(rt, &inp->inp_route); 1221 1.171 ozaki } 1222