|
|
1.1 root 1: /* udp.c */
2: /*
3: Copyright (C) 1992 Ross Biro
4:
5: This program is free software; you can redistribute it and/or modify
6: it under the terms of the GNU General Public License as published by
7: the Free Software Foundation; either version 2, or (at your option)
8: any later version.
9:
10: This program is distributed in the hope that it will be useful,
11: but WITHOUT ANY WARRANTY; without even the implied warranty of
12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13: GNU General Public License for more details.
14:
15: You should have received a copy of the GNU General Public License
16: along with this program; if not, write to the Free Software
17: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18:
19: The Author may be reached as [email protected] or
20: C/O Department of Mathematics; Stanford University; Stanford, CA 94305
21: */
22:
23: #include <linux/types.h>
24: #include <linux/sched.h>
25: #include <linux/fcntl.h>
26: #include <linux/socket.h>
27: #include <netinet/in.h>
28: #include "timer.h"
29: #include "ip.h"
30: #include "tcp.h"
31: #include "sock.h"
32: #include <linux/errno.h>
33: #include <linux/timer.h>
34: #include <asm/system.h>
35: #include <asm/segment.h>
36: #include "../kern_sock.h" /* for PRINTK */
37: #include "udp.h"
38: #include "icmp.h"
39:
40: #define min(a,b) ((a)<(b)?(a):(b))
41:
42: static void
43: print_uh(struct udp_header *uh)
44: {
45: PRINTK("source = %d, dest = %d\n", net16(uh->source), net16(uh->dest));
46: PRINTK("len = %d, check = %d\n", net16(uh->len), net16(uh->check));
47: }
48:
49:
50: int
51: udp_select (volatile struct sock *sk, int sel_type, select_table *wait)
52: {
53: select_wait(sk->sleep, wait);
54: switch (sel_type)
55: {
56: case SEL_IN:
57: if (sk->rqueue != NULL)
58: {
59: return (1);
60: }
61: return (0);
62:
63: case SEL_OUT:
64: if (sk->prot->wspace(sk) >= MIN_WRITE_SPACE)
65: {
66: return (1);
67: }
68: return (0);
69:
70: case SEL_EX:
71: if (sk->err) return (1); /* can this ever happen? */
72: return (0);
73: }
74: return (0);
75: }
76:
77: /* this routine is called by the icmp module when it gets some
78: sort of error condition. If err < 0 then the socket should
79: be closed and the error returned to the user. If err > 0
80: it's just the icmp type << 8 | icmp code.
81: header points to the first 8 bytes of the tcp header. We need
82: to find the appropriate port. */
83:
84: void
85: udp_err (int err, unsigned char *header, unsigned long daddr,
86: unsigned long saddr, struct ip_protocol *protocol)
87: {
88: struct tcp_header *th;
89: volatile struct sock *sk;
90:
91: th = (struct tcp_header *)header;
92: sk = get_sock (&udp_prot, net16(th->dest), saddr, th->source, daddr);
93:
94: if (sk == NULL) return;
95: if (err & 0xff00 == (ICMP_SOURCE_QUENCH << 8))
96: {
97: if (sk->cong_window > 1)
98: sk->cong_window = sk->cong_window/2;
99: return;
100: }
101:
102: sk->err = icmp_err_convert[err & 0xff].errno;
103: if (icmp_err_convert[err & 0xff].fatal)
104: {
105: sk->prot->close(sk, 0);
106: }
107:
108: return;
109:
110: }
111:
112: static unsigned short
113: udp_check (struct udp_header *uh, int len,
114: unsigned long saddr, unsigned long daddr)
115: {
116: unsigned long sum;
117: PRINTK ("udp_check (uh=%X, len = %d, saddr = %X, daddr = %X)\n",
118: uh, len, saddr, daddr);
119:
120: print_uh (uh);
121:
122: __asm__("\t addl %%ecx,%%ebx\n"
123: "\t adcl %%edx,%%ebx\n"
124: "\t adcl $0, %%ebx\n"
125: : "=b" (sum)
126: : "0" (daddr), "c" (saddr), "d" ((net16(len) << 16) + IP_UDP*256)
127: : "cx","bx","dx" );
128:
129: if (len > 3)
130: {
131: __asm__(
132: "\tclc\n"
133: "1:\n"
134: "\t lodsl\n"
135: "\t adcl %%eax, %%ebx\n"
136: "\t loop 1b\n"
137: "\t adcl $0, %%ebx\n"
138: : "=b" (sum) , "=S" (uh)
139: : "0" (sum), "c" (len/4) ,"1" (uh)
140: : "ax", "cx", "bx", "si" );
141: }
142:
143: /* convert from 32 bits to 16 bits. */
144: __asm__(
145: "\t movl %%ebx, %%ecx\n"
146: "\t shrl $16,%%ecx\n"
147: "\t addw %%cx, %%bx\n"
148: "\t adcw $0, %%bx\n"
149: : "=b" (sum)
150: : "0" (sum)
151: : "bx", "cx");
152:
153:
154: /* check for an extra word. */
155: if ((len & 2) != 0)
156: {
157: __asm__("\t lodsw\n"
158: "\t addw %%ax,%%bx\n"
159: "\t adcw $0, %%bx\n"
160: : "=b" (sum), "=S" (uh)
161: : "0" (sum) ,"1" (uh)
162: : "si", "ax", "bx");
163: }
164:
165: /* now check for the extra byte. */
166: if ((len & 1) != 0)
167: {
168: __asm__("\t lodsb\n"
169: "\t movb $0,%%ah\n"
170: "\t addw %%ax,%%bx\n"
171: "\t adcw $0, %%bx\n"
172: : "=b" (sum)
173: : "0" (sum) ,"S" (uh)
174: : "si", "ax", "bx");
175: }
176: /* we only want the bottom 16 bits, but we never cleared
177: the top 16. */
178: return ((~sum) & 0xffff);
179: }
180:
181: static void
182: udp_send_check (struct udp_header *uh, unsigned long saddr,
183: unsigned long daddr, int len, volatile struct sock *sk)
184: {
185: uh->check = 0;
186: if (sk && sk->no_check) return;
187: uh->check = udp_check (uh, len, saddr, daddr);
188: }
189:
190: static int
191: udp_loopback (volatile struct sock *sk, unsigned short port,
192: unsigned char *from,
193: int len, unsigned long daddr, unsigned long saddr)
194: {
195: struct udp_header *uh;
196: struct sk_buff *skb;
197: volatile struct sock *pair;
198: sk->inuse = 1;
199:
200: PRINTK ("udp_loopback \n");
201:
202: pair = get_sock (sk->prot, net16(port), saddr,
203: sk->dummy_th.source, daddr);
204:
205: if (pair == NULL) return (0);
206:
207: skb = pair->prot->rmalloc (pair,
208: sizeof (*skb) + sizeof (*uh) + len + 4,
209: 0);
210:
211: /* if we didn't get the memory, just drop the packet. */
212: if (skb == NULL) return (len);
213:
214: skb->mem_addr = skb;
215: skb->mem_len = sizeof (*skb) + len + sizeof (*uh) + 4;
216:
217: skb->daddr = saddr;
218: skb->saddr = daddr;
219:
220: skb->len = len;
221: skb->h.raw = (unsigned char *)(skb+1);
222:
223: uh = skb->h.uh;
224: uh -> source = sk->dummy_th.source;
225: uh -> dest = port;
226: uh -> len = len + sizeof (*uh);
227: verify_area (from , len);
228: memcpy_fromfs(uh+1, from, len);
229: pair->inuse = 1;
230: if (pair->rqueue == NULL)
231: {
232: pair->rqueue = skb;
233: skb->next = skb;
234: skb->prev = skb;
235: }
236: else
237: {
238: skb->next = pair->rqueue;
239: skb->prev = pair->rqueue->prev;
240: skb->prev->next = skb;
241: skb->next->prev = skb;
242: }
243: wake_up (pair->sleep);
244: release_sock (pair);
245: release_sock (sk);
246: return (len);
247:
248: }
249:
250: static int
251: udp_sendto (volatile struct sock *sk, unsigned char *from, int len,
252: int noblock,
253: unsigned flags, struct sockaddr_in *usin, int addr_len)
254: {
255: /* this should be easy, we just send the packet. */
256: struct sk_buff *skb;
257: struct udp_header *uh;
258: unsigned char *buff;
259: unsigned long saddr;
260: int copied=0;
261: int amt;
262: struct device *dev=NULL;
263: struct sockaddr_in sin;
264:
265: /* check the flags. */
266: if (flags) return (-EINVAL);
267: if (len < 0) return (-EINVAL);
268: if (len == 0) return (0);
269:
270: PRINTK ("sendto len = %d\n", len);
271:
272: /* get and verify the address. */
273: if (usin)
274: {
275: if (addr_len < sizeof (sin))
276: return (-EINVAL);
277: verify_area (usin, sizeof (sin));
278: memcpy_fromfs (&sin, usin, sizeof(sin));
279: if (sin.sin_family &&
280: sin.sin_family != AF_INET)
281: return (-EINVAL);
282: if (sin.sin_port == 0)
283: return (-EINVAL);
284: }
285: else
286: {
287: if (sk->state != TCP_ESTABLISHED)
288: return (-EINVAL);
289: sin.sin_family = AF_INET;
290: sin.sin_port = sk->dummy_th.dest;
291: sin.sin_addr.s_addr = sk->daddr;
292: }
293:
294: /* check for a valid saddr. */
295: saddr = sk->saddr;
296: if ((saddr & 0xff000000) == 0)
297: {
298: saddr = MY_IP_ADDR;
299: }
300:
301: /* if it's a broadcast, make sure we get it. */
302: if ((sin.sin_addr.s_addr & 0xff000000) == 0)
303: {
304: int err;
305: err = udp_loopback (sk, sin.sin_port, from, len,
306: sin.sin_addr.s_addr, saddr);
307: if (err < 0)
308: return (err);
309: }
310:
311: sk->inuse = 1;
312:
313: while (len > 0)
314: {
315: int tmp;
316: skb = sk->prot->wmalloc (sk, len + sizeof (*skb)
317: + sk->prot->max_header, 0);
318: /* this should never happen, but it is possible. */
319:
320: if (skb == NULL)
321: {
322: printk ("udp_sendto: write buffer full?\n");
323: print_sk(sk);
324: release_sock (sk);
325: if (copied || !noblock)
326: return (copied);
327: return (-EAGAIN);
328: }
329:
330: skb->mem_addr = skb;
331: skb->mem_len = len + sizeof (*skb) + sk->prot->max_header;
332: skb->sk = sk;
333: skb->free = 1;
334: skb->arp = 0;
335:
336: /* now build the ip and dev header. */
337: buff = (unsigned char *)(skb+1);
338: tmp = sk->prot->build_header (skb, saddr,
339: sin.sin_addr.s_addr, &dev,
340: IP_UDP, sk->opt, skb->mem_len);
341: if (tmp < 0 )
342: {
343: sk->prot->wfree (sk, skb->mem_addr, skb->mem_len);
344: release_sock (sk);
345: return (tmp);
346: }
347: buff += tmp;
348:
349: /* we shouldn't do this, instead we should just
350: let the ip protocol fragment the packet. */
351: amt = min (len + tmp + sizeof (*uh), dev->mtu);
352:
353: PRINTK ("amt = %d, dev = %X, dev->mtu = %d\n",
354: amt, dev, dev->mtu);
355:
356: skb->len = amt;
357: amt -= tmp;
358:
359: uh = (struct udp_header *)buff;
360: uh->len = net16(amt);
361: uh->source = sk->dummy_th.source;
362: uh->dest = sin.sin_port;
363:
364: amt -= sizeof (*uh);
365: buff += sizeof (*uh);
366:
367: verify_area (from, amt);
368: memcpy_fromfs( buff, from, amt);
369:
370: len -= amt;
371: copied += amt;
372: from += amt;
373: udp_send_check (uh, saddr, sin.sin_addr.s_addr,
374: amt+sizeof (*uh), sk);
375:
376: sk->prot->queue_xmit (sk, dev, skb, 1);
377: }
378: release_sock (sk);
379: return (copied);
380: }
381:
382: static int
383: udp_write (volatile struct sock *sk, unsigned char *buff, int len, int noblock,
384: unsigned flags)
385: {
386: return (udp_sendto (sk, buff, len, noblock, flags, NULL, 0));
387: }
388:
389: int
390: udp_recvfrom (volatile struct sock *sk, unsigned char *to, int len,
391: int noblock,
392: unsigned flags, struct sockaddr_in *sin, int *addr_len)
393: {
394: /* this should be easy, if there is something there we
395: return it, otherwise we block. */
396: int copied=0;
397: struct sk_buff *skb;
398: if (len == 0) return (0);
399: if (len < 0) return (-EINVAL);
400: if (addr_len)
401: {
402: verify_area (addr_len, sizeof(*addr_len));
403: put_fs_long (sizeof (*sin), addr_len);
404: }
405: sk->inuse = 1;
406: while (sk->rqueue == NULL)
407: {
408: if (noblock)
409: {
410: release_sock (sk);
411: return (-EAGAIN);
412: }
413: release_sock (sk);
414: cli();
415: if (sk->rqueue == NULL)
416: {
417: interruptible_sleep_on (sk->sleep);
418: if (current->signal & ~current->blocked)
419: {
420: return (-ERESTARTSYS);
421: }
422: }
423: sti();
424: }
425: skb = sk->rqueue;
426:
427: if (!(flags & MSG_PEEK))
428: {
429: if (skb->next == skb )
430: {
431: sk->rqueue = NULL;
432: }
433: else
434: {
435: sk->rqueue = sk->rqueue ->next;
436: skb->prev->next = skb->next;
437: skb->next->prev = skb->prev;
438: }
439: }
440: copied = min (len, skb->len);
441: verify_area (to, copied);
442: memcpy_tofs (to, skb->h.raw + sizeof (struct udp_header), copied);
443: /* copy the address. */
444: if (sin)
445: {
446: struct sockaddr_in addr;
447: addr.sin_family = AF_INET;
448: addr.sin_port = skb->h.uh->source;
449: addr.sin_addr.s_addr = skb->daddr;
450: verify_area (sin, sizeof (*sin));
451: memcpy_tofs(sin, &addr, sizeof (*sin));
452: }
453:
454: if (!(flags & MSG_PEEK))
455: {
456: free_skb (skb, FREE_READ);
457: }
458: release_sock (sk);
459: return (copied);
460:
461: }
462:
463:
464: int
465: udp_read (volatile struct sock *sk, unsigned char *buff, int len, int noblock,
466: unsigned flags)
467: {
468: return (udp_recvfrom (sk, buff, len, noblock, flags, NULL, NULL));
469: }
470:
471: int
472: udp_connect (volatile struct sock *sk, struct sockaddr_in *usin, int addr_len)
473: {
474: struct sockaddr_in sin;
475: if (addr_len < sizeof (sin)) return (-EINVAL);
476: verify_area (usin, sizeof (sin));
477: memcpy_fromfs (&sin, usin, sizeof (sin));
478: if (sin.sin_family && sin.sin_family != AF_INET)
479: return (-EAFNOSUPPORT);
480: sk->daddr = sin.sin_addr.s_addr;
481: sk->dummy_th.dest = sin.sin_port;
482: sk->state = TCP_ESTABLISHED;
483: return(0);
484: }
485:
486: static void
487: udp_close(volatile struct sock *sk, int timeout)
488: {
489: sk->inuse = 1;
490: sk->state = TCP_CLOSE;
491: if (sk->dead)
492: destroy_sock (sk);
493: else
494: release_sock (sk);
495: }
496:
497: int
498: udp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
499: unsigned long daddr, unsigned short len,
500: unsigned long saddr, int redo, struct ip_protocol *protocol)
501: {
502: /* all we need to do is get the socket, and then do a checksum. */
503: struct proto *prot=&udp_prot;
504: volatile struct sock *sk;
505: struct udp_header *uh;
506:
507: uh = (struct udp_header *) skb->h.uh;
508:
509: if (dev->add_arp) dev->add_arp (saddr, skb, dev);
510:
511: sk = get_sock (prot, net16(uh->dest), saddr, uh->source, daddr);
512:
513: /* if we don't know about the socket, forget about it. */
514: if (sk == NULL &&
515: (daddr & 0xff000000 != 0) && (daddr & 0xff000000 != 0xff000000))
516: {
517: icmp_reply (skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, dev);
518: skb->sk = NULL;
519: free_skb (skb, 0);
520: return (0);
521: }
522:
523:
524: if (!redo)
525: {
526: if (uh->check && udp_check (uh, len, saddr, daddr))
527: {
528: PRINTK ("bad udp checksum\n");
529: skb->sk = NULL;
530: free_skb (skb, 0);
531: return (0);
532: }
533:
534: skb->sk = sk;
535: skb->dev = dev;
536: skb->len = len;
537:
538: /* these are supposed to be switched. */
539: skb->daddr = saddr;
540: skb->saddr = daddr;
541:
542: /* Now deal with the in use. */
543: cli();
544: if (sk->inuse)
545: {
546: if (sk->back_log == NULL)
547: {
548: sk->back_log = skb;
549: skb->next = skb;
550: skb->prev = skb;
551: }
552: else
553: {
554: skb->next = sk->back_log;
555: skb->prev = sk->back_log->prev;
556: skb->prev->next = skb;
557: skb->next->prev = skb;
558: }
559: sti();
560: return (0);
561: }
562: sk->inuse = 1;
563: sti();
564: }
565:
566: /* charge it too the socket. */
567: if (sk->rmem_alloc + skb->mem_len >= SK_RMEM_MAX)
568: {
569: skb->sk = NULL;
570: free_skb (skb, 0);
571: release_sock (sk);
572: return (0);
573: }
574:
575: sk->rmem_alloc += skb->mem_len;
576:
577: /* At this point we should print the thing out. */
578: PRINTK ("<< \n");
579: print_sk (sk);
580:
581: /* now add it to the data chain and wake things up. */
582: if (sk->rqueue == NULL)
583: {
584: sk->rqueue = skb;
585: skb->next = skb;
586: skb->prev = skb;
587: }
588: else
589: {
590: skb->next = sk->rqueue;
591: skb->prev = sk->rqueue->prev;
592: skb->prev->next = skb;
593: skb->next->prev = skb;
594: }
595:
596: skb->len = len - sizeof (*uh);
597:
598: if (!sk->dead)
599: wake_up (sk->sleep);
600:
601: release_sock (sk);
602: return (0);
603: }
604:
605:
606:
607: struct proto udp_prot =
608: {
609: sock_wmalloc,
610: sock_rmalloc,
611: sock_wfree,
612: sock_rfree,
613: sock_rspace,
614: sock_wspace,
615: udp_close,
616: udp_read,
617: udp_write,
618: udp_sendto,
619: udp_recvfrom,
620: ip_build_header,
621: udp_connect,
622: NULL,
623: ip_queue_xmit,
624: ip_retransmit,
625: NULL,
626: NULL,
627: udp_rcv,
628: udp_select,
629: NULL,
630: NULL,
631: 128,
632: 0,
633: {NULL,}
634: };
635:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.