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