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

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