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

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