home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.2 / LINUX-1.2 / LINUX-1 / linux / drivers / net / loopback.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-04  |  3.4 KB  |  141 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.  *        Pseudo-driver for the loopback interface.
  7.  *
  8.  * Version:    @(#)loopback.c    1.0.4b    08/16/93
  9.  *
  10.  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  11.  *        Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  12.  *        Donald Becker, <becker@cesdis.gsfc.nasa.gov>
  13.  *
  14.  *        Alan Cox    :    Fixed oddments for NET3.014
  15.  *
  16.  *        This program is free software; you can redistribute it and/or
  17.  *        modify it under the terms of the GNU General Public License
  18.  *        as published by the Free Software Foundation; either version
  19.  *        2 of the License, or (at your option) any later version.
  20.  */
  21. #include <linux/config.h>
  22. #include <linux/kernel.h>
  23. #include <linux/sched.h>
  24. #include <linux/interrupt.h>
  25. #include <linux/fs.h>
  26. #include <linux/types.h>
  27. #include <linux/string.h>
  28. #include <linux/socket.h>
  29. #include <linux/errno.h>
  30. #include <linux/fcntl.h>
  31. #include <linux/in.h>
  32. #include <linux/if_ether.h>    /* For the statistics structure. */
  33.  
  34. #include <asm/system.h>
  35. #include <asm/segment.h>
  36. #include <asm/io.h>
  37.  
  38. #include <linux/inet.h>
  39. #include <linux/netdevice.h>
  40. #include <linux/etherdevice.h>
  41. #include <linux/skbuff.h>
  42.  
  43.  
  44. static int
  45. loopback_xmit(struct sk_buff *skb, struct device *dev)
  46. {
  47.   struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
  48.   int done;
  49.  
  50.   if (skb == NULL || dev == NULL) return(0);
  51.  
  52.   cli();
  53.   if (dev->tbusy != 0) {
  54.     sti();
  55.     stats->tx_errors++;
  56.     return(1);
  57.   }
  58.   dev->tbusy = 1;
  59.   sti();
  60.   
  61.   /* FIXME: Optimise so buffers with skb->free=1 are not copied but
  62.      instead are lobbed from tx queue to rx queue */
  63.  
  64.   done = dev_rint(skb->data, skb->len, 0, dev);
  65.   dev_kfree_skb(skb, FREE_WRITE);
  66.  
  67.   while (done != 1) {
  68.     done = dev_rint(NULL, 0, 0, dev);
  69.   }
  70.   stats->tx_packets++;
  71.  
  72.   dev->tbusy = 0;
  73.  
  74.   if (!intr_count && (bh_active & bh_mask)) {
  75.     start_bh_atomic();
  76.     do_bottom_half();
  77.     end_bh_atomic();
  78.   }
  79.  
  80.   return(0);
  81. }
  82.  
  83. static struct enet_statistics *
  84. get_stats(struct device *dev)
  85. {
  86.     return (struct enet_statistics *)dev->priv;
  87. }
  88.  
  89. static int loopback_open(struct device *dev)
  90. {
  91.     dev->flags|=IFF_LOOPBACK;
  92.     return 0;
  93. }
  94.  
  95. /* Initialize the rest of the LOOPBACK device. */
  96. int
  97. loopback_init(struct device *dev)
  98. {
  99.   int i;
  100.  
  101.   dev->mtu        = 2000;            /* MTU            */
  102.   dev->tbusy        = 0;
  103.   dev->hard_start_xmit    = loopback_xmit;
  104.   dev->open        = NULL;
  105. #if 1
  106.   dev->hard_header    = eth_header;
  107.   dev->hard_header_len    = ETH_HLEN;        /* 14            */
  108.   dev->addr_len        = ETH_ALEN;        /* 6            */
  109.   dev->type        = ARPHRD_ETHER;        /* 0x0001        */
  110.   dev->type_trans    = eth_type_trans;
  111.   dev->rebuild_header    = eth_rebuild_header;
  112.   dev->open        = loopback_open;
  113. #else
  114.   dev->hard_header_length = 0;
  115.   dev->addr_len        = 0;
  116.   dev->type        = 0;            /* loopback_type (0)    */
  117.   dev->hard_header    = NULL;
  118.   dev->type_trans    = NULL;
  119.   dev->rebuild_header    = NULL;
  120. #endif
  121.  
  122.   /* New-style flags. */
  123.   dev->flags        = IFF_LOOPBACK|IFF_BROADCAST;
  124.   dev->family        = AF_INET;
  125. #ifdef CONFIG_INET    
  126.   dev->pa_addr        = in_aton("127.0.0.1");
  127.   dev->pa_brdaddr    = in_aton("127.255.255.255");
  128.   dev->pa_mask        = in_aton("255.0.0.0");
  129.   dev->pa_alen        = sizeof(unsigned long);
  130. #endif  
  131.   dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL);
  132.   memset(dev->priv, 0, sizeof(struct enet_statistics));
  133.   dev->get_stats = get_stats;
  134.  
  135.   /* Fill in the generic fields of the device structure. */
  136.   for (i = 0; i < DEV_NUMBUFFS; i++)
  137.     skb_queue_head_init(&dev->buffs[i]);
  138.   
  139.   return(0);
  140. };
  141.