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 * Arnt Gulbrandsen, <agulbra@nvg.unit.no>
13 * Alan Cox, <Alan.Cox@linux.org>
14 *
15 * Fixes:
16 * Alan Cox : verify_area() calls
17 * Alan Cox : stopped close while in use off icmp
18 * messages. Not a fix but a botch that
19 * for udp at least is 'valid'.
20 * Alan Cox : Fixed icmp handling properly
21 * Alan Cox : Correct error for oversized datagrams
22 * Alan Cox : Tidied select() semantics.
23 * Alan Cox : udp_err() fixed properly, also now
24 * select and read wake correctly on errors
25 * Alan Cox : udp_send verify_area moved to avoid mem leak
26 * Alan Cox : UDP can count its memory
27 * Alan Cox : send to an unknown connection causes
28 * an ECONNREFUSED off the icmp, but
29 * does NOT close.
30 * Alan Cox : Switched to new sk_buff handlers. No more backlog!
31 * Alan Cox : Using generic datagram code. Even smaller and the PEEK
32 * bug no longer crashes it.
33 * Fred Van Kempen : Net2e support for sk->broadcast.
34 * Alan Cox : Uses skb_free_datagram
35 * Alan Cox : Added get/set sockopt support.
36 * Alan Cox : Broadcasting without option set returns EACCES.
37 * Alan Cox : No wakeup calls. Instead we now use the callbacks.
38 * Alan Cox : Use ip_tos and ip_ttl
39 * Alan Cox : SNMP Mibs
40 * Alan Cox : MSG_DONTROUTE, and 0.0.0.0 support.
41 * Matt Dillon : UDP length checks.
42 * Alan Cox : Smarter af_inet used properly.
43 * Alan Cox : Use new kernel side addressing.
44 * Alan Cox : Incorrect return on truncated datagram receive.
45 * Arnt Gulbrandsen : New udp_send and stuff
46 * Alan Cox : Cache last socket
47 * Alan Cox : Route cache
48 * Jon Peatfield : Minor efficientcy fix to sendto().
49 * Mike Shaver : RFC1122 checks.
50 *
51 *
52 * This program is free software; you can redistribute it and/or
53 * modify it under the terms of the GNU General Public License
54 * as published by the Free Software Foundation; either version
55 * 2 of the License, or (at your option) any later version.
56 */
57
58 /* RFC1122 Status:
59 4.1.3.1 (Ports):
60 SHOULD send ICMP_PORT_UNREACHABLE in reponse to datagrams to
61 an un-listened port. (OK)
62 4.1.3.2 (IP Options)
63 MUST pass IP options from IP -> application (OK)
64 MUST allow application to specify IP options (OK)
65 4.1.3.3 (ICMP Messages)
66 MUST pass ICMP error messages to application (OK)
67 4.1.3.4 (UDP Checksums)
68 MUST provide facility for checksumming (OK)
69 MAY allow application to control checksumming (OK)
70 MUST default to checksumming on (OK)
71 MUST discard silently datagrams with bad csums (OK)
72 4.1.3.5 (UDP Multihoming)
73 MUST allow application to specify source address (OK)
74 SHOULD be able to communicate the chosen src addr up to application
75 when application doesn't choose (NOT YET - doesnt seem to be in the BSD API)
76 [Does opening a SOCK_PACKET and snooping your output count 8)]
77 4.1.3.6 (Invalid Addresses)
78 MUST discard invalid source addresses (NOT YET -- will be implemented
79 in IP, so UDP will eventually be OK. Right now it's a violation.)
80 MUST only send datagrams with one of our addresses (NOT YET - ought to be OK )
81 950728 -- MS
82 */
83
84 #include <asm/system.h>
85 #include <asm/segment.h>
86 #include <linux/types.h>
87 #include <linux/sched.h>
88 #include <linux/fcntl.h>
89 #include <linux/socket.h>
90 #include <linux/sockios.h>
91 #include <linux/in.h>
92 #include <linux/errno.h>
93 #include <linux/timer.h>
94 #include <linux/termios.h>
95 #include <linux/mm.h>
96 #include <linux/config.h>
97 #include <linux/inet.h>
98 #include <linux/netdevice.h>
99 #include <net/snmp.h>
100 #include <net/ip.h>
101 #include <net/protocol.h>
102 #include <net/tcp.h>
103 #include <linux/skbuff.h>
104 #include <net/sock.h>
105 #include <net/udp.h>
106 #include <net/icmp.h>
107 #include <net/route.h>
108 #include <net/checksum.h>
109
110 /*
111 * Snmp MIB for the UDP layer
112 */
113
114 struct udp_mib udp_statistics;
115
116 /*
117 * Cached last hit socket
118 */
119
120 volatile unsigned long uh_cache_saddr,uh_cache_daddr;
121 volatile unsigned short uh_cache_dport, uh_cache_sport;
122 volatile struct sock *uh_cache_sk;
123
124 void udp_cache_zap(void)
/* ![[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)
*/
125 {
126 unsigned long flags;
127 save_flags(flags);
128 cli();
129 uh_cache_saddr=0;
130 uh_cache_daddr=0;
131 uh_cache_dport=0;
132 uh_cache_sport=0;
133 uh_cache_sk=NULL;
134 restore_flags(flags);
135 }
136
137 static int udp_deliver(struct sock *sk, struct udphdr *uh, struct sk_buff *skb, struct device *dev, long saddr, long daddr, int len);
138
139 #define min(a,b) ((a)<(b)?(a):(b))
140
141
142 /*
143 * This routine is called by the ICMP module when it gets some
144 * sort of error condition. If err < 0 then the socket should
145 * be closed and the error returned to the user. If err > 0
146 * it's just the icmp type << 8 | icmp code.
147 * Header points to the ip header of the error packet. We move
148 * on past this. Then (as it used to claim before adjustment)
149 * header points to the first 8 bytes of the udp header. We need
150 * to find the appropriate port.
151 */
152
153 void udp_err(int err, unsigned char *header, 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)
*/
154 unsigned long saddr, struct inet_protocol *protocol)
155 {
156 struct udphdr *th;
157 struct sock *sk;
158 struct iphdr *ip=(struct iphdr *)header;
159
160 header += 4*ip->ihl;
161
162 /*
163 * Find the 8 bytes of post IP header ICMP included for us
164 */
165
166 th = (struct udphdr *)header;
167
168 sk = get_sock(&udp_prot, th->source, daddr, th->dest, saddr);
169
170 if (sk == NULL)
171 return; /* No socket for error */
172
173 if ((err & 0xff00) == (ICMP_SOURCE_QUENCH << 8))
174 { /* Slow down! */
175 if (sk->cong_window > 1)
176 sk->cong_window = sk->cong_window/2;
177 return;
178 }
179
180 /*
181 * Various people wanted BSD UDP semantics. Well they've come
182 * back out because they slow down response to stuff like dead
183 * or unreachable name servers and they screw term users something
184 * chronic. Oh and it violates RFC1122. So basically fix your
185 * client code people.
186 */
187
188 /* RFC1122: OK. Passes ICMP errors back to application, as per */
189 /* 4.1.3.3. */
190 /* After the comment above, that should be no surprise. */
191
192 err &= 0xff;
193 if (err < 13 && icmp_err_convert[err].fatal)
194 {
195 sk->err = icmp_err_convert[err].errno;
196 sk->error_report(sk);
197 }
198 }
199
200
201 static unsigned short udp_check(struct udphdr *uh, int len, unsigned long saddr, unsigned long daddr, unsigned long base)
/* ![[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)
*/
202 {
203 return(csum_tcpudp_magic(saddr, daddr, len, IPPROTO_UDP, base));
204 }
205
206 struct udpfakehdr
207 {
208 struct udphdr uh;
209 int daddr;
210 int other;
211 const char *from;
212 int wcheck;
213 };
214
215 /*
216 * Copy and checksum a UDP packet from user space into a buffer. We still have to do the planning to
217 * get ip_build_xmit to spot direct transfer to network card and provide an additional callback mode
218 * for direct user->board I/O transfers. That one will be fun.
219 */
220
221 static void udp_getfrag(const void *p, int saddr, char * to, unsigned int offset, unsigned int fraglen)
/* ![[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)
*/
222 {
223 struct udpfakehdr *ufh = (struct udpfakehdr *)p;
224 const char *src;
225 char *dst;
226 unsigned int len;
227
228 if (offset)
229 {
230 len = fraglen;
231 src = ufh->from+(offset-sizeof(struct udphdr));
232 dst = to;
233 }
234 else
235 {
236 len = fraglen-sizeof(struct udphdr);
237 src = ufh->from;
238 dst = to+sizeof(struct udphdr);
239 }
240 ufh->wcheck = csum_partial_copy_fromuser(src, dst, len, ufh->wcheck);
241 if (offset == 0)
242 {
243 ufh->wcheck = csum_partial((char *)ufh, sizeof(struct udphdr),
244 ufh->wcheck);
245 ufh->uh.check = csum_tcpudp_magic(saddr, ufh->daddr,
246 ntohs(ufh->uh.len),
247 IPPROTO_UDP, ufh->wcheck);
248 if (ufh->uh.check == 0)
249 ufh->uh.check = -1;
250 memcpy(to, ufh, sizeof(struct udphdr));
251 }
252 }
253
254 /*
255 * Uncheckummed UDP is sufficiently criticial to stuff like ATM video conferencing
256 * that we use two routines for this for speed. Probably we ought to have a CONFIG_FAST_NET
257 * set for >10Mb/second boards to activate this sort of coding. Timing needed to verify if
258 * this is a valid decision.
259 */
260
261 static void udp_getfrag_nosum(const void *p, int saddr, char * to, unsigned int offset, unsigned int fraglen)
/* ![[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)
*/
262 {
263 struct udpfakehdr *ufh = (struct udpfakehdr *)p;
264 const char *src;
265 char *dst;
266 unsigned int len;
267
268 if (offset)
269 {
270 len = fraglen;
271 src = ufh->from+(offset-sizeof(struct udphdr));
272 dst = to;
273 }
274 else
275 {
276 len = fraglen-sizeof(struct udphdr);
277 src = ufh->from;
278 dst = to+sizeof(struct udphdr);
279 }
280 memcpy_fromfs(dst,src,len);
281 if (offset == 0)
282 memcpy(to, ufh, sizeof(struct udphdr));
283 }
284
285
286 /*
287 * Send UDP frames.
288 */
289
290 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)
*/
291 const unsigned char *from, int len, int rt)
292 {
293 int ulen = len + sizeof(struct udphdr);
294 int a;
295 struct udpfakehdr ufh;
296
297 ufh.uh.source = sk->dummy_th.source;
298 ufh.uh.dest = sin->sin_port;
299 ufh.uh.len = htons(ulen);
300 ufh.uh.check = 0;
301 ufh.daddr = sin->sin_addr.s_addr;
302 ufh.other = (htons(ulen) << 16) + IPPROTO_UDP*256;
303 ufh.from = from;
304 ufh.wcheck = 0;
305
306 /* RFC1122 Violation: there is no provision for passing IP options */
307 /* from the application layer to the IP one. It's a MUST (4.1.3.2), */
308 /* but it looks like it'd require some work on ip_build_xmit. */
309 /* Alan says he's got a Cunning Plan. -- MS */
310
311 /* RFC1122: OK. Provides the checksumming facility (MUST) as per */
312 /* 4.1.3.4. It's configurable by the application via setsockopt() */
313 /* (MAY) and it defaults to on (MUST). Almost makes up for the */
314 /* violation above. -- MS */
315
316 if(sk->no_check)
317 a = ip_build_xmit(sk, udp_getfrag_nosum, &ufh, ulen,
318 sin->sin_addr.s_addr, rt, IPPROTO_UDP);
319 else
320 a = ip_build_xmit(sk, udp_getfrag, &ufh, ulen,
321 sin->sin_addr.s_addr, rt, IPPROTO_UDP);
322 if(a<0)
323 return a;
324 udp_statistics.UdpOutDatagrams++;
325 return len;
326 }
327
328
329 static int udp_sendto(struct sock *sk, const 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)
*/
330 unsigned flags, struct sockaddr_in *usin, int addr_len)
331 {
332 struct sockaddr_in sin;
333 int tmp;
334
335 /*
336 * Check the flags. We support no flags for UDP sending
337 */
338 if (flags&~MSG_DONTROUTE)
339 return(-EINVAL);
340 /*
341 * Get and verify the address.
342 */
343
344 if (usin)
345 {
346 if (addr_len < sizeof(sin))
347 return(-EINVAL);
348 if (usin->sin_family && usin->sin_family != AF_INET)
349 return(-EINVAL);
350 if (usin->sin_port == 0)
351 return(-EINVAL);
352 }
353 else
354 {
355 if (sk->state != TCP_ESTABLISHED)
356 return(-EINVAL);
357 sin.sin_family = AF_INET;
358 sin.sin_port = sk->dummy_th.dest;
359 sin.sin_addr.s_addr = sk->daddr;
360 usin = &sin;
361 }
362
363 /*
364 * BSD socket semantics. You must set SO_BROADCAST to permit
365 * broadcasting of data.
366 */
367
368 /* RFC1122: OK. Allows the application to select the specific */
369 /* source address for an outgoing packet (MUST) as per 4.1.3.5. */
370 /* Optional addition: a mechanism for telling the application what */
371 /* address was used. (4.1.3.5, MAY) -- MS */
372
373 /* RFC1122: MUST ensure that all outgoing packets have one */
374 /* of this host's addresses as a source addr.(4.1.3.6) - bind in */
375 /* af_inet.c checks these. It does need work to allow BSD style */
376 /* bind to multicast as is done by xntpd */
377
378 if(usin->sin_addr.s_addr==INADDR_ANY)
379 usin->sin_addr.s_addr=ip_my_addr();
380
381 if(!sk->broadcast && ip_chk_addr(usin->sin_addr.s_addr)==IS_BROADCAST)
382 return -EACCES; /* Must turn broadcast on first */
383
384 sk->inuse = 1;
385
386 /* Send the packet. */
387 tmp = udp_send(sk, usin, from, len, flags);
388
389 /* The datagram has been sent off. Release the socket. */
390 release_sock(sk);
391 return(tmp);
392 }
393
394 /*
395 * In BSD SOCK_DGRAM a write is just like a send.
396 */
397
398 static int udp_write(struct sock *sk, const 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)
*/
399 unsigned flags)
400 {
401 return(udp_sendto(sk, buff, len, noblock, flags, NULL, 0));
402 }
403
404
405 /*
406 * IOCTL requests applicable to the UDP protocol
407 */
408
409 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)
*/
410 {
411 int err;
412 switch(cmd)
413 {
414 case TIOCOUTQ:
415 {
416 unsigned long amount;
417
418 if (sk->state == TCP_LISTEN) return(-EINVAL);
419 amount = sk->prot->wspace(sk)/*/2*/;
420 err=verify_area(VERIFY_WRITE,(void *)arg,
421 sizeof(unsigned long));
422 if(err)
423 return(err);
424 put_fs_long(amount,(unsigned long *)arg);
425 return(0);
426 }
427
428 case TIOCINQ:
429 {
430 struct sk_buff *skb;
431 unsigned long amount;
432
433 if (sk->state == TCP_LISTEN) return(-EINVAL);
434 amount = 0;
435 skb = skb_peek(&sk->receive_queue);
436 if (skb != NULL) {
437 /*
438 * We will only return the amount
439 * of this packet since that is all
440 * that will be read.
441 */
442 amount = skb->len;
443 }
444 err=verify_area(VERIFY_WRITE,(void *)arg,
445 sizeof(unsigned long));
446 if(err)
447 return(err);
448 put_fs_long(amount,(unsigned long *)arg);
449 return(0);
450 }
451
452 default:
453 return(-EINVAL);
454 }
455 return(0);
456 }
457
458
459 /*
460 * This should be easy, if there is something there we\
461 * return it, otherwise we block.
462 */
463
464 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)
*/
465 int noblock, unsigned flags, struct sockaddr_in *sin,
466 int *addr_len)
467 {
468 int copied = 0;
469 int truesize;
470 struct sk_buff *skb;
471 int er;
472
473 /*
474 * Check any passed addresses
475 */
476
477 if (addr_len)
478 *addr_len=sizeof(*sin);
479
480 /*
481 * From here the generic datagram does a lot of the work. Come
482 * the finished NET3, it will do _ALL_ the work!
483 */
484
485 skb=skb_recv_datagram(sk,flags,noblock,&er);
486 if(skb==NULL)
487 return er;
488
489 truesize = skb->len - sizeof(struct udphdr);
490 copied = min(len, truesize);
491
492 /*
493 * FIXME : should use udp header size info value
494 */
495
496 skb_copy_datagram(skb,sizeof(struct udphdr),to,copied);
497 sk->stamp=skb->stamp;
498
499 /* Copy the address. */
500 if (sin)
501 {
502 sin->sin_family = AF_INET;
503 sin->sin_port = skb->h.uh->source;
504 sin->sin_addr.s_addr = skb->daddr;
505 }
506
507 skb_free_datagram(skb);
508 release_sock(sk);
509 return(copied);
510 }
511
512 /*
513 * Read has the same semantics as recv in SOCK_DGRAM
514 */
515
516 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)
*/
517 unsigned flags)
518 {
519 return(udp_recvfrom(sk, buff, len, noblock, flags, NULL, NULL));
520 }
521
522
523 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)
*/
524 {
525 struct rtable *rt;
526 unsigned long sa;
527 if (addr_len < sizeof(*usin))
528 return(-EINVAL);
529
530 if (usin->sin_family && usin->sin_family != AF_INET)
531 return(-EAFNOSUPPORT);
532 if (usin->sin_addr.s_addr==INADDR_ANY)
533 usin->sin_addr.s_addr=ip_my_addr();
534
535 if(!sk->broadcast && ip_chk_addr(usin->sin_addr.s_addr)==IS_BROADCAST)
536 return -EACCES; /* Must turn broadcast on first */
537
538 rt=(sk->localroute?ip_rt_local:ip_rt_route)(usin->sin_addr.s_addr, NULL, &sa);
539 if(rt==NULL)
540 return -ENETUNREACH;
541 sk->saddr = sa; /* Update source address */
542 sk->daddr = usin->sin_addr.s_addr;
543 sk->dummy_th.dest = usin->sin_port;
544 sk->state = TCP_ESTABLISHED;
545 udp_cache_zap();
546 sk->ip_route_cache = rt;
547 sk->ip_route_stamp = rt_stamp;
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(uh_cache_sk==sk)
557 udp_cache_zap();
558 if (sk->dead)
559 destroy_sock(sk);
560 else
561 release_sock(sk);
562 }
563
564
565 /*
566 * All we need to do is get the socket, and then do a checksum.
567 */
568
569 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)
*/
570 unsigned long daddr, unsigned short len,
571 unsigned long saddr, int redo, struct inet_protocol *protocol)
572 {
573 struct sock *sk;
574 struct udphdr *uh;
575 unsigned short ulen;
576 int addr_type = IS_MYADDR;
577
578 if(!dev || dev->pa_addr!=daddr)
579 addr_type=ip_chk_addr(daddr);
580
581 /*
582 * Get the header.
583 */
584
585 uh = (struct udphdr *) skb->h.uh;
586
587 ip_statistics.IpInDelivers++;
588
589 /*
590 * Validate the packet and the UDP length.
591 */
592
593 ulen = ntohs(uh->len);
594
595 if (ulen > len || len < sizeof(*uh) || ulen < sizeof(*uh))
596 {
597 NETDEBUG(printk("UDP: short packet: %d/%d\n", ulen, len));
598 udp_statistics.UdpInErrors++;
599 kfree_skb(skb, FREE_WRITE);
600 return(0);
601 }
602
603 /* RFC1122 warning: According to 4.1.3.6, we MUST discard any */
604 /* datagram which has an invalid source address, either here or */
605 /* in IP. */
606 /* Right now, IP isn't doing it, and neither is UDP. It's on the */
607 /* FIXME list for IP, though, so I wouldn't worry about it. */
608 /* (That's the Right Place to do it, IMHO.) -- MS */
609
610 if (uh->check && (
611 ( skb->ip_summed && udp_check(uh, len, saddr, daddr, skb->csum ) ) ||
612 ( !skb->ip_summed && udp_check(uh, len, saddr, daddr,csum_partial((char*)uh, len, 0)))
613 )
614 )
615 {
616 /* <mea@utu.fi> wants to know, who sent it, to
617 go and stomp on the garbage sender... */
618
619 /* RFC1122: OK. Discards the bad packet silently (as far as */
620 /* the network is concered, anyway) as per 4.1.3.4 (MUST). */
621
622 NETDEBUG(printk("UDP: bad checksum. From %08lX:%d to %08lX:%d ulen %d\n",
623 ntohl(saddr),ntohs(uh->source),
624 ntohl(daddr),ntohs(uh->dest),
625 ulen));
626 udp_statistics.UdpInErrors++;
627 kfree_skb(skb, FREE_WRITE);
628 return(0);
629 }
630
631
632 len=ulen;
633
634 #ifdef CONFIG_IP_MULTICAST
635 if (addr_type!=IS_MYADDR)
636 {
637 /*
638 * Multicasts and broadcasts go to each listener.
639 */
640 struct sock *sknext=NULL;
641 sk=get_sock_mcast(udp_prot.sock_array[ntohs(uh->dest)&(SOCK_ARRAY_SIZE-1)], uh->dest,
642 saddr, uh->source, daddr);
643 if(sk)
644 {
645 do
646 {
647 struct sk_buff *skb1;
648
649 sknext=get_sock_mcast(sk->next, uh->dest, saddr, uh->source, daddr);
650 if(sknext)
651 skb1=skb_clone(skb,GFP_ATOMIC);
652 else
653 skb1=skb;
654 if(skb1)
655 udp_deliver(sk, uh, skb1, dev,saddr,daddr,len);
656 sk=sknext;
657 }
658 while(sknext!=NULL);
659 }
660 else
661 kfree_skb(skb, FREE_READ);
662 return 0;
663 }
664 #endif
665 if(saddr==uh_cache_saddr && daddr==uh_cache_daddr && uh->dest==uh_cache_dport && uh->source==uh_cache_sport)
666 sk=(struct sock *)uh_cache_sk;
667 else
668 {
669 sk = get_sock(&udp_prot, uh->dest, saddr, uh->source, daddr);
670 uh_cache_saddr=saddr;
671 uh_cache_daddr=daddr;
672 uh_cache_dport=uh->dest;
673 uh_cache_sport=uh->source;
674 uh_cache_sk=sk;
675 }
676
677 if (sk == NULL)
678 {
679 udp_statistics.UdpNoPorts++;
680 if (addr_type == IS_MYADDR)
681 {
682 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0, dev);
683 }
684 /*
685 * Hmm. We got an UDP broadcast to a port to which we
686 * don't wanna listen. Ignore it.
687 */
688 skb->sk = NULL;
689 kfree_skb(skb, FREE_WRITE);
690 return(0);
691 }
692 return udp_deliver(sk,uh,skb,dev, saddr, daddr, len);
693 }
694
695 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)
*/
696 {
697 skb->sk = sk;
698 skb->dev = dev;
699 skb_trim(skb,len);
700
701 /*
702 * These are supposed to be switched.
703 */
704
705 skb->daddr = saddr;
706 skb->saddr = daddr;
707
708
709 /*
710 * Charge it to the socket, dropping if the queue is full.
711 */
712
713 /* I assume this includes the IP options, as per RFC1122 (4.1.3.2). */
714 /* If not, please let me know. -- MS */
715
716 if (sock_queue_rcv_skb(sk,skb)<0)
717 {
718 udp_statistics.UdpInErrors++;
719 ip_statistics.IpInDiscards++;
720 ip_statistics.IpInDelivers--;
721 skb->sk = NULL;
722 kfree_skb(skb, FREE_WRITE);
723 release_sock(sk);
724 return(0);
725 }
726 udp_statistics.UdpInDatagrams++;
727 release_sock(sk);
728 return(0);
729 }
730
731
732 struct proto udp_prot = {
733 sock_wmalloc,
734 sock_rmalloc,
735 sock_wfree,
736 sock_rfree,
737 sock_rspace,
738 sock_wspace,
739 udp_close,
740 udp_read,
741 udp_write,
742 udp_sendto,
743 udp_recvfrom,
744 ip_build_header,
745 udp_connect,
746 NULL,
747 ip_queue_xmit,
748 NULL,
749 NULL,
750 NULL,
751 udp_rcv,
752 datagram_select,
753 udp_ioctl,
754 NULL,
755 NULL,
756 ip_setsockopt,
757 ip_getsockopt,
758 128,
759 0,
760 "UDP",
761 0, 0,
762 {NULL,}
763 };