This source file includes following definitions.
- min
- raw_err
- raw_rcv
- raw_sendto
- raw_write
- raw_close
- raw_init
- raw_recvfrom
- raw_read
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #include <asm/system.h>
19 #include <asm/segment.h>
20 #include <linux/types.h>
21 #include <linux/sched.h>
22 #include <linux/errno.h>
23 #include <linux/timer.h>
24 #include <linux/mm.h>
25 #include <linux/kernel.h>
26 #include <linux/fcntl.h>
27 #include <linux/socket.h>
28 #include <linux/in.h>
29 #include "inet.h"
30 #include "timer.h"
31 #include "dev.h"
32 #include "ip.h"
33 #include "protocol.h"
34 #include "tcp.h"
35 #include "skbuff.h"
36 #include "sock.h"
37 #include "icmp.h"
38 #include "udp.h"
39
40
41 static unsigned long
42 min(unsigned long a, unsigned long b)
43 {
44 if (a < b) return(a);
45 return(b);
46 }
47
48
49
50 void
51 raw_err (int err, unsigned char *header, unsigned long daddr,
52 unsigned long saddr, struct inet_protocol *protocol)
53 {
54 struct sock *sk;
55
56 DPRINTF((DBG_RAW, "raw_err(err=%d, hdr=%X, daddr=%X, saddr=%X, protocl=%X)\n",
57 err, header, daddr, saddr, protocol));
58
59 if (protocol == NULL) return;
60 sk = protocol->data;
61 if (sk == NULL) return;
62
63
64 if (err & 0xff00 == (ICMP_SOURCE_QUENCH << 8)) {
65 if (sk->cong_window > 1) sk->cong_window = sk->cong_window/2;
66 return;
67 }
68
69 sk->err = icmp_err_convert[err & 0xff].errno;
70
71
72 #if 0
73 if (icmp_err_convert[err & 0xff].fatal) {
74 sk->prot->close(sk, 0);
75 }
76 #endif
77 return;
78 }
79
80
81
82
83
84
85 int
86 raw_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
87 unsigned long daddr, unsigned short len, unsigned long saddr,
88 int redo, struct inet_protocol *protocol)
89 {
90 struct sock *sk;
91
92 DPRINTF((DBG_RAW, "raw_rcv(skb=%X, dev=%X, opt=%X, daddr=%X,\n"
93 " len=%d, saddr=%X, redo=%d, protocol=%X)\n",
94 skb, dev, opt, daddr, len, saddr, redo, protocol));
95
96 if (skb == NULL) return(0);
97 if (protocol == NULL) {
98 kfree_skb(skb, FREE_READ);
99 return(0);
100 }
101 sk = protocol->data;
102 if (sk == NULL) {
103 kfree_skb(skb, FREE_READ);
104 return(0);
105 }
106
107
108 skb->sk = sk;
109 skb->len = len;
110 skb->dev = dev;
111 skb->saddr = daddr;
112 skb->daddr = saddr;
113
114 if (!redo) {
115
116 cli();
117 if (sk->inuse) {
118 DPRINTF((DBG_RAW, "raw_rcv adding to backlog.\n"));
119 if (sk->back_log == NULL) {
120 sk->back_log = skb;
121 skb->next = skb;
122 skb->prev = skb;
123 } else {
124 skb->next = sk->back_log;
125 skb->prev = sk->back_log->prev;
126 skb->prev->next = skb;
127 skb->next->prev = skb;
128 }
129 sti();
130 return(0);
131 }
132 sk->inuse = 1;
133 sti();
134 }
135
136
137 if (sk->rmem_alloc + skb->mem_len >= SK_RMEM_MAX) {
138 skb->sk = NULL;
139 kfree_skb(skb, FREE_READ);
140 return(0);
141 }
142 sk->rmem_alloc += skb->mem_len;
143
144
145 if (sk->rqueue == NULL) {
146 sk->rqueue = skb;
147 skb->next = skb;
148 skb->prev = skb;
149 } else {
150 skb->next = sk->rqueue;
151 skb->prev = sk->rqueue->prev;
152 skb->prev->next = skb;
153 skb->next->prev = skb;
154 }
155 wake_up(sk->sleep);
156 release_sock(sk);
157 return(0);
158 }
159
160
161
162 static int
163 raw_sendto(struct sock *sk, unsigned char *from, int len,
164 int noblock,
165 unsigned flags, struct sockaddr_in *usin, int addr_len)
166 {
167 struct sk_buff *skb;
168 struct device *dev=NULL;
169 struct sockaddr_in sin;
170 int tmp;
171
172 DPRINTF((DBG_RAW, "raw_sendto(sk=%X, from=%X, len=%d, noblock=%d, flags=%X,\n"
173 " usin=%X, addr_len = %d)\n", sk, from, len, noblock,
174 flags, usin, addr_len));
175
176
177 if (flags) return(-EINVAL);
178 if (len < 0) return(-EINVAL);
179
180
181 if (usin) {
182 if (addr_len < sizeof(sin)) return(-EINVAL);
183
184 memcpy_fromfs(&sin, usin, sizeof(sin));
185 if (sin.sin_family && sin.sin_family != AF_INET) return(-EINVAL);
186 } else {
187 if (sk->state != TCP_ESTABLISHED) return(-EINVAL);
188 sin.sin_family = AF_INET;
189 sin.sin_port = sk->protocol;
190 sin.sin_addr.s_addr = sk->daddr;
191 }
192 if (sin.sin_port == 0) sin.sin_port = sk->protocol;
193
194 sk->inuse = 1;
195 skb = NULL;
196 while (skb == NULL) {
197 skb = sk->prot->wmalloc(sk, len+sizeof(*skb) + sk->prot->max_header,
198 0, GFP_KERNEL);
199
200
201 if (skb == NULL) {
202 int tmp;
203
204 DPRINTF((DBG_RAW, "raw_sendto: write buffer full?\n"));
205 if (noblock) return(-EAGAIN);
206 tmp = sk->wmem_alloc;
207 release_sock(sk);
208 cli();
209 if (tmp <= sk->wmem_alloc) {
210 interruptible_sleep_on(sk->sleep);
211 if (current->signal & ~current->blocked) {
212 sti();
213 return(-ERESTARTSYS);
214 }
215 }
216 sk->inuse = 1;
217 sti();
218 }
219 }
220 skb->lock = 0;
221 skb->mem_addr = skb;
222 skb->mem_len = len + sizeof(*skb) +sk->prot->max_header;
223 skb->sk = sk;
224
225 skb->free = 1;
226 skb->arp = 0;
227
228 tmp = sk->prot->build_header(skb, sk->saddr,
229 sin.sin_addr.s_addr, &dev,
230 sk->protocol, sk->opt, skb->mem_len);
231 if (tmp < 0) {
232 DPRINTF((DBG_RAW, "raw_sendto: error building ip header.\n"));
233 sk->prot->wfree(sk, skb->mem_addr, skb->mem_len);
234 release_sock(sk);
235 return(tmp);
236 }
237
238
239 memcpy_fromfs ((unsigned char *)(skb+1)+tmp, from, len);
240 skb->len = tmp + len;
241 sk->prot->queue_xmit(sk, dev, skb, 1);
242 release_sock(sk);
243 return(len);
244 }
245
246
247 static int
248 raw_write(struct sock *sk, unsigned char *buff, int len, int noblock,
249 unsigned flags)
250 {
251 return(raw_sendto(sk, buff, len, noblock, flags, NULL, 0));
252 }
253
254
255 static void
256 raw_close(struct sock *sk, int timeout)
257 {
258 sk->inuse = 1;
259 sk->state = TCP_CLOSE;
260
261 DPRINTF((DBG_RAW, "raw_close: deleting protocol %d\n",
262 ((struct inet_protocol *)sk->pair)->protocol));
263
264 if (inet_del_protocol((struct inet_protocol *)sk->pair) < 0)
265 DPRINTF((DBG_RAW, "raw_close: del_protocol failed.\n"));
266 kfree_s((void *)sk->pair, sizeof (struct inet_protocol));
267 sk->pair = NULL;
268 release_sock(sk);
269 }
270
271
272 static int
273 raw_init(struct sock *sk)
274 {
275 struct inet_protocol *p;
276
277 p = kmalloc(sizeof (*p), GFP_KERNEL);
278 if (p == NULL) return(-ENOMEM);
279
280 p->handler = raw_rcv;
281 p->protocol = sk->protocol;
282 p->data = (void *)sk;
283 p->err_handler = raw_err;
284 inet_add_protocol(p);
285
286
287 sk->pair = (struct sock *)p;
288
289 DPRINTF((DBG_RAW, "raw init added protocol %d\n", sk->protocol));
290
291 return(0);
292 }
293
294
295
296
297
298
299 int
300 raw_recvfrom(struct sock *sk, unsigned char *to, int len,
301 int noblock, unsigned flags, struct sockaddr_in *sin,
302 int *addr_len)
303 {
304 int copied=0;
305 struct sk_buff *skb;
306
307 DPRINTF((DBG_RAW, "raw_recvfrom (sk=%X, to=%X, len=%d, noblock=%d, flags=%X,\n"
308 " sin=%X, addr_len=%X)\n",
309 sk, to, len, noblock, flags, sin, addr_len));
310
311 if (len == 0) return(0);
312 if (len < 0) return(-EINVAL);
313
314 if (sk->shutdown & RCV_SHUTDOWN) return(0);
315 if (addr_len) {
316 verify_area(VERIFY_WRITE, addr_len, sizeof(*addr_len));
317 put_fs_long(sizeof(*sin), addr_len);
318 }
319 sk->inuse = 1;
320 while (sk->rqueue == NULL) {
321 if (noblock) {
322 release_sock(sk);
323 if (copied) return(copied);
324 return(-EAGAIN);
325 }
326 release_sock(sk);
327 cli();
328 if (sk->rqueue == NULL) {
329 interruptible_sleep_on(sk->sleep);
330 if (current->signal & ~current->blocked) {
331 sti();
332 return(-ERESTARTSYS);
333 }
334 }
335 sk->inuse = 1;
336 sti();
337 }
338 skb = sk->rqueue;
339
340 if (!(flags & MSG_PEEK)) {
341 if (skb->next == skb) {
342 sk->rqueue = NULL;
343 } else {
344 sk->rqueue = (struct sk_buff *)sk->rqueue ->next;
345 skb->prev->next = skb->next;
346 skb->next->prev = skb->prev;
347 }
348 }
349 copied = min(len, skb->len);
350 verify_area(VERIFY_WRITE, to, copied);
351 memcpy_tofs(to, skb->h.raw, copied);
352
353
354 if (sin) {
355 struct sockaddr_in addr;
356
357 addr.sin_family = AF_INET;
358 addr.sin_addr.s_addr = skb->daddr;
359 verify_area(VERIFY_WRITE, sin, sizeof(*sin));
360 memcpy_tofs(sin, &addr, sizeof(*sin));
361 }
362
363 if (!(flags & MSG_PEEK)) {
364 kfree_skb(skb, FREE_READ);
365 }
366 release_sock(sk);
367 return (copied);
368 }
369
370
371 int
372 raw_read (struct sock *sk, unsigned char *buff, int len, int noblock,
373 unsigned flags)
374 {
375 return(raw_recvfrom(sk, buff, len, noblock, flags, NULL, NULL));
376 }
377
378
379 struct proto raw_prot = {
380 sock_wmalloc,
381 sock_rmalloc,
382 sock_wfree,
383 sock_rfree,
384 sock_rspace,
385 sock_wspace,
386 raw_close,
387 raw_read,
388 raw_write,
389 raw_sendto,
390 raw_recvfrom,
391 ip_build_header,
392 udp_connect,
393 NULL,
394 ip_queue_xmit,
395 ip_retransmit,
396 NULL,
397 NULL,
398 raw_rcv,
399 udp_select,
400 NULL,
401 raw_init,
402 NULL,
403 128,
404 0,
405 {NULL,},
406 "RAW"
407 };