make CTRL macro safe for ANSI
[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 *
b72a6efb 17 * @(#)raw_usrreq.c 7.5 (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
2e62d00d 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;
126472ab 56 struct sockproto *proto;
02122dcc 57 struct sockaddr *src, *dst;
8df9431e 58{
94a62155 59 register struct rawcb *rp;
b72a6efb 60 register struct mbuf *m = m0;
94a62155 61 struct socket *last;
8df9431e 62
94a62155
BJ
63 last = 0;
64 for (rp = rawcb.rcb_next; rp != &rawcb; rp = rp->rcb_next) {
b72a6efb 65 if (rp->rcb_proto.sp_family != proto->sp_family)
94a62155 66 continue;
829f867e 67 if (rp->rcb_proto.sp_protocol &&
b72a6efb 68 rp->rcb_proto.sp_protocol != proto->sp_protocol)
126472ab 69 continue;
94a62155
BJ
70 /*
71 * We assume the lower level routines have
72 * placed the address in a canonical format
126472ab 73 * suitable for a structure comparison.
b72a6efb
KS
74 *
75 * Note that if the lengths are not the same
76 * the comparison will fail at the first byte.
94a62155 77 */
b72a6efb
KS
78#define equal(a1, a2) \
79 (bcmp((caddr_t)(a1), (caddr_t)(a2), a1->sa_len) == 0)
80 if (rp->rcb_laddr && !equal(rp->rcb_laddr, dst))
126472ab 81 continue;
b72a6efb 82 if (rp->rcb_faddr && !equal(rp->rcb_faddr, src))
94a62155 83 continue;
94a62155
BJ
84 if (last) {
85 struct mbuf *n;
b72a6efb
KS
86 if (n = m_copy(m, 0, (int)M_COPYALL)) {
87 if (sbappendaddr(&last->so_rcv, src,
fa1454d3
MK
88 n, (struct mbuf *)0) == 0)
89 /* should notify about lost packet */
90 m_freem(n);
91 else
92 sorwakeup(last);
faad37c0 93 }
94a62155 94 }
126472ab 95 last = rp->rcb_socket;
94a62155 96 }
72e4f44e 97 if (last) {
b72a6efb
KS
98 if (sbappendaddr(&last->so_rcv, src,
99 m, (struct mbuf *)0) == 0)
100 m_freem(m);
fa1454d3
MK
101 else
102 sorwakeup(last);
fa1454d3
MK
103 } else
104 m_freem(m);
8df9431e
BJ
105}
106
a1edc12b 107/*ARGSUSED*/
72e4f44e
SL
108raw_ctlinput(cmd, arg)
109 int cmd;
8011f5df 110 struct sockaddr *arg;
72e4f44e 111{
39674d5f
SL
112
113 if (cmd < 0 || cmd > PRC_NCMDS)
114 return;
a1edc12b 115 /* INCOMPLETE */
72e4f44e
SL
116}
117
8df9431e 118/*ARGSUSED*/
b72a6efb 119raw_usrreq(so, req, m, nam, rights, control)
8df9431e
BJ
120 struct socket *so;
121 int req;
b72a6efb 122 struct mbuf *m, *nam, *rights, *control;
8df9431e 123{
94a62155 124 register struct rawcb *rp = sotorawcb(so);
9e9695c7 125 register int error = 0;
b72a6efb 126 int len;
94a62155 127
6624ec0b
MK
128 if (req == PRU_CONTROL)
129 return (EOPNOTSUPP);
9e9695c7
SL
130 if (rights && rights->m_len) {
131 error = EOPNOTSUPP;
132 goto release;
133 }
b72a6efb 134 if (rp == 0) {
9e9695c7
SL
135 error = EINVAL;
136 goto release;
137 }
94a62155
BJ
138 switch (req) {
139
140 /*
141 * Allocate a raw control block and fill in the
142 * necessary info to allow packets to be routed to
143 * the appropriate raw interface routine.
144 */
145 case PRU_ATTACH:
9e9695c7
SL
146 if ((so->so_state & SS_PRIV) == 0) {
147 error = EACCES;
4945768c 148 break;
9e9695c7 149 }
829f867e 150 error = raw_attach(so, (int)nam);
94a62155
BJ
151 break;
152
153 /*
154 * Destroy state just before socket deallocation.
155 * Flush data or not depending on the options.
156 */
157 case PRU_DETACH:
9e9695c7
SL
158 if (rp == 0) {
159 error = ENOTCONN;
4945768c 160 break;
9e9695c7 161 }
94a62155
BJ
162 raw_detach(rp);
163 break;
164
b72a6efb 165#ifdef notdef
94a62155
BJ
166 /*
167 * If a socket isn't bound to a single address,
168 * the raw input routine will hand it anything
169 * within that protocol family (assuming there's
170 * nothing else around it should go to).
171 */
172 case PRU_CONNECT:
b72a6efb 173 if (rp->rcb_faddr) {
9e9695c7 174 error = EISCONN;
4945768c 175 break;
9e9695c7 176 }
b72a6efb
KS
177 nam = m_copym(nam, 0, M_COPYALL, M_WAIT);
178 rp->rcb_faddr = mtod(nam, struct sockaddr *);
94a62155
BJ
179 soisconnected(so);
180 break;
181
9e9695c7 182 case PRU_BIND:
b72a6efb 183 if (rp->rcb_laddr) {
9e9695c7 184 error = EINVAL; /* XXX */
4945768c 185 break;
9e9695c7
SL
186 }
187 error = raw_bind(so, nam);
188 break;
b72a6efb
KS
189#endif
190
191 case PRU_CONNECT2:
192 error = EOPNOTSUPP;
193 goto release;
9e9695c7 194
94a62155 195 case PRU_DISCONNECT:
b72a6efb 196 if (rp->rcb_faddr == 0) {
9e9695c7 197 error = ENOTCONN;
4945768c 198 break;
9e9695c7 199 }
94a62155
BJ
200 raw_disconnect(rp);
201 soisdisconnected(so);
202 break;
203
204 /*
205 * Mark the connection as being incapable of further input.
206 */
207 case PRU_SHUTDOWN:
208 socantsendmore(so);
209 break;
210
211 /*
212 * Ship a packet out. The appropriate raw output
213 * routine handles any massaging necessary.
214 */
215 case PRU_SEND:
14fa60f2 216 if (nam) {
b72a6efb 217 if (rp->rcb_faddr) {
9e9695c7 218 error = EISCONN;
4945768c 219 break;
9e9695c7 220 }
b72a6efb
KS
221 rp->rcb_faddr = mtod(nam, struct sockaddr *);
222 } else if (rp->rcb_faddr == 0) {
9e9695c7 223 error = ENOTCONN;
4945768c 224 break;
9e9695c7 225 }
8a2f82db 226 error = (*so->so_proto->pr_output)(m, so);
9e9695c7 227 m = NULL;
14fa60f2 228 if (nam)
b72a6efb 229 rp->rcb_faddr = 0;
94a62155
BJ
230 break;
231
232 case PRU_ABORT:
233 raw_disconnect(rp);
234 sofree(so);
235 soisdisconnected(so);
236 break;
237
0f12c0aa
MK
238 case PRU_SENSE:
239 /*
240 * stat: don't bother with a blocksize.
241 */
242 return (0);
243
94a62155
BJ
244 /*
245 * Not supported.
246 */
799dcac1 247 case PRU_RCVOOB:
94a62155 248 case PRU_RCVD:
799dcac1
JB
249 return(EOPNOTSUPP);
250
1fe3d605 251 case PRU_LISTEN:
799dcac1 252 case PRU_ACCEPT:
94a62155
BJ
253 case PRU_SENDOOB:
254 error = EOPNOTSUPP;
255 break;
8df9431e 256
126472ab 257 case PRU_SOCKADDR:
b72a6efb
KS
258 if (rp->rcb_laddr == 0) {
259 error = EINVAL;
260 break;
261 }
262 len = rp->rcb_laddr->sa_len;
263 bcopy((caddr_t)rp->rcb_laddr, mtod(nam, caddr_t), (unsigned)len);
264 nam->m_len = len;
126472ab
SL
265 break;
266
a7343092 267 case PRU_PEERADDR:
b72a6efb
KS
268 if (rp->rcb_faddr == 0) {
269 error = ENOTCONN;
270 break;
271 }
272 len = rp->rcb_faddr->sa_len;
273 bcopy((caddr_t)rp->rcb_faddr, mtod(nam, caddr_t), (unsigned)len);
274 nam->m_len = len;
a7343092
SL
275 break;
276
94a62155
BJ
277 default:
278 panic("raw_usrreq");
279 }
9e9695c7
SL
280release:
281 if (m != NULL)
282 m_freem(m);
94a62155 283 return (error);
8df9431e 284}
b72a6efb
KS
285
286rawintr() {} /* XXX - referenced by locore. will soon go away */