revert between 56095 -> 55830 in arch
[AROS.git] / workbench / network / stacks / AROSTCP / bsdsocket / net / raw_usrreq.c
blobaa0e2f00fd562752d3d214ebd7348ed0481cf0f8
1 /*
2 * Copyright (C) 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>
3 * Helsinki University of Technology, Finland.
4 * All rights reserved.
5 * Copyright (C) 2005 Neil Cafferkey
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19 * MA 02111-1307, USA.
23 /*
24 * Mach Operating System
25 * Copyright (c) 1992 Carnegie Mellon University
26 * All Rights Reserved.
28 * Permission to use, copy, modify and distribute this software and its
29 * documentation is hereby granted, provided that both the copyright
30 * notice and this permission notice appear in all copies of the
31 * software, derivative works or modified versions, and any portions
32 * thereof, and that both notices appear in supporting documentation.
34 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
35 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
36 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
38 * Carnegie Mellon requests users of this software to return to
40 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
41 * School of Computer Science
42 * Carnegie Mellon University
43 * Pittsburgh PA 15213-3890
45 * any improvements or extensions that they make and grant Carnegie Mellon
46 * the rights to redistribute these changes.
50 * Copyright (c) 1980, 1986 Regents of the University of California.
51 * All rights reserved.
53 * Redistribution and use in source and binary forms, with or without
54 * modification, are permitted provided that the following conditions
55 * are met:
56 * 1. Redistributions of source code must retain the above copyright
57 * notice, this list of conditions and the following disclaimer.
58 * 2. Redistributions in binary form must reproduce the above copyright
59 * notice, this list of conditions and the following disclaimer in the
60 * documentation and/or other materials provided with the distribution.
61 * 3. All advertising materials mentioning features or use of this software
62 * must display the following acknowledgement:
63 * This product includes software developed by the University of
64 * California, Berkeley and its contributors.
65 * 4. Neither the name of the University nor the names of its contributors
66 * may be used to endorse or promote products derived from this software
67 * without specific prior written permission.
69 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
70 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
71 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
72 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
73 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
74 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
75 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
76 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
77 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
78 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
79 * SUCH DAMAGE.
81 * @(#)raw_usrreq.c 7.9 (Berkeley) 6/28/90
84 #include <conf.h>
86 #include <sys/param.h>
87 #include <sys/malloc.h>
88 #include <sys/mbuf.h>
89 #include <sys/domain.h>
90 #include <sys/protosw.h>
91 #include <sys/socket.h>
92 #include <sys/socketvar.h>
93 #include <sys/errno.h>
94 #include <sys/systm.h>
96 #include <net/if.h>
97 #include <net/route.h>
98 #include <net/netisr.h>
99 #include <net/raw_cb.h>
101 #include <net/raw_usrreq_protos.h>
102 #include <net/raw_cb_protos.h>
103 #include <kern/uipc_socket_protos.h>
104 #include <kern/uipc_socket2_protos.h>
106 struct ifqueue rawintrq = {0};
109 * Initialize raw connection block q.
111 void
112 raw_init(void)
114 rawcb.rcb_next = rawcb.rcb_prev = &rawcb;
115 rawintrq.ifq_maxlen = IFQ_MAXLEN;
120 * Raw protocol input routine. Find the socket
121 * associated with the packet(s) and move them over. If
122 * nothing exists for this packet, drop it.
125 * Raw protocol interface.
128 int STKARGFUN
129 raw_input(struct mbuf *m0,
130 struct sockproto *proto,
131 struct sockaddr *src,
132 struct sockaddr *dst)
134 register struct rawcb *rp;
135 register struct mbuf *m = m0;
136 register int sockets = 0;
137 struct socket *last;
139 last = 0;
140 for (rp = rawcb.rcb_next; rp != &rawcb; rp = rp->rcb_next) {
141 if (rp->rcb_proto.sp_family != proto->sp_family)
142 continue;
143 if (rp->rcb_proto.sp_protocol &&
144 rp->rcb_proto.sp_protocol != proto->sp_protocol)
145 continue;
147 * We assume the lower level routines have
148 * placed the address in a canonical format
149 * suitable for a structure comparison.
151 * Note that if the lengths are not the same
152 * the comparison will fail at the first byte.
154 #define equal(a1, a2) \
155 (bcmp((caddr_t)(a1), (caddr_t)(a2), a1->sa_len) == 0)
156 if (rp->rcb_laddr && !equal(rp->rcb_laddr, dst))
157 continue;
158 if (rp->rcb_faddr && !equal(rp->rcb_faddr, src))
159 continue;
160 if (last) {
161 struct mbuf *n;
162 if (n = m_copy(m, 0, (int)M_COPYALL)) {
163 if (sbappendaddr(&last->so_rcv, src,
164 n, (struct mbuf *)0) == 0)
165 /* should notify about lost packet */
166 m_freem(n);
167 else {
168 sorwakeup(last);
169 sockets++;
173 last = rp->rcb_socket;
175 if (last) {
176 if (sbappendaddr(&last->so_rcv, src,
177 m, (struct mbuf *)0) == 0)
178 m_freem(m);
179 else {
180 sorwakeup(last);
181 sockets++;
183 } else
184 m_freem(m);
185 return (sockets);
188 void
189 raw_ctlinput(int cmd, struct sockaddr *arg, caddr_t arg2)
191 if (cmd < 0 || cmd > PRC_NCMDS)
192 return;
193 /* INCOMPLETE */
197 raw_usrreq(struct socket *so,
198 int req,
199 struct mbuf *m,
200 struct mbuf *nam,
201 struct mbuf *control)
203 register struct rawcb *rp = sotorawcb(so);
204 register int error = 0;
205 int len;
207 if (req == PRU_CONTROL)
208 return (EOPNOTSUPP);
209 if (control && control->m_len) {
210 error = EOPNOTSUPP;
211 goto release;
213 if (rp == 0) {
214 error = EINVAL;
215 goto release;
217 switch (req) {
220 * Allocate a raw control block and fill in the
221 * necessary info to allow packets to be routed to
222 * the appropriate raw interface routine.
224 case PRU_ATTACH:
225 if ((so->so_state & SS_PRIV) == 0) {
226 error = EACCES;
227 break;
229 error = raw_attach(so, (long)nam);
230 break;
233 * Destroy state just before socket deallocation.
234 * Flush data or not depending on the options.
236 case PRU_DETACH:
237 if (rp == 0) {
238 error = ENOTCONN;
239 break;
241 raw_detach(rp);
242 break;
244 #ifdef notdef
246 * If a socket isn't bound to a single address,
247 * the raw input routine will hand it anything
248 * within that protocol family (assuming there's
249 * nothing else around it should go to).
251 case PRU_CONNECT:
252 if (rp->rcb_faddr) {
253 error = EISCONN;
254 break;
256 nam = m_copym(nam, 0, M_COPYALL, M_WAIT);
257 rp->rcb_faddr = mtod(nam, struct sockaddr *);
258 soisconnected(so);
259 break;
261 case PRU_BIND:
262 if (rp->rcb_laddr) {
263 error = EINVAL; /* XXX */
264 break;
266 error = raw_bind(so, nam);
267 break;
268 #endif
270 case PRU_CONNECT2:
271 error = EOPNOTSUPP;
272 goto release;
274 case PRU_DISCONNECT:
275 if (rp->rcb_faddr == 0) {
276 error = ENOTCONN;
277 break;
279 raw_disconnect(rp);
280 soisdisconnected(so);
281 break;
284 * Mark the connection as being incapable of further input.
286 case PRU_SHUTDOWN:
287 socantsendmore(so);
288 break;
291 * Ship a packet out. The appropriate raw output
292 * routine handles any massaging necessary.
294 case PRU_SEND:
295 if (nam) {
296 if (rp->rcb_faddr) {
297 error = EISCONN;
298 break;
300 rp->rcb_faddr = mtod(nam, struct sockaddr *);
301 } else if (rp->rcb_faddr == 0) {
302 error = ENOTCONN;
303 break;
305 error = (*so->so_proto->pr_output)(m, so);
306 m = NULL;
307 if (nam)
308 rp->rcb_faddr = 0;
309 break;
311 case PRU_ABORT:
312 raw_disconnect(rp);
313 sofree(so);
314 soisdisconnected(so);
315 break;
317 case PRU_SENSE:
319 * stat: don't bother with a blocksize.
321 return (0);
324 * Not supported.
326 case PRU_RCVOOB:
327 case PRU_RCVD:
328 return(EOPNOTSUPP);
330 case PRU_LISTEN:
331 case PRU_ACCEPT:
332 case PRU_SENDOOB:
333 error = EOPNOTSUPP;
334 break;
336 case PRU_SOCKADDR:
337 if (rp->rcb_laddr == 0) {
338 error = EINVAL;
339 break;
341 len = rp->rcb_laddr->sa_len;
342 aligned_bcopy((caddr_t)rp->rcb_laddr, mtod(nam, caddr_t), (unsigned)len);
343 nam->m_len = len;
344 break;
346 case PRU_PEERADDR:
347 if (rp->rcb_faddr == 0) {
348 error = ENOTCONN;
349 break;
351 len = rp->rcb_faddr->sa_len;
352 aligned_bcopy((caddr_t)rp->rcb_faddr, mtod(nam, caddr_t), (unsigned)len);
353 nam->m_len = len;
354 break;
356 default:
357 panic("raw_usrreq");
359 release:
360 if (m != NULL)
361 m_freem(m);
362 return (error);