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