123177Smckusick /* 2*60847Skarels * Copyright (c) 1982, 1986, 1991, 1993 Regents of the University of California. 332787Sbostic * All rights reserved. 423177Smckusick * 544475Sbostic * %sccs.include.redist.c% 632787Sbostic * 7*60847Skarels * @(#)in_pcb.c 7.27 (Berkeley) 05/31/93 823177Smckusick */ 94905Swnj 1056531Sbostic #include <sys/param.h> 1156531Sbostic #include <sys/systm.h> 1256531Sbostic #include <sys/malloc.h> 1356531Sbostic #include <sys/mbuf.h> 1456531Sbostic #include <sys/protosw.h> 1556531Sbostic #include <sys/socket.h> 1656531Sbostic #include <sys/socketvar.h> 1756531Sbostic #include <sys/ioctl.h> 1856531Sbostic #include <sys/errno.h> 19*60847Skarels #include <sys/time.h> 20*60847Skarels #include <sys/proc.h> 2148464Skarels 2256531Sbostic #include <net/if.h> 2356531Sbostic #include <net/route.h> 2448464Skarels 2556531Sbostic #include <netinet/in.h> 2656531Sbostic #include <netinet/in_systm.h> 2756531Sbostic #include <netinet/ip.h> 2856531Sbostic #include <netinet/in_pcb.h> 2956531Sbostic #include <netinet/in_var.h> 304905Swnj 3156531Sbostic #include <netinet/ip_var.h> 3254716Ssklower 335240Sroot struct in_addr zeroin_addr; 345161Swnj 357506Sroot in_pcballoc(so, head) 367506Sroot struct socket *so; 377506Sroot struct inpcb *head; 387506Sroot { 397506Sroot struct mbuf *m; 407506Sroot register struct inpcb *inp; 417506Sroot 4254716Ssklower MALLOC(inp, struct inpcb *, sizeof(*inp), M_PCB, M_WAITOK); 4354716Ssklower if (inp == NULL) 447506Sroot return (ENOBUFS); 4554716Ssklower bzero((caddr_t)inp, sizeof(*inp)); 467506Sroot inp->inp_head = head; 477506Sroot inp->inp_socket = so; 487506Sroot insque(inp, head); 497506Sroot so->so_pcb = (caddr_t)inp; 507506Sroot return (0); 517506Sroot } 527506Sroot 538270Sroot in_pcbbind(inp, nam) 547506Sroot register struct inpcb *inp; 558270Sroot struct mbuf *nam; 567506Sroot { 577506Sroot register struct socket *so = inp->inp_socket; 587506Sroot register struct inpcb *head = inp->inp_head; 598270Sroot register struct sockaddr_in *sin; 60*60847Skarels struct proc *p = curproc; /* XXX */ 617506Sroot u_short lport = 0; 62*60847Skarels int wild = 0, reuseport = (so->so_options & SO_REUSEPORT); 63*60847Skarels int error; 647506Sroot 6518374Skarels if (in_ifaddr == 0) 667506Sroot return (EADDRNOTAVAIL); 6710141Ssam if (inp->inp_lport || inp->inp_laddr.s_addr != INADDR_ANY) 688270Sroot return (EINVAL); 69*60847Skarels if ((so->so_options & (SO_REUSEADDR|SO_REUSEPORT)) == 0 && 7058373Smckusick ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 || 7158373Smckusick (so->so_options & SO_ACCEPTCONN) == 0)) 7258373Smckusick wild = INPLOOKUP_WILDCARD; 73*60847Skarels if (nam) { 74*60847Skarels sin = mtod(nam, struct sockaddr_in *); 75*60847Skarels if (nam->m_len != sizeof (*sin)) 76*60847Skarels return (EINVAL); 77*60847Skarels #ifdef notdef 78*60847Skarels /* 79*60847Skarels * We should check the family, but old programs 80*60847Skarels * incorrectly fail to initialize it. 81*60847Skarels */ 82*60847Skarels if (sin->sin_family != AF_INET) 83*60847Skarels return (EAFNOSUPPORT); 84*60847Skarels #endif 85*60847Skarels lport = sin->sin_port; 86*60847Skarels if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) { 87*60847Skarels /* 88*60847Skarels * Treat SO_REUSEADDR as SO_REUSEPORT for multicast; 89*60847Skarels * allow complete duplication of binding if 90*60847Skarels * SO_REUSEPORT is set, or if SO_REUSEADDR is set 91*60847Skarels * and a multicast address is bound on both 92*60847Skarels * new and duplicated sockets. 93*60847Skarels */ 94*60847Skarels if (so->so_options & SO_REUSEADDR) 95*60847Skarels reuseport = SO_REUSEADDR|SO_REUSEPORT; 96*60847Skarels } else if (sin->sin_addr.s_addr != INADDR_ANY) { 97*60847Skarels sin->sin_port = 0; /* yech... */ 98*60847Skarels if (ifa_ifwithaddr((struct sockaddr *)sin) == 0) 99*60847Skarels return (EADDRNOTAVAIL); 100*60847Skarels } 101*60847Skarels if (lport) { 102*60847Skarels struct inpcb *t; 1037506Sroot 104*60847Skarels /* GROSS */ 105*60847Skarels if (ntohs(lport) < IPPORT_RESERVED && 106*60847Skarels (error = suser(p->p_ucred, &p->p_acflag))) 107*60847Skarels return (error); 108*60847Skarels t = in_pcblookup(head, zeroin_addr, 0, 109*60847Skarels sin->sin_addr, lport, wild); 110*60847Skarels if (t && (reuseport & t->inp_socket->so_options) == 0) 111*60847Skarels return (EADDRINUSE); 112*60847Skarels } 113*60847Skarels inp->inp_laddr = sin->sin_addr; 1147506Sroot } 1155172Swnj if (lport == 0) 1165172Swnj do { 11726025Skarels if (head->inp_lport++ < IPPORT_RESERVED || 11826025Skarels head->inp_lport > IPPORT_USERRESERVED) 1195994Swnj head->inp_lport = IPPORT_RESERVED; 1205172Swnj lport = htons(head->inp_lport); 1215994Swnj } while (in_pcblookup(head, 12258373Smckusick zeroin_addr, 0, inp->inp_laddr, lport, wild)); 1235172Swnj inp->inp_lport = lport; 1244951Swnj return (0); 1254905Swnj } 1264905Swnj 1276116Swnj /* 1286116Swnj * Connect from a socket to a specified address. 1296116Swnj * Both address and port must be specified in argument sin. 1306116Swnj * If don't have a local address for this socket yet, 1316116Swnj * then pick one. 1326116Swnj */ 1338270Sroot in_pcbconnect(inp, nam) 13431976Skarels register struct inpcb *inp; 1358270Sroot struct mbuf *nam; 1364923Swnj { 13718374Skarels struct in_ifaddr *ia; 1386338Ssam struct sockaddr_in *ifaddr; 1398270Sroot register struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *); 1404923Swnj 1418270Sroot if (nam->m_len != sizeof (*sin)) 1428270Sroot return (EINVAL); 1434951Swnj if (sin->sin_family != AF_INET) 1444951Swnj return (EAFNOSUPPORT); 14518374Skarels if (sin->sin_port == 0) 1464951Swnj return (EADDRNOTAVAIL); 14718374Skarels if (in_ifaddr) { 14818655Skarels /* 14918655Skarels * If the destination address is INADDR_ANY, 15018655Skarels * use the primary local address. 15118655Skarels * If the supplied address is INADDR_BROADCAST, 15218655Skarels * and the primary interface supports broadcast, 15318655Skarels * choose the broadcast address for that interface. 15418655Skarels */ 15518374Skarels #define satosin(sa) ((struct sockaddr_in *)(sa)) 15658998Ssklower #define sintosa(sin) ((struct sockaddr *)(sin)) 15758998Ssklower #define ifatoia(ifa) ((struct in_ifaddr *)(ifa)) 15818374Skarels if (sin->sin_addr.s_addr == INADDR_ANY) 15918655Skarels sin->sin_addr = IA_SIN(in_ifaddr)->sin_addr; 16024807Skarels else if (sin->sin_addr.s_addr == (u_long)INADDR_BROADCAST && 16118655Skarels (in_ifaddr->ia_ifp->if_flags & IFF_BROADCAST)) 16218655Skarels sin->sin_addr = satosin(&in_ifaddr->ia_broadaddr)->sin_addr; 16318374Skarels } 16410141Ssam if (inp->inp_laddr.s_addr == INADDR_ANY) { 16527262Skarels register struct route *ro; 16617271Skarels 16727262Skarels ia = (struct in_ifaddr *)0; 16827262Skarels /* 16927262Skarels * If route is known or can be allocated now, 17027262Skarels * our src addr is taken from the i/f, else punt. 17127262Skarels */ 17227262Skarels ro = &inp->inp_route; 17327262Skarels if (ro->ro_rt && 17430336Skarels (satosin(&ro->ro_dst)->sin_addr.s_addr != 17530336Skarels sin->sin_addr.s_addr || 17630336Skarels inp->inp_socket->so_options & SO_DONTROUTE)) { 17727262Skarels RTFREE(ro->ro_rt); 17827262Skarels ro->ro_rt = (struct rtentry *)0; 1796338Ssam } 18028847Skarels if ((inp->inp_socket->so_options & SO_DONTROUTE) == 0 && /*XXX*/ 18128847Skarels (ro->ro_rt == (struct rtentry *)0 || 18229826Skarels ro->ro_rt->rt_ifp == (struct ifnet *)0)) { 18327262Skarels /* No route yet, so try to acquire one */ 18427262Skarels ro->ro_dst.sa_family = AF_INET; 18537471Ssklower ro->ro_dst.sa_len = sizeof(struct sockaddr_in); 18627262Skarels ((struct sockaddr_in *) &ro->ro_dst)->sin_addr = 18727262Skarels sin->sin_addr; 18827262Skarels rtalloc(ro); 18927262Skarels } 19029826Skarels /* 19129826Skarels * If we found a route, use the address 19229826Skarels * corresponding to the outgoing interface 19329826Skarels * unless it is the loopback (in case a route 19429826Skarels * to our address on another net goes to loopback). 19529826Skarels */ 19658998Ssklower if (ro->ro_rt && !(ro->ro_rt->rt_ifp->if_flags & IFF_LOOPBACK)) 19758998Ssklower ia = ifatoia(ro->ro_rt->rt_ifa); 19828847Skarels if (ia == 0) { 19930336Skarels int fport = sin->sin_port; 20030336Skarels 20130336Skarels sin->sin_port = 0; 20258998Ssklower ia = ifatoia(ifa_ifwithdstaddr(sintosa(sin))); 20358998Ssklower if (ia == 0) 20458998Ssklower ia = ifatoia(ifa_ifwithnet(sintosa(sin))); 20530336Skarels sin->sin_port = fport; 20628847Skarels if (ia == 0) 20728847Skarels ia = in_ifaddr; 20828847Skarels if (ia == 0) 20928847Skarels return (EADDRNOTAVAIL); 21027262Skarels } 21154716Ssklower /* 21254716Ssklower * If the destination address is multicast and an outgoing 21354716Ssklower * interface has been set as a multicast option, use the 21454716Ssklower * address of that interface as our source address. 21554716Ssklower */ 21654716Ssklower if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) && 21754716Ssklower inp->inp_moptions != NULL) { 21854716Ssklower struct ip_moptions *imo; 21958998Ssklower struct ifnet *ifp; 22054716Ssklower 22154716Ssklower imo = inp->inp_moptions; 22254716Ssklower if (imo->imo_multicast_ifp != NULL) { 22354716Ssklower ifp = imo->imo_multicast_ifp; 22454716Ssklower for (ia = in_ifaddr; ia; ia = ia->ia_next) 22554716Ssklower if (ia->ia_ifp == ifp) 22654716Ssklower break; 22754716Ssklower if (ia == 0) 22854716Ssklower return (EADDRNOTAVAIL); 22954716Ssklower } 23054716Ssklower } 23118374Skarels ifaddr = (struct sockaddr_in *)&ia->ia_addr; 2325994Swnj } 2335994Swnj if (in_pcblookup(inp->inp_head, 2346116Swnj sin->sin_addr, 2356116Swnj sin->sin_port, 2366338Ssam inp->inp_laddr.s_addr ? inp->inp_laddr : ifaddr->sin_addr, 2376116Swnj inp->inp_lport, 2386116Swnj 0)) 2395172Swnj return (EADDRINUSE); 24014146Ssam if (inp->inp_laddr.s_addr == INADDR_ANY) { 24114146Ssam if (inp->inp_lport == 0) 24226382Skarels (void)in_pcbbind(inp, (struct mbuf *)0); 2436338Ssam inp->inp_laddr = ifaddr->sin_addr; 24414146Ssam } 2454951Swnj inp->inp_faddr = sin->sin_addr; 2464951Swnj inp->inp_fport = sin->sin_port; 2474923Swnj return (0); 2484923Swnj } 2494923Swnj 2505161Swnj in_pcbdisconnect(inp) 2514905Swnj struct inpcb *inp; 2524905Swnj { 2535161Swnj 25410141Ssam inp->inp_faddr.s_addr = INADDR_ANY; 2556028Sroot inp->inp_fport = 0; 2567506Sroot if (inp->inp_socket->so_state & SS_NOFDREF) 2575161Swnj in_pcbdetach(inp); 2585161Swnj } 2595161Swnj 2605161Swnj in_pcbdetach(inp) 2615161Swnj struct inpcb *inp; 2625161Swnj { 2634905Swnj struct socket *so = inp->inp_socket; 2644905Swnj 2655009Swnj so->so_pcb = 0; 2665009Swnj sofree(so); 26724807Skarels if (inp->inp_options) 26826382Skarels (void)m_free(inp->inp_options); 2696350Ssam if (inp->inp_route.ro_rt) 2706367Ssam rtfree(inp->inp_route.ro_rt); 27154716Ssklower ip_freemoptions(inp->inp_moptions); 2724983Swnj remque(inp); 27354716Ssklower FREE(inp, M_PCB); 2744905Swnj } 2754905Swnj 2768270Sroot in_setsockaddr(inp, nam) 2776509Ssam register struct inpcb *inp; 2788270Sroot struct mbuf *nam; 2796509Ssam { 28032071Skarels register struct sockaddr_in *sin; 2818270Sroot 2828270Sroot nam->m_len = sizeof (*sin); 2838270Sroot sin = mtod(nam, struct sockaddr_in *); 2846509Ssam bzero((caddr_t)sin, sizeof (*sin)); 2856509Ssam sin->sin_family = AF_INET; 28637471Ssklower sin->sin_len = sizeof(*sin); 2876509Ssam sin->sin_port = inp->inp_lport; 2886509Ssam sin->sin_addr = inp->inp_laddr; 2896509Ssam } 2906509Ssam 29114123Ssam in_setpeeraddr(inp, nam) 29231976Skarels struct inpcb *inp; 29314123Ssam struct mbuf *nam; 29414123Ssam { 29532071Skarels register struct sockaddr_in *sin; 29614123Ssam 29714123Ssam nam->m_len = sizeof (*sin); 29814123Ssam sin = mtod(nam, struct sockaddr_in *); 29914123Ssam bzero((caddr_t)sin, sizeof (*sin)); 30014123Ssam sin->sin_family = AF_INET; 30137471Ssklower sin->sin_len = sizeof(*sin); 30214123Ssam sin->sin_port = inp->inp_fport; 30314123Ssam sin->sin_addr = inp->inp_faddr; 30414123Ssam } 30514123Ssam 3065161Swnj /* 30717357Skarels * Pass some notification to all connections of a protocol 30840692Skarels * associated with address dst. The local address and/or port numbers 30940692Skarels * may be specified to limit the search. The "usual action" will be 31040692Skarels * taken, depending on the ctlinput cmd. The caller must filter any 31140692Skarels * cmds that are uninteresting (e.g., no error in the map). 31240692Skarels * Call the protocol specific routine (if any) to report 31340692Skarels * any errors for each matching socket. 31440692Skarels * 31540692Skarels * Must be called at splnet. 3166583Ssam */ 31740692Skarels in_pcbnotify(head, dst, fport, laddr, lport, cmd, notify) 3186583Ssam struct inpcb *head; 31940692Skarels struct sockaddr *dst; 32040692Skarels u_short fport, lport; 32140692Skarels struct in_addr laddr; 32240692Skarels int cmd, (*notify)(); 3236583Ssam { 3246583Ssam register struct inpcb *inp, *oinp; 32540692Skarels struct in_addr faddr; 32640692Skarels int errno; 32740692Skarels int in_rtchange(); 32840692Skarels extern u_char inetctlerrmap[]; 3296583Ssam 33040692Skarels if ((unsigned)cmd > PRC_NCMDS || dst->sa_family != AF_INET) 33140692Skarels return; 33240692Skarels faddr = ((struct sockaddr_in *)dst)->sin_addr; 33340692Skarels if (faddr.s_addr == INADDR_ANY) 33440692Skarels return; 33540692Skarels 33640692Skarels /* 33740692Skarels * Redirects go to all references to the destination, 33840692Skarels * and use in_rtchange to invalidate the route cache. 33940692Skarels * Dead host indications: notify all references to the destination. 34040692Skarels * Otherwise, if we have knowledge of the local port and address, 34140692Skarels * deliver only to that socket. 34240692Skarels */ 34340692Skarels if (PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) { 34440692Skarels fport = 0; 34540692Skarels lport = 0; 34640692Skarels laddr.s_addr = 0; 34740692Skarels if (cmd != PRC_HOSTDEAD) 34840692Skarels notify = in_rtchange; 34940692Skarels } 35040692Skarels errno = inetctlerrmap[cmd]; 3516583Ssam for (inp = head->inp_next; inp != head;) { 35240692Skarels if (inp->inp_faddr.s_addr != faddr.s_addr || 35340692Skarels inp->inp_socket == 0 || 35440692Skarels (lport && inp->inp_lport != lport) || 35540692Skarels (laddr.s_addr && inp->inp_laddr.s_addr != laddr.s_addr) || 35640692Skarels (fport && inp->inp_fport != fport)) { 3576583Ssam inp = inp->inp_next; 3586583Ssam continue; 3596583Ssam } 3606583Ssam oinp = inp; 3616583Ssam inp = inp->inp_next; 36224807Skarels if (notify) 36344381Skarels (*notify)(oinp, errno); 3646583Ssam } 3656583Ssam } 3666583Ssam 36717357Skarels /* 36825508Skarels * Check for alternatives when higher level complains 36925508Skarels * about service problems. For now, invalidate cached 37025508Skarels * routing information. If the route was created dynamically 37125508Skarels * (by a redirect), time to try a default gateway again. 37225508Skarels */ 37325508Skarels in_losing(inp) 37425508Skarels struct inpcb *inp; 37525508Skarels { 37625508Skarels register struct rtentry *rt; 37752555Ssklower struct rt_addrinfo info; 37825508Skarels 37925508Skarels if ((rt = inp->inp_route.ro_rt)) { 38055543Ssklower inp->inp_route.ro_rt = 0; 38152555Ssklower bzero((caddr_t)&info, sizeof(info)); 38252555Ssklower info.rti_info[RTAX_DST] = 38352555Ssklower (struct sockaddr *)&inp->inp_route.ro_dst; 38452555Ssklower info.rti_info[RTAX_GATEWAY] = rt->rt_gateway; 38552555Ssklower info.rti_info[RTAX_NETMASK] = rt_mask(rt); 38652555Ssklower rt_missmsg(RTM_LOSING, &info, rt->rt_flags, 0); 38725508Skarels if (rt->rt_flags & RTF_DYNAMIC) 38837471Ssklower (void) rtrequest(RTM_DELETE, rt_key(rt), 38937471Ssklower rt->rt_gateway, rt_mask(rt), rt->rt_flags, 39037471Ssklower (struct rtentry **)0); 39155543Ssklower else 39225508Skarels /* 39325508Skarels * A new route can be allocated 39425508Skarels * the next time output is attempted. 39525508Skarels */ 39655543Ssklower rtfree(rt); 39725508Skarels } 39825508Skarels } 39925508Skarels 40025508Skarels /* 40117357Skarels * After a routing change, flush old routing 40217357Skarels * and allocate a (hopefully) better one. 40317357Skarels */ 40417357Skarels in_rtchange(inp) 40525508Skarels register struct inpcb *inp; 40617357Skarels { 40717357Skarels if (inp->inp_route.ro_rt) { 40817357Skarels rtfree(inp->inp_route.ro_rt); 40917357Skarels inp->inp_route.ro_rt = 0; 41017357Skarels /* 41117357Skarels * A new route can be allocated the next time 41217357Skarels * output is attempted. 41317357Skarels */ 41417357Skarels } 41517357Skarels } 41617357Skarels 4174907Swnj struct inpcb * 4186028Sroot in_pcblookup(head, faddr, fport, laddr, lport, flags) 4194905Swnj struct inpcb *head; 4204951Swnj struct in_addr faddr, laddr; 4214905Swnj u_short fport, lport; 4226028Sroot int flags; 4234905Swnj { 4245994Swnj register struct inpcb *inp, *match = 0; 4255994Swnj int matchwild = 3, wildcard; 4264905Swnj 4275161Swnj for (inp = head->inp_next; inp != head; inp = inp->inp_next) { 4285994Swnj if (inp->inp_lport != lport) 4295161Swnj continue; 4305994Swnj wildcard = 0; 43110141Ssam if (inp->inp_laddr.s_addr != INADDR_ANY) { 43210141Ssam if (laddr.s_addr == INADDR_ANY) 4336116Swnj wildcard++; 4346116Swnj else if (inp->inp_laddr.s_addr != laddr.s_addr) 4355994Swnj continue; 4365994Swnj } else { 43710141Ssam if (laddr.s_addr != INADDR_ANY) 4385994Swnj wildcard++; 4395994Swnj } 44010141Ssam if (inp->inp_faddr.s_addr != INADDR_ANY) { 44110141Ssam if (faddr.s_addr == INADDR_ANY) 4426116Swnj wildcard++; 4436116Swnj else if (inp->inp_faddr.s_addr != faddr.s_addr || 4446028Sroot inp->inp_fport != fport) 4455994Swnj continue; 4465994Swnj } else { 44710141Ssam if (faddr.s_addr != INADDR_ANY) 4485994Swnj wildcard++; 4495994Swnj } 4506028Sroot if (wildcard && (flags & INPLOOKUP_WILDCARD) == 0) 4515994Swnj continue; 4525994Swnj if (wildcard < matchwild) { 4535161Swnj match = inp; 4545994Swnj matchwild = wildcard; 4555994Swnj if (matchwild == 0) 4565994Swnj break; 4575161Swnj } 4585161Swnj } 4595161Swnj return (match); 4604905Swnj } 461