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