home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.0 / LINUX-1.0 / LINUX-1 / linux / net / inet / packet.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-31  |  6.1 KB  |  276 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.  *        PACKET - implements raw packet sockets.
  7.  *
  8.  * Version:    @(#)packet.c    1.0.6    05/25/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() now used correctly
  15.  *        Alan Cox    :    new skbuff lists, look ma no backlogs!
  16.  *        Alan Cox    :    tidied skbuff lists.
  17.  *        Alan Cox    :    Now uses generic datagram routines I
  18.  *                    added. Also fixed the peek/read crash
  19.  *                    from all old Linux datagram code.
  20.  *        Alan Cox    :    Uses the improved datagram code.
  21.  *        Alan Cox    :    Added NULL's for socket options.
  22.  *
  23.  *
  24.  *        This program is free software; you can redistribute it and/or
  25.  *        modify it under the terms of the GNU General Public License
  26.  *        as published by the Free Software Foundation; either version
  27.  *        2 of the License, or (at your option) any later version.
  28.  */
  29. #include <linux/types.h>
  30. #include <linux/sched.h>
  31. #include <linux/fcntl.h>
  32. #include <linux/socket.h>
  33. #include <linux/in.h>
  34. #include "inet.h"
  35. #include "dev.h"
  36. #include "ip.h"
  37. #include "protocol.h"
  38. #include "tcp.h"
  39. #include "skbuff.h"
  40. #include "sock.h"
  41. #include <linux/errno.h>
  42. #include <linux/timer.h>
  43. #include <asm/system.h>
  44. #include <asm/segment.h>
  45. #include "udp.h"
  46. #include "raw.h"
  47.  
  48.  
  49. static unsigned long
  50. min(unsigned long a, unsigned long b)
  51. {
  52.   if (a < b) return(a);
  53.   return(b);
  54. }
  55.  
  56.  
  57. /* This should be the easiest of all, all we do is copy it into a buffer. */
  58. int
  59. packet_rcv(struct sk_buff *skb, struct device *dev,  struct packet_type *pt)
  60. {
  61.   struct sock *sk;
  62.  
  63.   sk = (struct sock *) pt->data;
  64.   skb->dev = dev;
  65.   skb->len += dev->hard_header_len;
  66.  
  67.   skb->sk = sk;
  68.  
  69.   /* Charge it too the socket. */
  70.   if (sk->rmem_alloc + skb->mem_len >= sk->rcvbuf) {
  71.     skb->sk = NULL;
  72.     kfree_skb(skb, FREE_READ);
  73.     return(0);
  74.   }
  75.   sk->rmem_alloc += skb->mem_len;
  76.   skb_queue_tail(&sk->rqueue,skb);
  77.   wake_up_interruptible(sk->sleep);
  78.   release_sock(sk);
  79.   return(0);
  80. }
  81.  
  82.  
  83. /* This will do terrible things if len + ipheader + devheader > dev->mtu */
  84. static int
  85. packet_sendto(struct sock *sk, unsigned char *from, int len,
  86.           int noblock, unsigned flags, struct sockaddr_in *usin,
  87.           int addr_len)
  88. {
  89.   struct sk_buff *skb;
  90.   struct device *dev;
  91.   struct sockaddr saddr;
  92.   int err;
  93.  
  94.   /* Check the flags. */
  95.   if (flags) return(-EINVAL);
  96.   if (len < 0) return(-EINVAL);
  97.  
  98.   /* Get and verify the address. */
  99.   if (usin) {
  100.     if (addr_len < sizeof(saddr)) return(-EINVAL);
  101.     err=verify_area(VERIFY_READ, usin, sizeof(saddr));
  102.     if(err)
  103.         return err;
  104.     memcpy_fromfs(&saddr, usin, sizeof(saddr));
  105.   } else
  106.     return(-EINVAL);
  107.     
  108.   err=verify_area(VERIFY_READ,from,len);
  109.   if(err)
  110.       return(err);
  111. /* Find the device first to size check it */
  112.  
  113.   saddr.sa_data[13] = 0;
  114.   dev = dev_get(saddr.sa_data);
  115.   if (dev == NULL) {
  116.     return(-ENXIO);
  117.   }
  118.   if(len>dev->mtu)
  119.       return -EMSGSIZE;
  120.  
  121. /* Now allocate the buffer, knowing 4K pagelimits wont break this line */  
  122.   skb = sk->prot->wmalloc(sk, len+sizeof(*skb), 0, GFP_KERNEL);
  123.  
  124.   /* This shouldn't happen, but it could. */
  125.   if (skb == NULL) {
  126.     DPRINTF((DBG_PKT, "packet_sendto: write buffer full?\n"));
  127.     return(-ENOMEM);
  128.   }
  129.   /* Fill it in */
  130.   skb->mem_addr = skb;
  131.   skb->mem_len = len + sizeof(*skb);
  132.   skb->sk = sk;
  133.   skb->free = 1;
  134.   memcpy_fromfs(skb->data, from, len);
  135.   skb->len = len;
  136.   skb->next = NULL;
  137.   skb->arp = 1;
  138.   if (dev->flags & IFF_UP) dev->queue_xmit(skb, dev, sk->priority);
  139.     else kfree_skb(skb, FREE_WRITE);
  140.   return(len);
  141. }
  142.  
  143.  
  144. static int
  145. packet_write(struct sock *sk, unsigned char *buff, 
  146.          int len, int noblock,  unsigned flags)
  147. {
  148.   return(packet_sendto(sk, buff, len, noblock, flags, NULL, 0));
  149. }
  150.  
  151.  
  152. static void
  153. packet_close(struct sock *sk, int timeout)
  154. {
  155.   sk->inuse = 1;
  156.   sk->state = TCP_CLOSE;
  157.   dev_remove_pack((struct packet_type *)sk->pair);
  158.   kfree_s((void *)sk->pair, sizeof(struct packet_type));
  159.   sk->pair = NULL;
  160.   release_sock(sk);
  161. }
  162.  
  163.  
  164. static int
  165. packet_init(struct sock *sk)
  166. {
  167.   struct packet_type *p;
  168.  
  169.   p = (struct packet_type *) kmalloc(sizeof(*p), GFP_KERNEL);
  170.   if (p == NULL) return(-ENOMEM);
  171.  
  172.   p->func = packet_rcv;
  173.   p->type = sk->num;
  174.   p->data = (void *)sk;
  175.   dev_add_pack(p);
  176.    
  177.   /* We need to remember this somewhere. */
  178.   sk->pair = (struct sock *)p;
  179.  
  180.   return(0);
  181. }
  182.  
  183.  
  184. /*
  185.  * This should be easy, if there is something there
  186.  * we return it, otherwise we block.
  187.  */
  188. int
  189. packet_recvfrom(struct sock *sk, unsigned char *to, int len,
  190.             int noblock, unsigned flags, struct sockaddr_in *sin,
  191.             int *addr_len)
  192. {
  193.   int copied=0;
  194.   struct sk_buff *skb;
  195.   struct sockaddr *saddr;
  196.   int err;
  197.  
  198.   saddr = (struct sockaddr *)sin;
  199.   if (len == 0) return(0);
  200.   if (len < 0) return(-EINVAL);
  201.  
  202.   if (sk->shutdown & RCV_SHUTDOWN) return(0);
  203.   if (addr_len) {
  204.       err=verify_area(VERIFY_WRITE, addr_len, sizeof(*addr_len));
  205.       if(err)
  206.           return err;
  207.       put_fs_long(sizeof(*saddr), addr_len);
  208.   }
  209.   
  210.   err=verify_area(VERIFY_WRITE,to,len);
  211.   if(err)
  212.       return err;
  213.   skb=skb_recv_datagram(sk,flags,noblock,&err);
  214.   if(skb==NULL)
  215.       return err;
  216.   copied = min(len, skb->len);
  217.  
  218.   memcpy_tofs(to, skb->data, copied);    /* Don't use skb_copy_datagram here: We can't get frag chains */
  219.  
  220.   /* Copy the address. */
  221.   if (saddr) {
  222.     struct sockaddr addr;
  223.  
  224.     addr.sa_family = skb->dev->type;
  225.     memcpy(addr.sa_data,skb->dev->name, 14);
  226.     verify_area(VERIFY_WRITE, saddr, sizeof(*saddr));
  227.     memcpy_tofs(saddr, &addr, sizeof(*saddr));
  228.   }
  229.  
  230.   skb_free_datagram(skb);        /* Its either been used up, or its a peek_copy anyway */
  231.  
  232.   release_sock(sk);
  233.   return(copied);
  234. }
  235.  
  236.  
  237. int
  238. packet_read(struct sock *sk, unsigned char *buff,
  239.         int len, int noblock, unsigned flags)
  240. {
  241.   return(packet_recvfrom(sk, buff, len, noblock, flags, NULL, NULL));
  242. }
  243.  
  244.  
  245. struct proto packet_prot = {
  246.   sock_wmalloc,
  247.   sock_rmalloc,
  248.   sock_wfree,
  249.   sock_rfree,
  250.   sock_rspace,
  251.   sock_wspace,
  252.   packet_close,
  253.   packet_read,
  254.   packet_write,
  255.   packet_sendto,
  256.   packet_recvfrom,
  257.   ip_build_header,
  258.   udp_connect,
  259.   NULL,
  260.   ip_queue_xmit,
  261.   ip_retransmit,
  262.   NULL,
  263.   NULL,
  264.   NULL, 
  265.   datagram_select,
  266.   NULL,
  267.   packet_init,
  268.   NULL,
  269.   NULL,    /* No set/get socket options */
  270.   NULL,
  271.   128,
  272.   0,
  273.   {NULL,},
  274.   "PACKET"
  275. };
  276.