|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.