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