root/net/ipv4/udp.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. udp_cache_zap
  2. udp_err
  3. udp_check
  4. udp_getfrag
  5. udp_getfrag_nosum
  6. udp_send
  7. udp_sendto
  8. udp_sendmsg
  9. udp_ioctl
  10. udp_recvmsg
  11. udp_connect
  12. udp_close
  13. udp_rcv
  14. udp_deliver

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

/* [previous][next][first][last][top][bottom][index][help] */