0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/uaccess.h>
0010 #include <linux/types.h>
0011 #include <linux/kernel.h>
0012 #include <linux/string.h>
0013 #include <linux/mm.h>
0014 #include <linux/socket.h>
0015 #include <linux/in.h>
0016 #include <linux/inet.h>
0017 #include <linux/netdevice.h>
0018 #include <linux/fcdevice.h>
0019 #include <linux/skbuff.h>
0020 #include <linux/errno.h>
0021 #include <linux/timer.h>
0022 #include <linux/net.h>
0023 #include <linux/proc_fs.h>
0024 #include <linux/init.h>
0025 #include <linux/export.h>
0026 #include <net/arp.h>
0027
0028
0029
0030
0031
0032 static int fc_header(struct sk_buff *skb, struct net_device *dev,
0033 unsigned short type,
0034 const void *daddr, const void *saddr, unsigned int len)
0035 {
0036 struct fch_hdr *fch;
0037 int hdr_len;
0038
0039
0040
0041
0042
0043 if (type == ETH_P_IP || type == ETH_P_ARP)
0044 {
0045 struct fcllc *fcllc;
0046
0047 hdr_len = sizeof(struct fch_hdr) + sizeof(struct fcllc);
0048 fch = skb_push(skb, hdr_len);
0049 fcllc = (struct fcllc *)(fch+1);
0050 fcllc->dsap = fcllc->ssap = EXTENDED_SAP;
0051 fcllc->llc = UI_CMD;
0052 fcllc->protid[0] = fcllc->protid[1] = fcllc->protid[2] = 0x00;
0053 fcllc->ethertype = htons(type);
0054 }
0055 else
0056 {
0057 hdr_len = sizeof(struct fch_hdr);
0058 fch = skb_push(skb, hdr_len);
0059 }
0060
0061 if(saddr)
0062 memcpy(fch->saddr,saddr,dev->addr_len);
0063 else
0064 memcpy(fch->saddr,dev->dev_addr,dev->addr_len);
0065
0066 if(daddr)
0067 {
0068 memcpy(fch->daddr,daddr,dev->addr_len);
0069 return hdr_len;
0070 }
0071 return -hdr_len;
0072 }
0073
0074 static const struct header_ops fc_header_ops = {
0075 .create = fc_header,
0076 };
0077
0078 static void fc_setup(struct net_device *dev)
0079 {
0080 dev->header_ops = &fc_header_ops;
0081 dev->type = ARPHRD_IEEE802;
0082 dev->hard_header_len = FC_HLEN;
0083 dev->mtu = 2024;
0084 dev->addr_len = FC_ALEN;
0085 dev->tx_queue_len = 100;
0086 dev->flags = IFF_BROADCAST;
0087
0088 memset(dev->broadcast, 0xFF, FC_ALEN);
0089 }
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102 struct net_device *alloc_fcdev(int sizeof_priv)
0103 {
0104 return alloc_netdev(sizeof_priv, "fc%d", NET_NAME_UNKNOWN, fc_setup);
0105 }
0106 EXPORT_SYMBOL(alloc_fcdev);