1*9638Ssam /* raw_cb.c 4.15 82/12/14 */ 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" 88975Sroot #include "../vax/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 */ 268394Swnj raw_attach(so) 275635Sroot register struct socket *so; 285635Sroot { 295635Sroot struct mbuf *m; 305635Sroot register struct rawcb *rp; 315635Sroot 32*9638Ssam m = m_getclr(M_DONTWAIT, MT_PCB); 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); 648975Sroot m_freem(dtom(rp)); 655635Sroot } 665635Sroot 675635Sroot /* 685635Sroot * Disconnect and possibly release resources. 695635Sroot */ 705635Sroot raw_disconnect(rp) 715635Sroot struct rawcb *rp; 725635Sroot { 738975Sroot 746509Ssam rp->rcb_flags &= ~RAW_FADDR; 757517Sroot if (rp->rcb_socket->so_state & SS_NOFDREF) 765635Sroot raw_detach(rp); 775635Sroot } 785635Sroot 798394Swnj raw_bind(so, nam) 808394Swnj register struct socket *so; 818394Swnj struct mbuf *nam; 828394Swnj { 838394Swnj struct sockaddr *addr = mtod(nam, struct sockaddr *); 848394Swnj register struct rawcb *rp; 858394Swnj 868394Swnj if (ifnet == 0) 878394Swnj return (EADDRNOTAVAIL); 888394Swnj { 899184Ssam #include "../h/domain.h" 908394Swnj #include "../netinet/in.h" 918394Swnj #include "../netinet/in_systm.h" 928394Swnj /* BEGIN DUBIOUS */ 938394Swnj /* 948394Swnj * Should we verify address not already in use? 958394Swnj * Some say yes, others no. 968394Swnj */ 978394Swnj switch (addr->sa_family) { 988394Swnj 998394Swnj case AF_IMPLINK: 1008394Swnj case AF_INET: 1018394Swnj if (((struct sockaddr_in *)addr)->sin_addr.s_addr && 1028394Swnj if_ifwithaddr(addr) == 0) 1038394Swnj return (EADDRNOTAVAIL); 1048394Swnj break; 1058394Swnj 1068394Swnj #ifdef PUP 1078394Swnj /* 1088394Swnj * Curious, we convert PUP address format to internet 1098394Swnj * to allow us to verify we're asking for an Ethernet 1108394Swnj * interface. This is wrong, but things are heavily 1118394Swnj * oriented towards the internet addressing scheme, and 1128394Swnj * converting internet to PUP would be very expensive. 1138394Swnj */ 1148394Swnj case AF_PUP: { 1158394Swnj #include "../netpup/pup.h" 1168394Swnj struct sockaddr_pup *spup = (struct sockaddr_pup *)addr; 1178394Swnj struct sockaddr_in inpup; 1188394Swnj 1199184Ssam bzero((caddr_t)&inpup, (unsigned)sizeof(inpup)); 1208394Swnj inpup.sin_family = AF_INET; 1218394Swnj inpup.sin_addr.s_net = spup->sp_net; 1228394Swnj inpup.sin_addr.s_impno = spup->sp_host; 1238394Swnj if (inpup.sin_addr.s_addr && 1248394Swnj if_ifwithaddr((struct sockaddr *)&inpup) == 0) 1258394Swnj return (EADDRNOTAVAIL); 1268394Swnj break; 1278394Swnj } 1288394Swnj #endif 1298394Swnj 1308394Swnj default: 1318394Swnj return (EAFNOSUPPORT); 1328394Swnj } 1338394Swnj } 1348394Swnj /* END DUBIOUS */ 1359184Ssam rp = sotorawcb(so); 1368394Swnj bcopy((caddr_t)addr, (caddr_t)&rp->rcb_laddr, sizeof (*addr)); 1378394Swnj rp->rcb_flags |= RAW_LADDR; 1388394Swnj return (0); 1398394Swnj } 1408394Swnj 1415635Sroot /* 1425635Sroot * Associate a peer's address with a 1435635Sroot * raw connection block. 1445635Sroot */ 1458394Swnj raw_connaddr(rp, nam) 1465635Sroot struct rawcb *rp; 1478394Swnj struct mbuf *nam; 1485635Sroot { 1498394Swnj struct sockaddr *addr = mtod(nam, struct sockaddr *); 1508394Swnj 1516509Ssam bcopy((caddr_t)addr, (caddr_t)&rp->rcb_faddr, sizeof(*addr)); 1526509Ssam rp->rcb_flags |= RAW_FADDR; 1535635Sroot } 154