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