reset optind before getopt() -- fixes 'make -k clean' failure
[unix-history] / usr / src / sys / net / raw_usrreq.c
... / ...
CommitLineData
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 are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16 *
17 * @(#)raw_usrreq.c 7.8 (Berkeley) %G%
18 */
19
20#include "param.h"
21#include "mbuf.h"
22#include "domain.h"
23#include "protosw.h"
24#include "socket.h"
25#include "socketvar.h"
26#include "errno.h"
27
28#include "if.h"
29#include "route.h"
30#include "netisr.h"
31#include "raw_cb.h"
32
33#include "machine/mtpr.h"
34
35/*
36 * Initialize raw connection block q.
37 */
38raw_init()
39{
40
41 rawcb.rcb_next = rawcb.rcb_prev = &rawcb;
42 rawintrq.ifq_maxlen = IFQ_MAXLEN;
43}
44
45
46/*
47 * Raw protocol input routine. Find the socket
48 * associated with the packet(s) and move them over. If
49 * nothing exists for this packet, drop it.
50 */
51/*
52 * Raw protocol interface.
53 */
54raw_input(m0, proto, src, dst)
55 struct mbuf *m0;
56 register struct sockproto *proto;
57 struct sockaddr *src, *dst;
58{
59 register struct rawcb *rp;
60 register struct mbuf *m = m0;
61 register int sockets = 0;
62 struct socket *last;
63
64 last = 0;
65 for (rp = rawcb.rcb_next; rp != &rawcb; rp = rp->rcb_next) {
66 if (rp->rcb_proto.sp_family != proto->sp_family)
67 continue;
68 if (rp->rcb_proto.sp_protocol &&
69 rp->rcb_proto.sp_protocol != proto->sp_protocol)
70 continue;
71 /*
72 * We assume the lower level routines have
73 * placed the address in a canonical format
74 * suitable for a structure comparison.
75 *
76 * Note that if the lengths are not the same
77 * the comparison will fail at the first byte.
78 */
79#define equal(a1, a2) \
80 (bcmp((caddr_t)(a1), (caddr_t)(a2), a1->sa_len) == 0)
81 if (rp->rcb_laddr && !equal(rp->rcb_laddr, dst))
82 continue;
83 if (rp->rcb_faddr && !equal(rp->rcb_faddr, src))
84 continue;
85 if (last) {
86 struct mbuf *n;
87 if (n = m_copy(m, 0, (int)M_COPYALL)) {
88 if (sbappendaddr(&last->so_rcv, src,
89 n, (struct mbuf *)0) == 0)
90 /* should notify about lost packet */
91 m_freem(n);
92 else {
93 sorwakeup(last);
94 sockets++;
95 }
96 }
97 }
98 last = rp->rcb_socket;
99 }
100 if (last) {
101 if (sbappendaddr(&last->so_rcv, src,
102 m, (struct mbuf *)0) == 0)
103 m_freem(m);
104 else {
105 sorwakeup(last);
106 sockets++;
107 }
108 } else
109 m_freem(m);
110 return (sockets);
111}
112
113/*ARGSUSED*/
114raw_ctlinput(cmd, arg)
115 int cmd;
116 struct sockaddr *arg;
117{
118
119 if (cmd < 0 || cmd > PRC_NCMDS)
120 return;
121 /* INCOMPLETE */
122}
123
124/*ARGSUSED*/
125raw_usrreq(so, req, m, nam, control)
126 struct socket *so;
127 int req;
128 struct mbuf *m, *nam, *control;
129{
130 register struct rawcb *rp = sotorawcb(so);
131 register int error = 0;
132 int len;
133
134 if (req == PRU_CONTROL)
135 return (EOPNOTSUPP);
136 if (control && control->m_len) {
137 error = EOPNOTSUPP;
138 goto release;
139 }
140 if (rp == 0) {
141 error = EINVAL;
142 goto release;
143 }
144 switch (req) {
145
146 /*
147 * Allocate a raw control block and fill in the
148 * necessary info to allow packets to be routed to
149 * the appropriate raw interface routine.
150 */
151 case PRU_ATTACH:
152 if ((so->so_state & SS_PRIV) == 0) {
153 error = EACCES;
154 break;
155 }
156 error = raw_attach(so, (int)nam);
157 break;
158
159 /*
160 * Destroy state just before socket deallocation.
161 * Flush data or not depending on the options.
162 */
163 case PRU_DETACH:
164 if (rp == 0) {
165 error = ENOTCONN;
166 break;
167 }
168 raw_detach(rp);
169 break;
170
171#ifdef notdef
172 /*
173 * If a socket isn't bound to a single address,
174 * the raw input routine will hand it anything
175 * within that protocol family (assuming there's
176 * nothing else around it should go to).
177 */
178 case PRU_CONNECT:
179 if (rp->rcb_faddr) {
180 error = EISCONN;
181 break;
182 }
183 nam = m_copym(nam, 0, M_COPYALL, M_WAIT);
184 rp->rcb_faddr = mtod(nam, struct sockaddr *);
185 soisconnected(so);
186 break;
187
188 case PRU_BIND:
189 if (rp->rcb_laddr) {
190 error = EINVAL; /* XXX */
191 break;
192 }
193 error = raw_bind(so, nam);
194 break;
195#endif
196
197 case PRU_CONNECT2:
198 error = EOPNOTSUPP;
199 goto release;
200
201 case PRU_DISCONNECT:
202 if (rp->rcb_faddr == 0) {
203 error = ENOTCONN;
204 break;
205 }
206 raw_disconnect(rp);
207 soisdisconnected(so);
208 break;
209
210 /*
211 * Mark the connection as being incapable of further input.
212 */
213 case PRU_SHUTDOWN:
214 socantsendmore(so);
215 break;
216
217 /*
218 * Ship a packet out. The appropriate raw output
219 * routine handles any massaging necessary.
220 */
221 case PRU_SEND:
222 if (nam) {
223 if (rp->rcb_faddr) {
224 error = EISCONN;
225 break;
226 }
227 rp->rcb_faddr = mtod(nam, struct sockaddr *);
228 } else if (rp->rcb_faddr == 0) {
229 error = ENOTCONN;
230 break;
231 }
232 error = (*so->so_proto->pr_output)(m, so);
233 m = NULL;
234 if (nam)
235 rp->rcb_faddr = 0;
236 break;
237
238 case PRU_ABORT:
239 raw_disconnect(rp);
240 sofree(so);
241 soisdisconnected(so);
242 break;
243
244 case PRU_SENSE:
245 /*
246 * stat: don't bother with a blocksize.
247 */
248 return (0);
249
250 /*
251 * Not supported.
252 */
253 case PRU_RCVOOB:
254 case PRU_RCVD:
255 return(EOPNOTSUPP);
256
257 case PRU_LISTEN:
258 case PRU_ACCEPT:
259 case PRU_SENDOOB:
260 error = EOPNOTSUPP;
261 break;
262
263 case PRU_SOCKADDR:
264 if (rp->rcb_laddr == 0) {
265 error = EINVAL;
266 break;
267 }
268 len = rp->rcb_laddr->sa_len;
269 bcopy((caddr_t)rp->rcb_laddr, mtod(nam, caddr_t), (unsigned)len);
270 nam->m_len = len;
271 break;
272
273 case PRU_PEERADDR:
274 if (rp->rcb_faddr == 0) {
275 error = ENOTCONN;
276 break;
277 }
278 len = rp->rcb_faddr->sa_len;
279 bcopy((caddr_t)rp->rcb_faddr, mtod(nam, caddr_t), (unsigned)len);
280 nam->m_len = len;
281 break;
282
283 default:
284 panic("raw_usrreq");
285 }
286release:
287 if (m != NULL)
288 m_freem(m);
289 return (error);
290}
291
292rawintr() {} /* XXX - referenced by locore. will soon go away */