Got rid of all ../h in the system. Changed the include
[unix-history] / usr / src / sys / net / raw_usrreq.c
CommitLineData
808c0cdd 1/* raw_usrreq.c 6.5 84/08/28 */
8df9431e 2
a0369dcf
JB
3#include "param.h"
4#include "mbuf.h"
5#include "domain.h"
6#include "protosw.h"
7#include "socket.h"
8#include "socketvar.h"
9#include "errno.h"
f4d55810 10
a0369dcf
JB
11#include "if.h"
12#include "route.h"
13#include "netisr.h"
14#include "raw_cb.h"
f4d55810
SL
15
16#include "../vax/mtpr.h"
94a62155
BJ
17
18/*
19 * Initialize raw connection block q.
1e977657 20 */
94a62155
BJ
21raw_init()
22{
1e977657 23
94a62155 24 rawcb.rcb_next = rawcb.rcb_prev = &rawcb;
1e977657 25 rawintrq.ifq_maxlen = IFQ_MAXLEN;
94a62155 26}
8df9431e
BJ
27
28/*
29 * Raw protocol interface.
30 */
02122dcc 31raw_input(m0, proto, src, dst)
94a62155 32 struct mbuf *m0;
126472ab 33 struct sockproto *proto;
02122dcc 34 struct sockaddr *src, *dst;
8df9431e 35{
94a62155
BJ
36 register struct mbuf *m;
37 struct raw_header *rh;
8df9431e
BJ
38 int s;
39
94a62155
BJ
40 /*
41 * Rip off an mbuf for a generic header.
42 */
cce93e4b 43 m = m_get(M_DONTWAIT, MT_HEADER);
94a62155
BJ
44 if (m == 0) {
45 m_freem(m0);
46 return;
47 }
48 m->m_next = m0;
94a62155
BJ
49 m->m_len = sizeof(struct raw_header);
50 rh = mtod(m, struct raw_header *);
126472ab
SL
51 rh->raw_dst = *dst;
52 rh->raw_src = *src;
53 rh->raw_proto = *proto;
94a62155
BJ
54
55 /*
56 * Header now contains enough info to decide
57 * which socket to place packet in (if any).
58 * Queue it up for the raw protocol process
59 * running at software interrupt level.
60 */
8df9431e 61 s = splimp();
1e977657
BJ
62 if (IF_QFULL(&rawintrq))
63 m_freem(m);
64 else
65 IF_ENQUEUE(&rawintrq, m);
8df9431e 66 splx(s);
9c8692e9 67 schednetisr(NETISR_RAW);
8df9431e
BJ
68}
69
94a62155
BJ
70/*
71 * Raw protocol input routine. Process packets entered
72 * into the queue at interrupt time. Find the socket
73 * associated with the packet(s) and move them over. If
74 * nothing exists for this packet, drop it.
75 */
8df9431e
BJ
76rawintr()
77{
78 int s;
79 struct mbuf *m;
94a62155 80 register struct rawcb *rp;
126472ab 81 register struct protosw *lproto;
02122dcc 82 register struct raw_header *rh;
94a62155 83 struct socket *last;
8df9431e 84
8df9431e
BJ
85next:
86 s = splimp();
8df9431e
BJ
87 IF_DEQUEUE(&rawintrq, m);
88 splx(s);
89 if (m == 0)
90 return;
126472ab 91 rh = mtod(m, struct raw_header *);
94a62155
BJ
92 last = 0;
93 for (rp = rawcb.rcb_next; rp != &rawcb; rp = rp->rcb_next) {
126472ab 94 lproto = rp->rcb_socket->so_proto;
61d42116 95 if (lproto->pr_domain->dom_family != rh->raw_proto.sp_family)
94a62155 96 continue;
126472ab
SL
97 if (lproto->pr_protocol &&
98 lproto->pr_protocol != rh->raw_proto.sp_protocol)
99 continue;
94a62155
BJ
100 /*
101 * We assume the lower level routines have
102 * placed the address in a canonical format
126472ab 103 * suitable for a structure comparison.
94a62155 104 */
02122dcc
SL
105#define equal(a1, a2) \
106 (bcmp((caddr_t)&(a1), (caddr_t)&(a2), sizeof (struct sockaddr)) == 0)
126472ab 107 if ((rp->rcb_flags & RAW_LADDR) &&
02122dcc 108 !equal(rp->rcb_laddr, rh->raw_dst))
126472ab
SL
109 continue;
110 if ((rp->rcb_flags & RAW_FADDR) &&
02122dcc 111 !equal(rp->rcb_faddr, rh->raw_src))
94a62155 112 continue;
94a62155
BJ
113 if (last) {
114 struct mbuf *n;
f832270b 115 if ((n = m_copy(m->m_next, 0, (int)M_COPYALL)) == 0)
94a62155 116 goto nospace;
9e9695c7
SL
117 if (sbappendaddr(&last->so_rcv, &rh->raw_src,
118 n, (struct mbuf *)0) == 0) {
126472ab 119 /* should notify about lost packet */
faad37c0
SL
120 m_freem(n);
121 goto nospace;
122 }
94a62155
BJ
123 sorwakeup(last);
124 }
125nospace:
126472ab 126 last = rp->rcb_socket;
94a62155 127 }
72e4f44e
SL
128 if (last) {
129 m = m_free(m); /* header */
9e9695c7
SL
130 if (sbappendaddr(&last->so_rcv, &rh->raw_src,
131 m, (struct mbuf *)0) == 0)
72e4f44e
SL
132 goto drop;
133 sorwakeup(last);
134 goto next;
135 }
8df9431e
BJ
136drop:
137 m_freem(m);
138 goto next;
139}
140
a1edc12b 141/*ARGSUSED*/
72e4f44e
SL
142raw_ctlinput(cmd, arg)
143 int cmd;
144 caddr_t arg;
145{
39674d5f
SL
146
147 if (cmd < 0 || cmd > PRC_NCMDS)
148 return;
a1edc12b 149 /* INCOMPLETE */
72e4f44e
SL
150}
151
8df9431e 152/*ARGSUSED*/
9e9695c7 153raw_usrreq(so, req, m, nam, rights)
8df9431e
BJ
154 struct socket *so;
155 int req;
9e9695c7 156 struct mbuf *m, *nam, *rights;
8df9431e 157{
94a62155 158 register struct rawcb *rp = sotorawcb(so);
9e9695c7 159 register int error = 0;
94a62155 160
9e9695c7
SL
161 if (rights && rights->m_len) {
162 error = EOPNOTSUPP;
163 goto release;
164 }
165 if (rp == 0 && req != PRU_ATTACH) {
166 error = EINVAL;
167 goto release;
168 }
94a62155
BJ
169 switch (req) {
170
171 /*
172 * Allocate a raw control block and fill in the
173 * necessary info to allow packets to be routed to
174 * the appropriate raw interface routine.
175 */
176 case PRU_ATTACH:
9e9695c7
SL
177 if ((so->so_state & SS_PRIV) == 0) {
178 error = EACCES;
4945768c 179 break;
9e9695c7
SL
180 }
181 if (rp) {
182 error = EINVAL;
4945768c 183 break;
9e9695c7 184 }
14fa60f2 185 error = raw_attach(so);
94a62155
BJ
186 break;
187
188 /*
189 * Destroy state just before socket deallocation.
190 * Flush data or not depending on the options.
191 */
192 case PRU_DETACH:
9e9695c7
SL
193 if (rp == 0) {
194 error = ENOTCONN;
4945768c 195 break;
9e9695c7 196 }
94a62155
BJ
197 raw_detach(rp);
198 break;
199
200 /*
201 * If a socket isn't bound to a single address,
202 * the raw input routine will hand it anything
203 * within that protocol family (assuming there's
204 * nothing else around it should go to).
205 */
206 case PRU_CONNECT:
9e9695c7
SL
207 if (rp->rcb_flags & RAW_FADDR) {
208 error = EISCONN;
4945768c 209 break;
9e9695c7 210 }
14fa60f2 211 raw_connaddr(rp, nam);
94a62155
BJ
212 soisconnected(so);
213 break;
214
4945768c
SL
215 case PRU_CONNECT2:
216 error = EOPNOTSUPP;
217 goto release;
218
9e9695c7
SL
219 case PRU_BIND:
220 if (rp->rcb_flags & RAW_LADDR) {
221 error = EINVAL; /* XXX */
4945768c 222 break;
9e9695c7
SL
223 }
224 error = raw_bind(so, nam);
225 break;
226
94a62155 227 case PRU_DISCONNECT:
9e9695c7
SL
228 if ((rp->rcb_flags & RAW_FADDR) == 0) {
229 error = ENOTCONN;
4945768c 230 break;
9e9695c7 231 }
71fb71a3
SL
232 if (rp->rcb_route.ro_rt)
233 rtfree(rp->rcb_route.ro_rt);
94a62155
BJ
234 raw_disconnect(rp);
235 soisdisconnected(so);
236 break;
237
238 /*
239 * Mark the connection as being incapable of further input.
240 */
241 case PRU_SHUTDOWN:
242 socantsendmore(so);
243 break;
244
245 /*
246 * Ship a packet out. The appropriate raw output
247 * routine handles any massaging necessary.
248 */
249 case PRU_SEND:
14fa60f2 250 if (nam) {
9e9695c7
SL
251 if (rp->rcb_flags & RAW_FADDR) {
252 error = EISCONN;
4945768c 253 break;
9e9695c7 254 }
14fa60f2 255 raw_connaddr(rp, nam);
9e9695c7
SL
256 } else if ((rp->rcb_flags & RAW_FADDR) == 0) {
257 error = ENOTCONN;
4945768c 258 break;
9e9695c7 259 }
71fb71a3
SL
260 /*
261 * Check for routing. If new foreign address, or
262 * no route presently in use, try to allocate new
263 * route. On failure, just hand packet to output
264 * routine anyway in case it can handle it.
265 */
266 if ((rp->rcb_flags & RAW_DONTROUTE) == 0)
267 if (!equal(rp->rcb_faddr, rp->rcb_route.ro_dst) ||
268 rp->rcb_route.ro_rt == 0) {
799dcac1
JB
269 if (rp->rcb_route.ro_rt) {
270 RTFREE(rp->rcb_route.ro_rt);
271 rp->rcb_route.ro_rt = NULL;
272 }
71fb71a3
SL
273 rp->rcb_route.ro_dst = rp->rcb_faddr;
274 rtalloc(&rp->rcb_route);
275 }
8a2f82db 276 error = (*so->so_proto->pr_output)(m, so);
9e9695c7 277 m = NULL;
14fa60f2 278 if (nam)
126472ab 279 rp->rcb_flags &= ~RAW_FADDR;
94a62155
BJ
280 break;
281
282 case PRU_ABORT:
283 raw_disconnect(rp);
284 sofree(so);
285 soisdisconnected(so);
286 break;
287
0f12c0aa
MK
288 case PRU_SENSE:
289 /*
290 * stat: don't bother with a blocksize.
291 */
292 return (0);
293
94a62155
BJ
294 /*
295 * Not supported.
296 */
799dcac1
JB
297 case PRU_CONTROL:
298 case PRU_RCVOOB:
94a62155 299 case PRU_RCVD:
799dcac1
JB
300 return(EOPNOTSUPP);
301
302 case PRU_ACCEPT:
94a62155
BJ
303 case PRU_SENDOOB:
304 error = EOPNOTSUPP;
305 break;
8df9431e 306
126472ab 307 case PRU_SOCKADDR:
ac76a23d 308 bcopy((caddr_t)&rp->rcb_laddr, mtod(nam, caddr_t),
14fa60f2
BJ
309 sizeof (struct sockaddr));
310 nam->m_len = sizeof (struct sockaddr);
126472ab
SL
311 break;
312
a7343092
SL
313 case PRU_PEERADDR:
314 bcopy((caddr_t)&rp->rcb_faddr, mtod(nam, caddr_t),
315 sizeof (struct sockaddr));
316 nam->m_len = sizeof (struct sockaddr);
317 break;
318
94a62155
BJ
319 default:
320 panic("raw_usrreq");
321 }
9e9695c7
SL
322release:
323 if (m != NULL)
324 m_freem(m);
94a62155 325 return (error);
8df9431e 326}