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