home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / net / inet / udp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-26  |  16.0 KB  |  736 lines

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