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 / eth.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-19  |  4.9 KB  |  188 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.  *        Ethernet-type device handling.
  7.  *
  8.  * Version:    @(#)eth.c    1.0.7    05/25/93
  9.  *
  10.  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  11.  *        Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  12.  *        Mark Evans, <evansmp@uhura.aston.ac.uk>
  13.  * 
  14.  * Fixes:
  15.  *        Mr Linux    : Arp problems
  16.  *        Alan Cox    : Generic queue tidyup (very tiny here)
  17.  *        Alan Cox    : eth_header ntohs should be htons
  18.  *        Alan Cox    : eth_rebuild_header missing an htons and
  19.  *                  minor other things.
  20.  *        Tegge        : Arp bug fixes. 
  21.  *
  22.  *        This program is free software; you can redistribute it and/or
  23.  *        modify it under the terms of the GNU General Public License
  24.  *        as published by the Free Software Foundation; either version
  25.  *        2 of the License, or (at your option) any later version.
  26.  */
  27. #include <asm/segment.h>
  28. #include <asm/system.h>
  29. #include <linux/types.h>
  30. #include <linux/kernel.h>
  31. #include <linux/sched.h>
  32. #include <linux/string.h>
  33. #include <linux/mm.h>
  34. #include <linux/socket.h>
  35. #include <linux/in.h>
  36. #include "inet.h"
  37. #include "dev.h"
  38. #include "eth.h"
  39. #include "ip.h"
  40. #include "route.h"
  41. #include "protocol.h"
  42. #include "tcp.h"
  43. #include "skbuff.h"
  44. #include "sock.h"
  45. #include <linux/errno.h>
  46. #include "arp.h"
  47.  
  48.  
  49. /* Display an Ethernet address in readable format. */
  50. char *eth_print(unsigned char *ptr)
  51. {
  52.   static char buff[64];
  53.  
  54.   if (ptr == NULL) return("[NONE]");
  55.   sprintf(buff, "%02X:%02X:%02X:%02X:%02X:%02X",
  56.     (ptr[0] & 255), (ptr[1] & 255), (ptr[2] & 255),
  57.     (ptr[3] & 255), (ptr[4] & 255), (ptr[5] & 255)
  58.   );
  59.   return(buff);
  60. }
  61.  
  62. void eth_setup(char *str, int *ints)
  63. {
  64.     struct device *d = dev_base;
  65.  
  66.     if (!str || !*str)
  67.         return;
  68.     while (d) {
  69.         if (!strcmp(str,d->name)) {
  70.             if (ints[0] > 0)
  71.                 d->irq=ints[1];
  72.             if (ints[0] > 1)
  73.                 d->base_addr=ints[2];
  74.             if (ints[0] > 2)
  75.                 d->mem_start=ints[3];
  76.             if (ints[0] > 3)
  77.                 d->mem_end=ints[4];
  78.             break;
  79.         }
  80.         d=d->next;
  81.     }
  82. }
  83.  
  84. /* Display the contents of the Ethernet MAC header. */
  85. void
  86. eth_dump(struct ethhdr *eth)
  87. {
  88.   if (inet_debug != DBG_ETH) return;
  89.  
  90.   printk("eth: SRC = %s ", eth_print(eth->h_source));
  91.   printk("DST = %s ", eth_print(eth->h_dest));
  92.   printk("TYPE = %04X\n", ntohs(eth->h_proto));
  93. }
  94.  
  95.  
  96. /* Create the Ethernet MAC header. */
  97. int
  98. eth_header(unsigned char *buff, struct device *dev, unsigned short type,
  99.        unsigned long daddr, unsigned long saddr, unsigned len)
  100. {
  101.   struct ethhdr *eth;
  102.  
  103.   DPRINTF((DBG_DEV, "ETH: header(%s, ", in_ntoa(saddr)));
  104.   DPRINTF((DBG_DEV, "%s, 0x%X)\n", in_ntoa(daddr), type));
  105.  
  106.   /* Fill in the basic Ethernet MAC header. */
  107.   eth = (struct ethhdr *) buff;
  108.   eth->h_proto = htons(type);
  109.  
  110.   /* We don't ARP for the LOOPBACK device... */
  111.   if (dev->flags & IFF_LOOPBACK) {
  112.     DPRINTF((DBG_DEV, "ETH: No header for loopback\n"));
  113.     memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
  114.     memset(eth->h_dest, 0, dev->addr_len);
  115.     return(dev->hard_header_len);
  116.   }
  117.  
  118.   /* Check if we can use the MAC BROADCAST address. */
  119.   if (chk_addr(daddr) == IS_BROADCAST) {
  120.     DPRINTF((DBG_DEV, "ETH: Using MAC Broadcast\n"));
  121.     memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
  122.     memcpy(eth->h_dest, dev->broadcast, dev->addr_len);
  123.     return(dev->hard_header_len);
  124.   }
  125.   cli();
  126.   memcpy(eth->h_source, &saddr, 4);
  127.   /* No. Ask ARP to resolve the Ethernet address. */
  128.   if (arp_find(eth->h_dest, daddr, dev, dev->pa_addr)) 
  129.   {
  130.         sti();
  131.         if(type!=ETH_P_IP)
  132.             printk("Erk: protocol %X got into an arp request state!\n",type);
  133.     return(-dev->hard_header_len);
  134.   } 
  135.   else
  136.   {
  137.       memcpy(eth->h_source,dev->dev_addr,dev->addr_len);    /* This was missing causing chaos if the
  138.                                      header built correctly! */
  139.       sti();
  140.       return(dev->hard_header_len);
  141.   }
  142. }
  143.  
  144.  
  145. /* Rebuild the Ethernet MAC header. */
  146. int
  147. eth_rebuild_header(void *buff, struct device *dev)
  148. {
  149.   struct ethhdr *eth;
  150.   unsigned long src, dst;
  151.  
  152.   DPRINTF((DBG_DEV, "ETH: Using MAC Broadcast\n"));
  153.   eth = (struct ethhdr *) buff;
  154.   src = *(unsigned long *) eth->h_source;
  155.   dst = *(unsigned long *) eth->h_dest;
  156.   DPRINTF((DBG_DEV, "ETH: RebuildHeader: SRC=%s ", in_ntoa(src)));
  157.   DPRINTF((DBG_DEV, "DST=%s\n", in_ntoa(dst)));
  158.   if(eth->h_proto!=htons(ETH_P_ARP))    /* This ntohs kind of helps a bit! */
  159.       if (arp_find(eth->h_dest, dst, dev, dev->pa_addr /* src */)) return(1);
  160.   memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
  161.   return(0);
  162. }
  163.  
  164.  
  165. /* Add an ARP entry for a host on this interface. */
  166. void
  167. eth_add_arp(unsigned long addr, struct sk_buff *skb, struct device *dev)
  168. {
  169.   struct ethhdr *eth;
  170.  
  171.   eth = (struct ethhdr *) skb->data;
  172.   arp_add(addr, eth->h_source, dev);
  173. }
  174.  
  175.  
  176. /* Determine the packet's protocol ID. */
  177. unsigned short
  178. eth_type_trans(struct sk_buff *skb, struct device *dev)
  179. {
  180.   struct ethhdr *eth;
  181.  
  182.   eth = (struct ethhdr *) skb->data;
  183.  
  184.   if(ntohs(eth->h_proto)<1536)
  185.       return(htons(ETH_P_802_3));
  186.   return(eth->h_proto);
  187. }
  188.