root/net/802/fddi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fddi_header
  2. fddi_type_trans
  3. fddi_setup
  4. alloc_fddidev

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * INET         An implementation of the TCP/IP protocol suite for the LINUX
   4  *              operating system.  INET is implemented using the BSD Socket
   5  *              interface as the means of communication with the user level.
   6  *
   7  *              FDDI-type device handling.
   8  *
   9  * Version:     @(#)fddi.c      1.0.0   08/12/96
  10  *
  11  * Authors:     Lawrence V. Stefani, <stefani@lkg.dec.com>
  12  *
  13  *              fddi.c is based on previous eth.c and tr.c work by
  14  *                      Ross Biro
  15  *                      Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  16  *                      Mark Evans, <evansmp@uhura.aston.ac.uk>
  17  *                      Florian La Roche, <rzsfl@rz.uni-sb.de>
  18  *                      Alan Cox, <gw4pts@gw4pts.ampr.org>
  19  *
  20  *      Changes
  21  *              Alan Cox                :       New arp/rebuild header
  22  *              Maciej W. Rozycki       :       IPv6 support
  23  */
  24 
  25 #include <linux/module.h>
  26 #include <linux/types.h>
  27 #include <linux/kernel.h>
  28 #include <linux/string.h>
  29 #include <linux/mm.h>
  30 #include <linux/socket.h>
  31 #include <linux/in.h>
  32 #include <linux/inet.h>
  33 #include <linux/netdevice.h>
  34 #include <linux/fddidevice.h>
  35 #include <linux/if_ether.h>
  36 #include <linux/skbuff.h>
  37 #include <linux/errno.h>
  38 #include <net/arp.h>
  39 #include <net/sock.h>
  40 
  41 /*
  42  * Create the FDDI MAC header for an arbitrary protocol layer
  43  *
  44  * saddr=NULL   means use device source address
  45  * daddr=NULL   means leave destination address (eg unresolved arp)
  46  */
  47 
  48 static int fddi_header(struct sk_buff *skb, struct net_device *dev,
  49                        unsigned short type,
  50                        const void *daddr, const void *saddr, unsigned int len)
  51 {
  52         int hl = FDDI_K_SNAP_HLEN;
  53         struct fddihdr *fddi;
  54 
  55         if(type != ETH_P_IP && type != ETH_P_IPV6 && type != ETH_P_ARP)
  56                 hl=FDDI_K_8022_HLEN-3;
  57         fddi = skb_push(skb, hl);
  58         fddi->fc                         = FDDI_FC_K_ASYNC_LLC_DEF;
  59         if(type == ETH_P_IP || type == ETH_P_IPV6 || type == ETH_P_ARP)
  60         {
  61                 fddi->hdr.llc_snap.dsap          = FDDI_EXTENDED_SAP;
  62                 fddi->hdr.llc_snap.ssap          = FDDI_EXTENDED_SAP;
  63                 fddi->hdr.llc_snap.ctrl          = FDDI_UI_CMD;
  64                 fddi->hdr.llc_snap.oui[0]        = 0x00;
  65                 fddi->hdr.llc_snap.oui[1]        = 0x00;
  66                 fddi->hdr.llc_snap.oui[2]        = 0x00;
  67                 fddi->hdr.llc_snap.ethertype     = htons(type);
  68         }
  69 
  70         /* Set the source and destination hardware addresses */
  71 
  72         if (saddr != NULL)
  73                 memcpy(fddi->saddr, saddr, dev->addr_len);
  74         else
  75                 memcpy(fddi->saddr, dev->dev_addr, dev->addr_len);
  76 
  77         if (daddr != NULL)
  78         {
  79                 memcpy(fddi->daddr, daddr, dev->addr_len);
  80                 return hl;
  81         }
  82 
  83         return -hl;
  84 }
  85 
  86 /*
  87  * Determine the packet's protocol ID and fill in skb fields.
  88  * This routine is called before an incoming packet is passed
  89  * up.  It's used to fill in specific skb fields and to set
  90  * the proper pointer to the start of packet data (skb->data).
  91  */
  92 
  93 __be16 fddi_type_trans(struct sk_buff *skb, struct net_device *dev)
  94 {
  95         struct fddihdr *fddi = (struct fddihdr *)skb->data;
  96         __be16 type;
  97 
  98         /*
  99          * Set mac.raw field to point to FC byte, set data field to point
 100          * to start of packet data.  Assume 802.2 SNAP frames for now.
 101          */
 102 
 103         skb->dev = dev;
 104         skb_reset_mac_header(skb);      /* point to frame control (FC) */
 105 
 106         if(fddi->hdr.llc_8022_1.dsap==0xe0)
 107         {
 108                 skb_pull(skb, FDDI_K_8022_HLEN-3);
 109                 type = htons(ETH_P_802_2);
 110         }
 111         else
 112         {
 113                 skb_pull(skb, FDDI_K_SNAP_HLEN);                /* adjust for 21 byte header */
 114                 type=fddi->hdr.llc_snap.ethertype;
 115         }
 116 
 117         /* Set packet type based on destination address and flag settings */
 118 
 119         if (*fddi->daddr & 0x01)
 120         {
 121                 if (memcmp(fddi->daddr, dev->broadcast, FDDI_K_ALEN) == 0)
 122                         skb->pkt_type = PACKET_BROADCAST;
 123                 else
 124                         skb->pkt_type = PACKET_MULTICAST;
 125         }
 126 
 127         else if (dev->flags & IFF_PROMISC)
 128         {
 129                 if (memcmp(fddi->daddr, dev->dev_addr, FDDI_K_ALEN))
 130                         skb->pkt_type = PACKET_OTHERHOST;
 131         }
 132 
 133         /* Assume 802.2 SNAP frames, for now */
 134 
 135         return type;
 136 }
 137 
 138 EXPORT_SYMBOL(fddi_type_trans);
 139 
 140 static const struct header_ops fddi_header_ops = {
 141         .create         = fddi_header,
 142 };
 143 
 144 
 145 static void fddi_setup(struct net_device *dev)
 146 {
 147         dev->header_ops         = &fddi_header_ops;
 148         dev->type               = ARPHRD_FDDI;
 149         dev->hard_header_len    = FDDI_K_SNAP_HLEN+3;   /* Assume 802.2 SNAP hdr len + 3 pad bytes */
 150         dev->mtu                = FDDI_K_SNAP_DLEN;     /* Assume max payload of 802.2 SNAP frame */
 151         dev->min_mtu            = FDDI_K_SNAP_HLEN;
 152         dev->max_mtu            = FDDI_K_SNAP_DLEN;
 153         dev->addr_len           = FDDI_K_ALEN;
 154         dev->tx_queue_len       = 100;                  /* Long queues on FDDI */
 155         dev->flags              = IFF_BROADCAST | IFF_MULTICAST;
 156 
 157         memset(dev->broadcast, 0xFF, FDDI_K_ALEN);
 158 }
 159 
 160 /**
 161  * alloc_fddidev - Register FDDI device
 162  * @sizeof_priv: Size of additional driver-private structure to be allocated
 163  *      for this FDDI device
 164  *
 165  * Fill in the fields of the device structure with FDDI-generic values.
 166  *
 167  * Constructs a new net device, complete with a private data area of
 168  * size @sizeof_priv.  A 32-byte (not bit) alignment is enforced for
 169  * this private data area.
 170  */
 171 struct net_device *alloc_fddidev(int sizeof_priv)
 172 {
 173         return alloc_netdev(sizeof_priv, "fddi%d", NET_NAME_UNKNOWN,
 174                             fddi_setup);
 175 }
 176 EXPORT_SYMBOL(alloc_fddidev);
 177 
 178 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */