1 /* 2 * Copyright (c) 1982, 1986, 1991, 1993, 1995 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)in_pcb.c 8.4 (Berkeley) 05/24/95 8 */ 9 10 #include <sys/param.h> 11 #include <sys/systm.h> 12 #include <sys/malloc.h> 13 #include <sys/mbuf.h> 14 #include <sys/protosw.h> 15 #include <sys/socket.h> 16 #include <sys/socketvar.h> 17 #include <sys/ioctl.h> 18 #include <sys/errno.h> 19 #include <sys/time.h> 20 #include <sys/proc.h> 21 22 #include <net/if.h> 23 #include <net/route.h> 24 25 #include <netinet/in.h> 26 #include <netinet/in_systm.h> 27 #include <netinet/ip.h> 28 #include <netinet/in_pcb.h> 29 #include <netinet/in_var.h> 30 #include <netinet/ip_var.h> 31 32 struct in_addr zeroin_addr; 33 34 int 35 in_pcballoc(so, head) 36 struct socket *so; 37 struct inpcb *head; 38 { 39 register struct inpcb *inp; 40 41 MALLOC(inp, struct inpcb *, sizeof(*inp), M_PCB, M_NOWAIT); 42 if (inp == NULL) 43 return (ENOBUFS); 44 bzero((caddr_t)inp, sizeof(*inp)); 45 inp->inp_head = head; 46 inp->inp_socket = so; 47 insque(inp, head); 48 so->so_pcb = (caddr_t)inp; 49 return (0); 50 } 51 52 int 53 in_pcbbind(inp, nam) 54 register struct inpcb *inp; 55 struct mbuf *nam; 56 { 57 register struct socket *so = inp->inp_socket; 58 register struct inpcb *head = inp->inp_head; 59 register struct sockaddr_in *sin; 60 struct proc *p = curproc; /* XXX */ 61 u_short lport = 0; 62 int wild = 0, reuseport = (so->so_options & SO_REUSEPORT); 63 int error; 64 65 if (in_ifaddr == 0) 66 return (EADDRNOTAVAIL); 67 if (inp->inp_lport || inp->inp_laddr.s_addr != INADDR_ANY) 68 return (EINVAL); 69 if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0 && 70 ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 || 71 (so->so_options & SO_ACCEPTCONN) == 0)) 72 wild = INPLOOKUP_WILDCARD; 73 if (nam) { 74 sin = mtod(nam, struct sockaddr_in *); 75 if (nam->m_len != sizeof (*sin)) 76 return (EINVAL); 77 #ifdef notdef 78 /* 79 * We should check the family, but old programs 80 * incorrectly fail to initialize it. 81 */ 82 if (sin->sin_family != AF_INET) 83 return (EAFNOSUPPORT); 84 #endif 85 lport = sin->sin_port; 86 if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { 87 /* 88 * Treat SO_REUSEADDR as SO_REUSEPORT for multicast; 89 * allow complete duplication of binding if 90 * SO_REUSEPORT is set, or if SO_REUSEADDR is set 91 * and a multicast address is bound on both 92 * new and duplicated sockets. 93 */ 94 if (so->so_options & SO_REUSEADDR) 95 reuseport = SO_REUSEADDR|SO_REUSEPORT; 96 } else if (sin->sin_addr.s_addr != INADDR_ANY) { 97 sin->sin_port = 0; /* yech... */ 98 if (ifa_ifwithaddr((struct sockaddr *)sin) == 0) 99 return (EADDRNOTAVAIL); 100 } 101 if (lport) { 102 struct inpcb *t; 103 104 /* GROSS */ 105 if (ntohs(lport) < IPPORT_RESERVED && 106 (error = suser(p->p_ucred, &p->p_acflag))) 107 return (EACCES); 108 t = in_pcblookup(head, zeroin_addr, 0, 109 sin->sin_addr, lport, wild); 110 if (t && (reuseport & t->inp_socket->so_options) == 0) 111 return (EADDRINUSE); 112 } 113 inp->inp_laddr = sin->sin_addr; 114 } 115 if (lport == 0) 116 do { 117 if (head->inp_lport++ < IPPORT_RESERVED || 118 head->inp_lport > IPPORT_USERRESERVED) 119 head->inp_lport = IPPORT_RESERVED; 120 lport = htons(head->inp_lport); 121 } while (in_pcblookup(head, 122 zeroin_addr, 0, inp->inp_laddr, lport, wild)); 123 inp->inp_lport = lport; 124 return (0); 125 } 126 127 /* 128 * Connect from a socket to a specified address. 129 * Both address and port must be specified in argument sin. 130 * If don't have a local address for this socket yet, 131 * then pick one. 132 */ 133 int 134 in_pcbconnect(inp, nam) 135 register struct inpcb *inp; 136 struct mbuf *nam; 137 { 138 struct in_ifaddr *ia; 139 struct sockaddr_in *ifaddr; 140 register struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *); 141 142 if (nam->m_len != sizeof (*sin)) 143 return (EINVAL); 144 if (sin->sin_family != AF_INET) 145 return (EAFNOSUPPORT); 146 if (sin->sin_port == 0) 147 return (EADDRNOTAVAIL); 148 if (in_ifaddr) { 149 /* 150 * If the destination address is INADDR_ANY, 151 * use the primary local address. 152 * If the supplied address is INADDR_BROADCAST, 153 * and the primary interface supports broadcast, 154 * choose the broadcast address for that interface. 155 */ 156 #define satosin(sa) ((struct sockaddr_in *)(sa)) 157 #define sintosa(sin) ((struct sockaddr *)(sin)) 158 #define ifatoia(ifa) ((struct in_ifaddr *)(ifa)) 159 if (sin->sin_addr.s_addr == INADDR_ANY) 160 sin->sin_addr = IA_SIN(in_ifaddr)->sin_addr; 161 else if (sin->sin_addr.s_addr == (u_long)INADDR_BROADCAST && 162 (in_ifaddr->ia_ifp->if_flags & IFF_BROADCAST)) 163 sin->sin_addr = satosin(&in_ifaddr->ia_broadaddr)->sin_addr; 164 } 165 if (inp->inp_laddr.s_addr == INADDR_ANY) { 166 register struct route *ro; 167 168 ia = (struct in_ifaddr *)0; 169 /* 170 * If route is known or can be allocated now, 171 * our src addr is taken from the i/f, else punt. 172 */ 173 ro = &inp->inp_route; 174 if (ro->ro_rt && 175 (satosin(&ro->ro_dst)->sin_addr.s_addr != 176 sin->sin_addr.s_addr || 177 inp->inp_socket->so_options & SO_DONTROUTE)) { 178 RTFREE(ro->ro_rt); 179 ro->ro_rt = (struct rtentry *)0; 180 } 181 if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/ 182 (ro->ro_rt == (struct rtentry *)0 || 183 ro->ro_rt->rt_ifp == (struct ifnet *)0)) { 184 /* No route yet, so try to acquire one */ 185 ro->ro_dst.sa_family = AF_INET; 186 ro->ro_dst.sa_len = sizeof(struct sockaddr_in); 187 ((struct sockaddr_in *) &ro->ro_dst)->sin_addr = 188 sin->sin_addr; 189 rtalloc(ro); 190 } 191 /* 192 * If we found a route, use the address 193 * corresponding to the outgoing interface 194 * unless it is the loopback (in case a route 195 * to our address on another net goes to loopback). 196 */ 197 if (ro->ro_rt && !(ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK)) 198 ia = ifatoia(ro->ro_rt->rt_ifa); 199 if (ia == 0) { 200 u_short fport = sin->sin_port; 201 202 sin->sin_port = 0; 203 ia = ifatoia(ifa_ifwithdstaddr(sintosa(sin))); 204 if (ia == 0) 205 ia = ifatoia(ifa_ifwithnet(sintosa(sin))); 206 sin->sin_port = fport; 207 if (ia == 0) 208 ia = in_ifaddr; 209 if (ia == 0) 210 return (EADDRNOTAVAIL); 211 } 212 /* 213 * If the destination address is multicast and an outgoing 214 * interface has been set as a multicast option, use the 215 * address of that interface as our source address. 216 */ 217 if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) && 218 inp->inp_moptions != NULL) { 219 struct ip_moptions *imo; 220 struct ifnet *ifp; 221 222 imo = inp->inp_moptions; 223 if (imo->imo_multicast_ifp != NULL) { 224 ifp = imo->imo_multicast_ifp; 225 for (ia = in_ifaddr; ia; ia = ia->ia_next) 226 if (ia->ia_ifp == ifp) 227 break; 228 if (ia == 0) 229 return (EADDRNOTAVAIL); 230 } 231 } 232 ifaddr = (struct sockaddr_in *)&ia->ia_addr; 233 } 234 if (in_pcblookup(inp->inp_head, 235 sin->sin_addr, 236 sin->sin_port, 237 inp->inp_laddr.s_addr ? inp->inp_laddr : ifaddr->sin_addr, 238 inp->inp_lport, 239 0)) 240 return (EADDRINUSE); 241 if (inp->inp_laddr.s_addr == INADDR_ANY) { 242 if (inp->inp_lport == 0) 243 (void)in_pcbbind(inp, (struct mbuf *)0); 244 inp->inp_laddr = ifaddr->sin_addr; 245 } 246 inp->inp_faddr = sin->sin_addr; 247 inp->inp_fport = sin->sin_port; 248 return (0); 249 } 250 251 int 252 in_pcbdisconnect(inp) 253 struct inpcb *inp; 254 { 255 256 inp->inp_faddr.s_addr = INADDR_ANY; 257 inp->inp_fport = 0; 258 if (inp->inp_socket->so_state & SS_NOFDREF) 259 in_pcbdetach(inp); 260 } 261 262 int 263 in_pcbdetach(inp) 264 struct inpcb *inp; 265 { 266 struct socket *so = inp->inp_socket; 267 268 so->so_pcb = 0; 269 sofree(so); 270 if (inp->inp_options) 271 (void)m_free(inp->inp_options); 272 if (inp->inp_route.ro_rt) 273 rtfree(inp->inp_route.ro_rt); 274 ip_freemoptions(inp->inp_moptions); 275 remque(inp); 276 FREE(inp, M_PCB); 277 } 278 279 int 280 in_setsockaddr(inp, nam) 281 register struct inpcb *inp; 282 struct mbuf *nam; 283 { 284 register struct sockaddr_in *sin; 285 286 nam->m_len = sizeof (*sin); 287 sin = mtod(nam, struct sockaddr_in *); 288 bzero((caddr_t)sin, sizeof (*sin)); 289 sin->sin_family = AF_INET; 290 sin->sin_len = sizeof(*sin); 291 sin->sin_port = inp->inp_lport; 292 sin->sin_addr = inp->inp_laddr; 293 } 294 295 int 296 in_setpeeraddr(inp, nam) 297 struct inpcb *inp; 298 struct mbuf *nam; 299 { 300 register struct sockaddr_in *sin; 301 302 nam->m_len = sizeof (*sin); 303 sin = mtod(nam, struct sockaddr_in *); 304 bzero((caddr_t)sin, sizeof (*sin)); 305 sin->sin_family = AF_INET; 306 sin->sin_len = sizeof(*sin); 307 sin->sin_port = inp->inp_fport; 308 sin->sin_addr = inp->inp_faddr; 309 } 310 311 /* 312 * Pass some notification to all connections of a protocol 313 * associated with address dst. The local address and/or port numbers 314 * may be specified to limit the search. The "usual action" will be 315 * taken, depending on the ctlinput cmd. The caller must filter any 316 * cmds that are uninteresting (e.g., no error in the map). 317 * Call the protocol specific routine (if any) to report 318 * any errors for each matching socket. 319 * 320 * Must be called at splnet. 321 */ 322 int 323 in_pcbnotify(head, dst, fport_arg, laddr, lport_arg, cmd, notify) 324 struct inpcb *head; 325 struct sockaddr *dst; 326 u_int fport_arg, lport_arg; 327 struct in_addr laddr; 328 int cmd; 329 void (*notify) __P((struct inpcb *, int)); 330 { 331 extern u_char inetctlerrmap[]; 332 register struct inpcb *inp, *oinp; 333 struct in_addr faddr; 334 u_short fport = fport_arg, lport = lport_arg; 335 int errno; 336 337 if ((unsigned)cmd > PRC_NCMDS || dst->sa_family != AF_INET) 338 return; 339 faddr = ((struct sockaddr_in *)dst)->sin_addr; 340 if (faddr.s_addr == INADDR_ANY) 341 return; 342 343 /* 344 * Redirects go to all references to the destination, 345 * and use in_rtchange to invalidate the route cache. 346 * Dead host indications: notify all references to the destination. 347 * Otherwise, if we have knowledge of the local port and address, 348 * deliver only to that socket. 349 */ 350 if (PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) { 351 fport = 0; 352 lport = 0; 353 laddr.s_addr = 0; 354 if (cmd != PRC_HOSTDEAD) 355 notify = in_rtchange; 356 } 357 errno = inetctlerrmap[cmd]; 358 for (inp = head->inp_next; inp != head;) { 359 if (inp->inp_faddr.s_addr != faddr.s_addr || 360 inp->inp_socket == 0 || 361 (lport && inp->inp_lport != lport) || 362 (laddr.s_addr && inp->inp_laddr.s_addr != laddr.s_addr) || 363 (fport && inp->inp_fport != fport)) { 364 inp = inp->inp_next; 365 continue; 366 } 367 oinp = inp; 368 inp = inp->inp_next; 369 if (notify) 370 (*notify)(oinp, errno); 371 } 372 } 373 374 /* 375 * Check for alternatives when higher level complains 376 * about service problems. For now, invalidate cached 377 * routing information. If the route was created dynamically 378 * (by a redirect), time to try a default gateway again. 379 */ 380 int 381 in_losing(inp) 382 struct inpcb *inp; 383 { 384 register struct rtentry *rt; 385 struct rt_addrinfo info; 386 387 if ((rt = inp->inp_route.ro_rt)) { 388 inp->inp_route.ro_rt = 0; 389 bzero((caddr_t)&info, sizeof(info)); 390 info.rti_info[RTAX_DST] = 391 (struct sockaddr *)&inp->inp_route.ro_dst; 392 info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 393 info.rti_info[RTAX_NETMASK] = rt_mask(rt); 394 rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0); 395 if (rt->rt_flags & RTF_DYNAMIC) 396 (void) rtrequest(RTM_DELETE, rt_key(rt), 397 rt->rt_gateway, rt_mask(rt), rt->rt_flags, 398 (struct rtentry **)0); 399 else 400 /* 401 * A new route can be allocated 402 * the next time output is attempted. 403 */ 404 rtfree(rt); 405 } 406 } 407 408 /* 409 * After a routing change, flush old routing 410 * and allocate a (hopefully) better one. 411 */ 412 void 413 in_rtchange(inp, errno) 414 register struct inpcb *inp; 415 int errno; 416 { 417 if (inp->inp_route.ro_rt) { 418 rtfree(inp->inp_route.ro_rt); 419 inp->inp_route.ro_rt = 0; 420 /* 421 * A new route can be allocated the next time 422 * output is attempted. 423 */ 424 } 425 } 426 427 struct inpcb * 428 in_pcblookup(head, faddr, fport_arg, laddr, lport_arg, flags) 429 struct inpcb *head; 430 struct in_addr faddr, laddr; 431 u_int fport_arg, lport_arg; 432 int flags; 433 { 434 register struct inpcb *inp, *match = 0; 435 int matchwild = 3, wildcard; 436 u_short fport = fport_arg, lport = lport_arg; 437 438 for (inp = head->inp_next; inp != head; inp = inp->inp_next) { 439 if (inp->inp_lport != lport) 440 continue; 441 wildcard = 0; 442 if (inp->inp_laddr.s_addr != INADDR_ANY) { 443 if (laddr.s_addr == INADDR_ANY) 444 wildcard++; 445 else if (inp->inp_laddr.s_addr != laddr.s_addr) 446 continue; 447 } else { 448 if (laddr.s_addr != INADDR_ANY) 449 wildcard++; 450 } 451 if (inp->inp_faddr.s_addr != INADDR_ANY) { 452 if (faddr.s_addr == INADDR_ANY) 453 wildcard++; 454 else if (inp->inp_faddr.s_addr != faddr.s_addr || 455 inp->inp_fport != fport) 456 continue; 457 } else { 458 if (faddr.s_addr != INADDR_ANY) 459 wildcard++; 460 } 461 if (wildcard && (flags & INPLOOKUP_WILDCARD) == 0) 462 continue; 463 if (wildcard < matchwild) { 464 match = inp; 465 matchwild = wildcard; 466 if (matchwild == 0) 467 break; 468 } 469 } 470 return (match); 471 } 472