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 * 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 *
33 * @(#)raw_usrreq.c 8.1 (Berkeley) 6/10/93
34 * $Id: raw_usrreq.c,v 1.5 1995/02/16 01:11:38 wollman Exp $
35 */
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/mbuf.h>
40#include <sys/domain.h>
41#include <sys/protosw.h>
42#include <sys/socket.h>
43#include <sys/socketvar.h>
44#include <sys/errno.h>
45
46#include <net/if.h>
47#include <net/route.h>
48#include <net/netisr.h>
49#include <net/raw_cb.h>
50
51/*
52 * Initialize raw connection block q.
53 */
54void
55raw_init()
56{
57
58 rawcb.rcb_next = rawcb.rcb_prev = &rawcb;
59}
60
61
62/*
63 * Raw protocol input routine. Find the socket
64 * associated with the packet(s) and move them over. If
65 * nothing exists for this packet, drop it.
66 */
67/*
68 * Raw protocol interface.
69 */
70void
71raw_input(m0, proto, src, dst)
72 struct mbuf *m0;
73 register struct sockproto *proto;
74 struct sockaddr *src, *dst;
75{
76 register struct rawcb *rp;
77 register struct mbuf *m = m0;
78 register int sockets = 0;
79 struct socket *last;
80
81 last = 0;
82 for (rp = rawcb.rcb_next; rp != &rawcb; rp = rp->rcb_next) {
83 if (rp->rcb_proto.sp_family != proto->sp_family)
84 continue;
85 if (rp->rcb_proto.sp_protocol &&
86 rp->rcb_proto.sp_protocol != proto->sp_protocol)
87 continue;
88 /*
89 * We assume the lower level routines have
90 * placed the address in a canonical format
91 * suitable for a structure comparison.
92 *
93 * Note that if the lengths are not the same
94 * the comparison will fail at the first byte.
95 */
96#define equal(a1, a2) \
97 (bcmp((caddr_t)(a1), (caddr_t)(a2), a1->sa_len) == 0)
98 if (rp->rcb_laddr && !equal(rp->rcb_laddr, dst))
99 continue;
100 if (rp->rcb_faddr && !equal(rp->rcb_faddr, src))
101 continue;
102 if (last) {
103 struct mbuf *n;
104 n = m_copy(m, 0, (int)M_COPYALL);
105 if (n) {
106 if (sbappendaddr(&last->so_rcv, src,
107 n, (struct mbuf *)0) == 0)
108 /* should notify about lost packet */
109 m_freem(n);
110 else {
111 sorwakeup(last);
112 sockets++;
113 }
114 }
115 }
116 last = rp->rcb_socket;
117 }
118 if (last) {
119 if (sbappendaddr(&last->so_rcv, src,
120 m, (struct mbuf *)0) == 0)
121 m_freem(m);
122 else {
123 sorwakeup(last);
124 sockets++;
125 }
126 } else
127 m_freem(m);
128}
129
130/*ARGSUSED*/
131void
132raw_ctlinput(cmd, arg)
133 int cmd;
134 struct sockaddr *arg;
135{
136
137 if (cmd < 0 || cmd > PRC_NCMDS)
138 return;
139 /* INCOMPLETE */
140}
141
142/*ARGSUSED*/
143int
144raw_usrreq(so, req, m, nam, control)
145 struct socket *so;
146 int req;
147 struct mbuf *m, *nam, *control;
148{
149 register struct rawcb *rp = sotorawcb(so);
150 register int error = 0;
151 int len;
152
153 if (req == PRU_CONTROL)
154 return (EOPNOTSUPP);
155 if (control && control->m_len) {
156 error = EOPNOTSUPP;
157 goto release;
158 }
159 if (rp == 0) {
160 error = EINVAL;
161 goto release;
162 }
163 switch (req) {
164
165 /*
166 * Allocate a raw control block and fill in the
167 * necessary info to allow packets to be routed to
168 * the appropriate raw interface routine.
169 */
170 case PRU_ATTACH:
171 if ((so->so_state & SS_PRIV) == 0) {
172 error = EACCES;
173 break;
174 }
175 error = raw_attach(so, (int)nam);
176 break;
177
178 /*
179 * Destroy state just before socket deallocation.
180 * Flush data or not depending on the options.
181 */
182 case PRU_DETACH:
183 if (rp == 0) {
184 error = ENOTCONN;
185 break;
186 }
187 raw_detach(rp);
188 break;
189
190 /*
191 * If a socket isn't bound to a single address,
192 * the raw input routine will hand it anything
193 * within that protocol family (assuming there's
194 * nothing else around it should go to).
195 */
196 case PRU_CONNECT:
197 error = EINVAL;
198#if 0
199 if (rp->rcb_faddr) {
200 error = EISCONN;
201 break;
202 }
203 nam = m_copym(nam, 0, M_COPYALL, M_WAIT);
204 rp->rcb_faddr = mtod(nam, struct sockaddr *);
205 soisconnected(so);
206#endif
207 break;
208
209 case PRU_BIND:
210 error = EINVAL;
211#if 0
212 if (rp->rcb_laddr) {
213 error = EINVAL; /* XXX */
214 break;
215 }
216 error = raw_bind(so, nam);
217#endif
218 break;
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}
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 * 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 *
33 * @(#)raw_usrreq.c 8.1 (Berkeley) 6/10/93
34 * $Id: raw_usrreq.c,v 1.5 1995/02/16 01:11:38 wollman Exp $
35 */
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/mbuf.h>
40#include <sys/domain.h>
41#include <sys/protosw.h>
42#include <sys/socket.h>
43#include <sys/socketvar.h>
44#include <sys/errno.h>
45
46#include <net/if.h>
47#include <net/route.h>
48#include <net/netisr.h>
49#include <net/raw_cb.h>
50
51/*
52 * Initialize raw connection block q.
53 */
54void
55raw_init()
56{
57
58 rawcb.rcb_next = rawcb.rcb_prev = &rawcb;
59}
60
61
62/*
63 * Raw protocol input routine. Find the socket
64 * associated with the packet(s) and move them over. If
65 * nothing exists for this packet, drop it.
66 */
67/*
68 * Raw protocol interface.
69 */
70void
71raw_input(m0, proto, src, dst)
72 struct mbuf *m0;
73 register struct sockproto *proto;
74 struct sockaddr *src, *dst;
75{
76 register struct rawcb *rp;
77 register struct mbuf *m = m0;
78 register int sockets = 0;
79 struct socket *last;
80
81 last = 0;
82 for (rp = rawcb.rcb_next; rp != &rawcb; rp = rp->rcb_next) {
83 if (rp->rcb_proto.sp_family != proto->sp_family)
84 continue;
85 if (rp->rcb_proto.sp_protocol &&
86 rp->rcb_proto.sp_protocol != proto->sp_protocol)
87 continue;
88 /*
89 * We assume the lower level routines have
90 * placed the address in a canonical format
91 * suitable for a structure comparison.
92 *
93 * Note that if the lengths are not the same
94 * the comparison will fail at the first byte.
95 */
96#define equal(a1, a2) \
97 (bcmp((caddr_t)(a1), (caddr_t)(a2), a1->sa_len) == 0)
98 if (rp->rcb_laddr && !equal(rp->rcb_laddr, dst))
99 continue;
100 if (rp->rcb_faddr && !equal(rp->rcb_faddr, src))
101 continue;
102 if (last) {
103 struct mbuf *n;
104 n = m_copy(m, 0, (int)M_COPYALL);
105 if (n) {
106 if (sbappendaddr(&last->so_rcv, src,
107 n, (struct mbuf *)0) == 0)
108 /* should notify about lost packet */
109 m_freem(n);
110 else {
111 sorwakeup(last);
112 sockets++;
113 }
114 }
115 }
116 last = rp->rcb_socket;
117 }
118 if (last) {
119 if (sbappendaddr(&last->so_rcv, src,
120 m, (struct mbuf *)0) == 0)
121 m_freem(m);
122 else {
123 sorwakeup(last);
124 sockets++;
125 }
126 } else
127 m_freem(m);
128}
129
130/*ARGSUSED*/
131void
132raw_ctlinput(cmd, arg)
133 int cmd;
134 struct sockaddr *arg;
135{
136
137 if (cmd < 0 || cmd > PRC_NCMDS)
138 return;
139 /* INCOMPLETE */
140}
141
142/*ARGSUSED*/
143int
144raw_usrreq(so, req, m, nam, control)
145 struct socket *so;
146 int req;
147 struct mbuf *m, *nam, *control;
148{
149 register struct rawcb *rp = sotorawcb(so);
150 register int error = 0;
151 int len;
152
153 if (req == PRU_CONTROL)
154 return (EOPNOTSUPP);
155 if (control && control->m_len) {
156 error = EOPNOTSUPP;
157 goto release;
158 }
159 if (rp == 0) {
160 error = EINVAL;
161 goto release;
162 }
163 switch (req) {
164
165 /*
166 * Allocate a raw control block and fill in the
167 * necessary info to allow packets to be routed to
168 * the appropriate raw interface routine.
169 */
170 case PRU_ATTACH:
171 if ((so->so_state & SS_PRIV) == 0) {
172 error = EACCES;
173 break;
174 }
175 error = raw_attach(so, (int)nam);
176 break;
177
178 /*
179 * Destroy state just before socket deallocation.
180 * Flush data or not depending on the options.
181 */
182 case PRU_DETACH:
183 if (rp == 0) {
184 error = ENOTCONN;
185 break;
186 }
187 raw_detach(rp);
188 break;
189
190 /*
191 * If a socket isn't bound to a single address,
192 * the raw input routine will hand it anything
193 * within that protocol family (assuming there's
194 * nothing else around it should go to).
195 */
196 case PRU_CONNECT:
197 error = EINVAL;
198#if 0
199 if (rp->rcb_faddr) {
200 error = EISCONN;
201 break;
202 }
203 nam = m_copym(nam, 0, M_COPYALL, M_WAIT);
204 rp->rcb_faddr = mtod(nam, struct sockaddr *);
205 soisconnected(so);
206#endif
207 break;
208
209 case PRU_BIND:
210 error = EINVAL;
211#if 0
212 if (rp->rcb_laddr) {
213 error = EINVAL; /* XXX */
214 break;
215 }
216 error = raw_bind(so, nam);
217#endif
218 break;
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}