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_recvfrom
  11. udp_read
  12. udp_connect
  13. udp_close
  14. udp_rcv
  15. 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  *              Alan Cox        :       Checksum precompute is bogus is some lame
  49  *                                      software is padding its udp frames in IP!
  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 #include <asm/system.h>
  59 #include <asm/segment.h>
  60 #include <linux/types.h>
  61 #include <linux/sched.h>
  62 #include <linux/fcntl.h>
  63 #include <linux/socket.h>
  64 #include <linux/sockios.h>
  65 #include <linux/in.h>
  66 #include <linux/errno.h>
  67 #include <linux/timer.h>
  68 #include <linux/termios.h>
  69 #include <linux/mm.h>
  70 #include <linux/config.h>
  71 #include <linux/inet.h>
  72 #include <linux/netdevice.h>
  73 #include <net/snmp.h>
  74 #include <net/ip.h>
  75 #include <net/protocol.h>
  76 #include <net/tcp.h>
  77 #include <linux/skbuff.h>
  78 #include <net/sock.h>
  79 #include <net/udp.h>
  80 #include <net/icmp.h>
  81 #include <net/route.h>
  82 #include <net/checksum.h>
  83 
  84 /*
  85  *      SNMP MIB for the UDP layer
  86  */
  87 
  88 struct udp_mib          udp_statistics;
  89 
  90 /*
  91  *      Cached last hit socket
  92  */
  93  
  94 volatile unsigned long  uh_cache_saddr,uh_cache_daddr;
  95 volatile unsigned short  uh_cache_dport, uh_cache_sport;
  96 volatile struct sock *uh_cache_sk;
  97 
  98 void udp_cache_zap(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  99 {
 100         unsigned long flags;
 101         save_flags(flags);
 102         cli();
 103         uh_cache_saddr=0;
 104         uh_cache_daddr=0;
 105         uh_cache_dport=0;
 106         uh_cache_sport=0;
 107         uh_cache_sk=NULL;
 108         restore_flags(flags);
 109 }
 110 
 111 static int udp_deliver(struct sock *sk, struct udphdr *uh, struct sk_buff *skb, struct device *dev, long saddr, long daddr, int len);
 112 
 113 #define min(a,b)        ((a)<(b)?(a):(b))
 114 
 115 
 116 /*
 117  * This routine is called by the ICMP module when it gets some
 118  * sort of error condition.  If err < 0 then the socket should
 119  * be closed and the error returned to the user.  If err > 0
 120  * it's just the icmp type << 8 | icmp code.  
 121  * Header points to the ip header of the error packet. We move
 122  * on past this. Then (as it used to claim before adjustment)
 123  * header points to the first 8 bytes of the udp header.  We need
 124  * to find the appropriate port.
 125  */
 126 
 127 void udp_err(int err, unsigned char *header, unsigned long daddr,
     /* [previous][next][first][last][top][bottom][index][help] */
 128         unsigned long saddr, struct inet_protocol *protocol)
 129 {
 130         struct udphdr *th;
 131         struct sock *sk;
 132         struct iphdr *ip=(struct iphdr *)header;
 133   
 134         header += 4*ip->ihl;
 135 
 136         /*
 137          *      Find the 8 bytes of post IP header ICMP included for us
 138          */  
 139         
 140         th = (struct udphdr *)header;  
 141    
 142         sk = get_sock(&udp_prot, th->source, daddr, th->dest, saddr);
 143 
 144         if (sk == NULL) 
 145                 return; /* No socket for error */
 146         
 147         if ((err & 0xff00) == (ICMP_SOURCE_QUENCH << 8)) 
 148         {       /* Slow down! */
 149                 if (sk->cong_window > 1) 
 150                         sk->cong_window = sk->cong_window/2;
 151                 return;
 152         }
 153 
 154         /*
 155          *      Various people wanted BSD UDP semantics. Well they've come 
 156          *      back out because they slow down response to stuff like dead
 157          *      or unreachable name servers and they screw term users something
 158          *      chronic. Oh and it violates RFC1122. So basically fix your 
 159          *      client code people.
 160          */
 161          
 162         if (icmp_err_convert[err & 0xff].fatal)
 163         {
 164                 sk->err = icmp_err_convert[err & 0xff].errno;
 165                 sk->error_report(sk);
 166         }
 167 }
 168 
 169 
 170 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] */
 171 {
 172         return(csum_tcpudp_magic(saddr, daddr, len, IPPROTO_UDP, base));
 173 }
 174 
 175 struct udpfakehdr 
 176 {
 177         struct udphdr uh;
 178         int daddr;
 179         int other;
 180         char *from;
 181         int wcheck;
 182 };
 183 
 184 /*
 185  *      Copy and checksum a UDP packet from user space into a buffer. We still have to do the planning to
 186  *      get ip_build_xmit to spot direct transfer to network card and provide an additional callback mode
 187  *      for direct user->board I/O transfers. That one will be fun.
 188  */
 189  
 190 static void udp_getfrag(void *p, int saddr, char * to, unsigned int offset, unsigned int fraglen) 
     /* [previous][next][first][last][top][bottom][index][help] */
 191 {
 192         struct udpfakehdr *ufh = (struct udpfakehdr *)p;
 193         char *src, *dst;
 194         unsigned int len;
 195 
 196         if (offset) 
 197         {
 198                 len = fraglen;
 199                 src = ufh->from+(offset-sizeof(struct udphdr));
 200                 dst = to;
 201         }
 202         else 
 203         {
 204                 len = fraglen-sizeof(struct udphdr);
 205                 src = ufh->from;
 206                 dst = to+sizeof(struct udphdr);
 207         }
 208         ufh->wcheck = csum_partial_copy_fromuser(src, dst, len, ufh->wcheck);
 209         if (offset == 0) 
 210         {
 211                 ufh->wcheck = csum_partial((char *)ufh, sizeof(struct udphdr),
 212                                    ufh->wcheck);
 213                 ufh->uh.check = csum_tcpudp_magic(saddr, ufh->daddr, 
 214                                           ntohs(ufh->uh.len),
 215                                           IPPROTO_UDP, ufh->wcheck);
 216                 if (ufh->uh.check == 0)
 217                         ufh->uh.check = -1;
 218                 memcpy(to, ufh, sizeof(struct udphdr));
 219         }
 220 }
 221 
 222 /*
 223  *      Uncheckummed UDP is sufficiently criticial to stuff like ATM video conferencing
 224  *      that we use two routines for this for speed. Probably we ought to have a CONFIG_FAST_NET
 225  *      set for >10Mb/second boards to activate this sort of coding. Timing needed to verify if
 226  *      this is a valid decision.
 227  */
 228  
 229 static void udp_getfrag_nosum(void *p, int saddr, char * to, unsigned int offset, unsigned int fraglen) 
     /* [previous][next][first][last][top][bottom][index][help] */
 230 {
 231         struct udpfakehdr *ufh = (struct udpfakehdr *)p;
 232         char *src, *dst;
 233         unsigned int len;
 234 
 235         if (offset) 
 236         {
 237                 len = fraglen;
 238                 src = ufh->from+(offset-sizeof(struct udphdr));
 239                 dst = to;
 240         }
 241         else 
 242         {
 243                 len = fraglen-sizeof(struct udphdr);
 244                 src = ufh->from;
 245                 dst = to+sizeof(struct udphdr);
 246         }
 247         memcpy_fromfs(dst,src,len);
 248         if (offset == 0) 
 249                 memcpy(to, ufh, sizeof(struct udphdr));
 250 }
 251 
 252 
 253 /*
 254  *      Send UDP frames.
 255  */
 256  
 257 static int udp_send(struct sock *sk, struct sockaddr_in *sin,
     /* [previous][next][first][last][top][bottom][index][help] */
 258                       unsigned char *from, int len, int rt) 
 259 {
 260         int ulen = len + sizeof(struct udphdr);
 261         int a;
 262         struct udpfakehdr ufh;
 263 
 264         ufh.uh.source = sk->dummy_th.source;
 265         ufh.uh.dest = sin->sin_port;
 266         ufh.uh.len = htons(ulen);
 267         ufh.uh.check = 0;
 268         ufh.daddr = sin->sin_addr.s_addr;
 269         ufh.other = (htons(ulen) << 16) + IPPROTO_UDP*256;
 270         ufh.from = from;
 271         ufh.wcheck = 0;
 272         if(sk->no_check)
 273                 a = ip_build_xmit(sk, udp_getfrag_nosum, &ufh, ulen, 
 274                         sin->sin_addr.s_addr, rt, IPPROTO_UDP);
 275         else
 276                 a = ip_build_xmit(sk, udp_getfrag, &ufh, ulen, 
 277                         sin->sin_addr.s_addr, rt, IPPROTO_UDP);
 278         if(a<0)
 279                 return a;
 280         udp_statistics.UdpOutDatagrams++;
 281         return len;
 282 }
 283 
 284 
 285 static int udp_sendto(struct sock *sk, unsigned char *from, int len, int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
 286            unsigned flags, struct sockaddr_in *usin, int addr_len)
 287 {
 288         struct sockaddr_in sin;
 289         int tmp;
 290 
 291         /* 
 292          *      Check the flags. We support no flags for UDP sending
 293          */
 294         if (flags&~MSG_DONTROUTE) 
 295                 return(-EINVAL);
 296         /*
 297          *      Get and verify the address. 
 298          */
 299          
 300         if (usin) 
 301         {
 302                 if (addr_len < sizeof(sin)) 
 303                         return(-EINVAL);
 304                 memcpy(&sin,usin,sizeof(sin));
 305                 if (sin.sin_family && sin.sin_family != AF_INET) 
 306                         return(-EINVAL);
 307                 if (sin.sin_port == 0) 
 308                         return(-EINVAL);
 309         } 
 310         else 
 311         {
 312                 if (sk->state != TCP_ESTABLISHED) 
 313                         return(-EINVAL);
 314                 sin.sin_family = AF_INET;
 315                 sin.sin_port = sk->dummy_th.dest;
 316                 sin.sin_addr.s_addr = sk->daddr;
 317         }
 318   
 319         /*
 320          *      BSD socket semantics. You must set SO_BROADCAST to permit
 321          *      broadcasting of data.
 322          */
 323          
 324         if(sin.sin_addr.s_addr==INADDR_ANY)
 325                 sin.sin_addr.s_addr=ip_my_addr();
 326                 
 327         if(!sk->broadcast && ip_chk_addr(sin.sin_addr.s_addr)==IS_BROADCAST)
 328                 return -EACCES;                 /* Must turn broadcast on first */
 329 
 330         sk->inuse = 1;
 331 
 332         /* Send the packet. */
 333         tmp = udp_send(sk, &sin, from, len, flags);
 334 
 335         /* The datagram has been sent off.  Release the socket. */
 336         release_sock(sk);
 337         return(tmp);
 338 }
 339 
 340 /*
 341  *      In BSD SOCK_DGRAM a write is just like a send.
 342  */
 343 
 344 static int udp_write(struct sock *sk, unsigned char *buff, int len, int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
 345           unsigned flags)
 346 {
 347         return(udp_sendto(sk, buff, len, noblock, flags, NULL, 0));
 348 }
 349 
 350 
 351 /*
 352  *      IOCTL requests applicable to the UDP protocol
 353  */
 354  
 355 int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 356 {
 357         int err;
 358         switch(cmd) 
 359         {
 360                 case TIOCOUTQ:
 361                 {
 362                         unsigned long amount;
 363 
 364                         if (sk->state == TCP_LISTEN) return(-EINVAL);
 365                         amount = sk->prot->wspace(sk)/*/2*/;
 366                         err=verify_area(VERIFY_WRITE,(void *)arg,
 367                                         sizeof(unsigned long));
 368                         if(err)
 369                                 return(err);
 370                         put_fs_long(amount,(unsigned long *)arg);
 371                         return(0);
 372                 }
 373 
 374                 case TIOCINQ:
 375                 {
 376                         struct sk_buff *skb;
 377                         unsigned long amount;
 378 
 379                         if (sk->state == TCP_LISTEN) return(-EINVAL);
 380                         amount = 0;
 381                         skb = skb_peek(&sk->receive_queue);
 382                         if (skb != NULL) {
 383                                 /*
 384                                  * We will only return the amount
 385                                  * of this packet since that is all
 386                                  * that will be read.
 387                                  */
 388                                 amount = skb->len;
 389                         }
 390                         err=verify_area(VERIFY_WRITE,(void *)arg,
 391                                                 sizeof(unsigned long));
 392                         if(err)
 393                                 return(err);
 394                         put_fs_long(amount,(unsigned long *)arg);
 395                         return(0);
 396                 }
 397 
 398                 default:
 399                         return(-EINVAL);
 400         }
 401         return(0);
 402 }
 403 
 404 
 405 /*
 406  *      This should be easy, if there is something there we\
 407  *      return it, otherwise we block.
 408  */
 409 
 410 int udp_recvfrom(struct sock *sk, unsigned char *to, int len,
     /* [previous][next][first][last][top][bottom][index][help] */
 411              int noblock, unsigned flags, struct sockaddr_in *sin,
 412              int *addr_len)
 413 {
 414         int copied = 0;
 415         int truesize;
 416         struct sk_buff *skb;
 417         int er;
 418 
 419         /*
 420          *      Check any passed addresses
 421          */
 422          
 423         if (addr_len) 
 424                 *addr_len=sizeof(*sin);
 425   
 426         /*
 427          *      From here the generic datagram does a lot of the work. Come
 428          *      the finished NET3, it will do _ALL_ the work!
 429          */
 430                 
 431         skb=skb_recv_datagram(sk,flags,noblock,&er);
 432         if(skb==NULL)
 433                 return er;
 434   
 435         truesize = skb->len - sizeof(struct udphdr);
 436         copied = min(len, truesize);
 437 
 438         /*
 439          *      FIXME : should use udp header size info value 
 440          */
 441          
 442         skb_copy_datagram(skb,sizeof(struct udphdr),to,copied);
 443         sk->stamp=skb->stamp;
 444 
 445         /* Copy the address. */
 446         if (sin) 
 447         {
 448                 sin->sin_family = AF_INET;
 449                 sin->sin_port = skb->h.uh->source;
 450                 sin->sin_addr.s_addr = skb->daddr;
 451         }
 452   
 453         skb_free_datagram(skb);
 454         release_sock(sk);
 455         return(copied);
 456 }
 457 
 458 /*
 459  *      Read has the same semantics as recv in SOCK_DGRAM
 460  */
 461 
 462 int udp_read(struct sock *sk, unsigned char *buff, int len, int noblock,
     /* [previous][next][first][last][top][bottom][index][help] */
 463          unsigned flags)
 464 {
 465         return(udp_recvfrom(sk, buff, len, noblock, flags, NULL, NULL));
 466 }
 467 
 468 
 469 int udp_connect(struct sock *sk, struct sockaddr_in *usin, int addr_len)
     /* [previous][next][first][last][top][bottom][index][help] */
 470 {
 471         struct rtable *rt;
 472         unsigned long sa;
 473         if (addr_len < sizeof(*usin)) 
 474                 return(-EINVAL);
 475 
 476         if (usin->sin_family && usin->sin_family != AF_INET) 
 477                 return(-EAFNOSUPPORT);
 478         if (usin->sin_addr.s_addr==INADDR_ANY)
 479                 usin->sin_addr.s_addr=ip_my_addr();
 480 
 481         if(!sk->broadcast && ip_chk_addr(usin->sin_addr.s_addr)==IS_BROADCAST)
 482                 return -EACCES;                 /* Must turn broadcast on first */
 483         
 484         rt=(sk->localroute?ip_rt_local:ip_rt_route)(usin->sin_addr.s_addr, NULL, &sa);
 485         if(rt==NULL)
 486                 return -ENETUNREACH;
 487         sk->saddr = sa;         /* Update source address */
 488         sk->daddr = usin->sin_addr.s_addr;
 489         sk->dummy_th.dest = usin->sin_port;
 490         sk->state = TCP_ESTABLISHED;
 491         udp_cache_zap();
 492         sk->ip_route_cache = rt;
 493         sk->ip_route_stamp = rt_stamp;
 494         return(0);
 495 }
 496 
 497 
 498 static void udp_close(struct sock *sk, int timeout)
     /* [previous][next][first][last][top][bottom][index][help] */
 499 {
 500         sk->inuse = 1;
 501         sk->state = TCP_CLOSE;
 502         if(uh_cache_sk==sk)
 503                 udp_cache_zap();
 504         if (sk->dead) 
 505                 destroy_sock(sk);
 506         else
 507                 release_sock(sk);
 508 }
 509 
 510 
 511 /*
 512  *      All we need to do is get the socket, and then do a checksum. 
 513  */
 514  
 515 int udp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
     /* [previous][next][first][last][top][bottom][index][help] */
 516         unsigned long daddr, unsigned short len,
 517         unsigned long saddr, int redo, struct inet_protocol *protocol)
 518 {
 519         struct sock *sk;
 520         struct udphdr *uh;
 521         unsigned short ulen;
 522         int addr_type = IS_MYADDR;
 523         
 524         if(!dev || dev->pa_addr!=daddr)
 525                 addr_type=ip_chk_addr(daddr);
 526                 
 527         /*
 528          *      Get the header.
 529          */
 530          
 531         uh = (struct udphdr *) skb->h.uh;
 532         
 533         ip_statistics.IpInDelivers++;
 534 
 535         /*
 536          *      Validate the packet and the UDP length.
 537          */
 538          
 539         ulen = ntohs(uh->len);
 540         
 541         if(ulen!=len)
 542                 skb->ip_summed=0;       /* Bogoid padded frame */
 543 
 544         if (ulen > len || len < sizeof(*uh) || ulen < sizeof(*uh)) 
 545         {
 546                 NETDEBUG(printk("UDP: short packet: %d/%d\n", ulen, len));
 547                 udp_statistics.UdpInErrors++;
 548                 kfree_skb(skb, FREE_WRITE);
 549                 return(0);
 550         }
 551 
 552         if (uh->check && (
 553                 ( skb->ip_summed && udp_check(uh, len, saddr, daddr, skb->csum ) ) ||
 554                 ( !skb->ip_summed && udp_check(uh, len, saddr, daddr,csum_partial((char*)uh, len, 0)))
 555                          )
 556            )
 557         {
 558                 /* <mea@utu.fi> wants to know, who sent it, to
 559                    go and stomp on the garbage sender... */
 560                 NETDEBUG(printk("UDP: bad checksum. From %08lX:%d to %08lX:%d ulen %d\n",
 561                        ntohl(saddr),ntohs(uh->source),
 562                        ntohl(daddr),ntohs(uh->dest),
 563                        ulen));
 564                 udp_statistics.UdpInErrors++;
 565                 kfree_skb(skb, FREE_WRITE);
 566                 return(0);
 567         }
 568 
 569 
 570         len=ulen;
 571 
 572 #ifdef CONFIG_IP_MULTICAST
 573         if (addr_type!=IS_MYADDR)
 574         {
 575                 /*
 576                  *      Multicasts and broadcasts go to each listener.
 577                  */
 578                 struct sock *sknext=NULL;
 579                 sk=get_sock_mcast(udp_prot.sock_array[ntohs(uh->dest)&(SOCK_ARRAY_SIZE-1)], uh->dest,
 580                                 saddr, uh->source, daddr);
 581                 if(sk)
 582                 {               
 583                         do
 584                         {
 585                                 struct sk_buff *skb1;
 586 
 587                                 sknext=get_sock_mcast(sk->next, uh->dest, saddr, uh->source, daddr);
 588                                 if(sknext)
 589                                         skb1=skb_clone(skb,GFP_ATOMIC);
 590                                 else
 591                                         skb1=skb;
 592                                 if(skb1)
 593                                         udp_deliver(sk, uh, skb1, dev,saddr,daddr,len);
 594                                 sk=sknext;
 595                         }
 596                         while(sknext!=NULL);
 597                 }
 598                 else
 599                         kfree_skb(skb, FREE_READ);
 600                 return 0;
 601         }       
 602 #endif
 603         if(saddr==uh_cache_saddr && daddr==uh_cache_daddr && uh->dest==uh_cache_dport && uh->source==uh_cache_sport)
 604                 sk=(struct sock *)uh_cache_sk;
 605         else
 606         {
 607                 sk = get_sock(&udp_prot, uh->dest, saddr, uh->source, daddr);
 608                 uh_cache_saddr=saddr;
 609                 uh_cache_daddr=daddr;
 610                 uh_cache_dport=uh->dest;
 611                 uh_cache_sport=uh->source;
 612                 uh_cache_sk=sk;
 613         }
 614         
 615         if (sk == NULL) 
 616         {
 617                 udp_statistics.UdpNoPorts++;
 618                 if (addr_type == IS_MYADDR) 
 619                 {
 620                         icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0, dev);
 621                 }
 622                 /*
 623                  * Hmm.  We got an UDP broadcast to a port to which we
 624                  * don't wanna listen.  Ignore it.
 625                  */
 626                 skb->sk = NULL;
 627                 kfree_skb(skb, FREE_WRITE);
 628                 return(0);
 629         }
 630         return udp_deliver(sk,uh,skb,dev, saddr, daddr, len);
 631 }
 632 
 633 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] */
 634 {
 635         skb->sk = sk;
 636         skb->dev = dev;
 637         skb_trim(skb,len);
 638 
 639         /*
 640          *      These are supposed to be switched. 
 641          */
 642          
 643         skb->daddr = saddr;
 644         skb->saddr = daddr;
 645 
 646 
 647         /*
 648          *      Charge it to the socket, dropping if the queue is full.
 649          */
 650 
 651         if (sock_queue_rcv_skb(sk,skb)<0) 
 652         {
 653                 udp_statistics.UdpInErrors++;
 654                 ip_statistics.IpInDiscards++;
 655                 ip_statistics.IpInDelivers--;
 656                 skb->sk = NULL;
 657                 kfree_skb(skb, FREE_WRITE);
 658                 release_sock(sk);
 659                 return(0);
 660         }
 661         udp_statistics.UdpInDatagrams++;
 662         release_sock(sk);
 663         return(0);
 664 }
 665 
 666 
 667 struct proto udp_prot = {
 668         sock_wmalloc,
 669         sock_rmalloc,
 670         sock_wfree,
 671         sock_rfree,
 672         sock_rspace,
 673         sock_wspace,
 674         udp_close,
 675         udp_read,
 676         udp_write,
 677         udp_sendto,
 678         udp_recvfrom,
 679         ip_build_header,
 680         udp_connect,
 681         NULL,
 682         ip_queue_xmit,
 683         NULL,
 684         NULL,
 685         NULL,
 686         udp_rcv,
 687         datagram_select,
 688         udp_ioctl,
 689         NULL,
 690         NULL,
 691         ip_setsockopt,
 692         ip_getsockopt,
 693         128,
 694         0,
 695         "UDP",
 696         0, 0,
 697         {NULL,}
 698 };
 699 

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