fix up header file dependencies
[unix-history] / usr / src / sys / net / raw_usrreq.c
CommitLineData
f832270b 1/* raw_usrreq.c 4.18 82/07/24 */
8df9431e
BJ
2
3#include "../h/param.h"
4#include "../h/mbuf.h"
94a62155 5#include "../h/protosw.h"
8df9431e
BJ
6#include "../h/socket.h"
7#include "../h/socketvar.h"
8#include "../h/mtpr.h"
9#include "../net/in.h"
10#include "../net/in_systm.h"
11#include "../net/if.h"
94a62155 12#include "../net/raw_cb.h"
126472ab 13#include <errno.h>
94a62155 14
1e977657
BJ
15int rawqmaxlen = IFQ_MAXLEN;
16
94a62155
BJ
17/*
18 * Initialize raw connection block q.
1e977657 19 */
94a62155
BJ
20raw_init()
21{
1e977657 22
94a62155 23 rawcb.rcb_next = rawcb.rcb_prev = &rawcb;
1e977657 24 rawintrq.ifq_maxlen = IFQ_MAXLEN;
94a62155 25}
8df9431e
BJ
26
27/*
28 * Raw protocol interface.
29 */
02122dcc 30raw_input(m0, proto, src, dst)
94a62155 31 struct mbuf *m0;
126472ab 32 struct sockproto *proto;
02122dcc 33 struct sockaddr *src, *dst;
8df9431e 34{
94a62155
BJ
35 register struct mbuf *m;
36 struct raw_header *rh;
8df9431e
BJ
37 int s;
38
94a62155
BJ
39 /*
40 * Rip off an mbuf for a generic header.
41 */
42 m = m_get(M_DONTWAIT);
43 if (m == 0) {
44 m_freem(m0);
45 return;
46 }
47 m->m_next = m0;
48 m->m_off = MMINOFF;
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
SL
94 lproto = rp->rcb_socket->so_proto;
95 if (lproto->pr_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;
126472ab
SL
117 if (sbappendaddr(&last->so_rcv, &rh->raw_src, n)==0) {
118 /* should notify about lost packet */
faad37c0
SL
119 m_freem(n);
120 goto nospace;
121 }
94a62155
BJ
122 sorwakeup(last);
123 }
124nospace:
126472ab 125 last = rp->rcb_socket;
94a62155 126 }
72e4f44e
SL
127 if (last) {
128 m = m_free(m); /* header */
129 if (sbappendaddr(&last->so_rcv, &rh->raw_src, m) == 0)
130 goto drop;
131 sorwakeup(last);
132 goto next;
133 }
8df9431e
BJ
134drop:
135 m_freem(m);
136 goto next;
137}
138
72e4f44e
SL
139raw_ctlinput(cmd, arg)
140 int cmd;
141 caddr_t arg;
142{
39674d5f
SL
143
144 if (cmd < 0 || cmd > PRC_NCMDS)
145 return;
72e4f44e
SL
146}
147
8df9431e
BJ
148/*ARGSUSED*/
149raw_usrreq(so, req, m, addr)
150 struct socket *so;
151 int req;
152 struct mbuf *m;
153 caddr_t addr;
154{
94a62155
BJ
155 register struct rawcb *rp = sotorawcb(so);
156 int error = 0;
8df9431e 157
94a62155
BJ
158 if (rp == 0 && req != PRU_ATTACH)
159 return (EINVAL);
160
161 switch (req) {
162
163 /*
164 * Allocate a raw control block and fill in the
165 * necessary info to allow packets to be routed to
166 * the appropriate raw interface routine.
167 */
168 case PRU_ATTACH:
1e977657 169 if ((so->so_state & SS_PRIV) == 0)
72e4f44e 170 return (EACCES);
94a62155 171 if (rp)
1e977657 172 return (EINVAL);
94a62155
BJ
173 error = raw_attach(so, (struct sockaddr *)addr);
174 break;
175
176 /*
177 * Destroy state just before socket deallocation.
178 * Flush data or not depending on the options.
179 */
180 case PRU_DETACH:
181 if (rp == 0)
182 return (ENOTCONN);
183 raw_detach(rp);
184 break;
185
186 /*
187 * If a socket isn't bound to a single address,
188 * the raw input routine will hand it anything
189 * within that protocol family (assuming there's
190 * nothing else around it should go to).
191 */
192 case PRU_CONNECT:
126472ab 193 if (rp->rcb_flags & RAW_FADDR)
94a62155
BJ
194 return (EISCONN);
195 raw_connaddr(rp, (struct sockaddr *)addr);
196 soisconnected(so);
197 break;
198
199 case PRU_DISCONNECT:
126472ab 200 if ((rp->rcb_flags & RAW_FADDR) == 0)
94a62155
BJ
201 return (ENOTCONN);
202 raw_disconnect(rp);
203 soisdisconnected(so);
204 break;
205
206 /*
207 * Mark the connection as being incapable of further input.
208 */
209 case PRU_SHUTDOWN:
210 socantsendmore(so);
211 break;
212
213 /*
214 * Ship a packet out. The appropriate raw output
215 * routine handles any massaging necessary.
216 */
217 case PRU_SEND:
218 if (addr) {
126472ab 219 if (rp->rcb_flags & RAW_FADDR)
94a62155
BJ
220 return (EISCONN);
221 raw_connaddr(rp, (struct sockaddr *)addr);
126472ab 222 } else if ((rp->rcb_flags & RAW_FADDR) == 0)
94a62155 223 return (ENOTCONN);
8a2f82db 224 error = (*so->so_proto->pr_output)(m, so);
94a62155 225 if (addr)
126472ab 226 rp->rcb_flags &= ~RAW_FADDR;
94a62155
BJ
227 break;
228
229 case PRU_ABORT:
230 raw_disconnect(rp);
231 sofree(so);
232 soisdisconnected(so);
233 break;
234
235 /*
236 * Not supported.
237 */
238 case PRU_ACCEPT:
239 case PRU_RCVD:
240 case PRU_CONTROL:
241 case PRU_SENSE:
242 case PRU_RCVOOB:
243 case PRU_SENDOOB:
244 error = EOPNOTSUPP;
245 break;
8df9431e 246
126472ab
SL
247 case PRU_SOCKADDR:
248 bcopy(addr, (caddr_t)&rp->rcb_laddr, sizeof (struct sockaddr));
249 break;
250
94a62155
BJ
251 default:
252 panic("raw_usrreq");
253 }
254 return (error);
8df9431e 255}