1*8975Sroot /* raw_cb.c 4.13 82/10/31 */ 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" 8*8975Sroot #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 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); 64*8975Sroot m_freem(dtom(rp)); 655635Sroot } 665635Sroot 675635Sroot /* 685635Sroot * Disconnect and possibly release resources. 695635Sroot */ 705635Sroot raw_disconnect(rp) 715635Sroot struct rawcb *rp; 725635Sroot { 73*8975Sroot 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 { 898394Swnj #include "../netinet/in.h" 908394Swnj #include "../netinet/in_systm.h" 918394Swnj /* BEGIN DUBIOUS */ 928394Swnj /* 938394Swnj * Should we verify address not already in use? 948394Swnj * Some say yes, others no. 958394Swnj */ 968394Swnj switch (addr->sa_family) { 978394Swnj 988394Swnj case AF_IMPLINK: 998394Swnj case AF_INET: 1008394Swnj if (((struct sockaddr_in *)addr)->sin_addr.s_addr && 1018394Swnj if_ifwithaddr(addr) == 0) 1028394Swnj return (EADDRNOTAVAIL); 1038394Swnj break; 1048394Swnj 1058394Swnj #ifdef PUP 1068394Swnj /* 1078394Swnj * Curious, we convert PUP address format to internet 1088394Swnj * to allow us to verify we're asking for an Ethernet 1098394Swnj * interface. This is wrong, but things are heavily 1108394Swnj * oriented towards the internet addressing scheme, and 1118394Swnj * converting internet to PUP would be very expensive. 1128394Swnj */ 1138394Swnj case AF_PUP: { 1148394Swnj #include "../netpup/pup.h" 1158394Swnj struct sockaddr_pup *spup = (struct sockaddr_pup *)addr; 1168394Swnj struct sockaddr_in inpup; 1178394Swnj 1188394Swnj bzero((caddr_t)&inpup, sizeof(inpup)); 1198394Swnj inpup.sin_family = AF_INET; 1208394Swnj inpup.sin_addr.s_net = spup->sp_net; 1218394Swnj inpup.sin_addr.s_impno = spup->sp_host; 1228394Swnj if (inpup.sin_addr.s_addr && 1238394Swnj if_ifwithaddr((struct sockaddr *)&inpup) == 0) 1248394Swnj return (EADDRNOTAVAIL); 1258394Swnj break; 1268394Swnj } 1278394Swnj #endif 1288394Swnj 1298394Swnj default: 1308394Swnj return (EAFNOSUPPORT); 1318394Swnj } 1328394Swnj } 1338394Swnj /* END DUBIOUS */ 1348394Swnj bcopy((caddr_t)addr, (caddr_t)&rp->rcb_laddr, sizeof (*addr)); 1358394Swnj rp->rcb_flags |= RAW_LADDR; 1368394Swnj return (0); 1378394Swnj } 1388394Swnj 1395635Sroot /* 1405635Sroot * Associate a peer's address with a 1415635Sroot * raw connection block. 1425635Sroot */ 1438394Swnj raw_connaddr(rp, nam) 1445635Sroot struct rawcb *rp; 1458394Swnj struct mbuf *nam; 1465635Sroot { 1478394Swnj struct sockaddr *addr = mtod(nam, struct sockaddr *); 1488394Swnj 1496509Ssam bcopy((caddr_t)addr, (caddr_t)&rp->rcb_faddr, sizeof(*addr)); 1506509Ssam rp->rcb_flags |= RAW_FADDR; 1515635Sroot } 152