1 /* $NetBSD: raw_usrreq.c,v 1.34 2008/04/24 11:38:37 ad Exp $ */
4 * Copyright (c) 1980, 1986, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * @(#)raw_usrreq.c 8.1 (Berkeley) 6/10/93
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: raw_usrreq.c,v 1.34 2008/04/24 11:38:37 ad Exp $");
37 #include <sys/param.h>
39 #include <sys/domain.h>
40 #include <sys/protosw.h>
41 #include <sys/socket.h>
42 #include <sys/socketvar.h>
43 #include <sys/errno.h>
44 #include <sys/systm.h>
46 #include <sys/kauth.h>
49 #include <net/route.h>
50 #include <net/netisr.h>
51 #include <net/raw_cb.h>
53 #include <machine/stdarg.h>
56 * Initialize raw connection block q.
66 equal(const struct sockaddr
*a1
, const struct sockaddr
*a2
)
68 return memcmp(a1
, a2
, a1
->sa_len
) == 0;
72 * Raw protocol input routine. Find the socket
73 * associated with the packet(s) and move them over. If
74 * nothing exists for this packet, drop it.
77 * Raw protocol interface.
80 raw_input(struct mbuf
*m0
, ...)
86 struct sockproto
*proto
;
87 struct sockaddr
*src
, *dst
;
89 KASSERT(mutex_owned(softnet_lock
));
92 proto
= va_arg(ap
, struct sockproto
*);
93 src
= va_arg(ap
, struct sockaddr
*);
94 dst
= va_arg(ap
, struct sockaddr
*);
98 LIST_FOREACH(rp
, &rawcb
, rcb_list
) {
99 if (rp
->rcb_proto
.sp_family
!= proto
->sp_family
)
101 if (rp
->rcb_proto
.sp_protocol
&&
102 rp
->rcb_proto
.sp_protocol
!= proto
->sp_protocol
)
105 * We assume the lower level routines have
106 * placed the address in a canonical format
107 * suitable for a structure comparison.
109 * Note that if the lengths are not the same
110 * the comparison will fail at the first byte.
112 if (rp
->rcb_laddr
&& !equal(rp
->rcb_laddr
, dst
))
114 if (rp
->rcb_faddr
&& !equal(rp
->rcb_faddr
, src
))
118 if ((n
= m_copy(m
, 0, M_COPYALL
)) == NULL
)
120 else if (sbappendaddr(&last
->so_rcv
, src
, n
, NULL
) == 0)
121 /* should notify about lost packet */
127 last
= rp
->rcb_socket
;
129 if (last
== NULL
|| sbappendaddr(&last
->so_rcv
, src
, m
, NULL
) == 0)
138 raw_ctlinput(int cmd
, const struct sockaddr
*arg
, void *d
)
141 if ((unsigned)cmd
>= PRC_NCMDS
)
148 raw_setsockaddr(struct rawcb
*rp
, struct mbuf
*nam
)
151 nam
->m_len
= rp
->rcb_laddr
->sa_len
;
152 memcpy(mtod(nam
, void *), rp
->rcb_laddr
, (size_t)nam
->m_len
);
156 raw_setpeeraddr(struct rawcb
*rp
, struct mbuf
*nam
)
159 nam
->m_len
= rp
->rcb_faddr
->sa_len
;
160 memcpy(mtod(nam
, void *), rp
->rcb_faddr
, (size_t)nam
->m_len
);
165 raw_usrreq(struct socket
*so
, int req
, struct mbuf
*m
, struct mbuf
*nam
,
166 struct mbuf
*control
, struct lwp
*l
)
172 if (req
== PRU_CONTROL
)
176 KERNEL_LOCK(1, NULL
);
179 if (req
!= PRU_SEND
&& req
!= PRU_SENDOOB
&& control
)
180 panic("raw_usrreq: unexpected control mbuf");
182 if (rp
== NULL
&& req
!= PRU_ATTACH
) {
190 * Allocate a raw control block and fill in the
191 * necessary info to allow packets to be routed to
192 * the appropriate raw interface routine.
199 /* XXX: raw socket permissions are checked in socreate() */
201 error
= raw_attach(so
, (int)(long)nam
);
205 * Destroy state just before socket deallocation.
206 * Flush data or not depending on the options.
213 * If a socket isn't bound to a single address,
214 * the raw input routine will hand it anything
215 * within that protocol family (assuming there's
216 * nothing else around it should go to).
226 soisdisconnected(so
);
231 * Mark the connection as being incapable of further input.
242 * Ship a packet out. The appropriate raw output
243 * routine handles any massaging necessary.
246 if (control
&& control
->m_len
) {
253 if ((so
->so_state
& SS_ISCONNECTED
) != 0) {
257 error
= (*so
->so_proto
->pr_usrreq
)(so
, PRU_CONNECT
,
265 if ((so
->so_state
& SS_ISCONNECTED
) == 0) {
270 error
= (*so
->so_proto
->pr_output
)(m
, so
);
277 * stat: don't bother with a blocksize.
295 if (rp
->rcb_laddr
== NULL
) {
299 raw_setsockaddr(rp
, nam
);
303 if (rp
->rcb_faddr
== NULL
) {
307 raw_setpeeraddr(rp
, nam
);
315 KERNEL_UNLOCK_ONE(NULL
);