|
|
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: *
1.1.1.2 ! root 33: * from: @(#)raw_usrreq.c 7.9 (Berkeley) 6/28/90
! 34: * raw_usrreq.c,v 1.3 1993/05/22 11:42:17 cgd Exp
1.1 root 35: */
36:
37: #include "param.h"
1.1.1.2 ! root 38: #include "socket.h"
1.1 root 39: #include "mbuf.h"
40: #include "domain.h"
41: #include "protosw.h"
42: #include "socket.h"
43: #include "socketvar.h"
44: #include "errno.h"
45:
46: #include "if.h"
47: #include "route.h"
48: #include "netisr.h"
49: #include "raw_cb.h"
50:
51: #include "machine/mtpr.h"
52:
53: /*
54: * Initialize raw connection block q.
55: */
56: raw_init()
57: {
58:
59: rawcb.rcb_next = rawcb.rcb_prev = &rawcb;
60: rawintrq.ifq_maxlen = IFQ_MAXLEN;
61: }
62:
63:
64: /*
65: * Raw protocol input routine. Find the socket
66: * associated with the packet(s) and move them over. If
67: * nothing exists for this packet, drop it.
68: */
69: /*
70: * Raw protocol interface.
71: */
72: raw_input(m0, proto, src, dst)
73: struct mbuf *m0;
74: register struct sockproto *proto;
75: struct sockaddr *src, *dst;
76: {
77: register struct rawcb *rp;
78: register struct mbuf *m = m0;
79: register int sockets = 0;
80: struct socket *last;
81:
82: last = 0;
83: for (rp = rawcb.rcb_next; rp != &rawcb; rp = rp->rcb_next) {
84: if (rp->rcb_proto.sp_family != proto->sp_family)
85: continue;
86: if (rp->rcb_proto.sp_protocol &&
87: rp->rcb_proto.sp_protocol != proto->sp_protocol)
88: continue;
89: /*
90: * We assume the lower level routines have
91: * placed the address in a canonical format
92: * suitable for a structure comparison.
93: *
94: * Note that if the lengths are not the same
95: * the comparison will fail at the first byte.
96: */
97: #define equal(a1, a2) \
98: (bcmp((caddr_t)(a1), (caddr_t)(a2), a1->sa_len) == 0)
99: if (rp->rcb_laddr && !equal(rp->rcb_laddr, dst))
100: continue;
101: if (rp->rcb_faddr && !equal(rp->rcb_faddr, src))
102: continue;
103: if (last) {
104: struct mbuf *n;
105: if (n = m_copy(m, 0, (int)M_COPYALL)) {
106: if (sbappendaddr(&last->so_rcv, src,
107: n, (struct mbuf *)0) == 0)
108: /* should notify about lost packet */
109: m_freem(n);
110: else {
111: sorwakeup(last);
112: sockets++;
113: }
114: }
115: }
116: last = rp->rcb_socket;
117: }
118: if (last) {
119: if (sbappendaddr(&last->so_rcv, src,
120: m, (struct mbuf *)0) == 0)
121: m_freem(m);
122: else {
123: sorwakeup(last);
124: sockets++;
125: }
126: } else
127: m_freem(m);
128: return (sockets);
129: }
130:
131: /*ARGSUSED*/
132: raw_ctlinput(cmd, arg)
133: int cmd;
134: struct sockaddr *arg;
135: {
136:
137: if (cmd < 0 || cmd > PRC_NCMDS)
138: return;
139: /* INCOMPLETE */
140: }
141:
142: /*ARGSUSED*/
143: raw_usrreq(so, req, m, nam, control)
144: struct socket *so;
145: int req;
146: struct mbuf *m, *nam, *control;
147: {
148: register struct rawcb *rp = sotorawcb(so);
149: register int error = 0;
150: int len;
151:
152: if (req == PRU_CONTROL)
153: return (EOPNOTSUPP);
154: if (control && control->m_len) {
155: error = EOPNOTSUPP;
156: goto release;
157: }
158: if (rp == 0) {
159: error = EINVAL;
160: goto release;
161: }
162: switch (req) {
163:
164: /*
165: * Allocate a raw control block and fill in the
166: * necessary info to allow packets to be routed to
167: * the appropriate raw interface routine.
168: */
169: case PRU_ATTACH:
170: if ((so->so_state & SS_PRIV) == 0) {
171: error = EACCES;
172: break;
173: }
174: error = raw_attach(so, (int)nam);
175: break;
176:
177: /*
178: * Destroy state just before socket deallocation.
179: * Flush data or not depending on the options.
180: */
181: case PRU_DETACH:
182: if (rp == 0) {
183: error = ENOTCONN;
184: break;
185: }
186: raw_detach(rp);
187: break;
188:
189: #ifdef notdef
190: /*
191: * If a socket isn't bound to a single address,
192: * the raw input routine will hand it anything
193: * within that protocol family (assuming there's
194: * nothing else around it should go to).
195: */
196: case PRU_CONNECT:
197: if (rp->rcb_faddr) {
198: error = EISCONN;
199: break;
200: }
201: nam = m_copym(nam, 0, M_COPYALL, M_WAIT);
202: rp->rcb_faddr = mtod(nam, struct sockaddr *);
203: soisconnected(so);
204: break;
205:
206: case PRU_BIND:
207: if (rp->rcb_laddr) {
208: error = EINVAL; /* XXX */
209: break;
210: }
211: error = raw_bind(so, nam);
212: break;
213: #endif
214:
215: case PRU_CONNECT2:
216: error = EOPNOTSUPP;
217: goto release;
218:
219: case PRU_DISCONNECT:
220: if (rp->rcb_faddr == 0) {
221: error = ENOTCONN;
222: break;
223: }
224: raw_disconnect(rp);
225: soisdisconnected(so);
226: break;
227:
228: /*
229: * Mark the connection as being incapable of further input.
230: */
231: case PRU_SHUTDOWN:
232: socantsendmore(so);
233: break;
234:
235: /*
236: * Ship a packet out. The appropriate raw output
237: * routine handles any massaging necessary.
238: */
239: case PRU_SEND:
240: if (nam) {
241: if (rp->rcb_faddr) {
242: error = EISCONN;
243: break;
244: }
245: rp->rcb_faddr = mtod(nam, struct sockaddr *);
246: } else if (rp->rcb_faddr == 0) {
247: error = ENOTCONN;
248: break;
249: }
250: error = (*so->so_proto->pr_output)(m, so);
251: m = NULL;
252: if (nam)
253: rp->rcb_faddr = 0;
254: break;
255:
256: case PRU_ABORT:
257: raw_disconnect(rp);
258: sofree(so);
259: soisdisconnected(so);
260: break;
261:
262: case PRU_SENSE:
263: /*
264: * stat: don't bother with a blocksize.
265: */
266: return (0);
267:
268: /*
269: * Not supported.
270: */
271: case PRU_RCVOOB:
272: case PRU_RCVD:
273: return(EOPNOTSUPP);
274:
275: case PRU_LISTEN:
276: case PRU_ACCEPT:
277: case PRU_SENDOOB:
278: error = EOPNOTSUPP;
279: break;
280:
281: case PRU_SOCKADDR:
282: if (rp->rcb_laddr == 0) {
283: error = EINVAL;
284: break;
285: }
286: len = rp->rcb_laddr->sa_len;
287: bcopy((caddr_t)rp->rcb_laddr, mtod(nam, caddr_t), (unsigned)len);
288: nam->m_len = len;
289: break;
290:
291: case PRU_PEERADDR:
292: if (rp->rcb_faddr == 0) {
293: error = ENOTCONN;
294: break;
295: }
296: len = rp->rcb_faddr->sa_len;
297: bcopy((caddr_t)rp->rcb_faddr, mtod(nam, caddr_t), (unsigned)len);
298: nam->m_len = len;
299: break;
300:
301: default:
302: panic("raw_usrreq");
303: }
304: release:
305: if (m != NULL)
306: m_freem(m);
307: return (error);
308: }
309:
310: 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.