Main Page | Class List | File List | Class Members | File Members

udp.c

Go to the documentation of this file.
00001 /* 00002 * INET An implementation of the TCP/IP protocol suite for the LINUX 00003 * operating system. INET is implemented using the BSD Socket 00004 * interface as the means of communication with the user level. 00005 * 00006 * The User Datagram Protocol (UDP). 00007 * 00008 * Version: $Id: udp.c,v 1.100.2.4 2002/03/05 12:47:34 davem Exp $ 00009 * 00010 * Authors: Ross Biro, <bir7@leland.Stanford.Edu> 00011 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 00012 * Arnt Gulbrandsen, <agulbra@nvg.unit.no> 00013 * Alan Cox, <Alan.Cox@linux.org> 00014 * 00015 * Fixes: 00016 * Alan Cox : verify_area() calls 00017 * Alan Cox : stopped close while in use off icmp 00018 * messages. Not a fix but a botch that 00019 * for udp at least is 'valid'. 00020 * Alan Cox : Fixed icmp handling properly 00021 * Alan Cox : Correct error for oversized datagrams 00022 * Alan Cox : Tidied select() semantics. 00023 * Alan Cox : udp_err() fixed properly, also now 00024 * select and read wake correctly on errors 00025 * Alan Cox : udp_send verify_area moved to avoid mem leak 00026 * Alan Cox : UDP can count its memory 00027 * Alan Cox : send to an unknown connection causes 00028 * an ECONNREFUSED off the icmp, but 00029 * does NOT close. 00030 * Alan Cox : Switched to new sk_buff handlers. No more backlog! 00031 * Alan Cox : Using generic datagram code. Even smaller and the PEEK 00032 * bug no longer crashes it. 00033 * Fred Van Kempen : Net2e support for sk->broadcast. 00034 * Alan Cox : Uses skb_free_datagram 00035 * Alan Cox : Added get/set sockopt support. 00036 * Alan Cox : Broadcasting without option set returns EACCES. 00037 * Alan Cox : No wakeup calls. Instead we now use the callbacks. 00038 * Alan Cox : Use ip_tos and ip_ttl 00039 * Alan Cox : SNMP Mibs 00040 * Alan Cox : MSG_DONTROUTE, and 0.0.0.0 support. 00041 * Matt Dillon : UDP length checks. 00042 * Alan Cox : Smarter af_inet used properly. 00043 * Alan Cox : Use new kernel side addressing. 00044 * Alan Cox : Incorrect return on truncated datagram receive. 00045 * Arnt Gulbrandsen : New udp_send and stuff 00046 * Alan Cox : Cache last socket 00047 * Alan Cox : Route cache 00048 * Jon Peatfield : Minor efficiency fix to sendto(). 00049 * Mike Shaver : RFC1122 checks. 00050 * Alan Cox : Nonblocking error fix. 00051 * Willy Konynenberg : Transparent proxying support. 00052 * Mike McLagan : Routing by source 00053 * David S. Miller : New socket lookup architecture. 00054 * Last socket cache retained as it 00055 * does have a high hit rate. 00056 * Olaf Kirch : Don't linearise iovec on sendmsg. 00057 * Andi Kleen : Some cleanups, cache destination entry 00058 * for connect. 00059 * Vitaly E. Lavrov : Transparent proxy revived after year coma. 00060 * Melvin Smith : Check msg_name not msg_namelen in sendto(), 00061 * return ENOTCONN for unconnected sockets (POSIX) 00062 * Janos Farkas : don't deliver multi/broadcasts to a different 00063 * bound-to-device socket 00064 * YOSHIFUJI Hideaki @USAGI and: Support IPV6_V6ONLY socket option, which 00065 * Alexey Kuznetsov: allow both IPv4 and IPv6 sockets to bind 00066 * a single port at the same time. 00067 * 00068 * 00069 * This program is free software; you can redistribute it and/or 00070 * modify it under the terms of the GNU General Public License 00071 * as published by the Free Software Foundation; either version 00072 * 2 of the License, or (at your option) any later version. 00073 */ 00074 00075 #include <asm/system.h> 00076 #include <asm/uaccess.h> 00077 #include <asm/ioctls.h> 00078 #include <linux/types.h> 00079 #include <linux/fcntl.h> 00080 #include <linux/socket.h> 00081 #include <linux/sockios.h> 00082 #include <linux/in.h> 00083 #include <linux/errno.h> 00084 #include <linux/timer.h> 00085 #include <linux/mm.h> 00086 #include <linux/config.h> 00087 #include <linux/inet.h> 00088 #include <linux/netdevice.h> 00089 #include <net/snmp.h> 00090 #include <net/ip.h> 00091 #include <net/ipv6.h> 00092 #include <net/protocol.h> 00093 #include <linux/skbuff.h> 00094 #include <net/sock.h> 00095 #include <net/udp.h> 00096 #include <net/icmp.h> 00097 #include <net/route.h> 00098 #include <net/inet_common.h> 00099 #include <net/checksum.h> 00100 00101 /* 00102 * Snmp MIB for the UDP layer 00103 */ 00104 00105 struct udp_mib udp_statistics[NR_CPUS*2]; 00106 00107 struct sock *udp_hash[UDP_HTABLE_SIZE]; 00108 rwlock_t udp_hash_lock = RW_LOCK_UNLOCKED; 00109 00110 /* Shared by v4/v6 udp. */ 00111 int udp_port_rover; 00112 00113 static int udp_v4_get_port(struct sock *sk, unsigned short snum) 00114 { 00115 write_lock_bh(&udp_hash_lock); 00116 if (snum == 0) { 00117 int best_size_so_far, best, result, i; 00118 00119 if (udp_port_rover > sysctl_local_port_range[1] || 00120 udp_port_rover < sysctl_local_port_range[0]) 00121 udp_port_rover = sysctl_local_port_range[0]; 00122 best_size_so_far = 32767; 00123 best = result = udp_port_rover; 00124 for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) { 00125 struct sock *sk; 00126 int size; 00127 00128 sk = udp_hash[result & (UDP_HTABLE_SIZE - 1)]; 00129 if (!sk) { 00130 if (result > sysctl_local_port_range[1]) 00131 result = sysctl_local_port_range[0] + 00132 ((result - sysctl_local_port_range[0]) & 00133 (UDP_HTABLE_SIZE - 1)); 00134 goto gotit; 00135 } 00136 size = 0; 00137 do { 00138 if (++size >= best_size_so_far) 00139 goto next; 00140 } while ((sk = sk->next) != NULL); 00141 best_size_so_far = size; 00142 best = result; 00143 next:; 00144 } 00145 result = best; 00146 for(i = 0; i < (1 << 16) / UDP_HTABLE_SIZE; i++, result += UDP_HTABLE_SIZE) { 00147 if (result > sysctl_local_port_range[1]) 00148 result = sysctl_local_port_range[0] 00149 + ((result - sysctl_local_port_range[0]) & 00150 (UDP_HTABLE_SIZE - 1)); 00151 if (!udp_lport_inuse(result)) 00152 break; 00153 } 00154 if (i >= (1 << 16) / UDP_HTABLE_SIZE) 00155 goto fail; 00156 gotit: 00157 udp_port_rover = snum = result; 00158 } else { 00159 struct sock *sk2; 00160 00161 for (sk2 = udp_hash[snum & (UDP_HTABLE_SIZE - 1)]; 00162 sk2 != NULL; 00163 sk2 = sk2->next) { 00164 if (sk2->num == snum && 00165 sk2 != sk && 00166 !ipv6_only_sock(sk2) && 00167 (!sk2->bound_dev_if || 00168 !sk->bound_dev_if || 00169 sk2->bound_dev_if == sk->bound_dev_if) && 00170 (!sk2->rcv_saddr || 00171 !sk->rcv_saddr || 00172 sk2->rcv_saddr == sk->rcv_saddr) && 00173 (!sk2->reuse || !sk->reuse)) 00174 goto fail; 00175 } 00176 } 00177 sk->num = snum; 00178 if (sk->pprev == NULL) { 00179 struct sock **skp = &udp_hash[snum & (UDP_HTABLE_SIZE - 1)]; 00180 if ((sk->next = *skp) != NULL) 00181 (*skp)->pprev = &sk->next; 00182 *skp = sk; 00183 sk->pprev = skp; 00184 sock_prot_inc_use(sk->prot); 00185 sock_hold(sk); 00186 } 00187 write_unlock_bh(&udp_hash_lock); 00188 return 0; 00189 00190 fail: 00191 write_unlock_bh(&udp_hash_lock); 00192 return 1; 00193 } 00194 00195 static void udp_v4_hash(struct sock *sk) 00196 { 00197 BUG(); 00198 } 00199 00200 static void udp_v4_unhash(struct sock *sk) 00201 { 00202 write_lock_bh(&udp_hash_lock); 00203 if (sk->pprev) { 00204 if (sk->next) 00205 sk->next->pprev = sk->pprev; 00206 *sk->pprev = sk->next; 00207 sk->pprev = NULL; 00208 sk->num = 0; 00209 sock_prot_dec_use(sk->prot); 00210 __sock_put(sk); 00211 } 00212 write_unlock_bh(&udp_hash_lock); 00213 } 00214 00215 /* UDP is nearly always wildcards out the wazoo, it makes no sense to try 00216 * harder than this. -DaveM 00217 */ 00218 struct sock *udp_v4_lookup_longway(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif) 00219 { 00220 struct sock *sk, *result = NULL; 00221 unsigned short hnum = ntohs(dport); 00222 int badness = -1; 00223 00224 for(sk = udp_hash[hnum & (UDP_HTABLE_SIZE - 1)]; sk != NULL; sk = sk->next) { 00225 if(sk->num == hnum && !ipv6_only_sock(sk)) { 00226 int score; 00227 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 00228 score = sk->family == PF_INET ? 1 : 0; 00229 #else 00230 score = 1; 00231 #endif 00232 if(sk->rcv_saddr) { 00233 if(sk->rcv_saddr != daddr) 00234 continue; 00235 score+=2; 00236 } 00237 if(sk->daddr) { 00238 if(sk->daddr != saddr) 00239 continue; 00240 score+=2; 00241 } 00242 if(sk->dport) { 00243 if(sk->dport != sport) 00244 continue; 00245 score+=2; 00246 } 00247 if(sk->bound_dev_if) { 00248 if(sk->bound_dev_if != dif) 00249 continue; 00250 score+=2; 00251 } 00252 if(score == 9) { 00253 result = sk; 00254 break; 00255 } else if(score > badness) { 00256 result = sk; 00257 badness = score; 00258 } 00259 } 00260 } 00261 return result; 00262 } 00263 00264 __inline__ struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif) 00265 { 00266 struct sock *sk; 00267 00268 read_lock(&udp_hash_lock); 00269 sk = udp_v4_lookup_longway(saddr, sport, daddr, dport, dif); 00270 if (sk) 00271 sock_hold(sk); 00272 read_unlock(&udp_hash_lock); 00273 return sk; 00274 } 00275 00276 extern int ip_mc_sf_allow(struct sock *sk, u32 local, u32 rmt, int dif); 00277 00278 static inline struct sock *udp_v4_mcast_next(struct sock *sk, 00279 u16 loc_port, u32 loc_addr, 00280 u16 rmt_port, u32 rmt_addr, 00281 int dif) 00282 { 00283 struct sock *s = sk; 00284 unsigned short hnum = ntohs(loc_port); 00285 for(; s; s = s->next) { 00286 if ((s->num != hnum) || 00287 (s->daddr && s->daddr!=rmt_addr) || 00288 (s->dport != rmt_port && s->dport != 0) || 00289 (s->rcv_saddr && s->rcv_saddr != loc_addr) || 00290 ipv6_only_sock(s) || 00291 (s->bound_dev_if && s->bound_dev_if != dif)) 00292 continue; 00293 if (!ip_mc_sf_allow(sk, loc_addr, rmt_addr, dif)) 00294 continue; 00295 break; 00296 } 00297 return s; 00298 } 00299 00300 /* 00301 * This routine is called by the ICMP module when it gets some 00302 * sort of error condition. If err < 0 then the socket should 00303 * be closed and the error returned to the user. If err > 0 00304 * it's just the icmp type << 8 | icmp code. 00305 * Header points to the ip header of the error packet. We move 00306 * on past this. Then (as it used to claim before adjustment) 00307 * header points to the first 8 bytes of the udp header. We need 00308 * to find the appropriate port. 00309 */ 00310 00311 void udp_err(struct sk_buff *skb, u32 info) 00312 { 00313 struct iphdr *iph = (struct iphdr*)skb->data; 00314 struct udphdr *uh = (struct udphdr*)(skb->data+(iph->ihl<<2)); 00315 int type = skb->h.icmph->type; 00316 int code = skb->h.icmph->code; 00317 struct sock *sk; 00318 int harderr; 00319 int err; 00320 00321 sk = udp_v4_lookup(iph->daddr, uh->dest, iph->saddr, uh->source, skb->dev->ifindex); 00322 if (sk == NULL) { 00323 ICMP_INC_STATS_BH(IcmpInErrors); 00324 return; /* No socket for error */ 00325 } 00326 00327 err = 0; 00328 harderr = 0; 00329 00330 switch (type) { 00331 default: 00332 case ICMP_TIME_EXCEEDED: 00333 err = EHOSTUNREACH; 00334 break; 00335 case ICMP_SOURCE_QUENCH: 00336 goto out; 00337 case ICMP_PARAMETERPROB: 00338 err = EPROTO; 00339 harderr = 1; 00340 break; 00341 case ICMP_DEST_UNREACH: 00342 if (code == ICMP_FRAG_NEEDED) { /* Path MTU discovery */ 00343 if (sk->protinfo.af_inet.pmtudisc != IP_PMTUDISC_DONT) { 00344 err = EMSGSIZE; 00345 harderr = 1; 00346 break; 00347 } 00348 goto out; 00349 } 00350 err = EHOSTUNREACH; 00351 if (code <= NR_ICMP_UNREACH) { 00352 harderr = icmp_err_convert[code].fatal; 00353 err = icmp_err_convert[code].errno; 00354 } 00355 break; 00356 } 00357 00358 /* 00359 * RFC1122: OK. Passes ICMP errors back to application, as per 00360 * 4.1.3.3. 00361 */ 00362 if (!sk->protinfo.af_inet.recverr) { 00363 if (!harderr || sk->state != TCP_ESTABLISHED) 00364 goto out; 00365 } else { 00366 ip_icmp_error(sk, skb, err, uh->dest, info, (u8*)(uh+1)); 00367 } 00368 sk->err = err; 00369 sk->error_report(sk); 00370 out: 00371 sock_put(sk); 00372 } 00373 00374 00375 static unsigned short udp_check(struct udphdr *uh, int len, unsigned long saddr, unsigned long daddr, unsigned long base) 00376 { 00377 return(csum_tcpudp_magic(saddr, daddr, len, IPPROTO_UDP, base)); 00378 } 00379 00380 struct udpfakehdr 00381 { 00382 struct udphdr uh; 00383 u32 saddr; 00384 u32 daddr; 00385 struct iovec *iov; 00386 u32 wcheck; 00387 }; 00388 00389 /* 00390 * Copy and checksum a UDP packet from user space into a buffer. 00391 */ 00392 00393 static int udp_getfrag(const void *p, char * to, unsigned int offset, unsigned int fraglen) 00394 { 00395 struct udpfakehdr *ufh = (struct udpfakehdr *)p; 00396 if (offset==0) { 00397 if (csum_partial_copy_fromiovecend(to+sizeof(struct udphdr), ufh->iov, offset, 00398 fraglen-sizeof(struct udphdr), &ufh->wcheck)) 00399 return -EFAULT; 00400 ufh->wcheck = csum_partial((char *)ufh, sizeof(struct udphdr), 00401 ufh->wcheck); 00402 ufh->uh.check = csum_tcpudp_magic(ufh->saddr, ufh->daddr, 00403 ntohs(ufh->uh.len), 00404 IPPROTO_UDP, ufh->wcheck); 00405 if (ufh->uh.check == 0) 00406 ufh->uh.check = -1; 00407 memcpy(to, ufh, sizeof(struct udphdr)); 00408 return 0; 00409 } 00410 if (csum_partial_copy_fromiovecend(to, ufh->iov, offset-sizeof(struct udphdr), 00411 fraglen, &ufh->wcheck)) 00412 return -EFAULT; 00413 return 0; 00414 } 00415 00416 /* 00417 * Copy a UDP packet from user space into a buffer without checksumming. 00418 */ 00419 00420 static int udp_getfrag_nosum(const void *p, char * to, unsigned int offset, unsigned int fraglen) 00421 { 00422 struct udpfakehdr *ufh = (struct udpfakehdr *)p; 00423 00424 if (offset==0) { 00425 memcpy(to, ufh, sizeof(struct udphdr)); 00426 return memcpy_fromiovecend(to+sizeof(struct udphdr), ufh->iov, offset, 00427 fraglen-sizeof(struct udphdr)); 00428 } 00429 return memcpy_fromiovecend(to, ufh->iov, offset-sizeof(struct udphdr), 00430 fraglen); 00431 } 00432 00461 int udp_sendmsg(struct sock *sk, struct msghdr *msg, int len) 00462 { 00463 int ulen = len + sizeof(struct udphdr); 00464 struct ipcm_cookie ipc; 00465 struct udpfakehdr ufh; 00466 struct rtable *rt = NULL; 00467 int free = 0; 00468 int connected = 0; 00469 u32 daddr; 00470 u8 tos; 00471 int err; 00472 00473 /* This check is ONLY to check for arithmetic overflow 00474 on integer(!) len. Not more! Real check will be made 00475 in ip_build_xmit --ANK 00476 00477 BTW socket.c -> af_*.c -> ... make multiple 00478 invalid conversions size_t -> int. We MUST repair it f.e. 00479 by replacing all of them with size_t and revise all 00480 the places sort of len += sizeof(struct iphdr) 00481 If len was ULONG_MAX-10 it would be cathastrophe --ANK 00482 */ 00483 00484 if (len < 0 || len > 0xFFFF) 00485 return -EMSGSIZE; 00486 00487 /* 00488 * Check the flags. 00489 */ 00490 00491 if (msg->msg_flags&MSG_OOB) /* Mirror BSD error message compatibility */ 00492 return -EOPNOTSUPP; 00493 00494 /* 00495 * Get and verify the address. 00496 */ 00497 00498 if (msg->msg_name) { 00499 struct sockaddr_in * usin = (struct sockaddr_in*)msg->msg_name; 00500 if (msg->msg_namelen < sizeof(*usin)) 00501 return -EINVAL; 00502 if (usin->sin_family != AF_INET) { 00503 if (usin->sin_family != AF_UNSPEC) 00504 return -EINVAL; 00505 } 00506 00507 ufh.daddr = usin->sin_addr.s_addr; 00508 ufh.uh.dest = usin->sin_port; 00509 if (ufh.uh.dest == 0) 00510 return -EINVAL; 00511 } else { 00512 if (sk->state != TCP_ESTABLISHED) 00513 return -EDESTADDRREQ; 00514 ufh.daddr = sk->daddr; 00515 ufh.uh.dest = sk->dport; 00516 /* Open fast path for connected socket. 00517 Route will not be used, if at least one option is set. 00518 */ 00519 connected = 1; 00520 } 00521 ipc.addr = sk->saddr; 00522 ufh.uh.source = sk->sport; 00523 00524 ipc.opt = NULL; 00525 ipc.oif = sk->bound_dev_if; 00526 if (msg->msg_controllen) { 00527 err = ip_cmsg_send(msg, &ipc); 00528 if (err) 00529 return err; 00530 if (ipc.opt) 00531 free = 1; 00532 connected = 0; 00533 } 00534 if (!ipc.opt) 00535 ipc.opt = sk->protinfo.af_inet.opt; 00536 00537 ufh.saddr = ipc.addr; 00538 ipc.addr = daddr = ufh.daddr; 00539 00540 if (ipc.opt && ipc.opt->srr) { 00541 if (!daddr) 00542 return -EINVAL; 00543 daddr = ipc.opt->faddr; 00544 connected = 0; 00545 } 00546 tos = RT_TOS(sk->protinfo.af_inet.tos); 00547 if (sk->localroute || (msg->msg_flags&MSG_DONTROUTE) || 00548 (ipc.opt && ipc.opt->is_strictroute)) { 00549 tos |= RTO_ONLINK; 00550 connected = 0; 00551 } 00552 00553 if (MULTICAST(daddr)) { 00554 if (!ipc.oif) 00555 ipc.oif = sk->protinfo.af_inet.mc_index; 00556 if (!ufh.saddr) 00557 ufh.saddr = sk->protinfo.af_inet.mc_addr; 00558 connected = 0; 00559 } 00560 00561 if (connected) 00562 rt = (struct rtable*)sk_dst_check(sk, 0); 00563 00564 if (rt == NULL) { 00565 err = ip_route_output(&rt, daddr, ufh.saddr, tos, ipc.oif); 00566 if (err) 00567 goto out; 00568 00569 err = -EACCES; 00570 if (rt->rt_flags&RTCF_BROADCAST && !sk->broadcast) 00571 goto out; 00572 if (connected) 00573 sk_dst_set(sk, dst_clone(&rt->u.dst)); 00574 } 00575 00576 if (msg->msg_flags&MSG_CONFIRM) 00577 goto do_confirm; 00578 back_from_confirm: 00579 00580 ufh.saddr = rt->rt_src; 00581 if (!ipc.addr) 00582 ufh.daddr = ipc.addr = rt->rt_dst; 00583 ufh.uh.len = htons(ulen); 00584 ufh.uh.check = 0; 00585 ufh.iov = msg->msg_iov; 00586 ufh.wcheck = 0; 00587 00588 /* RFC1122: OK. Provides the checksumming facility (MUST) as per */ 00589 /* 4.1.3.4. It's configurable by the application via setsockopt() */ 00590 /* (MAY) and it defaults to on (MUST). */ 00591 00592 err = ip_build_xmit(sk, 00593 (sk->no_check == UDP_CSUM_NOXMIT ? 00594 udp_getfrag_nosum : 00595 udp_getfrag), 00596 &ufh, ulen, &ipc, rt, msg->msg_flags); 00597 00598 out: 00599 ip_rt_put(rt); 00600 if (free) 00601 kfree(ipc.opt); 00602 if (!err) { 00603 UDP_INC_STATS_USER(UdpOutDatagrams); 00604 return len; 00605 } 00606 return err; 00607 00608 do_confirm: 00609 dst_confirm(&rt->u.dst); 00610 if (!(msg->msg_flags&MSG_PROBE) || len) 00611 goto back_from_confirm; 00612 err = 0; 00613 goto out; 00614 } 00615 00616 /* 00617 * IOCTL requests applicable to the UDP protocol 00618 */ 00619 00620 int udp_ioctl(struct sock *sk, int cmd, unsigned long arg) 00621 { 00622 switch(cmd) 00623 { 00624 case SIOCOUTQ: 00625 { 00626 int amount = atomic_read(&sk->wmem_alloc); 00627 return put_user(amount, (int *)arg); 00628 } 00629 00630 case SIOCINQ: 00631 { 00632 struct sk_buff *skb; 00633 unsigned long amount; 00634 00635 amount = 0; 00636 spin_lock_irq(&sk->receive_queue.lock); 00637 skb = skb_peek(&sk->receive_queue); 00638 if (skb != NULL) { 00639 /* 00640 * We will only return the amount 00641 * of this packet since that is all 00642 * that will be read. 00643 */ 00644 amount = skb->len - sizeof(struct udphdr); 00645 } 00646 spin_unlock_irq(&sk->receive_queue.lock); 00647 return put_user(amount, (int *)arg); 00648 } 00649 00650 default: 00651 return -ENOIOCTLCMD; 00652 } 00653 return(0); 00654 } 00655 00656 static __inline__ int __udp_checksum_complete(struct sk_buff *skb) 00657 { 00658 return (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)); 00659 } 00660 00661 static __inline__ int udp_checksum_complete(struct sk_buff *skb) 00662 { 00663 return skb->ip_summed != CHECKSUM_UNNECESSARY && 00664 __udp_checksum_complete(skb); 00665 } 00666 00667 /* 00668 * This should be easy, if there is something there we 00669 * return it, otherwise we block. 00670 */ 00671 00672 int udp_recvmsg(struct sock *sk, struct msghdr *msg, int len, 00673 int noblock, int flags, int *addr_len) 00674 { 00675 struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name; 00676 struct sk_buff *skb; 00677 int copied, err; 00678 00679 /* 00680 * Check any passed addresses 00681 */ 00682 if (addr_len) 00683 *addr_len=sizeof(*sin); 00684 00685 if (flags & MSG_ERRQUEUE) 00686 return ip_recv_error(sk, msg, len); 00687 00688 skb = skb_recv_datagram(sk, flags, noblock, &err); 00689 if (!skb) 00690 goto out; 00691 00692 copied = skb->len - sizeof(struct udphdr); 00693 if (copied > len) { 00694 copied = len; 00695 msg->msg_flags |= MSG_TRUNC; 00696 } 00697 00698 if (skb->ip_summed==CHECKSUM_UNNECESSARY) { 00699 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov, 00700 copied); 00701 } else if (msg->msg_flags&MSG_TRUNC) { 00702 if (__udp_checksum_complete(skb)) 00703 goto csum_copy_err; 00704 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov, 00705 copied); 00706 } else { 00707 err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov); 00708 00709 if (err == -EINVAL) 00710 goto csum_copy_err; 00711 } 00712 00713 if (err) 00714 goto out_free; 00715 00716 sock_recv_timestamp(msg, sk, skb); 00717 00718 /* Copy the address. */ 00719 if (sin) 00720 { 00721 sin->sin_family = AF_INET; 00722 sin->sin_port = skb->h.uh->source; 00723 sin->sin_addr.s_addr = skb->nh.iph->saddr; 00724 memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); 00725 } 00726 if (sk->protinfo.af_inet.cmsg_flags) 00727 ip_cmsg_recv(msg, skb); 00728 err = copied; 00729 00730 out_free: 00731 skb_free_datagram(sk, skb); 00732 out: 00733 return err; 00734 00735 csum_copy_err: 00736 UDP_INC_STATS_BH(UdpInErrors); 00737 00738 /* Clear queue. */ 00739 if (flags&MSG_PEEK) { 00740 int clear = 0; 00741 spin_lock_irq(&sk->receive_queue.lock); 00742 if (skb == skb_peek(&sk->receive_queue)) { 00743 __skb_unlink(skb, &sk->receive_queue); 00744 clear = 1; 00745 } 00746 spin_unlock_irq(&sk->receive_queue.lock); 00747 if (clear) 00748 kfree_skb(skb); 00749 } 00750 00751 skb_free_datagram(sk, skb); 00752 00753 return -EAGAIN; 00754 } 00755 00756 int udp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) 00757 { 00758 struct sockaddr_in *usin = (struct sockaddr_in *) uaddr; 00759 struct rtable *rt; 00760 u32 saddr; 00761 int oif; 00762 int err; 00763 00764 00765 if (addr_len < sizeof(*usin)) 00766 return -EINVAL; 00767 00768 if (usin->sin_family != AF_INET) 00769 return -EAFNOSUPPORT; 00770 00771 sk_dst_reset(sk); 00772 00773 oif = sk->bound_dev_if; 00774 saddr = sk->saddr; 00775 if (MULTICAST(usin->sin_addr.s_addr)) { 00776 if (!oif) 00777 oif = sk->protinfo.af_inet.mc_index; 00778 if (!saddr) 00779 saddr = sk->protinfo.af_inet.mc_addr; 00780 } 00781 err = ip_route_connect(&rt, usin->sin_addr.s_addr, saddr, 00782 RT_CONN_FLAGS(sk), oif); 00783 if (err) 00784 return err; 00785 if ((rt->rt_flags&RTCF_BROADCAST) && !sk->broadcast) { 00786 ip_rt_put(rt); 00787 return -EACCES; 00788 } 00789 if(!sk->saddr) 00790 sk->saddr = rt->rt_src; /* Update source address */ 00791 if(!sk->rcv_saddr) 00792 sk->rcv_saddr = rt->rt_src; 00793 sk->daddr = rt->rt_dst; 00794 sk->dport = usin->sin_port; 00795 sk->state = TCP_ESTABLISHED; 00796 sk->protinfo.af_inet.id = jiffies; 00797 00798 sk_dst_set(sk, &rt->u.dst); 00799 return(0); 00800 } 00801 00802 int udp_disconnect(struct sock *sk, int flags) 00803 { 00804 /* 00805 * 1003.1g - break association. 00806 */ 00807 00808 sk->state = TCP_CLOSE; 00809 sk->daddr = 0; 00810 sk->dport = 0; 00811 sk->bound_dev_if = 0; 00812 if (!(sk->userlocks&SOCK_BINDADDR_LOCK)) { 00813 sk->rcv_saddr = 0; 00814 sk->saddr = 0; 00815 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 00816 memset(&sk->net_pinfo.af_inet6.saddr, 0, 16); 00817 memset(&sk->net_pinfo.af_inet6.rcv_saddr, 0, 16); 00818 #endif 00819 } 00820 if (!(sk->userlocks&SOCK_BINDPORT_LOCK)) { 00821 sk->prot->unhash(sk); 00822 sk->sport = 0; 00823 } 00824 sk_dst_reset(sk); 00825 return 0; 00826 } 00827 00828 static void udp_close(struct sock *sk, long timeout) 00829 { 00830 inet_sock_release(sk); 00831 } 00832 00833 static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) 00834 { 00835 /* 00836 * Charge it to the socket, dropping if the queue is full. 00837 */ 00838 00839 #if defined(CONFIG_FILTER) 00840 if (sk->filter && skb->ip_summed != CHECKSUM_UNNECESSARY) { 00841 if (__udp_checksum_complete(skb)) { 00842 UDP_INC_STATS_BH(UdpInErrors); 00843 IP_INC_STATS_BH(IpInDiscards); 00844 ip_statistics[smp_processor_id()*2].IpInDelivers--; 00845 kfree_skb(skb); 00846 return -1; 00847 } 00848 skb->ip_summed = CHECKSUM_UNNECESSARY; 00849 } 00850 #endif 00851 00852 if (sock_queue_rcv_skb(sk,skb)<0) { 00853 UDP_INC_STATS_BH(UdpInErrors); 00854 IP_INC_STATS_BH(IpInDiscards); 00855 ip_statistics[smp_processor_id()*2].IpInDelivers--; 00856 kfree_skb(skb); 00857 return -1; 00858 } 00859 UDP_INC_STATS_BH(UdpInDatagrams); 00860 return 0; 00861 } 00862 00863 /* 00864 * Multicasts and broadcasts go to each listener. 00865 * 00866 * Note: called only from the BH handler context, 00867 * so we don't need to lock the hashes. 00868 */ 00869 static int udp_v4_mcast_deliver(struct sk_buff *skb, struct udphdr *uh, 00870 u32 saddr, u32 daddr) 00871 { 00872 struct sock *sk; 00873 int dif; 00874 00875 read_lock(&udp_hash_lock); 00876 sk = udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]; 00877 dif = skb->dev->ifindex; 00878 sk = udp_v4_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); 00879 if (sk) { 00880 struct sock *sknext = NULL; 00881 00882 do { 00883 struct sk_buff *skb1 = skb; 00884 00885 sknext = udp_v4_mcast_next(sk->next, uh->dest, daddr, 00886 uh->source, saddr, dif); 00887 if(sknext) 00888 skb1 = skb_clone(skb, GFP_ATOMIC); 00889 00890 if(skb1) 00891 udp_queue_rcv_skb(sk, skb1); 00892 sk = sknext; 00893 } while(sknext); 00894 } else 00895 kfree_skb(skb); 00896 read_unlock(&udp_hash_lock); 00897 return 0; 00898 } 00899 00900 /* Initialize UDP checksum. If exited with zero value (success), 00901 * CHECKSUM_UNNECESSARY means, that no more checks are required. 00902 * Otherwise, csum completion requires chacksumming packet body, 00903 * including udp header and folding it to skb->csum. 00904 */ 00905 static int udp_checksum_init(struct sk_buff *skb, struct udphdr *uh, 00906 unsigned short ulen, u32 saddr, u32 daddr) 00907 { 00908 if (uh->check == 0) { 00909 skb->ip_summed = CHECKSUM_UNNECESSARY; 00910 } else if (skb->ip_summed == CHECKSUM_HW) { 00911 skb->ip_summed = CHECKSUM_UNNECESSARY; 00912 if (!udp_check(uh, ulen, saddr, daddr, skb->csum)) 00913 return 0; 00914 NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "udp v4 hw csum failure.\n")); 00915 skb->ip_summed = CHECKSUM_NONE; 00916 } 00917 if (skb->ip_summed != CHECKSUM_UNNECESSARY) 00918 skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0); 00919 /* Probably, we should checksum udp header (it should be in cache 00920 * in any case) and data in tiny packets (< rx copybreak). 00921 */ 00922 return 0; 00923 } 00924 00925 /* 00926 * All we need to do is get the socket, and then do a checksum. 00927 */ 00928 00944 int udp_rcv(struct sk_buff *skb) 00945 { 00946 struct sock *sk; 00947 struct udphdr *uh; 00948 unsigned short ulen; 00949 struct rtable *rt = (struct rtable*)skb->dst; 00950 u32 saddr = skb->nh.iph->saddr; 00951 u32 daddr = skb->nh.iph->daddr; 00952 int len = skb->len; 00953 00954 IP_INC_STATS_BH(IpInDelivers); 00955 00956 /* 00957 * Validate the packet and the UDP length. 00958 */ 00959 if (!pskb_may_pull(skb, sizeof(struct udphdr))) 00960 goto no_header; 00961 00962 uh = skb->h.uh; 00963 00964 ulen = ntohs(uh->len); 00965 00966 if (ulen > len || ulen < sizeof(*uh)) 00967 goto short_packet; 00968 00969 if (pskb_trim(skb, ulen)) 00970 goto short_packet; 00971 00972 if (udp_checksum_init(skb, uh, ulen, saddr, daddr) < 0) 00973 goto csum_error; 00974 00975 if(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST)) 00976 return udp_v4_mcast_deliver(skb, uh, saddr, daddr); 00977 00978 sk = udp_v4_lookup(saddr, uh->source, daddr, uh->dest, skb->dev->ifindex); 00979 00980 if (sk != NULL) { 00981 udp_queue_rcv_skb(sk, skb); 00982 sock_put(sk); 00983 return 0; 00984 } 00985 00986 /* No socket. Drop packet silently, if checksum is wrong */ 00987 if (udp_checksum_complete(skb)) 00988 goto csum_error; 00989 00990 UDP_INC_STATS_BH(UdpNoPorts); 00991 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); 00992 00993 /* 00994 * Hmm. We got an UDP packet to a port to which we 00995 * don't wanna listen. Ignore it. 00996 */ 00997 kfree_skb(skb); 00998 return(0); 00999 01000 short_packet: 01001 NETDEBUG(if (net_ratelimit()) 01002 printk(KERN_DEBUG "UDP: short packet: %u.%u.%u.%u:%u %d/%d to %u.%u.%u.%u:%u\n", 01003 NIPQUAD(saddr), 01004 ntohs(uh->source), 01005 ulen, 01006 len, 01007 NIPQUAD(daddr), 01008 ntohs(uh->dest))); 01009 no_header: 01010 UDP_INC_STATS_BH(UdpInErrors); 01011 kfree_skb(skb); 01012 return(0); 01013 01014 csum_error: 01015 /* 01016 * RFC1122: OK. Discards the bad packet silently (as far as 01017 * the network is concerned, anyway) as per 4.1.3.4 (MUST). 01018 */ 01019 NETDEBUG(if (net_ratelimit()) 01020 printk(KERN_DEBUG "UDP: bad checksum. From %d.%d.%d.%d:%d to %d.%d.%d.%d:%d ulen %d\n", 01021 NIPQUAD(saddr), 01022 ntohs(uh->source), 01023 NIPQUAD(daddr), 01024 ntohs(uh->dest), 01025 ulen)); 01026 UDP_INC_STATS_BH(UdpInErrors); 01027 kfree_skb(skb); 01028 return(0); 01029 } 01030 01031 static void get_udp_sock(struct sock *sp, char *tmpbuf, int i) 01032 { 01033 unsigned int dest, src; 01034 __u16 destp, srcp; 01035 01036 dest = sp->daddr; 01037 src = sp->rcv_saddr; 01038 destp = ntohs(sp->dport); 01039 srcp = ntohs(sp->sport); 01040 sprintf(tmpbuf, "%4d: %08X:%04X %08X:%04X" 01041 " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p", 01042 i, src, srcp, dest, destp, sp->state, 01043 atomic_read(&sp->wmem_alloc), atomic_read(&sp->rmem_alloc), 01044 0, 0L, 0, 01045 sock_i_uid(sp), 0, 01046 sock_i_ino(sp), 01047 atomic_read(&sp->refcnt), sp); 01048 } 01049 01050 int udp_get_info(char *buffer, char **start, off_t offset, int length) 01051 { 01052 int len = 0, num = 0, i; 01053 off_t pos = 0; 01054 off_t begin; 01055 char tmpbuf[129]; 01056 01057 if (offset < 128) 01058 len += sprintf(buffer, "%-127s\n", 01059 " sl local_address rem_address st tx_queue " 01060 "rx_queue tr tm->when retrnsmt uid timeout inode"); 01061 pos = 128; 01062 read_lock(&udp_hash_lock); 01063 for (i = 0; i < UDP_HTABLE_SIZE; i++) { 01064 struct sock *sk; 01065 01066 for (sk = udp_hash[i]; sk; sk = sk->next, num++) { 01067 if (sk->family != PF_INET) 01068 continue; 01069 pos += 128; 01070 if (pos <= offset) 01071 continue; 01072 get_udp_sock(sk, tmpbuf, i); 01073 len += sprintf(buffer+len, "%-127s\n", tmpbuf); 01074 if(len >= length) 01075 goto out; 01076 } 01077 } 01078 out: 01079 read_unlock(&udp_hash_lock); 01080 begin = len - (pos - offset); 01081 *start = buffer + begin; 01082 len -= begin; 01083 if(len > length) 01084 len = length; 01085 if (len < 0) 01086 len = 0; 01087 return len; 01088 } 01089 01090 struct proto udp_prot = { 01091 name: "UDP", 01092 close: udp_close, 01093 connect: udp_connect, 01094 disconnect: udp_disconnect, 01095 ioctl: udp_ioctl, 01096 setsockopt: ip_setsockopt, 01097 getsockopt: ip_getsockopt, 01098 sendmsg: udp_sendmsg, 01099 recvmsg: udp_recvmsg, 01100 backlog_rcv: udp_queue_rcv_skb, 01101 hash: udp_v4_hash, 01102 unhash: udp_v4_unhash, 01103 get_port: udp_v4_get_port, 01104 };

Generated on Wed Dec 1 21:25:33 2004 for Linux 2.4.23 Networking by doxygen 1.3.8