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 / eth.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-24  |  4.7 KB  |  197 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.  *        Florian  La Roche, <rzsfl@rz.uni-sb.de>
  14.  *        Alan Cox, <gw4pts@gw4pts.ampr.org>
  15.  * 
  16.  * Fixes:
  17.  *        Mr Linux    : Arp problems
  18.  *        Alan Cox    : Generic queue tidyup (very tiny here)
  19.  *        Alan Cox    : eth_header ntohs should be htons
  20.  *        Alan Cox    : eth_rebuild_header missing an htons and
  21.  *                  minor other things.
  22.  *        Tegge        : Arp bug fixes. 
  23.  *        Florian        : Removed many unnecessary functions, code cleanup
  24.  *                  and changes for new arp and skbuff.
  25.  *        Alan Cox    : Redid header building to reflect new format.
  26.  *        Alan Cox    : ARP only when compiled with CONFIG_INET
  27.  *        Greg Page    : 802.2 and SNAP stuff
  28.  *
  29.  *        This program is free software; you can redistribute it and/or
  30.  *        modify it under the terms of the GNU General Public License
  31.  *        as published by the Free Software Foundation; either version
  32.  *        2 of the License, or (at your option) any later version.
  33.  */
  34. #include <asm/segment.h>
  35. #include <asm/system.h>
  36. #include <linux/types.h>
  37. #include <linux/kernel.h>
  38. #include <linux/sched.h>
  39. #include <linux/string.h>
  40. #include <linux/mm.h>
  41. #include <linux/socket.h>
  42. #include <linux/in.h>
  43. #include <linux/inet.h>
  44. #include <linux/netdevice.h>
  45. #include <linux/etherdevice.h>
  46. #include <linux/skbuff.h>
  47. #include <linux/errno.h>
  48. #include <linux/config.h>
  49.  
  50. #include "arp.h"
  51.  
  52. void eth_setup(char *str, int *ints)
  53. {
  54.     struct device *d = dev_base;
  55.  
  56.     if (!str || !*str)
  57.         return;
  58.     while (d) 
  59.     {
  60.         if (!strcmp(str,d->name)) 
  61.         {
  62.             if (ints[0] > 0)
  63.                 d->irq=ints[1];
  64.             if (ints[0] > 1)
  65.                 d->base_addr=ints[2];
  66.             if (ints[0] > 2)
  67.                 d->mem_start=ints[3];
  68.             if (ints[0] > 3)
  69.                 d->mem_end=ints[4];
  70.             break;
  71.         }
  72.         d=d->next;
  73.     }
  74. }
  75.  
  76.  
  77. /*
  78.  *     Create the Ethernet MAC header for an arbitrary protocol layer 
  79.  *
  80.  *    saddr=NULL    means use device source address
  81.  *    daddr=NULL    means leave destination address (eg unresolved arp)
  82.  */
  83.  
  84. int eth_header(unsigned char *buff, struct device *dev, unsigned short type,
  85.        void *daddr, void *saddr, unsigned len,
  86.        struct sk_buff *skb)
  87. {
  88.     struct ethhdr *eth = (struct ethhdr *)buff;
  89.  
  90.     /* 
  91.      *    Set the protocol type. For a packet of type ETH_P_802_3 we put the length
  92.      *    in here instead. It is up to the 802.2 layer to carry protocol information.
  93.      */
  94.     
  95.     if(type!=ETH_P_802_3) 
  96.         eth->h_proto = htons(type);
  97.     else
  98.         eth->h_proto = htons(len);
  99.  
  100.     /*
  101.      *    Set the source hardware address. 
  102.      */
  103.      
  104.     if(saddr)
  105.         memcpy(eth->h_source,saddr,dev->addr_len);
  106.     else
  107.         memcpy(eth->h_source,dev->dev_addr,dev->addr_len);
  108.  
  109.     /*
  110.      *    Anyway, the loopback-device should never use this function... 
  111.      */
  112.  
  113.     if (dev->flags & IFF_LOOPBACK) 
  114.     {
  115.         memset(eth->h_dest, 0, dev->addr_len);
  116.         return(dev->hard_header_len);
  117.     }
  118.     
  119.     if(daddr)
  120.     {
  121.         memcpy(eth->h_dest,daddr,dev->addr_len);
  122.         return dev->hard_header_len;
  123.     }
  124.     
  125.     return -dev->hard_header_len;
  126. }
  127.  
  128.  
  129. /*
  130.  *    Rebuild the Ethernet MAC header. This is called after an ARP
  131.  *    (or in future other address resolution) has completed on this
  132.  *    sk_buff. We now let ARP fill in the other fields.
  133.  */
  134.  
  135. int eth_rebuild_header(void *buff, struct device *dev, unsigned long dst,
  136.             struct sk_buff *skb)
  137. {
  138.     struct ethhdr *eth = (struct ethhdr *)buff;
  139.  
  140.     /*
  141.      *    Only ARP/IP is currently supported
  142.      */
  143.      
  144.     if(eth->h_proto != htons(ETH_P_IP)) 
  145.     {
  146.         printk("eth_rebuild_header: Don't know how to resolve type %d addresses?\n",(int)eth->h_proto);
  147.         memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
  148.         return 0;
  149.     }
  150.  
  151.     /*
  152.      *    Try and get ARP to resolve the header.
  153.      */
  154. #ifdef CONFIG_INET     
  155.     return arp_find(eth->h_dest, dst, dev, dev->pa_addr, skb)? 1 : 0;
  156. #else
  157.     return 0;    
  158. #endif    
  159. }
  160.  
  161.  
  162. /*
  163.  *    Determine the packet's protocol ID. The rule here is that we 
  164.  *    assume 802.3 if the type field is short enough to be a length.
  165.  *    This is normal practice and works for any 'now in use' protocol.
  166.  */
  167.  
  168. unsigned short eth_type_trans(struct sk_buff *skb, struct device *dev)
  169. {
  170.     struct ethhdr *eth = (struct ethhdr *) skb->data;
  171.     unsigned char *rawp;
  172.     
  173.     if(*eth->h_dest&1)
  174.     {
  175.         if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0)
  176.             skb->pkt_type=PACKET_BROADCAST;
  177.         else
  178.             skb->pkt_type=PACKET_MULTICAST;
  179.     }
  180.     
  181.     if(dev->flags&IFF_PROMISC)
  182.     {
  183.         if(memcmp(eth->h_dest,dev->dev_addr, ETH_ALEN))
  184.             skb->pkt_type=PACKET_OTHERHOST;
  185.     }
  186.     
  187.     if (ntohs(eth->h_proto) >= 1536)
  188.         return eth->h_proto;
  189.         
  190.     rawp = (unsigned char *)(eth + 1);
  191.     
  192.     if (*(unsigned short *)rawp == 0xFFFF)
  193.         return htons(ETH_P_802_3);
  194.         
  195.     return htons(ETH_P_802_2);
  196. }
  197.