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