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 type, int code, unsigned char *header, __u32 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 __u32 saddr, struct inet_protocol *protocol)
155 {
156 struct udphdr *uh;
157 struct sock *sk;
158
159 /*
160 * Find the 8 bytes of post IP header ICMP included for us
161 */
162
163 uh = (struct udphdr *)header;
164
165 sk = get_sock(&udp_prot, uh->source, daddr, uh->dest, saddr);
166
167 if (sk == NULL)
168 return; /* No socket for error */
169
170 if (type == ICMP_SOURCE_QUENCH)
171 { /* Slow down! */
172 if (sk->cong_window > 1)
173 sk->cong_window = sk->cong_window/2;
174 return;
175 }
176
177 if (type == ICMP_PARAMETERPROB)
178 {
179 sk->err = EPROTO;
180 sk->error_report(sk);
181 return;
182 }
183
184 /*
185 * Various people wanted BSD UDP semantics. Well they've come
186 * back out because they slow down response to stuff like dead
187 * or unreachable name servers and they screw term users something
188 * chronic. Oh and it violates RFC1122. So basically fix your
189 * client code people.
190 */
191
192 /* RFC1122: OK. Passes ICMP errors back to application, as per */
193 /* 4.1.3.3. */
194 /* After the comment above, that should be no surprise. */
195
196 if (code < 13 && icmp_err_convert[code].fatal)
197 {
198 sk->err = icmp_err_convert[code].errno;
199 sk->error_report(sk);
200 }
201 }
202
203
204 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)
*/
205 {
206 return(csum_tcpudp_magic(saddr, daddr, len, IPPROTO_UDP, base));
207 }
208
209 struct udpfakehdr
210 {
211 struct udphdr uh;
212 int daddr;
213 int other;
214 const char *from;
215 int wcheck;
216 };
217
218 /*
219 * Copy and checksum a UDP packet from user space into a buffer. We still have to do the planning to
220 * get ip_build_xmit to spot direct transfer to network card and provide an additional callback mode
221 * for direct user->board I/O transfers. That one will be fun.
222 */
223
224 static void udp_getfrag(const void *p, __u32 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)
*/
225 {
226 struct udpfakehdr *ufh = (struct udpfakehdr *)p;
227 const char *src;
228 char *dst;
229 unsigned int len;
230
231 if (offset)
232 {
233 len = fraglen;
234 src = ufh->from+(offset-sizeof(struct udphdr));
235 dst = to;
236 }
237 else
238 {
239 len = fraglen-sizeof(struct udphdr);
240 src = ufh->from;
241 dst = to+sizeof(struct udphdr);
242 }
243 ufh->wcheck = csum_partial_copy_fromuser(src, dst, len, ufh->wcheck);
244 if (offset == 0)
245 {
246 ufh->wcheck = csum_partial((char *)ufh, sizeof(struct udphdr),
247 ufh->wcheck);
248 ufh->uh.check = csum_tcpudp_magic(saddr, ufh->daddr,
249 ntohs(ufh->uh.len),
250 IPPROTO_UDP, ufh->wcheck);
251 if (ufh->uh.check == 0)
252 ufh->uh.check = -1;
253 memcpy(to, ufh, sizeof(struct udphdr));
254 }
255 }
256
257 /*
258 * Uncheckummed UDP is sufficiently criticial to stuff like ATM video conferencing
259 * that we use two routines for this for speed. Probably we ought to have a CONFIG_FAST_NET
260 * set for >10Mb/second boards to activate this sort of coding. Timing needed to verify if
261 * this is a valid decision.
262 */
263
264 static void udp_getfrag_nosum(const void *p, __u32 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)
*/
265 {
266 struct udpfakehdr *ufh = (struct udpfakehdr *)p;
267 const char *src;
268 char *dst;
269 unsigned int len;
270
271 if (offset)
272 {
273 len = fraglen;
274 src = ufh->from+(offset-sizeof(struct udphdr));
275 dst = to;
276 }
277 else
278 {
279 len = fraglen-sizeof(struct udphdr);
280 src = ufh->from;
281 dst = to+sizeof(struct udphdr);
282 }
283 memcpy_fromfs(dst,src,len);
284 if (offset == 0)
285 memcpy(to, ufh, sizeof(struct udphdr));
286 }
287
288
289 /*
290 * Send UDP frames.
291 */
292
293 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)
*/
294 const unsigned char *from, int len, int rt,
295 __u32 saddr)
296 {
297 int ulen = len + sizeof(struct udphdr);
298 int a;
299 struct udpfakehdr ufh;
300
301 if(ulen>65535-sizeof(struct iphdr))
302 return -EMSGSIZE;
303
304 ufh.uh.source = sk->dummy_th.source;
305 ufh.uh.dest = sin->sin_port;
306 ufh.uh.len = htons(ulen);
307 ufh.uh.check = 0;
308 ufh.daddr = sin->sin_addr.s_addr;
309 ufh.other = (htons(ulen) << 16) + IPPROTO_UDP*256;
310 ufh.from = from;
311 ufh.wcheck = 0;
312
313 /* RFC1122 Violation: there is no provision for passing IP options */
314 /* from the application layer to the IP one. It's a MUST (4.1.3.2), */
315 /* but it looks like it'd require some work on ip_build_xmit. */
316 /* Alan says he's got a Cunning Plan. -- MS */
317
318 /* RFC1122: OK. Provides the checksumming facility (MUST) as per */
319 /* 4.1.3.4. It's configurable by the application via setsockopt() */
320 /* (MAY) and it defaults to on (MUST). Almost makes up for the */
321 /* violation above. -- MS */
322
323 if(sk->no_check)
324 a = ip_build_xmit(sk, udp_getfrag_nosum, &ufh, ulen,
325 sin->sin_addr.s_addr, saddr, sk->opt, rt, IPPROTO_UDP);
326 else
327 a = ip_build_xmit(sk, udp_getfrag, &ufh, ulen,
328 sin->sin_addr.s_addr, saddr, sk->opt, rt, IPPROTO_UDP);
329 if(a<0)
330 return a;
331 udp_statistics.UdpOutDatagrams++;
332 return len;
333 }
334
335
336 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)
*/
337 unsigned flags, struct sockaddr_in *usin, int addr_len)
338 {
339 struct sockaddr_in sin;
340 int tmp;
341 __u32 saddr=0;
342
343 /*
344 * Check the flags. We support no flags for UDP sending
345 */
346
347 if (flags&~MSG_DONTROUTE)
348 return(-EINVAL);
349 /*
350 * Get and verify the address.
351 */
352
353 if (usin)
354 {
355 if (addr_len < sizeof(sin))
356 return(-EINVAL);
357 if (usin->sin_family && usin->sin_family != AF_INET)
358 return(-EINVAL);
359 if (usin->sin_port == 0)
360 return(-EINVAL);
361 }
362 else
363 {
364 if (sk->state != TCP_ESTABLISHED)
365 return(-EINVAL);
366 sin.sin_family = AF_INET;
367 sin.sin_port = sk->dummy_th.dest;
368 sin.sin_addr.s_addr = sk->daddr;
369 usin = &sin;
370 }
371
372 /*
373 * BSD socket semantics. You must set SO_BROADCAST to permit
374 * broadcasting of data.
375 */
376
377 /* RFC1122: OK. Allows the application to select the specific */
378 /* source address for an outgoing packet (MUST) as per 4.1.3.5. */
379 /* Optional addition: a mechanism for telling the application what */
380 /* address was used. (4.1.3.5, MAY) -- MS */
381
382 /* RFC1122: MUST ensure that all outgoing packets have one */
383 /* of this host's addresses as a source addr.(4.1.3.6) - bind in */
384 /* af_inet.c checks these. It does need work to allow BSD style */
385 /* bind to multicast as is done by xntpd */
386
387 if(usin->sin_addr.s_addr==INADDR_ANY)
388 usin->sin_addr.s_addr=ip_my_addr();
389
390 if(!sk->broadcast && ip_chk_addr(usin->sin_addr.s_addr)==IS_BROADCAST)
391 return -EACCES; /* Must turn broadcast on first */
392
393 sk->inuse = 1;
394
395 /* Send the packet. */
396 tmp = udp_send(sk, usin, from, len, flags, saddr);
397
398 /* The datagram has been sent off. Release the socket. */
399 release_sock(sk);
400 return(tmp);
401 }
402
403 /*
404 * In BSD SOCK_DGRAM a write is just like a send.
405 */
406
407 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)
*/
408 unsigned flags)
409 {
410 return(udp_sendto(sk, buff, len, noblock, flags, NULL, 0));
411 }
412
413
414 /*
415 * IOCTL requests applicable to the UDP protocol
416 */
417
418 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)
*/
419 {
420 int err;
421 switch(cmd)
422 {
423 case TIOCOUTQ:
424 {
425 unsigned long amount;
426
427 if (sk->state == TCP_LISTEN) return(-EINVAL);
428 amount = sk->prot->wspace(sk)/*/2*/;
429 err=verify_area(VERIFY_WRITE,(void *)arg,
430 sizeof(unsigned long));
431 if(err)
432 return(err);
433 put_fs_long(amount,(unsigned long *)arg);
434 return(0);
435 }
436
437 case TIOCINQ:
438 {
439 struct sk_buff *skb;
440 unsigned long amount;
441
442 if (sk->state == TCP_LISTEN) return(-EINVAL);
443 amount = 0;
444 skb = skb_peek(&sk->receive_queue);
445 if (skb != NULL) {
446 /*
447 * We will only return the amount
448 * of this packet since that is all
449 * that will be read.
450 */
451 amount = skb->len;
452 }
453 err=verify_area(VERIFY_WRITE,(void *)arg,
454 sizeof(unsigned long));
455 if(err)
456 return(err);
457 put_fs_long(amount,(unsigned long *)arg);
458 return(0);
459 }
460
461 default:
462 return(-EINVAL);
463 }
464 return(0);
465 }
466
467
468 /*
469 * This should be easy, if there is something there we\
470 * return it, otherwise we block.
471 */
472
473 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)
*/
474 int noblock, unsigned flags, struct sockaddr_in *sin,
475 int *addr_len)
476 {
477 int copied = 0;
478 int truesize;
479 struct sk_buff *skb;
480 int er;
481
482 /*
483 * Check any passed addresses
484 */
485
486 if (addr_len)
487 *addr_len=sizeof(*sin);
488
489 /*
490 * From here the generic datagram does a lot of the work. Come
491 * the finished NET3, it will do _ALL_ the work!
492 */
493
494 skb=skb_recv_datagram(sk,flags,noblock,&er);
495 if(skb==NULL)
496 return er;
497
498 truesize = skb->len - sizeof(struct udphdr);
499 copied = min(len, truesize);
500
501 /*
502 * FIXME : should use udp header size info value
503 */
504
505 skb_copy_datagram(skb,sizeof(struct udphdr),to,copied);
506 sk->stamp=skb->stamp;
507
508 /* Copy the address. */
509 if (sin)
510 {
511 sin->sin_family = AF_INET;
512 sin->sin_port = skb->h.uh->source;
513 sin->sin_addr.s_addr = skb->daddr;
514 }
515
516 skb_free_datagram(skb);
517 release_sock(sk);
518 return(copied);
519 }
520
521 /*
522 * Read has the same semantics as recv in SOCK_DGRAM
523 */
524
525 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)
*/
526 unsigned flags)
527 {
528 return(udp_recvfrom(sk, buff, len, noblock, flags, NULL, NULL));
529 }
530
531
532 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)
*/
533 {
534 struct rtable *rt;
535 __u32 sa;
536 if (addr_len < sizeof(*usin))
537 return(-EINVAL);
538
539 if (usin->sin_family && usin->sin_family != AF_INET)
540 return(-EAFNOSUPPORT);
541 if (usin->sin_addr.s_addr==INADDR_ANY)
542 usin->sin_addr.s_addr=ip_my_addr();
543
544 if(!sk->broadcast && ip_chk_addr(usin->sin_addr.s_addr)==IS_BROADCAST)
545 return -EACCES; /* Must turn broadcast on first */
546
547 rt=(sk->localroute?ip_rt_local:ip_rt_route)((__u32)usin->sin_addr.s_addr, NULL, &sa);
548 if(rt==NULL)
549 return -ENETUNREACH;
550 sk->saddr = sa; /* Update source address */
551 sk->daddr = usin->sin_addr.s_addr;
552 sk->dummy_th.dest = usin->sin_port;
553 sk->state = TCP_ESTABLISHED;
554 udp_cache_zap();
555 sk->ip_route_cache = rt;
556 sk->ip_route_stamp = rt_stamp;
557 return(0);
558 }
559
560
561 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)
*/
562 {
563 sk->inuse = 1;
564 sk->state = TCP_CLOSE;
565 if(uh_cache_sk==sk)
566 udp_cache_zap();
567 if (sk->dead)
568 destroy_sock(sk);
569 else
570 release_sock(sk);
571 }
572
573
574 /*
575 * All we need to do is get the socket, and then do a checksum.
576 */
577
578 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)
*/
579 __u32 daddr, unsigned short len,
580 __u32 saddr, int redo, struct inet_protocol *protocol)
581 {
582 struct sock *sk;
583 struct udphdr *uh;
584 unsigned short ulen;
585 int addr_type = IS_MYADDR;
586
587 if(!dev || dev->pa_addr!=daddr)
588 addr_type=ip_chk_addr(daddr);
589
590 /*
591 * Get the header.
592 */
593
594 uh = (struct udphdr *) skb->h.uh;
595
596 ip_statistics.IpInDelivers++;
597
598 /*
599 * Validate the packet and the UDP length.
600 */
601
602 ulen = ntohs(uh->len);
603
604 if (ulen > len || len < sizeof(*uh) || ulen < sizeof(*uh))
605 {
606 NETDEBUG(printk("UDP: short packet: %d/%d\n", ulen, len));
607 udp_statistics.UdpInErrors++;
608 kfree_skb(skb, FREE_WRITE);
609 return(0);
610 }
611
612 /* RFC1122 warning: According to 4.1.3.6, we MUST discard any */
613 /* datagram which has an invalid source address, either here or */
614 /* in IP. */
615 /* Right now, IP isn't doing it, and neither is UDP. It's on the */
616 /* FIXME list for IP, though, so I wouldn't worry about it. */
617 /* (That's the Right Place to do it, IMHO.) -- MS */
618
619 if (uh->check && (
620 ( skb->ip_summed && udp_check(uh, len, saddr, daddr, skb->csum ) ) ||
621 ( !skb->ip_summed && udp_check(uh, len, saddr, daddr,csum_partial((char*)uh, len, 0)))
622 )
623 )
624 {
625 /* <mea@utu.fi> wants to know, who sent it, to
626 go and stomp on the garbage sender... */
627
628 /* RFC1122: OK. Discards the bad packet silently (as far as */
629 /* the network is concered, anyway) as per 4.1.3.4 (MUST). */
630
631 NETDEBUG(printk("UDP: bad checksum. From %08lX:%d to %08lX:%d ulen %d\n",
632 ntohl(saddr),ntohs(uh->source),
633 ntohl(daddr),ntohs(uh->dest),
634 ulen));
635 udp_statistics.UdpInErrors++;
636 kfree_skb(skb, FREE_WRITE);
637 return(0);
638 }
639
640
641 len=ulen;
642
643 #ifdef CONFIG_IP_MULTICAST
644 if (addr_type!=IS_MYADDR)
645 {
646 /*
647 * Multicasts and broadcasts go to each listener.
648 */
649 struct sock *sknext=NULL;
650 sk=get_sock_mcast(udp_prot.sock_array[ntohs(uh->dest)&(SOCK_ARRAY_SIZE-1)], uh->dest,
651 saddr, uh->source, daddr);
652 if(sk)
653 {
654 do
655 {
656 struct sk_buff *skb1;
657
658 sknext=get_sock_mcast(sk->next, uh->dest, saddr, uh->source, daddr);
659 if(sknext)
660 skb1=skb_clone(skb,GFP_ATOMIC);
661 else
662 skb1=skb;
663 if(skb1)
664 udp_deliver(sk, uh, skb1, dev,saddr,daddr,len);
665 sk=sknext;
666 }
667 while(sknext!=NULL);
668 }
669 else
670 kfree_skb(skb, FREE_READ);
671 return 0;
672 }
673 #endif
674 if(saddr==uh_cache_saddr && daddr==uh_cache_daddr && uh->dest==uh_cache_dport && uh->source==uh_cache_sport)
675 sk=(struct sock *)uh_cache_sk;
676 else
677 {
678 sk = get_sock(&udp_prot, uh->dest, saddr, uh->source, daddr);
679 uh_cache_saddr=saddr;
680 uh_cache_daddr=daddr;
681 uh_cache_dport=uh->dest;
682 uh_cache_sport=uh->source;
683 uh_cache_sk=sk;
684 }
685
686 if (sk == NULL)
687 {
688 udp_statistics.UdpNoPorts++;
689 if (addr_type == IS_MYADDR)
690 {
691 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0, dev);
692 }
693 /*
694 * Hmm. We got an UDP broadcast to a port to which we
695 * don't wanna listen. Ignore it.
696 */
697 skb->sk = NULL;
698 kfree_skb(skb, FREE_WRITE);
699 return(0);
700 }
701 return udp_deliver(sk,uh,skb,dev, saddr, daddr, len);
702 }
703
704 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)
*/
705 {
706 skb->sk = sk;
707 skb->dev = dev;
708 skb_trim(skb,len);
709
710 /*
711 * These are supposed to be switched.
712 */
713
714 skb->daddr = saddr;
715 skb->saddr = daddr;
716
717
718 /*
719 * Charge it to the socket, dropping if the queue is full.
720 */
721
722 /* I assume this includes the IP options, as per RFC1122 (4.1.3.2). */
723 /* If not, please let me know. -- MS */
724
725 if (sock_queue_rcv_skb(sk,skb)<0)
726 {
727 udp_statistics.UdpInErrors++;
728 ip_statistics.IpInDiscards++;
729 ip_statistics.IpInDelivers--;
730 skb->sk = NULL;
731 kfree_skb(skb, FREE_WRITE);
732 release_sock(sk);
733 return(0);
734 }
735 udp_statistics.UdpInDatagrams++;
736 release_sock(sk);
737 return(0);
738 }
739
740
741 struct proto udp_prot = {
742 sock_wmalloc,
743 sock_rmalloc,
744 sock_wfree,
745 sock_rfree,
746 sock_rspace,
747 sock_wspace,
748 udp_close,
749 udp_read,
750 udp_write,
751 udp_sendto,
752 udp_recvfrom,
753 ip_build_header,
754 udp_connect,
755 NULL,
756 ip_queue_xmit,
757 NULL,
758 NULL,
759 NULL,
760 udp_rcv,
761 datagram_select,
762 udp_ioctl,
763 NULL,
764 NULL,
765 ip_setsockopt,
766 ip_getsockopt,
767 128,
768 0,
769 "UDP",
770 0, 0,
771 {NULL,}
772 };