root/net/inet/udp.c

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

DEFINITIONS

This source file includes following definitions.
  1. print_udp
  2. udp_err
  3. udp_check
  4. udp_send_check
  5. udp_send
  6. udp_sendto
  7. udp_write
  8. udp_ioctl
  9. udp_recvfrom
  10. udp_read
  11. udp_connect
  12. udp_close
  13. udp_rcv

   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  *
  13  * Fixes:
  14  *              Alan Cox        :       verify_area() calls
  15  *              Alan Cox        :       stopped close while in use off icmp
  16  *                                      messages. Not a fix but a botch that
  17  *                                      for udp at least is 'valid'.
  18  *              Alan Cox        :       Fixed icmp handling properly
  19  *              Alan Cox        :       Correct error for oversized datagrams
  20  *              Alan Cox        :       Tidied select() semantics. 
  21  *              Alan Cox        :       udp_err() fixed properly, also now 
  22  *                                      select and read wake correctly on errors
  23  *              Alan Cox        :       udp_send verify_area moved to avoid mem leak
  24  *              Alan Cox        :       UDP can count its memory
  25  *              Alan Cox        :       send to an uknown connection causes
  26  *                                      an ECONNREFUSED off the icmp, but
  27  *                                      does NOT close.
  28  *              Alan Cox        :       Switched to new sk_buff handlers. No more backlog!
  29  *              Alan Cox        :       Using generic datagram code. Even smaller and the PEEK
  30  *                                      bug no longer crashes it.
  31  *              Fred Van Kempen :       Net2e support for sk->broadcast.
  32  *              Alan Cox        :       Uses skb_free_datagram
  33  *              Alan Cox        :       Added get/set sockopt support.
  34  *              Alan Cox        :       Broadcasting without option set returns EACCES.
  35  *              Alan Cox        :       No wakeup calls. Instead we now use the callbacks.
  36  *              Alan Cox        :       Use ip_tos and ip_ttl
  37  *              Alan Cox        :       SNMP Mibs
  38  *              Alan Cox        :       MSG_DONTROUTE, and 0.0.0.0 support.
  39  *              Matt Dillon     :       UDP length checks.
  40  *
  41  *
  42  *              This program is free software; you can redistribute it and/or
  43  *              modify it under the terms of the GNU General Public License
  44  *              as published by the Free Software Foundation; either version
  45  *              2 of the License, or (at your option) any later version.
  46  */
  47  
  48 #include <asm/system.h>
  49 #include <asm/segment.h>
  50 #include <linux/types.h>
  51 #include <linux/sched.h>
  52 #include <linux/fcntl.h>
  53 #include <linux/socket.h>
  54 #include <linux/sockios.h>
  55 #include <linux/in.h>
  56 #include <linux/errno.h>
  57 #include <linux/timer.h>
  58 #include <linux/termios.h>
  59 #include <linux/mm.h>
  60 #include <linux/inet.h>
  61 #include <linux/netdevice.h>
  62 #include "snmp.h"
  63 #include "ip.h"
  64 #include "protocol.h"
  65 #include "tcp.h"
  66 #include <linux/skbuff.h>
  67 #include "sock.h"
  68 #include "udp.h"
  69 #include "icmp.h"
  70 
  71 /*
  72  *      SNMP MIB for the UDP layer
  73  */
  74 
  75 struct udp_mib          udp_statistics;
  76 
  77 
  78 
  79 
  80 #define min(a,b)        ((a)<(b)?(a):(b))
  81 
  82 static void print_udp(struct udphdr *uh)
     /* [previous][next][first][last][top][bottom][index][help] */
  83 {
  84         if (inet_debug != DBG_UDP) 
  85                 return;
  86 
  87         if (uh == NULL) 
  88         {
  89                 printk("(NULL)\n");
  90                 return;
  91         }
  92         printk("UDP: source = %d, dest = %d\n", ntohs(uh->source), ntohs(uh->dest));
  93         printk("     len = %d, check = %d\n", ntohs(uh->len), ntohs(uh->check));
  94 }
  95 
  96 
  97 /*
  98  * This routine is called by the ICMP module when it gets some
  99  * sort of error condition.  If err < 0 then the socket should
 100  * be closed and the error returned to the user.  If err > 0
 101  * it's just the icmp type << 8 | icmp code.  
 102  * Header points to the ip header of the error packet. We move
 103  * on past this. Then (as it used to claim before adjustment)
 104  * header points to the first 8 bytes of the udp header.  We need
 105  * to find the appropriate port.
 106  */
 107 
 108 void udp_err(int err, unsigned char *header, unsigned long daddr,
     /* [previous][next][first][last][top][bottom][index][help] */
 109         unsigned long saddr, struct inet_protocol *protocol)
 110 {
 111         struct udphdr *th;
 112         struct sock *sk;
 113         struct iphdr *ip=(struct iphdr *)header;
 114   
 115         header += 4*ip->ihl;
 116 
 117         /*
 118          *      Find the 8 bytes of post IP header ICMP included for usA
 119          */  
 120         th = (struct udphdr *)header;  
 121    
 122         DPRINTF((DBG_UDP,"UDP: err(err=%d, header=%X, daddr=%X, saddr=%X, protocl=%X)\n\
 123                 sport=%d,dport=%d", err, header, daddr, saddr, protocol, (int)th->source,(int)th->dest));
 124 
 125         sk = get_sock(&udp_prot, th->source, daddr, th->dest, saddr);
 126 
 127         if (sk == NULL) 
 128                 return; /* No socket for error */
 129         
 130         if (err & 0xff00 ==(ICMP_SOURCE_QUENCH << 8)) 
 131         {       /* Slow down! */
 132                 if (sk->cong_window > 1) 
 133                         sk->cong_window = sk->cong_window/2;
 134                 return;
 135         }
 136 
 137         sk->err = icmp_err_convert[err & 0xff].errno;
 138 
 139         /*
 140          *      It's only fatal if we have connected to them. I'm not happy
 141          *      with this code. Some BSD comparisons need doing.
 142          */
 143          
 144         if (icmp_err_convert[err & 0xff].fatal && sk->state == TCP_ESTABLISHED) 
 145         {
 146                 sk->err=ECONNREFUSED;
 147         }
 148         
 149         sk->error_report(sk);
 150 }
 151 
 152 
 153 static unsigned short udp_check(struct udphdr *uh, int len, unsigned long saddr, unsigned long daddr)
     /* [previous][next][first][last][top][bottom][index][help] */
 154 {
 155         unsigned long sum;
 156 
 157         DPRINTF((DBG_UDP, "UDP: check(uh=%X, len = %d, saddr = %X, daddr = %X)\n",
 158                                                         uh, len, saddr, daddr));
 159 
 160         print_udp(uh);
 161 
 162         __asm__(  "\t addl %%ecx,%%ebx\n"
 163                   "\t adcl %%edx,%%ebx\n"
 164                   "\t adcl $0, %%ebx\n"
 165                   : "=b"(sum)
 166                   : "0"(daddr), "c"(saddr), "d"((ntohs(len) << 16) + IPPROTO_UDP*256)
 167                   : "cx","bx","dx" );
 168 
 169         if (len > 3) 
 170         {
 171                 __asm__("\tclc\n"
 172                         "1:\n"
 173                         "\t lodsl\n"
 174                         "\t adcl %%eax, %%ebx\n"
 175                         "\t loop 1b\n"
 176                         "\t adcl $0, %%ebx\n"
 177                         : "=b"(sum) , "=S"(uh)
 178                         : "0"(sum), "c"(len/4) ,"1"(uh)
 179                         : "ax", "cx", "bx", "si" );
 180         }
 181 
 182         /*
 183          *      Convert from 32 bits to 16 bits. 
 184          */
 185 
 186         __asm__("\t movl %%ebx, %%ecx\n"
 187                 "\t shrl $16,%%ecx\n"
 188                 "\t addw %%cx, %%bx\n"
 189                 "\t adcw $0, %%bx\n"
 190                 : "=b"(sum)
 191                 : "0"(sum)
 192                 : "bx", "cx");
 193         
 194         /* 
 195          *      Check for an extra word. 
 196          */
 197          
 198         if ((len & 2) != 0) 
 199         {
 200                 __asm__("\t lodsw\n"
 201                         "\t addw %%ax,%%bx\n"
 202                         "\t adcw $0, %%bx\n"
 203                         : "=b"(sum), "=S"(uh)
 204                         : "0"(sum) ,"1"(uh)
 205                         : "si", "ax", "bx");
 206         }
 207 
 208         /*
 209          *      Now check for the extra byte. 
 210          */
 211          
 212         if ((len & 1) != 0) 
 213         {
 214                 __asm__("\t lodsb\n"
 215                         "\t movb $0,%%ah\n"
 216                         "\t addw %%ax,%%bx\n"
 217                         "\t adcw $0, %%bx\n"
 218                         : "=b"(sum)
 219                         : "0"(sum) ,"S"(uh)
 220                         : "si", "ax", "bx");
 221         }
 222 
 223         /* 
 224          *      We only want the bottom 16 bits, but we never cleared the top 16. 
 225          */
 226 
 227         return((~sum) & 0xffff);
 228 }
 229 
 230 /*
 231  *      Generate UDP checksums. These may be disabled, eg for fast NFS over ethernet
 232  *      We default them enabled.. if you turn them off you either know what you are
 233  *      doing or get burned...
 234  */
 235 
 236 static void udp_send_check(struct udphdr *uh, unsigned long saddr, 
     /* [previous][next][first][last][top][bottom][index][help] */
 237                unsigned long daddr, int len, struct sock *sk)
 238 {
 239         uh->check = 0;
 240         if (sk && sk->no_check) 
 241                 return;
 242         uh->check = udp_check(uh, len, saddr, daddr);
 243         
 244         /*
 245          *      FFFF and 0 are the same, pick the right one as 0 in the
 246          *      actual field means no checksum.
 247          */
 248          
 249         if (uh->check == 0)
 250                 uh->check = 0xffff;
 251 }
 252 
 253 
 254 static int udp_send(struct sock *sk, struct sockaddr_in *sin,
     /* [previous][next][first][last][top][bottom][index][help] */
 255          unsigned char *from, int len, int rt)
 256 {
 257         struct sk_buff *skb;
 258         struct device *dev;
 259         struct udphdr *uh;
 260         unsigned char *buff;
 261         unsigned long saddr;
 262         int size, tmp;
 263         int err;
 264   
 265         DPRINTF((DBG_UDP, "UDP: send(dst=%s:%d buff=%X len=%d)\n",
 266                 in_ntoa(sin->sin_addr.s_addr), ntohs(sin->sin_port),
 267                 from, len));
 268 
 269         err=verify_area(VERIFY_READ, from, len);
 270         if(err)
 271                 return(err);
 272 
 273         /* 
 274          *      Allocate an sk_buff copy of the packet.
 275          */
 276          
 277         size = sk->prot->max_header + len;
 278         skb = sk->prot->wmalloc(sk, size, 0, GFP_KERNEL);
 279 
 280 
 281         if (skb == NULL) 
 282                 return(-ENOMEM);
 283 
 284         skb->sk       = NULL;   /* to avoid changing sk->saddr */
 285         skb->free     = 1;
 286         skb->localroute = sk->localroute|(rt&MSG_DONTROUTE);
 287 
 288         /*
 289          *      Now build the IP and MAC header. 
 290          */
 291          
 292         buff = skb->data;
 293         saddr = 0;
 294         dev = NULL;
 295         DPRINTF((DBG_UDP, "UDP: >> IP_Header: %X -> %X dev=%X prot=%X len=%d\n",
 296                         saddr, sin->sin_addr.s_addr, dev, IPPROTO_UDP, skb->mem_len));
 297         tmp = sk->prot->build_header(skb, saddr, sin->sin_addr.s_addr,
 298                         &dev, IPPROTO_UDP, sk->opt, skb->mem_len,sk->ip_tos,sk->ip_ttl);
 299         skb->sk=sk;     /* So memory is freed correctly */
 300         
 301         /*
 302          *      Unable to put a header on the packet.
 303          */
 304                             
 305         if (tmp < 0 ) 
 306         {
 307                 sk->prot->wfree(sk, skb->mem_addr, skb->mem_len);
 308                 return(tmp);
 309         }
 310         
 311         buff += tmp;
 312         saddr = skb->saddr; /*dev->pa_addr;*/
 313         DPRINTF((DBG_UDP, "UDP: >> MAC+IP len=%d\n", tmp));
 314 
 315         skb->len = tmp + sizeof(struct udphdr) + len;   /* len + UDP + IP + MAC */
 316         skb->dev = dev;
 317         
 318         /*
 319          *      Fill in the UDP header. 
 320          */
 321          
 322         uh = (struct udphdr *) buff;
 323         uh->len = htons(len + sizeof(struct udphdr));
 324         uh->source = sk->dummy_th.source;
 325         uh->dest = sin->sin_port;
 326         buff = (unsigned char *) (uh + 1);
 327 
 328         /*
 329          *      Copy the user data. 
 330          */
 331          
 332         memcpy_fromfs(buff, from, len);
 333 
 334         /*
 335          *      Set up the UDP checksum. 
 336          */
 337          
 338         udp_send_check(uh, saddr, sin->sin_addr.s_addr, skb->len - tmp, sk);
 339 
 340         /* 
 341          *      Send the datagram to the interface. 
 342          */
 343          
 344         udp_statistics.UdpOutDatagrams++;
 345          
 346         sk->prot->queue_xmit(sk, dev, skb, 1);
 347         return(len);
 348 }
 349 
 350 
 351 static int udp_sendto(struct sock *sk, unsigned char *from, int len, int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
 352            unsigned flags, struct sockaddr_in *usin, int addr_len)
 353 {
 354         struct sockaddr_in sin;
 355         int tmp;
 356         int err;
 357 
 358         DPRINTF((DBG_UDP, "UDP: sendto(len=%d, flags=%X)\n", len, flags));
 359 
 360         /* 
 361          *      Check the flags. We support no flags for UDP sending
 362          */
 363         if (flags&~MSG_DONTROUTE) 
 364                 return(-EINVAL);
 365         if (len < 0) 
 366                 return(-EINVAL);
 367         if (len == 0) 
 368                 return(0);
 369 
 370         /*
 371          *      Get and verify the address. 
 372          */
 373          
 374         if (usin) 
 375         {
 376                 if (addr_len < sizeof(sin)) 
 377                         return(-EINVAL);
 378                 err=verify_area(VERIFY_READ, usin, sizeof(sin));
 379                 if(err)
 380                         return err;
 381                 memcpy_fromfs(&sin, usin, sizeof(sin));
 382                 if (sin.sin_family && sin.sin_family != AF_INET) 
 383                         return(-EINVAL);
 384                 if (sin.sin_port == 0) 
 385                         return(-EINVAL);
 386         } 
 387         else 
 388         {
 389                 if (sk->state != TCP_ESTABLISHED) 
 390                         return(-EINVAL);
 391                 sin.sin_family = AF_INET;
 392                 sin.sin_port = sk->dummy_th.dest;
 393                 sin.sin_addr.s_addr = sk->daddr;
 394         }
 395   
 396         /*
 397          *      BSD socket semantics. You must set SO_BROADCAST to permit
 398          *      broadcasting of data.
 399          */
 400          
 401         if(sin.sin_addr.s_addr==INADDR_ANY)
 402                 sin.sin_addr.s_addr=ip_my_addr();
 403                 
 404         if(!sk->broadcast && ip_chk_addr(sin.sin_addr.s_addr)==IS_BROADCAST)
 405                 return -EACCES;                 /* Must turn broadcast on first */
 406 
 407         sk->inuse = 1;
 408 
 409         /* Send the packet. */
 410         tmp = udp_send(sk, &sin, from, len, flags);
 411 
 412         /* The datagram has been sent off.  Release the socket. */
 413         release_sock(sk);
 414         return(tmp);
 415 }
 416 
 417 /*
 418  *      In BSD SOCK_DGRAM a write is just like a send.
 419  */
 420 
 421 static int udp_write(struct sock *sk, unsigned char *buff, int len, int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
 422           unsigned flags)
 423 {
 424         return(udp_sendto(sk, buff, len, noblock, flags, NULL, 0));
 425 }
 426 
 427 
 428 /*
 429  *      IOCTL requests applicable to the UDP protocol
 430  */
 431  
 432 int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 433 {
 434         int err;
 435         switch(cmd) 
 436         {
 437                 case DDIOCSDBG:
 438                 {
 439                         int val;
 440 
 441                         if (!suser()) return(-EPERM);
 442                         err=verify_area(VERIFY_READ, (void *)arg, sizeof(int));
 443                         if(err)
 444                                 return err;
 445                         val = get_fs_long((int *)arg);
 446                         switch(val) {
 447                                 case 0:
 448                                         inet_debug = 0;
 449                                         break;
 450                                 case 1:
 451                                         inet_debug = DBG_UDP;
 452                                         break;
 453                                 default:
 454                                         return(-EINVAL);
 455                         }
 456                 }
 457                 break;
 458                 case TIOCOUTQ:
 459                 {
 460                         unsigned long amount;
 461 
 462                         if (sk->state == TCP_LISTEN) return(-EINVAL);
 463                         amount = sk->prot->wspace(sk)/*/2*/;
 464                         err=verify_area(VERIFY_WRITE,(void *)arg,
 465                                         sizeof(unsigned long));
 466                         if(err)
 467                                 return(err);
 468                         put_fs_long(amount,(unsigned long *)arg);
 469                         return(0);
 470                 }
 471 
 472                 case TIOCINQ:
 473                 {
 474                         struct sk_buff *skb;
 475                         unsigned long amount;
 476 
 477                         if (sk->state == TCP_LISTEN) return(-EINVAL);
 478                         amount = 0;
 479                         skb = skb_peek(&sk->receive_queue);
 480                         if (skb != NULL) {
 481                                 /*
 482                                  * We will only return the amount
 483                                  * of this packet since that is all
 484                                  * that will be read.
 485                                  */
 486                                 amount = skb->len;
 487                         }
 488                         err=verify_area(VERIFY_WRITE,(void *)arg,
 489                                                 sizeof(unsigned long));
 490                         if(err)
 491                                 return(err);
 492                         put_fs_long(amount,(unsigned long *)arg);
 493                         return(0);
 494                 }
 495 
 496                 default:
 497                         return(-EINVAL);
 498         }
 499         return(0);
 500 }
 501 
 502 
 503 /*
 504  *      This should be easy, if there is something there we\
 505  *      return it, otherwise we block.
 506  */
 507 
 508 int udp_recvfrom(struct sock *sk, unsigned char *to, int len,
     /* [previous][next][first][last][top][bottom][index][help] */
 509              int noblock, unsigned flags, struct sockaddr_in *sin,
 510              int *addr_len)
 511 {
 512         int copied = 0;
 513         struct sk_buff *skb;
 514         int er;
 515 
 516 
 517         /*
 518          * This will pick up errors that occured while the program
 519          * was doing something else.
 520          */
 521   
 522         if (sk->err) 
 523         {
 524                 int err;
 525         
 526                 err = -sk->err;
 527                 sk->err = 0;
 528                 return(err);
 529         }
 530 
 531         if (len == 0) 
 532                 return(0);
 533         if (len < 0) 
 534                 return(-EINVAL);
 535 
 536         /*
 537          *      Check any passed addresses
 538          */
 539          
 540         if (addr_len) 
 541         {
 542                 er=verify_area(VERIFY_WRITE, addr_len, sizeof(*addr_len));
 543                 if(er)
 544                         return(er);
 545                 put_fs_long(sizeof(*sin), addr_len);
 546         }
 547   
 548         if(sin)
 549         {
 550                 er=verify_area(VERIFY_WRITE, sin, sizeof(*sin));
 551                 if(er)
 552                         return(er);
 553         }
 554         
 555         /*
 556          *      Check the buffer we were given
 557          */
 558          
 559         er=verify_area(VERIFY_WRITE,to,len);
 560         if(er)
 561                 return er;
 562         
 563         /*
 564          *      From here the generic datagram does a lot of the work. Come
 565          *      the finished NET3, it will do _ALL_ the work!
 566          */
 567                 
 568         skb=skb_recv_datagram(sk,flags,noblock,&er);
 569         if(skb==NULL)
 570                 return er;
 571   
 572         copied = min(len, skb->len);
 573 
 574         /*
 575          *      FIXME : should use udp header size info value 
 576          */
 577          
 578         skb_copy_datagram(skb,sizeof(struct udphdr),to,copied);
 579         sk->stamp=skb->stamp;
 580 
 581         /* Copy the address. */
 582         if (sin) 
 583         {
 584                 struct sockaddr_in addr;
 585 
 586                 addr.sin_family = AF_INET;
 587                 addr.sin_port = skb->h.uh->source;
 588                 addr.sin_addr.s_addr = skb->daddr;
 589                 memcpy_tofs(sin, &addr, sizeof(*sin));
 590         }
 591   
 592         skb_free_datagram(skb);
 593         release_sock(sk);
 594         return(copied);
 595 }
 596 
 597 /*
 598  *      Read has the same semantics as recv in SOCK_DGRAM
 599  */
 600 
 601 int udp_read(struct sock *sk, unsigned char *buff, int len, int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
 602          unsigned flags)
 603 {
 604         return(udp_recvfrom(sk, buff, len, noblock, flags, NULL, NULL));
 605 }
 606 
 607 
 608 int
 609 udp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len)
     /* [previous][next][first][last][top][bottom][index][help] */
 610 {
 611         struct sockaddr_in sin;
 612         int er;
 613   
 614         if (addr_len < sizeof(sin)) 
 615                 return(-EINVAL);
 616 
 617         er=verify_area(VERIFY_READ, usin, sizeof(sin));
 618         if(er)
 619                 return er;
 620 
 621         memcpy_fromfs(&sin, usin, sizeof(sin));
 622         if (sin.sin_family && sin.sin_family != AF_INET) 
 623                 return(-EAFNOSUPPORT);
 624         if (sin.sin_addr.s_addr==INADDR_ANY)
 625                 sin.sin_addr.s_addr=ip_my_addr();
 626 
 627         if(!sk->broadcast && ip_chk_addr(sin.sin_addr.s_addr)==IS_BROADCAST)
 628                 return -EACCES;                 /* Must turn broadcast on first */
 629         
 630         sk->daddr = sin.sin_addr.s_addr;
 631         sk->dummy_th.dest = sin.sin_port;
 632         sk->state = TCP_ESTABLISHED;
 633         return(0);
 634 }
 635 
 636 
 637 static void
 638 udp_close(struct sock *sk, int timeout)
     /* [previous][next][first][last][top][bottom][index][help] */
 639 {
 640   sk->inuse = 1;
 641   sk->state = TCP_CLOSE;
 642   if (sk->dead) destroy_sock(sk);
 643     else release_sock(sk);
 644 }
 645 
 646 
 647 /*
 648  *      All we need to do is get the socket, and then do a checksum. 
 649  */
 650  
 651 int udp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
     /* [previous][next][first][last][top][bottom][index][help] */
 652         unsigned long daddr, unsigned short len,
 653         unsigned long saddr, int redo, struct inet_protocol *protocol)
 654 {
 655         struct sock *sk;
 656         struct udphdr *uh;
 657         unsigned short ulen;
 658                 
 659         /*
 660          *      Get the header.
 661          */
 662         uh = (struct udphdr *) skb->h.uh;
 663         
 664         ip_statistics.IpInDelivers++;
 665 
 666         /*
 667          *      Validate the packet and the UDP length.
 668          */
 669          
 670         ulen = ntohs(uh->len);
 671 
 672         if (ulen > len || len < sizeof(*uh) || ulen < sizeof(*uh)) 
 673         {
 674                 printk("UDP: short packet: %d/%d\n", ulen, len);
 675                 DPRINTF((DBG_UDP, "UDP: short packet %d/%d\n", ulen, len));
 676                 udp_statistics.UdpInErrors++;
 677                 kfree_skb(skb, FREE_WRITE);
 678                 return(0);
 679         }
 680         len=ulen;
 681 
 682         sk = get_sock(&udp_prot, uh->dest, saddr, uh->source, daddr);
 683         if (sk == NULL) 
 684         {
 685                 udp_statistics.UdpNoPorts++;
 686                 if (ip_chk_addr(daddr) == IS_MYADDR) 
 687                 {
 688                         icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, dev);
 689                 }
 690                 /*
 691                  * Hmm.  We got an UDP broadcast to a port to which we
 692                  * don't wanna listen.  Ignore it.
 693                  */
 694                 skb->sk = NULL;
 695                 kfree_skb(skb, FREE_WRITE);
 696                 return(0);
 697         }
 698 
 699         if (uh->check && udp_check(uh, len, saddr, daddr)) 
 700         {
 701                 printk("UDP: bad checksum.\n");
 702                 DPRINTF((DBG_UDP, "UDP: bad checksum\n"));
 703                 udp_statistics.UdpInErrors++;
 704                 kfree_skb(skb, FREE_WRITE);
 705                 return(0);
 706         }
 707 
 708         skb->sk = sk;
 709         skb->dev = dev;
 710         skb->len = len;
 711 
 712         /*
 713          *      These are supposed to be switched. 
 714          */
 715          
 716         skb->daddr = saddr;
 717         skb->saddr = daddr;
 718 
 719 
 720         /*
 721          *      Charge it to the socket, dropping if the queue is full.
 722          */
 723          
 724         if (sk->rmem_alloc + skb->mem_len >= sk->rcvbuf) 
 725         {
 726                 udp_statistics.UdpInErrors++;
 727                 ip_statistics.IpInDiscards++;
 728                 ip_statistics.IpInDelivers--;
 729                 skb->sk = NULL;
 730                 kfree_skb(skb, FREE_WRITE);
 731                 release_sock(sk);
 732                 return(0);
 733         }
 734         sk->rmem_alloc += skb->mem_len;
 735         udp_statistics.UdpInDatagrams++;
 736         
 737         /*
 738          *      At this point we should print the thing out. 
 739          */
 740 
 741         DPRINTF((DBG_UDP, "<< \n"));
 742         print_udp(uh);
 743 
 744         /*
 745          *      Now add it to the data chain and wake things up. 
 746          */
 747   
 748         skb->len = len - sizeof(*uh);  
 749         skb_queue_tail(&sk->receive_queue,skb);
 750 
 751 
 752         if (!sk->dead) 
 753                 sk->data_ready(sk,skb->len);
 754         
 755         release_sock(sk);
 756         return(0);
 757 }
 758 
 759 
 760 struct proto udp_prot = {
 761   sock_wmalloc,
 762   sock_rmalloc,
 763   sock_wfree,
 764   sock_rfree,
 765   sock_rspace,
 766   sock_wspace,
 767   udp_close,
 768   udp_read,
 769   udp_write,
 770   udp_sendto,
 771   udp_recvfrom,
 772   ip_build_header,
 773   udp_connect,
 774   NULL,
 775   ip_queue_xmit,
 776   ip_retransmit,
 777   NULL,
 778   NULL,
 779   udp_rcv,
 780   datagram_select,
 781   udp_ioctl,
 782   NULL,
 783   NULL,
 784   ip_setsockopt,
 785   ip_getsockopt,
 786   128,
 787   0,
 788   {NULL,},
 789   "UDP"
 790 };

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