reset optind before getopt() -- fixes 'make -k clean' failure
[unix-history] / usr / src / sys / net / raw_usrreq.c
CommitLineData
cb1c44c2 1/*
1810611d 2 * Copyright (c) 1980, 1986 Regents of the University of California.
5b519e94 3 * All rights reserved.
cb1c44c2 4 *
5b519e94 5 * Redistribution and use in source and binary forms are permitted
50c7758a
KB
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.
5b519e94 16 *
93790f32 17 * @(#)raw_usrreq.c 7.8 (Berkeley) %G%
cb1c44c2 18 */
8df9431e 19
a0369dcf
JB
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"
f4d55810 27
a0369dcf
JB
28#include "if.h"
29#include "route.h"
30#include "netisr.h"
31#include "raw_cb.h"
f4d55810 32
0e6c0944 33#include "machine/mtpr.h"
94a62155
BJ
34
35/*
36 * Initialize raw connection block q.
1e977657 37 */
94a62155
BJ
38raw_init()
39{
1e977657 40
94a62155 41 rawcb.rcb_next = rawcb.rcb_prev = &rawcb;
1e977657 42 rawintrq.ifq_maxlen = IFQ_MAXLEN;
94a62155 43}
8df9431e 44
b72a6efb
KS
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 */
8df9431e
BJ
51/*
52 * Raw protocol interface.
53 */
02122dcc 54raw_input(m0, proto, src, dst)
94a62155 55 struct mbuf *m0;
ad2ef60c 56 register struct sockproto *proto;
02122dcc 57 struct sockaddr *src, *dst;
8df9431e 58{
94a62155 59 register struct rawcb *rp;
b72a6efb 60 register struct mbuf *m = m0;
ad2ef60c 61 register int sockets = 0;
94a62155 62 struct socket *last;
8df9431e 63
94a62155
BJ
64 last = 0;
65 for (rp = rawcb.rcb_next; rp != &rawcb; rp = rp->rcb_next) {
b72a6efb 66 if (rp->rcb_proto.sp_family != proto->sp_family)
94a62155 67 continue;
829f867e 68 if (rp->rcb_proto.sp_protocol &&
b72a6efb 69 rp->rcb_proto.sp_protocol != proto->sp_protocol)
126472ab 70 continue;
94a62155
BJ
71 /*
72 * We assume the lower level routines have
73 * placed the address in a canonical format
126472ab 74 * suitable for a structure comparison.
b72a6efb
KS
75 *
76 * Note that if the lengths are not the same
77 * the comparison will fail at the first byte.
94a62155 78 */
b72a6efb
KS
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))
126472ab 82 continue;
b72a6efb 83 if (rp->rcb_faddr && !equal(rp->rcb_faddr, src))
94a62155 84 continue;
94a62155
BJ
85 if (last) {
86 struct mbuf *n;
b72a6efb
KS
87 if (n = m_copy(m, 0, (int)M_COPYALL)) {
88 if (sbappendaddr(&last->so_rcv, src,
fa1454d3
MK
89 n, (struct mbuf *)0) == 0)
90 /* should notify about lost packet */
91 m_freem(n);
ad2ef60c 92 else {
fa1454d3 93 sorwakeup(last);
ad2ef60c
KS
94 sockets++;
95 }
faad37c0 96 }
94a62155 97 }
126472ab 98 last = rp->rcb_socket;
94a62155 99 }
72e4f44e 100 if (last) {
b72a6efb
KS
101 if (sbappendaddr(&last->so_rcv, src,
102 m, (struct mbuf *)0) == 0)
103 m_freem(m);
ad2ef60c 104 else {
fa1454d3 105 sorwakeup(last);
ad2ef60c
KS
106 sockets++;
107 }
fa1454d3
MK
108 } else
109 m_freem(m);
ad2ef60c 110 return (sockets);
8df9431e
BJ
111}
112
a1edc12b 113/*ARGSUSED*/
72e4f44e
SL
114raw_ctlinput(cmd, arg)
115 int cmd;
8011f5df 116 struct sockaddr *arg;
72e4f44e 117{
39674d5f
SL
118
119 if (cmd < 0 || cmd > PRC_NCMDS)
120 return;
a1edc12b 121 /* INCOMPLETE */
72e4f44e
SL
122}
123
8df9431e 124/*ARGSUSED*/
93790f32 125raw_usrreq(so, req, m, nam, control)
8df9431e
BJ
126 struct socket *so;
127 int req;
93790f32 128 struct mbuf *m, *nam, *control;
8df9431e 129{
94a62155 130 register struct rawcb *rp = sotorawcb(so);
9e9695c7 131 register int error = 0;
b72a6efb 132 int len;
94a62155 133
6624ec0b
MK
134 if (req == PRU_CONTROL)
135 return (EOPNOTSUPP);
93790f32 136 if (control && control->m_len) {
9e9695c7
SL
137 error = EOPNOTSUPP;
138 goto release;
139 }
b72a6efb 140 if (rp == 0) {
9e9695c7
SL
141 error = EINVAL;
142 goto release;
143 }
94a62155
BJ
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:
9e9695c7
SL
152 if ((so->so_state & SS_PRIV) == 0) {
153 error = EACCES;
4945768c 154 break;
9e9695c7 155 }
829f867e 156 error = raw_attach(so, (int)nam);
94a62155
BJ
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:
9e9695c7
SL
164 if (rp == 0) {
165 error = ENOTCONN;
4945768c 166 break;
9e9695c7 167 }
94a62155
BJ
168 raw_detach(rp);
169 break;
170
b72a6efb 171#ifdef notdef
94a62155
BJ
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:
b72a6efb 179 if (rp->rcb_faddr) {
9e9695c7 180 error = EISCONN;
4945768c 181 break;
9e9695c7 182 }
b72a6efb
KS
183 nam = m_copym(nam, 0, M_COPYALL, M_WAIT);
184 rp->rcb_faddr = mtod(nam, struct sockaddr *);
94a62155
BJ
185 soisconnected(so);
186 break;
187
9e9695c7 188 case PRU_BIND:
b72a6efb 189 if (rp->rcb_laddr) {
9e9695c7 190 error = EINVAL; /* XXX */
4945768c 191 break;
9e9695c7
SL
192 }
193 error = raw_bind(so, nam);
194 break;
b72a6efb
KS
195#endif
196
197 case PRU_CONNECT2:
198 error = EOPNOTSUPP;
199 goto release;
9e9695c7 200
94a62155 201 case PRU_DISCONNECT:
b72a6efb 202 if (rp->rcb_faddr == 0) {
9e9695c7 203 error = ENOTCONN;
4945768c 204 break;
9e9695c7 205 }
94a62155
BJ
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:
14fa60f2 222 if (nam) {
b72a6efb 223 if (rp->rcb_faddr) {
9e9695c7 224 error = EISCONN;
4945768c 225 break;
9e9695c7 226 }
b72a6efb
KS
227 rp->rcb_faddr = mtod(nam, struct sockaddr *);
228 } else if (rp->rcb_faddr == 0) {
9e9695c7 229 error = ENOTCONN;
4945768c 230 break;
9e9695c7 231 }
8a2f82db 232 error = (*so->so_proto->pr_output)(m, so);
9e9695c7 233 m = NULL;
14fa60f2 234 if (nam)
b72a6efb 235 rp->rcb_faddr = 0;
94a62155
BJ
236 break;
237
238 case PRU_ABORT:
239 raw_disconnect(rp);
240 sofree(so);
241 soisdisconnected(so);
242 break;
243
0f12c0aa
MK
244 case PRU_SENSE:
245 /*
246 * stat: don't bother with a blocksize.
247 */
248 return (0);
249
94a62155
BJ
250 /*
251 * Not supported.
252 */
799dcac1 253 case PRU_RCVOOB:
94a62155 254 case PRU_RCVD:
799dcac1
JB
255 return(EOPNOTSUPP);
256
1fe3d605 257 case PRU_LISTEN:
799dcac1 258 case PRU_ACCEPT:
94a62155
BJ
259 case PRU_SENDOOB:
260 error = EOPNOTSUPP;
261 break;
8df9431e 262
126472ab 263 case PRU_SOCKADDR:
b72a6efb
KS
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;
126472ab
SL
271 break;
272
a7343092 273 case PRU_PEERADDR:
b72a6efb
KS
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;
a7343092
SL
281 break;
282
94a62155
BJ
283 default:
284 panic("raw_usrreq");
285 }
9e9695c7
SL
286release:
287 if (m != NULL)
288 m_freem(m);
94a62155 289 return (error);
8df9431e 290}
b72a6efb
KS
291
292rawintr() {} /* XXX - referenced by locore. will soon go away */