source: rtems/cpukit/libnetworking/net/raw_usrreq.c @ 39bad7e8

4.104.115
Last change on this file since 39bad7e8 was b3f8c9e1, checked in by Ralf Corsepius <ralf.corsepius@…>, on 12/22/08 at 07:47:28

Include <errno.h> (POSIX,C99) instead of <sys/errno.h> (BSD'ism).

  • Property mode set to 100644
File size: 6.7 KB
Line 
1/*
2 * Copyright (c) 1980, 1986, 1993
3 *      The Regents of the University of California.  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 * 4. Neither the name of the University nor the names of its contributors
14 *    may be used to endorse or promote products derived from this software
15 *    without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 *      @(#)raw_usrreq.c        8.1 (Berkeley) 6/10/93
30 * $FreeBSD: src/sys/net/raw_usrreq.c,v 1.44 2006/11/06 13:42:02 rwatson Exp $
31 */
32
33/*
34 * $Id$
35 */
36
37#include <sys/param.h>
38#include <rtems/bsd/sys/queue.h>
39#include <sys/systm.h>
40#include <sys/mbuf.h>
41#include <sys/domain.h>
42#include <sys/protosw.h>
43#include <sys/socket.h>
44#include <sys/socketvar.h>
45#include <errno.h>
46
47#include <net/if.h>
48#include <net/route.h>
49#include <net/netisr.h>
50#include <net/raw_cb.h>
51
52/*
53 * Initialize raw connection block q.
54 */
55void
56raw_init(void)
57{
58
59        LIST_INIT(&rawcb_list);
60}
61
62
63/*
64 * Raw protocol input routine.  Find the socket
65 * associated with the packet(s) and move them over.  If
66 * nothing exists for this packet, drop it.
67 */
68/*
69 * Raw protocol interface.
70 */
71void
72raw_input(struct mbuf *m0, struct sockproto *proto, struct sockaddr *src,
73    struct sockaddr *dst)
74{
75        register struct rawcb *rp;
76        register struct mbuf *m = m0;
77        struct socket *last;
78
79        last = 0;
80        LIST_FOREACH(rp, &rawcb_list, list) {
81                if (rp->rcb_proto.sp_family != proto->sp_family)
82                        continue;
83                if (rp->rcb_proto.sp_protocol  &&
84                    rp->rcb_proto.sp_protocol != proto->sp_protocol)
85                        continue;
86                /*
87                 * We assume the lower level routines have
88                 * placed the address in a canonical format
89                 * suitable for a structure comparison.
90                 *
91                 * Note that if the lengths are not the same
92                 * the comparison will fail at the first byte.
93                 */
94#define equal(a1, a2) \
95  (bcmp((caddr_t)(a1), (caddr_t)(a2), a1->sa_len) == 0)
96                if (rp->rcb_laddr && !equal(rp->rcb_laddr, dst))
97                        continue;
98                if (rp->rcb_faddr && !equal(rp->rcb_faddr, src))
99                        continue;
100                if (last) {
101                        struct mbuf *n;
102                        n = m_copy(m, 0, (int)M_COPYALL);
103                        if (n) {
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                                }
111                        }
112                }
113                last = rp->rcb_socket;
114        }
115        if (last) {
116                if (sbappendaddr(&last->so_rcv, src,
117                    m, (struct mbuf *)0) == 0)
118                        m_freem(m);
119                else {
120                        sorwakeup(last);
121                }
122        } else
123                m_freem(m);
124}
125
126void
127raw_ctlinput(int cmd, struct sockaddr *arg, void *dummy)
128{
129
130        if (cmd < 0 || cmd > PRC_NCMDS)
131                return;
132        /* INCOMPLETE */
133}
134
135int
136raw_usrreq( struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
137    struct mbuf *control)
138{
139        register struct rawcb *rp = sotorawcb(so);
140        register int error = 0;
141        int len;
142
143        if (req == PRU_CONTROL)
144                return (EOPNOTSUPP);
145        if (control && control->m_len) {
146                error = EOPNOTSUPP;
147                goto release;
148        }
149        if (rp == 0) {
150                error = EINVAL;
151                goto release;
152        }
153        switch (req) {
154
155        /*
156         * Allocate a raw control block and fill in the
157         * necessary info to allow packets to be routed to
158         * the appropriate raw interface routine.
159         */
160        case PRU_ATTACH:
161                if ((so->so_state & SS_PRIV) == 0) {
162                        error = EACCES;
163                        break;
164                }
165                error = raw_attach(so, (intptr_t)nam);
166                break;
167
168        /*
169         * Destroy state just before socket deallocation.
170         * Flush data or not depending on the options.
171         */
172        case PRU_DETACH:
173                if (rp == 0) {
174                        error = ENOTCONN;
175                        break;
176                }
177                raw_detach(rp);
178                break;
179
180        /*
181         * If a socket isn't bound to a single address,
182         * the raw input routine will hand it anything
183         * within that protocol family (assuming there's
184         * nothing else around it should go to).
185         */
186        case PRU_CONNECT:
187                error = EINVAL;
188#if 0
189                if (rp->rcb_faddr) {
190                        error = EISCONN;
191                        break;
192                }
193                nam = m_copym(nam, 0, M_COPYALL, M_WAIT);
194                rp->rcb_faddr = mtod(nam, struct sockaddr *);
195                soisconnected(so);
196#endif
197                break;
198
199        case PRU_BIND:
200                error = EINVAL;
201#if 0
202                if (rp->rcb_laddr) {
203                        error = EINVAL;                 /* XXX */
204                        break;
205                }
206                error = raw_bind(so, nam);
207#endif
208                break;
209
210        case PRU_CONNECT2:
211                error = EOPNOTSUPP;
212                goto release;
213
214        case PRU_DISCONNECT:
215                if (rp->rcb_faddr == 0) {
216                        error = ENOTCONN;
217                        break;
218                }
219                raw_disconnect(rp);
220                soisdisconnected(so);
221                break;
222
223        /*
224         * Mark the connection as being incapable of further input.
225         */
226        case PRU_SHUTDOWN:
227                socantsendmore(so);
228                break;
229
230        /*
231         * Ship a packet out.  The appropriate raw output
232         * routine handles any massaging necessary.
233         */
234        case PRU_SEND:
235                if (nam) {
236                        if (rp->rcb_faddr) {
237                                error = EISCONN;
238                                break;
239                        }
240                        rp->rcb_faddr = mtod(nam, struct sockaddr *);
241                } else if (rp->rcb_faddr == 0) {
242                        error = ENOTCONN;
243                        break;
244                }
245                error = (*so->so_proto->pr_output)(m, so);
246                m = NULL;
247                if (nam)
248                        rp->rcb_faddr = 0;
249                break;
250
251        case PRU_ABORT:
252                raw_disconnect(rp);
253                sofree(so);
254                soisdisconnected(so);
255                break;
256
257        case PRU_SENSE:
258                /*
259                 * stat: don't bother with a blocksize.
260                 */
261                return (0);
262
263        /*
264         * Not supported.
265         */
266        case PRU_RCVOOB:
267        case PRU_RCVD:
268                return(EOPNOTSUPP);
269
270        case PRU_LISTEN:
271        case PRU_ACCEPT:
272        case PRU_SENDOOB:
273                error = EOPNOTSUPP;
274                break;
275
276        case PRU_SOCKADDR:
277                if (rp->rcb_laddr == 0) {
278                        error = EINVAL;
279                        break;
280                }
281                len = rp->rcb_laddr->sa_len;
282                bcopy((caddr_t)rp->rcb_laddr, mtod(nam, caddr_t), (unsigned)len);
283                nam->m_len = len;
284                break;
285
286        case PRU_PEERADDR:
287                if (rp->rcb_faddr == 0) {
288                        error = ENOTCONN;
289                        break;
290                }
291                len = rp->rcb_faddr->sa_len;
292                bcopy((caddr_t)rp->rcb_faddr, mtod(nam, caddr_t), (unsigned)len);
293                nam->m_len = len;
294                break;
295
296        default:
297                panic("raw_usrreq");
298        }
299release:
300        if (m != NULL)
301                m_freem(m);
302        return (error);
303}
Note: See TracBrowser for help on using the repository browser.