1 /*
2 * INET An implementation of the TCP/IP protocol suite for the LINUX
3 * operating system. INET is implemented using the BSD Socket
4 * interface as the means of communication with the user level.
5 *
6 * The User Datagram Protocol (UDP).
7 *
8 * Version: @(#)udp.c 1.0.13 06/02/93
9 *
10 * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 *
13 * Fixes:
14 * Alan Cox : verify_area() calls
15 * Alan Cox : stopped close while in use off icmp
16 * messages. Not a fix but a botch that
17 * for udp at least is 'valid'.
18 * Alan Cox : Fixed icmp handling properly
19 * Alan Cox : Correct error for oversized datagrams
20 * Alan Cox : Tidied select() semantics.
21 * Alan Cox : udp_err() fixed properly, also now
22 * select and read wake correctly on errors
23 * Alan Cox : udp_send verify_area moved to avoid mem leak
24 * Alan Cox : UDP can count its memory
25 * Alan Cox : send to an unknown connection causes
26 * an ECONNREFUSED off the icmp, but
27 * does NOT close.
28 * Alan Cox : Switched to new sk_buff handlers. No more backlog!
29 * Alan Cox : Using generic datagram code. Even smaller and the PEEK
30 * bug no longer crashes it.
31 * Fred Van Kempen : Net2e support for sk->broadcast.
32 * Alan Cox : Uses skb_free_datagram
33 * Alan Cox : Added get/set sockopt support.
34 * Alan Cox : Broadcasting without option set returns EACCES.
35 * Alan Cox : No wakeup calls. Instead we now use the callbacks.
36 * Alan Cox : Use ip_tos and ip_ttl
37 * Alan Cox : SNMP Mibs
38 * Alan Cox : MSG_DONTROUTE, and 0.0.0.0 support.
39 * Matt Dillon : UDP length checks.
40 * Alan Cox : Smarter af_inet used properly.
41 * Alan Cox : Use new kernel side addressing.
42 * Alan Cox : Incorrect return on truncated datagram receive.
43 *
44 *
45 * This program is free software; you can redistribute it and/or
46 * modify it under the terms of the GNU General Public License
47 * as published by the Free Software Foundation; either version
48 * 2 of the License, or (at your option) any later version.
49 */
50
51 #include <asm/system.h>
52 #include <asm/segment.h>
53 #include <linux/types.h>
54 #include <linux/sched.h>
55 #include <linux/fcntl.h>
56 #include <linux/socket.h>
57 #include <linux/sockios.h>
58 #include <linux/in.h>
59 #include <linux/errno.h>
60 #include <linux/timer.h>
61 #include <linux/termios.h>
62 #include <linux/mm.h>
63 #include <linux/config.h>
64 #include <linux/inet.h>
65 #include <linux/netdevice.h>
66 #include "snmp.h"
67 #include "ip.h"
68 #include "protocol.h"
69 #include "tcp.h"
70 #include <linux/skbuff.h>
71 #include "sock.h"
72 #include "udp.h"
73 #include "icmp.h"
74 #include "route.h"
75
76 /*
77 * SNMP MIB for the UDP layer
78 */
79
80 struct udp_mib udp_statistics;
81
82
83 static int udp_deliver(struct sock *sk, struct udphdr *uh, struct sk_buff *skb, struct device *dev, long saddr, long daddr, int len);
84
85 #define min(a,b) ((a)<(b)?(a):(b))
86
87
88 /*
89 * This routine is called by the ICMP module when it gets some
90 * sort of error condition. If err < 0 then the socket should
91 * be closed and the error returned to the user. If err > 0
92 * it's just the icmp type << 8 | icmp code.
93 * Header points to the ip header of the error packet. We move
94 * on past this. Then (as it used to claim before adjustment)
95 * header points to the first 8 bytes of the udp header. We need
96 * to find the appropriate port.
97 */
98
99 void udp_err(int err, unsigned char *header, unsigned long daddr,
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
100 unsigned long saddr, struct inet_protocol *protocol)
101 {
102 struct udphdr *th;
103 struct sock *sk;
104 struct iphdr *ip=(struct iphdr *)header;
105
106 header += 4*ip->ihl;
107
108 /*
109 * Find the 8 bytes of post IP header ICMP included for us
110 */
111
112 th = (struct udphdr *)header;
113
114 sk = get_sock(&udp_prot, th->source, daddr, th->dest, saddr);
115
116 if (sk == NULL)
117 return; /* No socket for error */
118
119 if (err & 0xff00 ==(ICMP_SOURCE_QUENCH << 8))
120 { /* Slow down! */
121 if (sk->cong_window > 1)
122 sk->cong_window = sk->cong_window/2;
123 return;
124 }
125
126 /*
127 * Various people wanted BSD UDP semantics. Well they've come
128 * back out because they slow down response to stuff like dead
129 * or unreachable name servers and they screw term users something
130 * chronic. Oh and it violates RFC1122. So basically fix your
131 * client code people.
132 */
133
134 #ifdef CONFIG_I_AM_A_BROKEN_BSD_WEENIE
135 /*
136 * It's only fatal if we have connected to them. I'm not happy
137 * with this code. Some BSD comparisons need doing.
138 */
139
140 if (icmp_err_convert[err & 0xff].fatal && sk->state == TCP_ESTABLISHED)
141 {
142 sk->err = icmp_err_convert[err & 0xff].errno;
143 sk->error_report(sk);
144 }
145 #else
146 if (icmp_err_convert[err & 0xff].fatal)
147 {
148 sk->err = icmp_err_convert[err & 0xff].errno;
149 sk->error_report(sk);
150 }
151 #endif
152 }
153
154
155 static unsigned short udp_check(struct udphdr *uh, int len, unsigned long saddr, unsigned long daddr)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
156 {
157 unsigned long sum;
158
159 __asm__( "\t addl %%ecx,%%ebx\n"
160 "\t adcl %%edx,%%ebx\n"
161 "\t adcl $0, %%ebx\n"
162 : "=b"(sum)
163 : "0"(daddr), "c"(saddr), "d"((ntohs(len) << 16) + IPPROTO_UDP*256)
164 : "cx","bx","dx" );
165
166 if (len > 3)
167 {
168 __asm__("\tclc\n"
169 "1:\n"
170 "\t lodsl\n"
171 "\t adcl %%eax, %%ebx\n"
172 "\t loop 1b\n"
173 "\t adcl $0, %%ebx\n"
174 : "=b"(sum) , "=S"(uh)
175 : "0"(sum), "c"(len/4) ,"1"(uh)
176 : "ax", "cx", "bx", "si" );
177 }
178
179 /*
180 * Convert from 32 bits to 16 bits.
181 */
182
183 __asm__("\t movl %%ebx, %%ecx\n"
184 "\t shrl $16,%%ecx\n"
185 "\t addw %%cx, %%bx\n"
186 "\t adcw $0, %%bx\n"
187 : "=b"(sum)
188 : "0"(sum)
189 : "bx", "cx");
190
191 /*
192 * Check for an extra word.
193 */
194
195 if ((len & 2) != 0)
196 {
197 __asm__("\t lodsw\n"
198 "\t addw %%ax,%%bx\n"
199 "\t adcw $0, %%bx\n"
200 : "=b"(sum), "=S"(uh)
201 : "0"(sum) ,"1"(uh)
202 : "si", "ax", "bx");
203 }
204
205 /*
206 * Now check for the extra byte.
207 */
208
209 if ((len & 1) != 0)
210 {
211 __asm__("\t lodsb\n"
212 "\t movb $0,%%ah\n"
213 "\t addw %%ax,%%bx\n"
214 "\t adcw $0, %%bx\n"
215 : "=b"(sum)
216 : "0"(sum) ,"S"(uh)
217 : "si", "ax", "bx");
218 }
219
220 /*
221 * We only want the bottom 16 bits, but we never cleared the top 16.
222 */
223
224 return((~sum) & 0xffff);
225 }
226
227 /*
228 * Generate UDP checksums. These may be disabled, eg for fast NFS over ethernet
229 * We default them enabled.. if you turn them off you either know what you are
230 * doing or get burned...
231 */
232
233 static void udp_send_check(struct udphdr *uh, unsigned long saddr,
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
234 unsigned long daddr, int len, struct sock *sk)
235 {
236 uh->check = 0;
237 if (sk && sk->no_check)
238 return;
239 uh->check = udp_check(uh, len, saddr, daddr);
240
241 /*
242 * FFFF and 0 are the same, pick the right one as 0 in the
243 * actual field means no checksum.
244 */
245
246 if (uh->check == 0)
247 uh->check = 0xffff;
248 }
249
250
251 static int udp_send(struct sock *sk, struct sockaddr_in *sin,
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
252 unsigned char *from, int len, int rt)
253 {
254 struct sk_buff *skb;
255 struct device *dev;
256 struct udphdr *uh;
257 unsigned char *buff;
258 unsigned long saddr;
259 int size, tmp;
260 int ttl;
261
262 /*
263 * Allocate an sk_buff copy of the packet.
264 */
265
266 size = sk->prot->max_header + len;
267 skb = sock_alloc_send_skb(sk, size, 0, &tmp);
268
269
270 if (skb == NULL)
271 return tmp;
272
273 skb->sk = NULL; /* to avoid changing sk->saddr */
274 skb->free = 1;
275 skb->localroute = sk->localroute|(rt&MSG_DONTROUTE);
276
277 /*
278 * Now build the IP and MAC header.
279 */
280
281 buff = skb->data;
282 saddr = sk->saddr;
283 dev = NULL;
284 ttl = sk->ip_ttl;
285 #ifdef CONFIG_IP_MULTICAST
286 if (MULTICAST(sin->sin_addr.s_addr))
287 ttl = sk->ip_mc_ttl;
288 #endif
289 tmp = sk->prot->build_header(skb, saddr, sin->sin_addr.s_addr,
290 &dev, IPPROTO_UDP, sk->opt, skb->mem_len,sk->ip_tos,ttl);
291
292 skb->sk=sk; /* So memory is freed correctly */
293
294 /*
295 * Unable to put a header on the packet.
296 */
297
298 if (tmp < 0 )
299 {
300 sk->prot->wfree(sk, skb->mem_addr, skb->mem_len);
301 return(tmp);
302 }
303
304 buff += tmp;
305 saddr = skb->saddr; /*dev->pa_addr;*/
306 skb->len = tmp + sizeof(struct udphdr) + len; /* len + UDP + IP + MAC */
307 skb->dev = dev;
308
309 /*
310 * Fill in the UDP header.
311 */
312
313 uh = (struct udphdr *) buff;
314 uh->len = htons(len + sizeof(struct udphdr));
315 uh->source = sk->dummy_th.source;
316 uh->dest = sin->sin_port;
317 buff = (unsigned char *) (uh + 1);
318
319 /*
320 * Copy the user data.
321 */
322
323 memcpy_fromfs(buff, from, len);
324
325 /*
326 * Set up the UDP checksum.
327 */
328
329 udp_send_check(uh, saddr, sin->sin_addr.s_addr, skb->len - tmp, sk);
330
331 /*
332 * Send the datagram to the interface.
333 */
334
335 udp_statistics.UdpOutDatagrams++;
336
337 sk->prot->queue_xmit(sk, dev, skb, 1);
338 return(len);
339 }
340
341
342 static int udp_sendto(struct sock *sk, unsigned char *from, int len, int noblock,
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
343 unsigned flags, struct sockaddr_in *usin, int addr_len)
344 {
345 struct sockaddr_in sin;
346 int tmp;
347
348 /*
349 * Check the flags. We support no flags for UDP sending
350 */
351 if (flags&~MSG_DONTROUTE)
352 return(-EINVAL);
353 /*
354 * Get and verify the address.
355 */
356
357 if (usin)
358 {
359 if (addr_len < sizeof(sin))
360 return(-EINVAL);
361 memcpy(&sin,usin,sizeof(sin));
362 if (sin.sin_family && sin.sin_family != AF_INET)
363 return(-EINVAL);
364 if (sin.sin_port == 0)
365 return(-EINVAL);
366 }
367 else
368 {
369 if (sk->state != TCP_ESTABLISHED)
370 return(-EINVAL);
371 sin.sin_family = AF_INET;
372 sin.sin_port = sk->dummy_th.dest;
373 sin.sin_addr.s_addr = sk->daddr;
374 }
375
376 /*
377 * BSD socket semantics. You must set SO_BROADCAST to permit
378 * broadcasting of data.
379 */
380
381 if(sin.sin_addr.s_addr==INADDR_ANY)
382 sin.sin_addr.s_addr=ip_my_addr();
383
384 if(!sk->broadcast && ip_chk_addr(sin.sin_addr.s_addr)==IS_BROADCAST)
385 return -EACCES; /* Must turn broadcast on first */
386
387 sk->inuse = 1;
388
389 /* Send the packet. */
390 tmp = udp_send(sk, &sin, from, len, flags);
391
392 /* The datagram has been sent off. Release the socket. */
393 release_sock(sk);
394 return(tmp);
395 }
396
397 /*
398 * In BSD SOCK_DGRAM a write is just like a send.
399 */
400
401 static int udp_write(struct sock *sk, unsigned char *buff, int len, int noblock,
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
402 unsigned flags)
403 {
404 return(udp_sendto(sk, buff, len, noblock, flags, NULL, 0));
405 }
406
407
408 /*
409 * IOCTL requests applicable to the UDP protocol
410 */
411
412 int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
413 {
414 int err;
415 switch(cmd)
416 {
417 case TIOCOUTQ:
418 {
419 unsigned long amount;
420
421 if (sk->state == TCP_LISTEN) return(-EINVAL);
422 amount = sk->prot->wspace(sk)/*/2*/;
423 err=verify_area(VERIFY_WRITE,(void *)arg,
424 sizeof(unsigned long));
425 if(err)
426 return(err);
427 put_fs_long(amount,(unsigned long *)arg);
428 return(0);
429 }
430
431 case TIOCINQ:
432 {
433 struct sk_buff *skb;
434 unsigned long amount;
435
436 if (sk->state == TCP_LISTEN) return(-EINVAL);
437 amount = 0;
438 skb = skb_peek(&sk->receive_queue);
439 if (skb != NULL) {
440 /*
441 * We will only return the amount
442 * of this packet since that is all
443 * that will be read.
444 */
445 amount = skb->len;
446 }
447 err=verify_area(VERIFY_WRITE,(void *)arg,
448 sizeof(unsigned long));
449 if(err)
450 return(err);
451 put_fs_long(amount,(unsigned long *)arg);
452 return(0);
453 }
454
455 default:
456 return(-EINVAL);
457 }
458 return(0);
459 }
460
461
462 /*
463 * This should be easy, if there is something there we\
464 * return it, otherwise we block.
465 */
466
467 int udp_recvfrom(struct sock *sk, unsigned char *to, int len,
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
468 int noblock, unsigned flags, struct sockaddr_in *sin,
469 int *addr_len)
470 {
471 int copied = 0;
472 int truesize;
473 struct sk_buff *skb;
474 int er;
475
476 /*
477 * Check any passed addresses
478 */
479
480 if (addr_len)
481 *addr_len=sizeof(*sin);
482
483 /*
484 * From here the generic datagram does a lot of the work. Come
485 * the finished NET3, it will do _ALL_ the work!
486 */
487
488 skb=skb_recv_datagram(sk,flags,noblock,&er);
489 if(skb==NULL)
490 return er;
491
492 truesize = skb->len;
493 copied = min(len, truesize);
494
495 /*
496 * FIXME : should use udp header size info value
497 */
498
499 skb_copy_datagram(skb,sizeof(struct udphdr),to,copied);
500 sk->stamp=skb->stamp;
501
502 /* Copy the address. */
503 if (sin)
504 {
505 sin->sin_family = AF_INET;
506 sin->sin_port = skb->h.uh->source;
507 sin->sin_addr.s_addr = skb->daddr;
508 }
509
510 skb_free_datagram(skb);
511 release_sock(sk);
512 return(truesize);
513 }
514
515 /*
516 * Read has the same semantics as recv in SOCK_DGRAM
517 */
518
519 int udp_read(struct sock *sk, unsigned char *buff, int len, int noblock,
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
520 unsigned flags)
521 {
522 return(udp_recvfrom(sk, buff, len, noblock, flags, NULL, NULL));
523 }
524
525
526 int udp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
527 {
528 struct rtable *rt;
529 unsigned long sa;
530 if (addr_len < sizeof(*usin))
531 return(-EINVAL);
532
533 if (usin->sin_family && usin->sin_family != AF_INET)
534 return(-EAFNOSUPPORT);
535 if (usin->sin_addr.s_addr==INADDR_ANY)
536 usin->sin_addr.s_addr=ip_my_addr();
537
538 if(!sk->broadcast && ip_chk_addr(usin->sin_addr.s_addr)==IS_BROADCAST)
539 return -EACCES; /* Must turn broadcast on first */
540
541 rt=ip_rt_route(usin->sin_addr.s_addr, NULL, &sa);
542 if(rt==NULL)
543 return -ENETUNREACH;
544 sk->saddr = sa; /* Update source address */
545 sk->daddr = usin->sin_addr.s_addr;
546 sk->dummy_th.dest = usin->sin_port;
547 sk->state = TCP_ESTABLISHED;
548 return(0);
549 }
550
551
552 static void udp_close(struct sock *sk, int timeout)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
553 {
554 sk->inuse = 1;
555 sk->state = TCP_CLOSE;
556 if (sk->dead)
557 destroy_sock(sk);
558 else
559 release_sock(sk);
560 }
561
562
563 /*
564 * All we need to do is get the socket, and then do a checksum.
565 */
566
567 int udp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
568 unsigned long daddr, unsigned short len,
569 unsigned long saddr, int redo, struct inet_protocol *protocol)
570 {
571 struct sock *sk;
572 struct udphdr *uh;
573 unsigned short ulen;
574 int addr_type = IS_MYADDR;
575
576 if(!dev || dev->pa_addr!=daddr)
577 addr_type=ip_chk_addr(daddr);
578
579 /*
580 * Get the header.
581 */
582 uh = (struct udphdr *) skb->h.uh;
583
584 ip_statistics.IpInDelivers++;
585
586 /*
587 * Validate the packet and the UDP length.
588 */
589
590 ulen = ntohs(uh->len);
591
592 if (ulen > len || len < sizeof(*uh) || ulen < sizeof(*uh))
593 {
594 printk("UDP: short packet: %d/%d\n", ulen, len);
595 udp_statistics.UdpInErrors++;
596 kfree_skb(skb, FREE_WRITE);
597 return(0);
598 }
599
600 if (uh->check && udp_check(uh, len, saddr, daddr))
601 {
602 /* <mea@utu.fi> wants to know, who sent it, to
603 go and stomp on the garbage sender... */
604 printk("UDP: bad checksum. From %08lX:%d to %08lX:%d ulen %d\n",
605 ntohl(saddr),ntohs(uh->source),
606 ntohl(daddr),ntohs(uh->dest),
607 ulen);
608 udp_statistics.UdpInErrors++;
609 kfree_skb(skb, FREE_WRITE);
610 return(0);
611 }
612
613
614 len=ulen;
615
616 #ifdef CONFIG_IP_MULTICAST
617 if (addr_type!=IS_MYADDR)
618 {
619 /*
620 * Multicasts and broadcasts go to each listener.
621 */
622 struct sock *sknext=NULL;
623 sk=get_sock_mcast(udp_prot.sock_array[ntohs(uh->dest)&(SOCK_ARRAY_SIZE-1)], uh->dest,
624 saddr, uh->source, daddr);
625 if(sk)
626 {
627 do
628 {
629 struct sk_buff *skb1;
630
631 sknext=get_sock_mcast(sk->next, uh->dest, saddr, uh->source, daddr);
632 if(sknext)
633 skb1=skb_clone(skb,GFP_ATOMIC);
634 else
635 skb1=skb;
636 if(skb1)
637 udp_deliver(sk, uh, skb1, dev,saddr,daddr,len);
638 sk=sknext;
639 }
640 while(sknext!=NULL);
641 }
642 else
643 kfree_skb(skb, FREE_READ);
644 return 0;
645 }
646 #endif
647 sk = get_sock(&udp_prot, uh->dest, saddr, uh->source, daddr);
648 if (sk == NULL)
649 {
650 udp_statistics.UdpNoPorts++;
651 if (addr_type == IS_MYADDR)
652 {
653 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0, dev);
654 }
655 /*
656 * Hmm. We got an UDP broadcast to a port to which we
657 * don't wanna listen. Ignore it.
658 */
659 skb->sk = NULL;
660 kfree_skb(skb, FREE_WRITE);
661 return(0);
662 }
663
664 return udp_deliver(sk,uh,skb,dev, saddr, daddr, len);
665 }
666
667 static int udp_deliver(struct sock *sk, struct udphdr *uh, struct sk_buff *skb, struct device *dev, long saddr, long daddr, int len)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
668 {
669 skb->sk = sk;
670 skb->dev = dev;
671 skb->len = len;
672
673 /*
674 * These are supposed to be switched.
675 */
676
677 skb->daddr = saddr;
678 skb->saddr = daddr;
679
680
681 /*
682 * Charge it to the socket, dropping if the queue is full.
683 */
684
685 skb->len = len - sizeof(*uh);
686
687 if (sock_queue_rcv_skb(sk,skb)<0)
688 {
689 udp_statistics.UdpInErrors++;
690 ip_statistics.IpInDiscards++;
691 ip_statistics.IpInDelivers--;
692 skb->sk = NULL;
693 kfree_skb(skb, FREE_WRITE);
694 release_sock(sk);
695 return(0);
696 }
697 udp_statistics.UdpInDatagrams++;
698 release_sock(sk);
699 return(0);
700 }
701
702
703 struct proto udp_prot = {
704 sock_wmalloc,
705 sock_rmalloc,
706 sock_wfree,
707 sock_rfree,
708 sock_rspace,
709 sock_wspace,
710 udp_close,
711 udp_read,
712 udp_write,
713 udp_sendto,
714 udp_recvfrom,
715 ip_build_header,
716 udp_connect,
717 NULL,
718 ip_queue_xmit,
719 NULL,
720 NULL,
721 NULL,
722 udp_rcv,
723 datagram_select,
724 udp_ioctl,
725 NULL,
726 NULL,
727 ip_setsockopt,
728 ip_getsockopt,
729 128,
730 0,
731 {NULL,},
732 "UDP",
733 0, 0
734 };
735