|
|
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.