|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ ! 26: /* ! 27: * Copyright (c) 1980, 1986, 1993 ! 28: * The Regents of the University of California. All rights reserved. ! 29: * ! 30: * Redistribution and use in source and binary forms, with or without ! 31: * modification, are permitted provided that the following conditions ! 32: * are met: ! 33: * 1. Redistributions of source code must retain the above copyright ! 34: * notice, this list of conditions and the following disclaimer. ! 35: * 2. Redistributions in binary form must reproduce the above copyright ! 36: * notice, this list of conditions and the following disclaimer in the ! 37: * documentation and/or other materials provided with the distribution. ! 38: * 3. All advertising materials mentioning features or use of this software ! 39: * must display the following acknowledgement: ! 40: * This product includes software developed by the University of ! 41: * California, Berkeley and its contributors. ! 42: * 4. Neither the name of the University nor the names of its contributors ! 43: * may be used to endorse or promote products derived from this software ! 44: * without specific prior written permission. ! 45: * ! 46: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 47: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 48: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 49: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 50: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 51: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 52: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 53: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 54: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 55: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 56: * SUCH DAMAGE. ! 57: * ! 58: * @(#)raw_usrreq.c 8.1 (Berkeley) 6/10/93 ! 59: */ ! 60: ! 61: #include <sys/param.h> ! 62: #include <sys/mbuf.h> ! 63: #include <sys/domain.h> ! 64: #include <sys/protosw.h> ! 65: #include <sys/socket.h> ! 66: #include <sys/socketvar.h> ! 67: #include <sys/errno.h> ! 68: ! 69: #include <net/if.h> ! 70: #include <net/route.h> ! 71: #include <net/netisr.h> ! 72: #include <net/raw_cb.h> ! 73: ! 74: struct rawcb rawcb; /* head of list */ ! 75: ! 76: /* ! 77: * Initialize raw connection block q. ! 78: */ ! 79: void ! 80: raw_init() ! 81: { ! 82: ! 83: rawcb.rcb_next = rawcb.rcb_prev = &rawcb; ! 84: } ! 85: ! 86: ! 87: /* ! 88: * Raw protocol input routine. Find the socket ! 89: * associated with the packet(s) and move them over. If ! 90: * nothing exists for this packet, drop it. ! 91: */ ! 92: /* ! 93: * Raw protocol interface. ! 94: */ ! 95: void ! 96: raw_input(m0, proto, src, dst) ! 97: struct mbuf *m0; ! 98: register struct sockproto *proto; ! 99: struct sockaddr *src, *dst; ! 100: { ! 101: register struct rawcb *rp; ! 102: register struct mbuf *m = m0; ! 103: register int sockets = 0; ! 104: struct socket *last; ! 105: extern int bcmp(const void *, const void *, size_t); ! 106: ! 107: last = 0; ! 108: for (rp = rawcb.rcb_next; rp != &rawcb; rp = rp->rcb_next) { ! 109: if (rp->rcb_proto.sp_family != proto->sp_family) ! 110: continue; ! 111: if (rp->rcb_proto.sp_protocol && ! 112: rp->rcb_proto.sp_protocol != proto->sp_protocol) ! 113: continue; ! 114: /* ! 115: * We assume the lower level routines have ! 116: * placed the address in a canonical format ! 117: * suitable for a structure comparison. ! 118: * ! 119: * Note that if the lengths are not the same ! 120: * the comparison will fail at the first byte. ! 121: */ ! 122: #define equal(a1, a2) \ ! 123: (bcmp((caddr_t)(a1), (caddr_t)(a2), a1->sa_len) == 0) ! 124: if (rp->rcb_laddr && !equal(rp->rcb_laddr, dst)) ! 125: continue; ! 126: if (rp->rcb_faddr && !equal(rp->rcb_faddr, src)) ! 127: continue; ! 128: if (last) { ! 129: struct mbuf *n; ! 130: if ((n = m_copy(m, 0, (int)M_COPYALL))) { ! 131: if (sbappendaddr(&last->so_rcv, src, ! 132: n, (struct mbuf *)0) == 0) ! 133: /* should notify about lost packet */ ! 134: m_freem(n); ! 135: else { ! 136: sorwakeup(last); ! 137: sockets++; ! 138: } ! 139: } ! 140: } ! 141: last = rp->rcb_socket; ! 142: } ! 143: if (last) { ! 144: if (sbappendaddr(&last->so_rcv, src, ! 145: m, (struct mbuf *)0) == 0) ! 146: m_freem(m); ! 147: else { ! 148: sorwakeup(last); ! 149: sockets++; ! 150: } ! 151: } else ! 152: m_freem(m); ! 153: } ! 154: ! 155: /*ARGSUSED*/ ! 156: void ! 157: raw_ctlinput(cmd, arg) ! 158: int cmd; ! 159: struct sockaddr *arg; ! 160: { ! 161: ! 162: if (cmd < 0 || cmd > PRC_NCMDS) ! 163: return; ! 164: /* INCOMPLETE */ ! 165: } ! 166: ! 167: /*ARGSUSED*/ ! 168: int ! 169: raw_usrreq(so, req, m, nam, control) ! 170: struct socket *so; ! 171: int req; ! 172: struct mbuf *m, *nam, *control; ! 173: { ! 174: register struct rawcb *rp = sotorawcb(so); ! 175: register int error = 0; ! 176: int len; ! 177: extern void bcopy(const void *, void *, unsigned long); ! 178: extern void panic(const char *fmt, ...); ! 179: ! 180: if (req == PRU_CONTROL) ! 181: return (EOPNOTSUPP); ! 182: if (control && control->m_len) { ! 183: error = EOPNOTSUPP; ! 184: goto release; ! 185: } ! 186: if (rp == 0) { ! 187: error = EINVAL; ! 188: goto release; ! 189: } ! 190: switch (req) { ! 191: ! 192: /* ! 193: * Allocate a raw control block and fill in the ! 194: * necessary info to allow packets to be routed to ! 195: * the appropriate raw interface routine. ! 196: */ ! 197: case PRU_ATTACH: ! 198: if ((so->so_state & SS_PRIV) == 0) { ! 199: error = EACCES; ! 200: break; ! 201: } ! 202: error = raw_attach(so, (int)nam); ! 203: break; ! 204: ! 205: /* ! 206: * Destroy state just before socket deallocation. ! 207: * Flush data or not depending on the options. ! 208: */ ! 209: case PRU_DETACH: ! 210: if (rp == 0) { ! 211: error = ENOTCONN; ! 212: break; ! 213: } ! 214: raw_detach(rp); ! 215: break; ! 216: ! 217: #ifdef notdef ! 218: /* ! 219: * If a socket isn't bound to a single address, ! 220: * the raw input routine will hand it anything ! 221: * within that protocol family (assuming there's ! 222: * nothing else around it should go to). ! 223: */ ! 224: case PRU_CONNECT: ! 225: if (rp->rcb_faddr) { ! 226: error = EISCONN; ! 227: break; ! 228: } ! 229: nam = m_copym(nam, 0, M_COPYALL, M_WAIT); ! 230: rp->rcb_faddr = mtod(nam, struct sockaddr *); ! 231: soisconnected(so); ! 232: break; ! 233: ! 234: case PRU_BIND: ! 235: if (rp->rcb_laddr) { ! 236: error = EINVAL; /* XXX */ ! 237: break; ! 238: } ! 239: error = raw_bind(so, nam); ! 240: break; ! 241: #endif ! 242: ! 243: case PRU_CONNECT2: ! 244: error = EOPNOTSUPP; ! 245: goto release; ! 246: ! 247: case PRU_DISCONNECT: ! 248: if (rp->rcb_faddr == 0) { ! 249: error = ENOTCONN; ! 250: break; ! 251: } ! 252: raw_disconnect(rp); ! 253: soisdisconnected(so); ! 254: break; ! 255: ! 256: /* ! 257: * Mark the connection as being incapable of further input. ! 258: */ ! 259: case PRU_SHUTDOWN: ! 260: socantsendmore(so); ! 261: break; ! 262: ! 263: /* ! 264: * Ship a packet out. The appropriate raw output ! 265: * routine handles any massaging necessary. ! 266: */ ! 267: case PRU_SEND: ! 268: if (nam) { ! 269: if (rp->rcb_faddr) { ! 270: error = EISCONN; ! 271: break; ! 272: } ! 273: rp->rcb_faddr = mtod(nam, struct sockaddr *); ! 274: } else if (rp->rcb_faddr == 0) { ! 275: error = ENOTCONN; ! 276: break; ! 277: } ! 278: error = (*so->so_proto->pr_output)(m, so); ! 279: m = NULL; ! 280: if (nam) ! 281: rp->rcb_faddr = 0; ! 282: break; ! 283: ! 284: case PRU_ABORT: ! 285: raw_disconnect(rp); ! 286: sofree(so); ! 287: soisdisconnected(so); ! 288: break; ! 289: ! 290: case PRU_SENSE: ! 291: /* ! 292: * stat: don't bother with a blocksize. ! 293: */ ! 294: return (0); ! 295: ! 296: /* ! 297: * Not supported. ! 298: */ ! 299: case PRU_RCVOOB: ! 300: case PRU_RCVD: ! 301: return(EOPNOTSUPP); ! 302: ! 303: case PRU_LISTEN: ! 304: case PRU_ACCEPT: ! 305: case PRU_SENDOOB: ! 306: error = EOPNOTSUPP; ! 307: break; ! 308: ! 309: case PRU_SOCKADDR: ! 310: if (rp->rcb_laddr == 0) { ! 311: error = EINVAL; ! 312: break; ! 313: } ! 314: len = rp->rcb_laddr->sa_len; ! 315: bcopy((caddr_t)rp->rcb_laddr, mtod(nam, caddr_t), (unsigned)len); ! 316: nam->m_len = len; ! 317: break; ! 318: ! 319: case PRU_PEERADDR: ! 320: if (rp->rcb_faddr == 0) { ! 321: error = ENOTCONN; ! 322: break; ! 323: } ! 324: len = rp->rcb_faddr->sa_len; ! 325: bcopy((caddr_t)rp->rcb_faddr, mtod(nam, caddr_t), (unsigned)len); ! 326: nam->m_len = len; ! 327: break; ! 328: ! 329: default: ! 330: panic("raw_usrreq"); ! 331: } ! 332: release: ! 333: if (m != NULL) ! 334: m_freem(m); ! 335: return (error); ! 336: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.