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_write
  9. udp_ioctl
  10. udp_recvmsg
  11. udp_recvfrom
  12. udp_read
  13. udp_connect
  14. udp_close
  15. udp_rcv
  16. 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  *
  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][next][first][last][top][bottom][index][help] */
 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][next][first][last][top][bottom][index][help] */
 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][next][first][last][top][bottom][index][help] */
 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][next][first][last][top][bottom][index][help] */
 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][next][first][last][top][bottom][index][help] */
 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][next][first][last][top][bottom][index][help] */
 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][next][first][last][top][bottom][index][help] */
 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][next][first][last][top][bottom][index][help] */
 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][next][first][last][top][bottom][index][help] */
 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 = sock_wspace(sk);
 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_recvmsg(struct sock *sk, struct msghdr *msg, int len,
     /* [previous][next][first][last][top][bottom][index][help] */
 474              int noblock, int flags,int *addr_len)
 475 {
 476         int copied = 0;
 477         int truesize;
 478         struct sk_buff *skb;
 479         int er;
 480         struct sockaddr_in *sin=(struct sockaddr_in *)msg->msg_name;
 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_iovec(skb,sizeof(struct udphdr),msg->msg_iov,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 int udp_recvfrom(struct sock *sk, unsigned char *ubuf, int size, int noblock, unsigned flags,
     /* [previous][next][first][last][top][bottom][index][help] */
 522                 struct sockaddr_in *sa, int *addr_len)
 523 {
 524         struct iovec iov;
 525         struct msghdr msg;
 526 
 527         iov.iov_base = ubuf;
 528         iov.iov_len  = size;
 529 
 530         msg.msg_name      = (void *)sa;
 531         msg.msg_namelen   = 0;
 532         if (addr_len)
 533                 msg.msg_namelen = *addr_len;
 534         msg.msg_accrights = NULL;
 535         msg.msg_iov       = &iov;
 536         msg.msg_iovlen    = 1;
 537 
 538         return udp_recvmsg(sk, &msg, size, noblock, flags, addr_len);
 539 }
 540 
 541 
 542 /*
 543  *      Read has the same semantics as recv in SOCK_DGRAM
 544  */
 545 
 546 int udp_read(struct sock *sk, unsigned char *buff, int len, int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
 547          unsigned flags)
 548 {
 549         return(udp_recvfrom(sk, buff, len, noblock, flags, NULL, NULL));
 550 }
 551 
 552 
 553 int udp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len)
     /* [previous][next][first][last][top][bottom][index][help] */
 554 {
 555         struct rtable *rt;
 556         __u32 sa;
 557         if (addr_len < sizeof(*usin)) 
 558                 return(-EINVAL);
 559 
 560         if (usin->sin_family && usin->sin_family != AF_INET) 
 561                 return(-EAFNOSUPPORT);
 562         if (usin->sin_addr.s_addr==INADDR_ANY)
 563                 usin->sin_addr.s_addr=ip_my_addr();
 564 
 565         if(!sk->broadcast && ip_chk_addr(usin->sin_addr.s_addr)==IS_BROADCAST)
 566                 return -EACCES;                 /* Must turn broadcast on first */
 567         
 568         rt=(sk->localroute?ip_rt_local:ip_rt_route)((__u32)usin->sin_addr.s_addr, NULL, &sa);
 569         if(rt==NULL)
 570                 return -ENETUNREACH;
 571         sk->saddr = sa;         /* Update source address */
 572         sk->daddr = usin->sin_addr.s_addr;
 573         sk->dummy_th.dest = usin->sin_port;
 574         sk->state = TCP_ESTABLISHED;
 575         udp_cache_zap();
 576         sk->ip_route_cache = rt;
 577         sk->ip_route_stamp = rt_stamp;
 578         return(0);
 579 }
 580 
 581 
 582 static void udp_close(struct sock *sk, int timeout)
     /* [previous][next][first][last][top][bottom][index][help] */
 583 {
 584         sk->inuse = 1;
 585         sk->state = TCP_CLOSE;
 586         if(uh_cache_sk==sk)
 587                 udp_cache_zap();
 588         if (sk->dead) 
 589                 destroy_sock(sk);
 590         else
 591                 release_sock(sk);
 592 }
 593 
 594 
 595 /*
 596  *      All we need to do is get the socket, and then do a checksum. 
 597  */
 598  
 599 int udp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
     /* [previous][next][first][last][top][bottom][index][help] */
 600         __u32 daddr, unsigned short len,
 601         __u32 saddr, int redo, struct inet_protocol *protocol)
 602 {
 603         struct sock *sk;
 604         struct udphdr *uh;
 605         unsigned short ulen;
 606         int addr_type = IS_MYADDR;
 607         
 608         if(!dev || dev->pa_addr!=daddr)
 609                 addr_type=ip_chk_addr(daddr);
 610                 
 611         /*
 612          *      Get the header.
 613          */
 614          
 615         uh = (struct udphdr *) skb->h.uh;
 616         
 617         ip_statistics.IpInDelivers++;
 618 
 619         /*
 620          *      Validate the packet and the UDP length.
 621          */
 622          
 623         ulen = ntohs(uh->len);
 624         
 625         if (ulen > len || len < sizeof(*uh) || ulen < sizeof(*uh)) 
 626         {
 627                 NETDEBUG(printk("UDP: short packet: %d/%d\n", ulen, len));
 628                 udp_statistics.UdpInErrors++;
 629                 kfree_skb(skb, FREE_WRITE);
 630                 return(0);
 631         }
 632 
 633         /* RFC1122 warning: According to 4.1.3.6, we MUST discard any */
 634         /* datagram which has an invalid source address, either here or */
 635         /* in IP. */
 636         /* Right now, IP isn't doing it, and neither is UDP. It's on the */
 637         /* FIXME list for IP, though, so I wouldn't worry about it. */
 638         /* (That's the Right Place to do it, IMHO.) -- MS */
 639 
 640         if (uh->check && (
 641                 ( skb->ip_summed && udp_check(uh, len, saddr, daddr, skb->csum ) ) ||
 642                 ( !skb->ip_summed && udp_check(uh, len, saddr, daddr,csum_partial((char*)uh, len, 0)))
 643                          )
 644            )
 645         {
 646                 /* <mea@utu.fi> wants to know, who sent it, to
 647                    go and stomp on the garbage sender... */
 648 
 649           /* RFC1122: OK.  Discards the bad packet silently (as far as */
 650           /* the network is concered, anyway) as per 4.1.3.4 (MUST). */
 651 
 652                 NETDEBUG(printk("UDP: bad checksum. From %08lX:%d to %08lX:%d ulen %d\n",
 653                        ntohl(saddr),ntohs(uh->source),
 654                        ntohl(daddr),ntohs(uh->dest),
 655                        ulen));
 656                 udp_statistics.UdpInErrors++;
 657                 kfree_skb(skb, FREE_WRITE);
 658                 return(0);
 659         }
 660 
 661 
 662         len=ulen;
 663 
 664 #ifdef CONFIG_IP_MULTICAST
 665         if (addr_type!=IS_MYADDR)
 666         {
 667                 /*
 668                  *      Multicasts and broadcasts go to each listener.
 669                  */
 670                 struct sock *sknext=NULL;
 671                 sk=get_sock_mcast(udp_prot.sock_array[ntohs(uh->dest)&(SOCK_ARRAY_SIZE-1)], uh->dest,
 672                                 saddr, uh->source, daddr);
 673                 if(sk)
 674                 {               
 675                         do
 676                         {
 677                                 struct sk_buff *skb1;
 678 
 679                                 sknext=get_sock_mcast(sk->next, uh->dest, saddr, uh->source, daddr);
 680                                 if(sknext)
 681                                         skb1=skb_clone(skb,GFP_ATOMIC);
 682                                 else
 683                                         skb1=skb;
 684                                 if(skb1)
 685                                         udp_deliver(sk, uh, skb1, dev,saddr,daddr,len);
 686                                 sk=sknext;
 687                         }
 688                         while(sknext!=NULL);
 689                 }
 690                 else
 691                         kfree_skb(skb, FREE_READ);
 692                 return 0;
 693         }       
 694 #endif
 695         if(saddr==uh_cache_saddr && daddr==uh_cache_daddr && uh->dest==uh_cache_dport && uh->source==uh_cache_sport)
 696                 sk=(struct sock *)uh_cache_sk;
 697         else
 698         {
 699                 sk = get_sock(&udp_prot, uh->dest, saddr, uh->source, daddr);
 700                 uh_cache_saddr=saddr;
 701                 uh_cache_daddr=daddr;
 702                 uh_cache_dport=uh->dest;
 703                 uh_cache_sport=uh->source;
 704                 uh_cache_sk=sk;
 705         }
 706         
 707         if (sk == NULL) 
 708         {
 709                 udp_statistics.UdpNoPorts++;
 710                 if (addr_type == IS_MYADDR) 
 711                 {
 712                         icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0, dev);
 713                 }
 714                 /*
 715                  * Hmm.  We got an UDP broadcast to a port to which we
 716                  * don't wanna listen.  Ignore it.
 717                  */
 718                 skb->sk = NULL;
 719                 kfree_skb(skb, FREE_WRITE);
 720                 return(0);
 721         }
 722         return udp_deliver(sk,uh,skb,dev, saddr, daddr, len);
 723 }
 724 
 725 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] */
 726 {
 727         skb->sk = sk;
 728         skb->dev = dev;
 729         skb_trim(skb,len);
 730 
 731         /*
 732          *      These are supposed to be switched. 
 733          */
 734          
 735         skb->daddr = saddr;
 736         skb->saddr = daddr;
 737 
 738 
 739         /*
 740          *      Charge it to the socket, dropping if the queue is full.
 741          */
 742 
 743         /* I assume this includes the IP options, as per RFC1122 (4.1.3.2). */
 744         /* If not, please let me know. -- MS */
 745 
 746         if (sock_queue_rcv_skb(sk,skb)<0) 
 747         {
 748                 udp_statistics.UdpInErrors++;
 749                 ip_statistics.IpInDiscards++;
 750                 ip_statistics.IpInDelivers--;
 751                 skb->sk = NULL;
 752                 kfree_skb(skb, FREE_WRITE);
 753                 release_sock(sk);
 754                 return(0);
 755         }
 756         udp_statistics.UdpInDatagrams++;
 757         release_sock(sk);
 758         return(0);
 759 }
 760 
 761 
 762 struct proto udp_prot = {
 763         udp_close,
 764         udp_read,
 765         udp_write,
 766         udp_sendto,
 767         udp_recvfrom,
 768         ip_build_header,
 769         udp_connect,
 770         NULL,
 771         ip_queue_xmit,
 772         NULL,
 773         NULL,
 774         NULL,
 775         udp_rcv,
 776         datagram_select,
 777         udp_ioctl,
 778         NULL,
 779         NULL,
 780         ip_setsockopt,
 781         ip_getsockopt,
 782         NULL,
 783         udp_recvmsg,
 784         128,
 785         0,
 786         "UDP",
 787         0, 0,
 788         {NULL,}
 789 };

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