1 /* raw_cb.c 4.17 83/05/27 */ 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/errno.h" 9 10 #include "../net/if.h" 11 #include "../net/raw_cb.h" 12 #include "../netinet/in.h" 13 #include "../netpup/pup.h" 14 15 #include "../vax/mtpr.h" 16 17 /* 18 * Routines to manage the raw protocol control blocks. 19 * 20 * TODO: 21 * hash lookups by protocol family/protocol + address family 22 * take care of unique address problems per AF? 23 * redo address binding to allow wildcards 24 */ 25 26 /* 27 * Allocate a control block and a nominal amount 28 * of buffer space for the socket. 29 */ 30 raw_attach(so) 31 register struct socket *so; 32 { 33 struct mbuf *m; 34 register struct rawcb *rp; 35 36 m = m_getclr(M_DONTWAIT, MT_PCB); 37 if (m == 0) 38 return (ENOBUFS); 39 if (sbreserve(&so->so_snd, RAWSNDQ) == 0) 40 goto bad; 41 if (sbreserve(&so->so_rcv, RAWRCVQ) == 0) 42 goto bad2; 43 rp = mtod(m, struct rawcb *); 44 rp->rcb_socket = so; 45 insque(rp, &rawcb); 46 so->so_pcb = (caddr_t)rp; 47 rp->rcb_pcb = 0; 48 return (0); 49 bad2: 50 sbrelease(&so->so_snd); 51 bad: 52 (void) m_free(m); 53 return (ENOBUFS); 54 } 55 56 /* 57 * Detach the raw connection block and discard 58 * socket resources. 59 */ 60 raw_detach(rp) 61 register struct rawcb *rp; 62 { 63 struct socket *so = rp->rcb_socket; 64 65 so->so_pcb = 0; 66 sofree(so); 67 remque(rp); 68 m_freem(dtom(rp)); 69 } 70 71 /* 72 * Disconnect and possibly release resources. 73 */ 74 raw_disconnect(rp) 75 struct rawcb *rp; 76 { 77 78 rp->rcb_flags &= ~RAW_FADDR; 79 if (rp->rcb_socket->so_state & SS_NOFDREF) 80 raw_detach(rp); 81 } 82 83 raw_bind(so, nam) 84 register struct socket *so; 85 struct mbuf *nam; 86 { 87 struct sockaddr *addr = mtod(nam, struct sockaddr *); 88 register struct rawcb *rp; 89 90 if (ifnet == 0) 91 return (EADDRNOTAVAIL); 92 /* BEGIN DUBIOUS */ 93 /* 94 * Should we verify address not already in use? 95 * Some say yes, others no. 96 */ 97 switch (addr->sa_family) { 98 99 #ifdef INET 100 case AF_IMPLINK: 101 case AF_INET: { 102 if (((struct sockaddr_in *)addr)->sin_addr.s_addr && 103 if_ifwithaddr(addr) == 0) 104 return (EADDRNOTAVAIL); 105 break; 106 } 107 #endif 108 109 #ifdef PUP 110 /* 111 * Curious, we convert PUP address format to internet 112 * to allow us to verify we're asking for an Ethernet 113 * interface. This is wrong, but things are heavily 114 * oriented towards the internet addressing scheme, and 115 * converting internet to PUP would be very expensive. 116 */ 117 case AF_PUP: { 118 struct sockaddr_pup *spup = (struct sockaddr_pup *)addr; 119 struct sockaddr_in inpup; 120 121 bzero((caddr_t)&inpup, (unsigned)sizeof(inpup)); 122 inpup.sin_family = AF_INET; 123 inpup.sin_addr.s_net = spup->sp_net; 124 inpup.sin_addr.s_impno = spup->sp_host; 125 if (inpup.sin_addr.s_addr && 126 if_ifwithaddr((struct sockaddr *)&inpup) == 0) 127 return (EADDRNOTAVAIL); 128 break; 129 } 130 #endif 131 132 default: 133 return (EAFNOSUPPORT); 134 } 135 /* END DUBIOUS */ 136 rp = sotorawcb(so); 137 bcopy((caddr_t)addr, (caddr_t)&rp->rcb_laddr, sizeof (*addr)); 138 rp->rcb_flags |= RAW_LADDR; 139 return (0); 140 } 141 142 /* 143 * Associate a peer's address with a 144 * raw connection block. 145 */ 146 raw_connaddr(rp, nam) 147 struct rawcb *rp; 148 struct mbuf *nam; 149 { 150 struct sockaddr *addr = mtod(nam, struct sockaddr *); 151 152 bcopy((caddr_t)addr, (caddr_t)&rp->rcb_faddr, sizeof(*addr)); 153 rp->rcb_flags |= RAW_FADDR; 154 } 155