1*8394Swnj /* raw_cb.c 4.12 82/10/09 */ 25635Sroot 35635Sroot #include "../h/param.h" 45635Sroot #include "../h/systm.h" 55635Sroot #include "../h/mbuf.h" 65635Sroot #include "../h/socket.h" 75635Sroot #include "../h/socketvar.h" 85635Sroot #include "../h/mtpr.h" 95635Sroot #include "../net/if.h" 105635Sroot #include "../net/raw_cb.h" 117298Ssam #include <errno.h> 125635Sroot 135635Sroot /* 145635Sroot * Routines to manage the raw protocol control blocks. 155635Sroot * 165635Sroot * TODO: 175635Sroot * hash lookups by protocol family/protocol + address family 186339Ssam * take care of unique address problems per AF? 196045Swnj * redo address binding to allow wildcards 205635Sroot */ 215635Sroot 225635Sroot /* 235635Sroot * Allocate a control block and a nominal amount 245635Sroot * of buffer space for the socket. 255635Sroot */ 26*8394Swnj raw_attach(so) 275635Sroot register struct socket *so; 285635Sroot { 295635Sroot struct mbuf *m; 305635Sroot register struct rawcb *rp; 315635Sroot 325635Sroot m = m_getclr(M_DONTWAIT); 335635Sroot if (m == 0) 345635Sroot return (ENOBUFS); 355635Sroot if (sbreserve(&so->so_snd, RAWSNDQ) == 0) 365635Sroot goto bad; 375635Sroot if (sbreserve(&so->so_rcv, RAWRCVQ) == 0) 385635Sroot goto bad2; 395635Sroot rp = mtod(m, struct rawcb *); 405635Sroot rp->rcb_socket = so; 415635Sroot insque(rp, &rawcb); 425635Sroot so->so_pcb = (caddr_t)rp; 435635Sroot rp->rcb_pcb = 0; 445635Sroot return (0); 455635Sroot bad2: 465635Sroot sbrelease(&so->so_snd); 475635Sroot bad: 485635Sroot (void) m_free(m); 495635Sroot return (ENOBUFS); 505635Sroot } 515635Sroot 525635Sroot /* 535635Sroot * Detach the raw connection block and discard 545635Sroot * socket resources. 555635Sroot */ 565635Sroot raw_detach(rp) 575635Sroot register struct rawcb *rp; 585635Sroot { 595635Sroot struct socket *so = rp->rcb_socket; 605635Sroot 615635Sroot so->so_pcb = 0; 625635Sroot sofree(so); 635635Sroot remque(rp); 646339Ssam (void) m_freem(dtom(rp)); 655635Sroot } 665635Sroot 675635Sroot /* 685635Sroot * Disconnect and possibly release resources. 695635Sroot */ 705635Sroot raw_disconnect(rp) 715635Sroot struct rawcb *rp; 725635Sroot { 736509Ssam rp->rcb_flags &= ~RAW_FADDR; 747517Sroot if (rp->rcb_socket->so_state & SS_NOFDREF) 755635Sroot raw_detach(rp); 765635Sroot } 775635Sroot 78*8394Swnj raw_bind(so, nam) 79*8394Swnj register struct socket *so; 80*8394Swnj struct mbuf *nam; 81*8394Swnj { 82*8394Swnj struct sockaddr *addr = mtod(nam, struct sockaddr *); 83*8394Swnj struct mbuf *m; 84*8394Swnj register struct rawcb *rp; 85*8394Swnj 86*8394Swnj if (ifnet == 0) 87*8394Swnj return (EADDRNOTAVAIL); 88*8394Swnj { 89*8394Swnj #include "../netinet/in.h" 90*8394Swnj #include "../netinet/in_systm.h" 91*8394Swnj /* BEGIN DUBIOUS */ 92*8394Swnj /* 93*8394Swnj * Should we verify address not already in use? 94*8394Swnj * Some say yes, others no. 95*8394Swnj */ 96*8394Swnj switch (addr->sa_family) { 97*8394Swnj 98*8394Swnj case AF_IMPLINK: 99*8394Swnj case AF_INET: 100*8394Swnj if (((struct sockaddr_in *)addr)->sin_addr.s_addr && 101*8394Swnj if_ifwithaddr(addr) == 0) 102*8394Swnj return (EADDRNOTAVAIL); 103*8394Swnj break; 104*8394Swnj 105*8394Swnj #ifdef PUP 106*8394Swnj /* 107*8394Swnj * Curious, we convert PUP address format to internet 108*8394Swnj * to allow us to verify we're asking for an Ethernet 109*8394Swnj * interface. This is wrong, but things are heavily 110*8394Swnj * oriented towards the internet addressing scheme, and 111*8394Swnj * converting internet to PUP would be very expensive. 112*8394Swnj */ 113*8394Swnj case AF_PUP: { 114*8394Swnj #include "../netpup/pup.h" 115*8394Swnj struct sockaddr_pup *spup = (struct sockaddr_pup *)addr; 116*8394Swnj struct sockaddr_in inpup; 117*8394Swnj 118*8394Swnj bzero((caddr_t)&inpup, sizeof(inpup)); 119*8394Swnj inpup.sin_family = AF_INET; 120*8394Swnj inpup.sin_addr.s_net = spup->sp_net; 121*8394Swnj inpup.sin_addr.s_impno = spup->sp_host; 122*8394Swnj if (inpup.sin_addr.s_addr && 123*8394Swnj if_ifwithaddr((struct sockaddr *)&inpup) == 0) 124*8394Swnj return (EADDRNOTAVAIL); 125*8394Swnj break; 126*8394Swnj } 127*8394Swnj #endif 128*8394Swnj 129*8394Swnj default: 130*8394Swnj return (EAFNOSUPPORT); 131*8394Swnj } 132*8394Swnj } 133*8394Swnj /* END DUBIOUS */ 134*8394Swnj bcopy((caddr_t)addr, (caddr_t)&rp->rcb_laddr, sizeof (*addr)); 135*8394Swnj rp->rcb_flags |= RAW_LADDR; 136*8394Swnj return (0); 137*8394Swnj } 138*8394Swnj 1395635Sroot /* 1405635Sroot * Associate a peer's address with a 1415635Sroot * raw connection block. 1425635Sroot */ 143*8394Swnj raw_connaddr(rp, nam) 1445635Sroot struct rawcb *rp; 145*8394Swnj struct mbuf *nam; 1465635Sroot { 147*8394Swnj struct sockaddr *addr = mtod(nam, struct sockaddr *); 148*8394Swnj 1496509Ssam bcopy((caddr_t)addr, (caddr_t)&rp->rcb_faddr, sizeof(*addr)); 1506509Ssam rp->rcb_flags |= RAW_FADDR; 1515635Sroot } 152