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