source: rtems/cpukit/libnetworking/net/raw_usrreq.c @ b25b88e7

4.104.11
Last change on this file since b25b88e7 was b25b88e7, checked in by Ralf Corsepius <ralf.corsepius@…>, on Mar 28, 2010 at 5:50:29 AM

Add HAVE_CONFIG_H support to let files receive configure defines.

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