1 /* raw_cb.c 4.2 82/02/01 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/mbuf.h" 6 #include "../h/socket.h" 7 #include "../h/socketvar.h" 8 #include "../h/mtpr.h" 9 #include "../net/in.h" 10 #include "../net/in_systm.h" 11 #include "../net/if.h" 12 #include "../net/raw_cb.h" 13 #include "/usr/include/errno.h" 14 15 /* 16 * Routines to manage the raw protocol control blocks. 17 * 18 * TODO: 19 * hash lookups by protocol family/protocol + address family 20 * take care of unique address problems per AF 21 */ 22 23 /* 24 * Allocate a control block and a nominal amount 25 * of buffer space for the socket. 26 */ 27 raw_attach(so, addr) 28 register struct socket *so; 29 struct sockaddr *addr; 30 { 31 struct mbuf *m; 32 register struct rawcb *rp; 33 struct ifnet *ifp = ifnet; 34 35 COUNT(RAW_ATTACH); 36 /* 37 * Should we verify address not already in use? 38 * Some say yes, others no. 39 */ 40 if (addr) switch (addr->sa_family) { 41 42 case AF_INET: { 43 register struct sockaddr_in *sin = (struct sockaddr_in *)addr; 44 45 if (ifnet && sin->sin_addr.s_addr == 0) 46 sin->sin_addr = ifnet->if_addr; 47 ifp = if_ifwithaddr(sin->sin_addr); 48 break; 49 } 50 51 default: 52 return (EAFNOSUPPORT); 53 } 54 if (ifp == 0) 55 return (EADDRNOTAVAIL); 56 m = m_getclr(M_DONTWAIT); 57 if (m == 0) 58 return (ENOBUFS); 59 if (sbreserve(&so->so_snd, RAWSNDQ) == 0) 60 goto bad; 61 if (sbreserve(&so->so_rcv, RAWRCVQ) == 0) 62 goto bad2; 63 rp = mtod(m, struct rawcb *); 64 rp->rcb_socket = so; 65 insque(rp, &rawcb); 66 so->so_pcb = (caddr_t)rp; 67 rp->rcb_pcb = 0; 68 69 if (addr) 70 bcopy(addr, &so->so_addr, sizeof(*addr)); 71 return (0); 72 bad2: 73 sbrelease(&so->so_snd); 74 bad: 75 (void) m_free(m); 76 return (ENOBUFS); 77 } 78 79 /* 80 * Detach the raw connection block and discard 81 * socket resources. 82 */ 83 raw_detach(rp) 84 register struct rawcb *rp; 85 { 86 struct socket *so = rp->rcb_socket; 87 88 COUNT(RAW_DETACH); 89 so->so_pcb = 0; 90 sofree(so); 91 remque(rp); 92 (void) m_freem(dtom(rp)); 93 } 94 95 /* 96 * Disconnect and possibly release resources. 97 */ 98 raw_disconnect(rp) 99 struct rawcb *rp; 100 { 101 COUNT(RAW_DISCONNECT); 102 rp->rcb_flags &= ~RAW_ADDR; 103 if (rp->rcb_socket->so_state & SS_USERGONE) 104 raw_detach(rp); 105 } 106 107 /* 108 * Associate a peer's address with a 109 * raw connection block. 110 */ 111 raw_connaddr(rp, addr) 112 struct rawcb *rp; 113 struct sockaddr *addr; 114 { 115 COUNT(RAW_CONNADDR); 116 bcopy(addr, &rp->rcb_addr, sizeof(struct sockaddr)); 117 rp->rcb_flags |= RAW_ADDR; 118 } 119