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