This source file includes following definitions.
- print_uh
- udp_select
- udp_err
- udp_check
- udp_send_check
- udp_loopback
- udp_sendto
- udp_write
- udp_ioctl
- udp_recvfrom
- udp_read
- udp_connect
- udp_close
- udp_rcv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 #include <linux/types.h>
44 #include <linux/sched.h>
45 #include <linux/fcntl.h>
46 #include <linux/socket.h>
47 #include <netinet/in.h>
48 #include "timer.h"
49 #include "ip.h"
50 #include "tcp.h"
51 #include "sock.h"
52 #include <linux/errno.h>
53 #include <linux/timer.h>
54 #include <linux/termios.h>
55 #include <asm/system.h>
56 #include <asm/segment.h>
57 #include <linux/mm.h>
58 #include "../kern_sock.h"
59 #include "udp.h"
60 #include "icmp.h"
61
62 #define min(a,b) ((a)<(b)?(a):(b))
63
64 static void
65 print_uh(struct udp_header *uh)
66 {
67 if (uh == NULL)
68 {
69 PRINTK ("(NULL)\n");
70 return;
71 }
72 PRINTK("source = %d, dest = %d\n", net16(uh->source), net16(uh->dest));
73 PRINTK("len = %d, check = %d\n", net16(uh->len), net16(uh->check));
74 }
75
76
77 int
78 udp_select (volatile struct sock *sk, int sel_type, select_table *wait)
79 {
80 select_wait(sk->sleep, wait);
81 switch (sel_type)
82 {
83 case SEL_IN:
84 if (sk->rqueue != NULL)
85 {
86 return (1);
87 }
88 return (0);
89
90 case SEL_OUT:
91 if (sk->prot->wspace(sk) >= MIN_WRITE_SPACE)
92 {
93 return (1);
94 }
95 return (0);
96
97 case SEL_EX:
98 if (sk->err) return (1);
99 return (0);
100 }
101 return (0);
102 }
103
104
105
106
107
108
109
110
111 void
112 udp_err (int err, unsigned char *header, unsigned long daddr,
113 unsigned long saddr, struct ip_protocol *protocol)
114 {
115 struct tcp_header *th;
116 volatile struct sock *sk;
117
118 th = (struct tcp_header *)header;
119 sk = get_sock (&udp_prot, net16(th->dest), saddr, th->source, daddr);
120
121 if (sk == NULL) return;
122 if (err & 0xff00 == (ICMP_SOURCE_QUENCH << 8))
123 {
124 if (sk->cong_window > 1)
125 sk->cong_window = sk->cong_window/2;
126 return;
127 }
128
129 sk->err = icmp_err_convert[err & 0xff].errno;
130 if (icmp_err_convert[err & 0xff].fatal)
131 {
132 sk->prot->close(sk, 0);
133 }
134
135 return;
136
137 }
138
139 static unsigned short
140 udp_check (struct udp_header *uh, int len,
141 unsigned long saddr, unsigned long daddr)
142 {
143 unsigned long sum;
144 PRINTK ("udp_check (uh=%X, len = %d, saddr = %X, daddr = %X)\n",
145 uh, len, saddr, daddr);
146
147 print_uh (uh);
148
149 __asm__("\t addl %%ecx,%%ebx\n"
150 "\t adcl %%edx,%%ebx\n"
151 "\t adcl $0, %%ebx\n"
152 : "=b" (sum)
153 : "0" (daddr), "c" (saddr), "d" ((net16(len) << 16) + IPPROTO_UDP*256)
154 : "cx","bx","dx" );
155
156 if (len > 3)
157 {
158 __asm__(
159 "\tclc\n"
160 "1:\n"
161 "\t lodsl\n"
162 "\t adcl %%eax, %%ebx\n"
163 "\t loop 1b\n"
164 "\t adcl $0, %%ebx\n"
165 : "=b" (sum) , "=S" (uh)
166 : "0" (sum), "c" (len/4) ,"1" (uh)
167 : "ax", "cx", "bx", "si" );
168 }
169
170
171 __asm__(
172 "\t movl %%ebx, %%ecx\n"
173 "\t shrl $16,%%ecx\n"
174 "\t addw %%cx, %%bx\n"
175 "\t adcw $0, %%bx\n"
176 : "=b" (sum)
177 : "0" (sum)
178 : "bx", "cx");
179
180
181
182 if ((len & 2) != 0)
183 {
184 __asm__("\t lodsw\n"
185 "\t addw %%ax,%%bx\n"
186 "\t adcw $0, %%bx\n"
187 : "=b" (sum), "=S" (uh)
188 : "0" (sum) ,"1" (uh)
189 : "si", "ax", "bx");
190 }
191
192
193 if ((len & 1) != 0)
194 {
195 __asm__("\t lodsb\n"
196 "\t movb $0,%%ah\n"
197 "\t addw %%ax,%%bx\n"
198 "\t adcw $0, %%bx\n"
199 : "=b" (sum)
200 : "0" (sum) ,"S" (uh)
201 : "si", "ax", "bx");
202 }
203
204
205 return ((~sum) & 0xffff);
206 }
207
208 static void
209 udp_send_check (struct udp_header *uh, unsigned long saddr,
210 unsigned long daddr, int len, volatile struct sock *sk)
211 {
212 uh->check = 0;
213 if (sk && sk->no_check) return;
214 uh->check = udp_check (uh, len, saddr, daddr);
215 }
216
217 static int
218 udp_loopback (volatile struct sock *sk, unsigned short port,
219 unsigned char *from,
220 int len, unsigned long daddr, unsigned long saddr)
221 {
222 struct udp_header *uh;
223 struct sk_buff *skb;
224 volatile struct sock *pair;
225 sk->inuse = 1;
226
227 PRINTK ("udp_loopback \n");
228
229 pair = get_sock (sk->prot, net16(port), saddr,
230 sk->dummy_th.source, daddr);
231
232 if (pair == NULL) return (0);
233
234 skb = pair->prot->rmalloc (pair,
235 sizeof (*skb) + sizeof (*uh) + len + 4,
236 0, GFP_KERNEL);
237
238
239 if (skb == NULL) return (len);
240
241 skb->mem_addr = skb;
242 skb->mem_len = sizeof (*skb) + len + sizeof (*uh) + 4;
243
244 skb->daddr = saddr;
245 skb->saddr = daddr;
246
247 skb->len = len;
248 skb->h.raw = (unsigned char *)(skb+1);
249
250 uh = skb->h.uh;
251 uh -> source = sk->dummy_th.source;
252 uh -> dest = port;
253 uh -> len = len + sizeof (*uh);
254
255 memcpy_fromfs(uh+1, from, len);
256 pair->inuse = 1;
257 if (pair->rqueue == NULL)
258 {
259 pair->rqueue = skb;
260 skb->next = skb;
261 skb->prev = skb;
262 }
263 else
264 {
265 skb->next = pair->rqueue;
266 skb->prev = pair->rqueue->prev;
267 skb->prev->next = skb;
268 skb->next->prev = skb;
269 }
270 wake_up (pair->sleep);
271 release_sock (pair);
272 release_sock (sk);
273 return (len);
274
275 }
276
277 static int
278 udp_sendto (volatile struct sock *sk, unsigned char *from, int len,
279 int noblock,
280 unsigned flags, struct sockaddr_in *usin, int addr_len)
281 {
282
283 struct sk_buff *skb;
284 struct udp_header *uh;
285 unsigned char *buff;
286 unsigned long saddr;
287 int copied=0;
288 int amt;
289 struct device *dev=NULL;
290 struct sockaddr_in sin;
291
292
293 if (flags) return (-EINVAL);
294 if (len < 0) return (-EINVAL);
295 if (len == 0) return (0);
296
297 PRINTK ("sendto len = %d\n", len);
298
299
300 if (usin)
301 {
302 if (addr_len < sizeof (sin))
303 return (-EINVAL);
304
305 memcpy_fromfs (&sin, usin, sizeof(sin));
306 if (sin.sin_family &&
307 sin.sin_family != AF_INET)
308 return (-EINVAL);
309 if (sin.sin_port == 0)
310 return (-EINVAL);
311 }
312 else
313 {
314 if (sk->state != TCP_ESTABLISHED)
315 return (-EINVAL);
316 sin.sin_family = AF_INET;
317 sin.sin_port = sk->dummy_th.dest;
318 sin.sin_addr.s_addr = sk->daddr;
319 }
320
321
322 saddr = sk->saddr;
323 if ((saddr & 0xff000000) == 0)
324 {
325 saddr = MY_IP_ADDR;
326 }
327
328
329 if ((sin.sin_addr.s_addr & 0xff000000) == 0)
330 {
331 int err;
332 err = udp_loopback (sk, sin.sin_port, from, len,
333 sin.sin_addr.s_addr, saddr);
334 if (err < 0)
335 return (err);
336 }
337
338 sk->inuse = 1;
339
340 while (len > 0)
341 {
342 int tmp;
343 skb = sk->prot->wmalloc (sk, len + sizeof (*skb)
344 + sk->prot->max_header, 0,
345 GFP_KERNEL);
346
347
348 if (skb == NULL)
349 {
350 printk ("udp_sendto: write buffer full?\n");
351 print_sk(sk);
352 tmp = sk->wmem_alloc;
353 release_sock (sk);
354 if (copied) return (copied);
355 if (noblock) return (-EAGAIN);
356 cli();
357 if (tmp <= sk->wmem_alloc)
358 {
359 interruptible_sleep_on (sk->sleep);
360 if (current->signal & ~current->blocked)
361 {
362 sti();
363 if (copied) return (copied);
364 return (-ERESTARTSYS);
365 }
366 }
367 sk->inuse = 1;
368 sti();
369 continue;
370 }
371
372 skb->mem_addr = skb;
373 skb->mem_len = len + sizeof (*skb) + sk->prot->max_header;
374 skb->sk = sk;
375 skb->free = 1;
376 skb->arp = 0;
377
378
379 buff = (unsigned char *)(skb+1);
380 tmp = sk->prot->build_header (skb, saddr,
381 sin.sin_addr.s_addr, &dev,
382 IPPROTO_UDP, sk->opt, skb->mem_len);
383 if (tmp < 0 )
384 {
385 sk->prot->wfree (sk, skb->mem_addr, skb->mem_len);
386 release_sock (sk);
387 return (tmp);
388 }
389 buff += tmp;
390
391
392
393 amt = min (len + tmp + sizeof (*uh), dev->mtu);
394
395 PRINTK ("amt = %d, dev = %X, dev->mtu = %d\n",
396 amt, dev, dev->mtu);
397
398 skb->len = amt;
399 amt -= tmp;
400
401 uh = (struct udp_header *)buff;
402 uh->len = net16(amt);
403 uh->source = sk->dummy_th.source;
404 uh->dest = sin.sin_port;
405
406 amt -= sizeof (*uh);
407 buff += sizeof (*uh);
408
409
410 memcpy_fromfs( buff, from, amt);
411
412 len -= amt;
413 copied += amt;
414 from += amt;
415 udp_send_check (uh, saddr, sin.sin_addr.s_addr,
416 amt+sizeof (*uh), sk);
417
418 sk->prot->queue_xmit (sk, dev, skb, 1);
419 }
420 release_sock (sk);
421 return (copied);
422 }
423
424 static int
425 udp_write (volatile struct sock *sk, unsigned char *buff, int len, int noblock,
426 unsigned flags)
427 {
428 return (udp_sendto (sk, buff, len, noblock, flags, NULL, 0));
429 }
430
431
432 static int
433 udp_ioctl (volatile struct sock *sk, int cmd, unsigned long arg)
434 {
435 switch (cmd)
436 {
437 default:
438 return (-EINVAL);
439
440 case TIOCOUTQ:
441 {
442 unsigned long amount;
443 if (sk->state == TCP_LISTEN)
444 return (-EINVAL);
445 amount = sk->prot->wspace(sk)/2;
446 verify_area ((void *)arg, sizeof (unsigned long));
447 put_fs_long (amount, (unsigned long *)arg);
448 return (0);
449 }
450
451
452 case TIOCINQ:
453
454 {
455 struct sk_buff *skb;
456 unsigned long amount;
457 if (sk->state == TCP_LISTEN)
458 return (-EINVAL);
459 amount = 0;
460 skb = sk->rqueue;
461 if (skb != NULL)
462 {
463
464
465 amount = skb->len;
466 }
467
468 verify_area ((void *)arg, sizeof (unsigned long));
469 put_fs_long (amount, (unsigned long *)arg);
470 return (0);
471 }
472 }
473 }
474
475 int
476 udp_recvfrom (volatile struct sock *sk, unsigned char *to, int len,
477 int noblock,
478 unsigned flags, struct sockaddr_in *sin, int *addr_len)
479 {
480
481
482 int copied=0;
483 struct sk_buff *skb;
484 if (len == 0) return (0);
485 if (len < 0) return (-EINVAL);
486
487
488
489
490 if (sk->err)
491 {
492 int err;
493 err = -sk->err;
494 sk->err = 0;
495 return (err);
496 }
497 if (addr_len)
498 {
499 verify_area (addr_len, sizeof(*addr_len));
500 put_fs_long (sizeof (*sin), addr_len);
501 }
502 sk->inuse = 1;
503 while (sk->rqueue == NULL)
504 {
505 if (noblock)
506 {
507 release_sock (sk);
508 return (-EAGAIN);
509 }
510 release_sock (sk);
511 cli();
512 if (sk->rqueue == NULL)
513 {
514 interruptible_sleep_on (sk->sleep);
515 if (current->signal & ~current->blocked)
516 {
517 return (-ERESTARTSYS);
518 }
519 }
520 sti();
521 }
522 skb = sk->rqueue;
523
524 if (!(flags & MSG_PEEK))
525 {
526 if (skb->next == skb )
527 {
528 sk->rqueue = NULL;
529 }
530 else
531 {
532 sk->rqueue = sk->rqueue ->next;
533 skb->prev->next = skb->next;
534 skb->next->prev = skb->prev;
535 }
536 }
537 copied = min (len, skb->len);
538 verify_area (to, copied);
539 memcpy_tofs (to, skb->h.raw + sizeof (struct udp_header), copied);
540
541 if (sin)
542 {
543 struct sockaddr_in addr;
544 addr.sin_family = AF_INET;
545 addr.sin_port = skb->h.uh->source;
546 addr.sin_addr.s_addr = skb->daddr;
547 verify_area (sin, sizeof (*sin));
548 memcpy_tofs(sin, &addr, sizeof (*sin));
549 }
550
551 if (!(flags & MSG_PEEK))
552 {
553 kfree_skb (skb, FREE_READ);
554 }
555 release_sock (sk);
556 return (copied);
557
558 }
559
560
561 int
562 udp_read (volatile struct sock *sk, unsigned char *buff, int len, int noblock,
563 unsigned flags)
564 {
565 return (udp_recvfrom (sk, buff, len, noblock, flags, NULL, NULL));
566 }
567
568 int
569 udp_connect (volatile struct sock *sk, struct sockaddr_in *usin, int addr_len)
570 {
571 struct sockaddr_in sin;
572 if (addr_len < sizeof (sin)) return (-EINVAL);
573
574 memcpy_fromfs (&sin, usin, sizeof (sin));
575 if (sin.sin_family && sin.sin_family != AF_INET)
576 return (-EAFNOSUPPORT);
577 sk->daddr = sin.sin_addr.s_addr;
578 sk->dummy_th.dest = sin.sin_port;
579 sk->state = TCP_ESTABLISHED;
580 return(0);
581 }
582
583 static void
584 udp_close(volatile struct sock *sk, int timeout)
585 {
586 sk->inuse = 1;
587 sk->state = TCP_CLOSE;
588 if (sk->dead)
589 destroy_sock (sk);
590 else
591 release_sock (sk);
592 }
593
594 int
595 udp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
596 unsigned long daddr, unsigned short len,
597 unsigned long saddr, int redo, struct ip_protocol *protocol)
598 {
599
600 struct proto *prot=&udp_prot;
601 volatile struct sock *sk;
602 struct udp_header *uh;
603
604 uh = (struct udp_header *) skb->h.uh;
605
606 if (dev->add_arp) dev->add_arp (saddr, skb, dev);
607
608 sk = get_sock (prot, net16(uh->dest), saddr, uh->source, daddr);
609
610
611 if (sk == NULL)
612 {
613 if ((daddr & 0xff000000 != 0) && (daddr & 0xff000000 != 0xff000000))
614 {
615 icmp_reply (skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, dev);
616 }
617 skb->sk = NULL;
618 kfree_skb (skb, 0);
619 return (0);
620 }
621
622
623 if (!redo)
624 {
625 if (uh->check && udp_check (uh, len, saddr, daddr))
626 {
627 PRINTK ("bad udp checksum\n");
628 skb->sk = NULL;
629 kfree_skb (skb, 0);
630 return (0);
631 }
632
633 skb->sk = sk;
634 skb->dev = dev;
635 skb->len = len;
636
637
638 skb->daddr = saddr;
639 skb->saddr = daddr;
640
641
642 cli();
643 if (sk->inuse)
644 {
645 if (sk->back_log == NULL)
646 {
647 sk->back_log = skb;
648 skb->next = skb;
649 skb->prev = skb;
650 }
651 else
652 {
653 skb->next = sk->back_log;
654 skb->prev = sk->back_log->prev;
655 skb->prev->next = skb;
656 skb->next->prev = skb;
657 }
658 sti();
659 return (0);
660 }
661 sk->inuse = 1;
662 sti();
663 }
664
665
666 if (sk->rmem_alloc + skb->mem_len >= SK_RMEM_MAX)
667 {
668 skb->sk = NULL;
669 kfree_skb (skb, 0);
670 release_sock (sk);
671 return (0);
672 }
673
674 sk->rmem_alloc += skb->mem_len;
675
676
677 PRINTK ("<< \n");
678 print_sk (sk);
679
680
681 if (sk->rqueue == NULL)
682 {
683 sk->rqueue = skb;
684 skb->next = skb;
685 skb->prev = skb;
686 }
687 else
688 {
689 skb->next = sk->rqueue;
690 skb->prev = sk->rqueue->prev;
691 skb->prev->next = skb;
692 skb->next->prev = skb;
693 }
694
695 skb->len = len - sizeof (*uh);
696
697 if (!sk->dead)
698 wake_up (sk->sleep);
699
700 release_sock (sk);
701 return (0);
702 }
703
704
705
706 struct proto udp_prot =
707 {
708 sock_wmalloc,
709 sock_rmalloc,
710 sock_wfree,
711 sock_rfree,
712 sock_rspace,
713 sock_wspace,
714 udp_close,
715 udp_read,
716 udp_write,
717 udp_sendto,
718 udp_recvfrom,
719 ip_build_header,
720 udp_connect,
721 NULL,
722 ip_queue_xmit,
723 ip_retransmit,
724 NULL,
725 NULL,
726 udp_rcv,
727 udp_select,
728 udp_ioctl,
729 NULL,
730 128,
731 0,
732 {NULL,}
733 };
734