1*4951Swnj /* in_pcb.c 4.4 81/11/20 */ 24905Swnj 34905Swnj #include "../h/param.h" 4*4951Swnj #include "../h/systm.h" 5*4951Swnj #include "../h/dir.h" 6*4951Swnj #include "../h/user.h" 74905Swnj #include "../h/mbuf.h" 84905Swnj #include "../h/socket.h" 94905Swnj #include "../h/socketvar.h" 104905Swnj #include "../net/inet.h" 114905Swnj #include "../net/inet_systm.h" 12*4951Swnj #include "../net/if.h" 134907Swnj #include "../net/inet_pcb.h" 144905Swnj 15*4951Swnj /* 16*4951Swnj * Allocate a protocol control block, space 17*4951Swnj * for send and receive data, and local host information. 18*4951Swnj * Return error. If no error make socket point at pcb. 19*4951Swnj */ 20*4951Swnj in_pcballoc(so, head, sndcc, rcvcc, sin) 21*4951Swnj struct socket *so; 22*4951Swnj struct inpcb *head; 23*4951Swnj int sndcc, rcvcc; 24*4951Swnj struct sockaddr_in *sin; 254905Swnj { 264905Swnj struct mbuf *m; 27*4951Swnj register struct inpcb *inp; 28*4951Swnj struct ifnet *ifp; 29*4951Swnj u_long lport; 304905Swnj 31*4951Swnj if (sin) { 32*4951Swnj if (sin->sin_family != AF_INET) 33*4951Swnj return (EAFNOSUPPORT); 34*4951Swnj ifp = if_ifwithaddr(sin->sin_addr); 35*4951Swnj if (ifp == 0) 36*4951Swnj return (EADDRNOTAVAIL); 37*4951Swnj lport = sin->sin_port; 38*4951Swnj if (lport) { 39*4951Swnj inp = head->inp_next; 40*4951Swnj for (; inp != head; inp = inp->inp_next) 41*4951Swnj if (inp->inp_laddr.s_addr == 42*4951Swnj sin->sin_addr.s_addr && 43*4951Swnj inp->inp_lport == lport && 44*4951Swnj inp->inp_faddr.s_addr == 0) 45*4951Swnj return (EADDRINUSE); 46*4951Swnj } 47*4951Swnj } else { 48*4951Swnj ifp = if_ifwithaddr(ifnet->if_addr); 49*4951Swnj lport = 0; 50*4951Swnj } 514905Swnj m = m_getclr(M_WAIT); 52*4951Swnj if (m == 0) 53*4951Swnj return (0); 54*4951Swnj if (sbreserve(&so->so_snd, sndcc) == 0) 55*4951Swnj goto bad; 56*4951Swnj if (sbreserve(&so->so_rcv, rcvcc) == 0) 57*4951Swnj goto bad2; 58*4951Swnj inp = mtod(m, struct inpcb *); 59*4951Swnj inp->inp_laddr = ifp->if_addr; 60*4951Swnj if (lport) 61*4951Swnj goto gotport; 62*4951Swnj again: 63*4951Swnj if (head->inp_lport++ < 1024) 64*4951Swnj head->inp_lport = 1024; 65*4951Swnj for (inp = head->inp_next; inp != head; inp = inp->inp_next) 66*4951Swnj if (inp->inp_lport == head->inp_lport) 67*4951Swnj goto again; 68*4951Swnj lport = head->inp_lport; 69*4951Swnj gotport: 70*4951Swnj inp->inp_lport = lport; 71*4951Swnj insque(head, inp); 72*4951Swnj so->so_pcb = (caddr_t)inp; 73*4951Swnj return (0); 74*4951Swnj bad2: 75*4951Swnj sbrelease(&so->so_snd); 76*4951Swnj bad: 77*4951Swnj m_free(m); 78*4951Swnj return (ENOBUFS); 794905Swnj } 804905Swnj 81*4951Swnj in_pcbsetpeer(inp, sin) 82*4951Swnj struct inpcb *inp; 83*4951Swnj struct sockaddr_in *sin; 844923Swnj { 854923Swnj 86*4951Swnj if (sin->sin_family != AF_INET) 87*4951Swnj return (EAFNOSUPPORT); 88*4951Swnj if (sin->sin_addr.s_addr == 0 || sin->sin_port == 0) 89*4951Swnj return (EADDRNOTAVAIL); 90*4951Swnj /* should check not already in use... */ 91*4951Swnj inp->inp_faddr = sin->sin_addr; 92*4951Swnj inp->inp_fport = sin->sin_port; 934923Swnj return (0); 944923Swnj } 954923Swnj 964905Swnj in_pcbfree(inp) 974905Swnj struct inpcb *inp; 984905Swnj { 994905Swnj struct socket *so = inp->inp_socket; 1004905Swnj 101*4951Swnj if (so->so_state & SS_USERGONE) 1024905Swnj sofree(so); 1034905Swnj else 1044905Swnj so->so_pcb = 0; 1054907Swnj (void) m_free(dtom(inp)); 1064905Swnj } 1074905Swnj 1084907Swnj struct inpcb * 109*4951Swnj in_pcblookup(head, faddr, fport, laddr, lport) 1104905Swnj struct inpcb *head; 111*4951Swnj struct in_addr faddr, laddr; 1124905Swnj u_short fport, lport; 1134905Swnj { 1144905Swnj register struct inpcb *inp; 1154905Swnj 1164907Swnj for (inp = head->inp_next; inp != head; inp = inp->inp_next) 117*4951Swnj if (inp->inp_faddr.s_addr == faddr.s_addr && 1184905Swnj inp->inp_fport == fport && 119*4951Swnj inp->inp_laddr.s_addr == laddr.s_addr && 1204905Swnj inp->inp_lport == lport) 1214905Swnj return (inp); 1224907Swnj for (inp = head->inp_next; inp != head; inp = inp->inp_next) 123*4951Swnj if ((inp->inp_faddr.s_addr == faddr.s_addr || 124*4951Swnj inp->inp_faddr.s_addr == 0) && 1254905Swnj (inp->inp_fport == fport || inp->inp_fport == 0) && 126*4951Swnj inp->inp_laddr.s_addr == laddr.s_addr && 1274905Swnj (inp->inp_lport == lport || inp->inp_lport == 0)) 1284905Swnj return (inp); 1294905Swnj return (0); 1304905Swnj } 131