|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980, 1986 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that the above copyright notice and this paragraph are ! 7: * duplicated in all such forms and that any documentation, ! 8: * advertising materials, and other materials related to such ! 9: * distribution and use acknowledge that the software was developed ! 10: * by the University of California, Berkeley. The name of the ! 11: * University may not be used to endorse or promote products derived ! 12: * from this software without specific prior written permission. ! 13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 16: * ! 17: * @(#)raw_cb.c 7.6 (Berkeley) 6/27/88 ! 18: */ ! 19: ! 20: #include "param.h" ! 21: #include "systm.h" ! 22: #include "mbuf.h" ! 23: #include "socket.h" ! 24: #include "socketvar.h" ! 25: #include "domain.h" ! 26: #include "protosw.h" ! 27: #include "errno.h" ! 28: ! 29: #include "if.h" ! 30: #include "route.h" ! 31: #include "raw_cb.h" ! 32: #include "../netinet/in.h" ! 33: ! 34: #include "../machine/mtpr.h" ! 35: ! 36: /* ! 37: * Routines to manage the raw protocol control blocks. ! 38: * ! 39: * TODO: ! 40: * hash lookups by protocol family/protocol + address family ! 41: * take care of unique address problems per AF? ! 42: * redo address binding to allow wildcards ! 43: */ ! 44: ! 45: /* ! 46: * Allocate a control block and a nominal amount ! 47: * of buffer space for the socket. ! 48: */ ! 49: raw_attach(so, proto) ! 50: register struct socket *so; ! 51: int proto; ! 52: { ! 53: struct mbuf *m; ! 54: register struct rawcb *rp; ! 55: ! 56: m = m_getclr(M_DONTWAIT, MT_PCB); ! 57: if (m == 0) ! 58: return (ENOBUFS); ! 59: if (sbreserve(&so->so_snd, (u_long) RAWSNDQ) == 0) ! 60: goto bad; ! 61: if (sbreserve(&so->so_rcv, (u_long) RAWRCVQ) == 0) ! 62: goto bad2; ! 63: rp = mtod(m, struct rawcb *); ! 64: rp->rcb_socket = so; ! 65: so->so_pcb = (caddr_t)rp; ! 66: rp->rcb_pcb = 0; ! 67: rp->rcb_proto.sp_family = so->so_proto->pr_domain->dom_family; ! 68: rp->rcb_proto.sp_protocol = proto; ! 69: insque(rp, &rawcb); ! 70: return (0); ! 71: bad2: ! 72: sbrelease(&so->so_snd); ! 73: bad: ! 74: (void) m_free(m); ! 75: return (ENOBUFS); ! 76: } ! 77: ! 78: /* ! 79: * Detach the raw connection block and discard ! 80: * socket resources. ! 81: */ ! 82: raw_detach(rp) ! 83: register struct rawcb *rp; ! 84: { ! 85: struct socket *so = rp->rcb_socket; ! 86: ! 87: if (rp->rcb_route.ro_rt) ! 88: rtfree(rp->rcb_route.ro_rt); ! 89: so->so_pcb = 0; ! 90: sofree(so); ! 91: remque(rp); ! 92: if (rp->rcb_options) ! 93: m_freem(rp->rcb_options); ! 94: m_freem(dtom(rp)); ! 95: } ! 96: ! 97: /* ! 98: * Disconnect and possibly release resources. ! 99: */ ! 100: raw_disconnect(rp) ! 101: struct rawcb *rp; ! 102: { ! 103: ! 104: rp->rcb_flags &= ~RAW_FADDR; ! 105: if (rp->rcb_socket->so_state & SS_NOFDREF) ! 106: raw_detach(rp); ! 107: } ! 108: ! 109: raw_bind(so, nam) ! 110: register struct socket *so; ! 111: struct mbuf *nam; ! 112: { ! 113: struct sockaddr *addr = mtod(nam, struct sockaddr *); ! 114: register struct rawcb *rp; ! 115: ! 116: if (ifnet == 0) ! 117: return (EADDRNOTAVAIL); ! 118: /* BEGIN DUBIOUS */ ! 119: /* ! 120: * Should we verify address not already in use? ! 121: * Some say yes, others no. ! 122: */ ! 123: switch (addr->sa_family) { ! 124: ! 125: #ifdef INET ! 126: case AF_IMPLINK: ! 127: case AF_INET: { ! 128: if (((struct sockaddr_in *)addr)->sin_addr.s_addr && ! 129: ifa_ifwithaddr(addr) == 0) ! 130: return (EADDRNOTAVAIL); ! 131: break; ! 132: } ! 133: #endif ! 134: ! 135: default: ! 136: return (EAFNOSUPPORT); ! 137: } ! 138: /* END DUBIOUS */ ! 139: rp = sotorawcb(so); ! 140: bcopy((caddr_t)addr, (caddr_t)&rp->rcb_laddr, sizeof (*addr)); ! 141: rp->rcb_flags |= RAW_LADDR; ! 142: return (0); ! 143: } ! 144: ! 145: /* ! 146: * Associate a peer's address with a ! 147: * raw connection block. ! 148: */ ! 149: raw_connaddr(rp, nam) ! 150: struct rawcb *rp; ! 151: struct mbuf *nam; ! 152: { ! 153: struct sockaddr *addr = mtod(nam, struct sockaddr *); ! 154: ! 155: bcopy((caddr_t)addr, (caddr_t)&rp->rcb_faddr, sizeof(*addr)); ! 156: rp->rcb_flags |= RAW_FADDR; ! 157: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.