1: /* 2: * Copyright (c) 1980, 1986 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: * 6: * @(#)raw_cb.c 7.1 (Berkeley) 6/4/86 7: */ 8: 9: #include "param.h" 10: #include "systm.h" 11: #include "mbuf.h" 12: #include "socket.h" 13: #include "socketvar.h" 14: #include "domain.h" 15: #include "protosw.h" 16: #include "errno.h" 17: 18: #include "if.h" 19: #include "route.h" 20: #include "raw_cb.h" 21: #include "../netinet/in.h" 22: 23: #include "../vax/mtpr.h" 24: 25: /* 26: * Routines to manage the raw protocol control blocks. 27: * 28: * TODO: 29: * hash lookups by protocol family/protocol + address family 30: * take care of unique address problems per AF? 31: * redo address binding to allow wildcards 32: */ 33: 34: /* 35: * Allocate a control block and a nominal amount 36: * of buffer space for the socket. 37: */ 38: raw_attach(so, proto) 39: register struct socket *so; 40: int proto; 41: { 42: struct mbuf *m; 43: register struct rawcb *rp; 44: 45: m = m_getclr(M_DONTWAIT, MT_PCB); 46: if (m == 0) 47: return (ENOBUFS); 48: if (sbreserve(&so->so_snd, RAWSNDQ) == 0) 49: goto bad; 50: if (sbreserve(&so->so_rcv, RAWRCVQ) == 0) 51: goto bad2; 52: rp = mtod(m, struct rawcb *); 53: rp->rcb_socket = so; 54: so->so_pcb = (caddr_t)rp; 55: rp->rcb_pcb = 0; 56: rp->rcb_proto.sp_family = so->so_proto->pr_domain->dom_family; 57: rp->rcb_proto.sp_protocol = proto; 58: insque(rp, &rawcb); 59: return (0); 60: bad2: 61: sbrelease(&so->so_snd); 62: bad: 63: (void) m_free(m); 64: return (ENOBUFS); 65: } 66: 67: /* 68: * Detach the raw connection block and discard 69: * socket resources. 70: */ 71: raw_detach(rp) 72: register struct rawcb *rp; 73: { 74: struct socket *so = rp->rcb_socket; 75: 76: if (rp->rcb_route.ro_rt) 77: rtfree(rp->rcb_route.ro_rt); 78: so->so_pcb = 0; 79: sofree(so); 80: remque(rp); 81: if (rp->rcb_options) 82: m_freem(dtom(rp->rcb_options)); 83: m_freem(dtom(rp)); 84: } 85: 86: /* 87: * Disconnect and possibly release resources. 88: */ 89: raw_disconnect(rp) 90: struct rawcb *rp; 91: { 92: 93: rp->rcb_flags &= ~RAW_FADDR; 94: if (rp->rcb_socket->so_state & SS_NOFDREF) 95: raw_detach(rp); 96: } 97: 98: raw_bind(so, nam) 99: register struct socket *so; 100: struct mbuf *nam; 101: { 102: struct sockaddr *addr = mtod(nam, struct sockaddr *); 103: register struct rawcb *rp; 104: 105: if (ifnet == 0) 106: return (EADDRNOTAVAIL); 107: /* BEGIN DUBIOUS */ 108: /* 109: * Should we verify address not already in use? 110: * Some say yes, others no. 111: */ 112: switch (addr->sa_family) { 113: 114: #ifdef INET 115: case AF_IMPLINK: 116: case AF_INET: { 117: if (((struct sockaddr_in *)addr)->sin_addr.s_addr && 118: ifa_ifwithaddr(addr) == 0) 119: return (EADDRNOTAVAIL); 120: break; 121: } 122: #endif 123: 124: default: 125: return (EAFNOSUPPORT); 126: } 127: /* END DUBIOUS */ 128: rp = sotorawcb(so); 129: bcopy((caddr_t)addr, (caddr_t)&rp->rcb_laddr, sizeof (*addr)); 130: rp->rcb_flags |= RAW_LADDR; 131: return (0); 132: } 133: 134: /* 135: * Associate a peer's address with a 136: * raw connection block. 137: */ 138: raw_connaddr(rp, nam) 139: struct rawcb *rp; 140: struct mbuf *nam; 141: { 142: struct sockaddr *addr = mtod(nam, struct sockaddr *); 143: 144: bcopy((caddr_t)addr, (caddr_t)&rp->rcb_faddr, sizeof(*addr)); 145: rp->rcb_flags |= RAW_FADDR; 146: }