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