1*10890Ssam /* raw_cb.c 4.16 83/02/10 */ 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*10890Ssam #include "../h/errno.h" 9*10890Ssam 105635Sroot #include "../net/if.h" 115635Sroot #include "../net/raw_cb.h" 125635Sroot 13*10890Ssam #include "../vax/mtpr.h" 14*10890Ssam 155635Sroot /* 165635Sroot * Routines to manage the raw protocol control blocks. 175635Sroot * 185635Sroot * TODO: 195635Sroot * hash lookups by protocol family/protocol + address family 206339Ssam * take care of unique address problems per AF? 216045Swnj * redo address binding to allow wildcards 225635Sroot */ 235635Sroot 245635Sroot /* 255635Sroot * Allocate a control block and a nominal amount 265635Sroot * of buffer space for the socket. 275635Sroot */ 288394Swnj raw_attach(so) 295635Sroot register struct socket *so; 305635Sroot { 315635Sroot struct mbuf *m; 325635Sroot register struct rawcb *rp; 335635Sroot 349638Ssam m = m_getclr(M_DONTWAIT, MT_PCB); 355635Sroot if (m == 0) 365635Sroot return (ENOBUFS); 375635Sroot if (sbreserve(&so->so_snd, RAWSNDQ) == 0) 385635Sroot goto bad; 395635Sroot if (sbreserve(&so->so_rcv, RAWRCVQ) == 0) 405635Sroot goto bad2; 415635Sroot rp = mtod(m, struct rawcb *); 425635Sroot rp->rcb_socket = so; 435635Sroot insque(rp, &rawcb); 445635Sroot so->so_pcb = (caddr_t)rp; 455635Sroot rp->rcb_pcb = 0; 465635Sroot return (0); 475635Sroot bad2: 485635Sroot sbrelease(&so->so_snd); 495635Sroot bad: 505635Sroot (void) m_free(m); 515635Sroot return (ENOBUFS); 525635Sroot } 535635Sroot 545635Sroot /* 555635Sroot * Detach the raw connection block and discard 565635Sroot * socket resources. 575635Sroot */ 585635Sroot raw_detach(rp) 595635Sroot register struct rawcb *rp; 605635Sroot { 615635Sroot struct socket *so = rp->rcb_socket; 625635Sroot 635635Sroot so->so_pcb = 0; 645635Sroot sofree(so); 655635Sroot remque(rp); 668975Sroot m_freem(dtom(rp)); 675635Sroot } 685635Sroot 695635Sroot /* 705635Sroot * Disconnect and possibly release resources. 715635Sroot */ 725635Sroot raw_disconnect(rp) 735635Sroot struct rawcb *rp; 745635Sroot { 758975Sroot 766509Ssam rp->rcb_flags &= ~RAW_FADDR; 777517Sroot if (rp->rcb_socket->so_state & SS_NOFDREF) 785635Sroot raw_detach(rp); 795635Sroot } 805635Sroot 818394Swnj raw_bind(so, nam) 828394Swnj register struct socket *so; 838394Swnj struct mbuf *nam; 848394Swnj { 858394Swnj struct sockaddr *addr = mtod(nam, struct sockaddr *); 868394Swnj register struct rawcb *rp; 878394Swnj 888394Swnj if (ifnet == 0) 898394Swnj return (EADDRNOTAVAIL); 908394Swnj { 919184Ssam #include "../h/domain.h" 928394Swnj #include "../netinet/in.h" 938394Swnj #include "../netinet/in_systm.h" 948394Swnj /* BEGIN DUBIOUS */ 958394Swnj /* 968394Swnj * Should we verify address not already in use? 978394Swnj * Some say yes, others no. 988394Swnj */ 998394Swnj switch (addr->sa_family) { 1008394Swnj 1018394Swnj case AF_IMPLINK: 1028394Swnj case AF_INET: 1038394Swnj if (((struct sockaddr_in *)addr)->sin_addr.s_addr && 1048394Swnj if_ifwithaddr(addr) == 0) 1058394Swnj return (EADDRNOTAVAIL); 1068394Swnj break; 1078394Swnj 1088394Swnj #ifdef PUP 1098394Swnj /* 1108394Swnj * Curious, we convert PUP address format to internet 1118394Swnj * to allow us to verify we're asking for an Ethernet 1128394Swnj * interface. This is wrong, but things are heavily 1138394Swnj * oriented towards the internet addressing scheme, and 1148394Swnj * converting internet to PUP would be very expensive. 1158394Swnj */ 1168394Swnj case AF_PUP: { 1178394Swnj #include "../netpup/pup.h" 1188394Swnj struct sockaddr_pup *spup = (struct sockaddr_pup *)addr; 1198394Swnj struct sockaddr_in inpup; 1208394Swnj 1219184Ssam bzero((caddr_t)&inpup, (unsigned)sizeof(inpup)); 1228394Swnj inpup.sin_family = AF_INET; 1238394Swnj inpup.sin_addr.s_net = spup->sp_net; 1248394Swnj inpup.sin_addr.s_impno = spup->sp_host; 1258394Swnj if (inpup.sin_addr.s_addr && 1268394Swnj if_ifwithaddr((struct sockaddr *)&inpup) == 0) 1278394Swnj return (EADDRNOTAVAIL); 1288394Swnj break; 1298394Swnj } 1308394Swnj #endif 1318394Swnj 1328394Swnj default: 1338394Swnj return (EAFNOSUPPORT); 1348394Swnj } 1358394Swnj } 1368394Swnj /* END DUBIOUS */ 1379184Ssam rp = sotorawcb(so); 1388394Swnj bcopy((caddr_t)addr, (caddr_t)&rp->rcb_laddr, sizeof (*addr)); 1398394Swnj rp->rcb_flags |= RAW_LADDR; 1408394Swnj return (0); 1418394Swnj } 1428394Swnj 1435635Sroot /* 1445635Sroot * Associate a peer's address with a 1455635Sroot * raw connection block. 1465635Sroot */ 1478394Swnj raw_connaddr(rp, nam) 1485635Sroot struct rawcb *rp; 1498394Swnj struct mbuf *nam; 1505635Sroot { 1518394Swnj struct sockaddr *addr = mtod(nam, struct sockaddr *); 1528394Swnj 1536509Ssam bcopy((caddr_t)addr, (caddr_t)&rp->rcb_faddr, sizeof(*addr)); 1546509Ssam rp->rcb_flags |= RAW_FADDR; 1555635Sroot } 156