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