fddi.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:4k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  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.  * FDDI-type device handling.
  7.  *
  8.  * Version: @(#)fddi.c 1.0.0 08/12/96
  9.  *
  10.  * Authors: Lawrence V. Stefani, <stefani@lkg.dec.com>
  11.  *
  12.  * fddi.c is based on previous eth.c and tr.c work by
  13.  * Ross Biro, <bir7@leland.Stanford.Edu>
  14.  * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  15.  * Mark Evans, <evansmp@uhura.aston.ac.uk>
  16.  * Florian La Roche, <rzsfl@rz.uni-sb.de>
  17.  * Alan Cox, <gw4pts@gw4pts.ampr.org>
  18.  * 
  19.  * This program is free software; you can redistribute it and/or
  20.  * modify it under the terms of the GNU General Public License
  21.  * as published by the Free Software Foundation; either version
  22.  * 2 of the License, or (at your option) any later version.
  23.  *
  24.  * Changes
  25.  * Alan Cox : New arp/rebuild header
  26.  * Maciej W. Rozycki : IPv6 support
  27.  */
  28.  
  29. #include <linux/config.h>
  30. #include <asm/segment.h>
  31. #include <asm/system.h>
  32. #include <linux/types.h>
  33. #include <linux/kernel.h>
  34. #include <linux/sched.h>
  35. #include <linux/string.h>
  36. #include <linux/mm.h>
  37. #include <linux/socket.h>
  38. #include <linux/in.h>
  39. #include <linux/inet.h>
  40. #include <linux/netdevice.h>
  41. #include <linux/fddidevice.h>
  42. #include <linux/if_ether.h>
  43. #include <linux/skbuff.h>
  44. #include <linux/errno.h>
  45. #include <net/arp.h>
  46. #include <net/sock.h>
  47. /*
  48.  * Create the FDDI MAC header for an arbitrary protocol layer
  49.  *
  50.  * saddr=NULL means use device source address
  51.  * daddr=NULL means leave destination address (eg unresolved arp)
  52.  */
  53. int fddi_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
  54. void *daddr, void *saddr, unsigned len)
  55. {
  56. int hl = FDDI_K_SNAP_HLEN;
  57. struct fddihdr *fddi;
  58. if(type != ETH_P_IP && type != ETH_P_IPV6 && type != ETH_P_ARP)
  59. hl=FDDI_K_8022_HLEN-3;
  60. fddi = (struct fddihdr *)skb_push(skb, hl);
  61. fddi->fc  = FDDI_FC_K_ASYNC_LLC_DEF;
  62. if(type == ETH_P_IP || type == ETH_P_IPV6 || type == ETH_P_ARP)
  63. {
  64. fddi->hdr.llc_snap.dsap  = FDDI_EXTENDED_SAP;
  65. fddi->hdr.llc_snap.ssap  = FDDI_EXTENDED_SAP;
  66. fddi->hdr.llc_snap.ctrl  = FDDI_UI_CMD;
  67. fddi->hdr.llc_snap.oui[0]  = 0x00;
  68. fddi->hdr.llc_snap.oui[1]  = 0x00;
  69. fddi->hdr.llc_snap.oui[2]  = 0x00;
  70. fddi->hdr.llc_snap.ethertype  = htons(type);
  71. }
  72. /* Set the source and destination hardware addresses */
  73.  
  74. if (saddr != NULL)
  75. memcpy(fddi->saddr, saddr, dev->addr_len);
  76. else
  77. memcpy(fddi->saddr, dev->dev_addr, dev->addr_len);
  78. if (daddr != NULL)
  79. {
  80. memcpy(fddi->daddr, daddr, dev->addr_len);
  81. return(hl);
  82. }
  83. return(-hl);
  84. }
  85. /*
  86.  * Rebuild the FDDI MAC header. This is called after an ARP
  87.  * (or in future other address resolution) has completed on
  88.  * this sk_buff.  We now let ARP fill in the other fields.
  89.  */
  90.  
  91. int fddi_rebuild_header(struct sk_buff *skb)
  92. {
  93. struct fddihdr *fddi = (struct fddihdr *)skb->data;
  94. #ifdef CONFIG_INET
  95. if (fddi->hdr.llc_snap.ethertype == __constant_htons(ETH_P_IP))
  96. /* Try to get ARP to resolve the header and fill destination address */
  97. return arp_find(fddi->daddr, skb);
  98. else
  99. #endif
  100. {
  101. printk("%s: Don't know how to resolve type %02X addresses.n",
  102.        skb->dev->name, htons(fddi->hdr.llc_snap.ethertype));
  103. return(0);
  104. }
  105. }
  106. /*
  107.  * Determine the packet's protocol ID and fill in skb fields.
  108.  * This routine is called before an incoming packet is passed
  109.  * up.  It's used to fill in specific skb fields and to set
  110.  * the proper pointer to the start of packet data (skb->data).
  111.  */
  112.  
  113. unsigned short fddi_type_trans(struct sk_buff *skb, struct net_device *dev)
  114. {
  115. struct fddihdr *fddi = (struct fddihdr *)skb->data;
  116. unsigned short type;
  117. /*
  118.  * Set mac.raw field to point to FC byte, set data field to point
  119.  * to start of packet data.  Assume 802.2 SNAP frames for now.
  120.  */
  121. skb->mac.raw = skb->data; /* point to frame control (FC) */
  122. if(fddi->hdr.llc_8022_1.dsap==0xe0)
  123. {
  124. skb_pull(skb, FDDI_K_8022_HLEN-3);
  125. type = __constant_htons(ETH_P_802_2);
  126. }
  127. else
  128. {
  129. skb_pull(skb, FDDI_K_SNAP_HLEN); /* adjust for 21 byte header */
  130. type=fddi->hdr.llc_snap.ethertype;
  131. }
  132. /* Set packet type based on destination address and flag settings */
  133. if (*fddi->daddr & 0x01)
  134. {
  135. if (memcmp(fddi->daddr, dev->broadcast, FDDI_K_ALEN) == 0)
  136. skb->pkt_type = PACKET_BROADCAST;
  137. else
  138. skb->pkt_type = PACKET_MULTICAST;
  139. }
  140. else if (dev->flags & IFF_PROMISC)
  141. {
  142. if (memcmp(fddi->daddr, dev->dev_addr, FDDI_K_ALEN))
  143. skb->pkt_type = PACKET_OTHERHOST;
  144. }
  145. /* Assume 802.2 SNAP frames, for now */
  146. return(type);
  147. }