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

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