0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include <linux/module.h>
0020 #include <linux/types.h>
0021 #include <linux/kernel.h>
0022 #include <linux/string.h>
0023 #include <linux/mm.h>
0024 #include <linux/socket.h>
0025 #include <linux/in.h>
0026 #include <linux/inet.h>
0027 #include <linux/netdevice.h>
0028 #include <linux/hippidevice.h>
0029 #include <linux/skbuff.h>
0030 #include <linux/errno.h>
0031 #include <net/arp.h>
0032 #include <net/sock.h>
0033 #include <linux/uaccess.h>
0034
0035
0036
0037
0038
0039
0040
0041
0042 static int hippi_header(struct sk_buff *skb, struct net_device *dev,
0043 unsigned short type,
0044 const void *daddr, const void *saddr, unsigned int len)
0045 {
0046 struct hippi_hdr *hip = skb_push(skb, HIPPI_HLEN);
0047 struct hippi_cb *hcb = (struct hippi_cb *) skb->cb;
0048
0049 if (!len){
0050 len = skb->len - HIPPI_HLEN;
0051 printk("hippi_header(): length not supplied\n");
0052 }
0053
0054
0055
0056
0057
0058 hip->fp.fixed = htonl(0x04800018);
0059 hip->fp.d2_size = htonl(len + 8);
0060 hip->le.fc = 0;
0061 hip->le.double_wide = 0;
0062 hip->le.message_type = 0;
0063
0064 hip->le.dest_addr_type = 2;
0065 hip->le.src_addr_type = 2;
0066
0067 memcpy(hip->le.src_switch_addr, dev->dev_addr + 3, 3);
0068 memset_startat(&hip->le, 0, reserved);
0069
0070 hip->snap.dsap = HIPPI_EXTENDED_SAP;
0071 hip->snap.ssap = HIPPI_EXTENDED_SAP;
0072 hip->snap.ctrl = HIPPI_UI_CMD;
0073 hip->snap.oui[0] = 0x00;
0074 hip->snap.oui[1] = 0x00;
0075 hip->snap.oui[2] = 0x00;
0076 hip->snap.ethertype = htons(type);
0077
0078 if (daddr)
0079 {
0080 memcpy(hip->le.dest_switch_addr, daddr + 3, 3);
0081 memcpy(&hcb->ifield, daddr + 2, 4);
0082 return HIPPI_HLEN;
0083 }
0084 hcb->ifield = 0;
0085 return -((int)HIPPI_HLEN);
0086 }
0087
0088
0089
0090
0091
0092
0093 __be16 hippi_type_trans(struct sk_buff *skb, struct net_device *dev)
0094 {
0095 struct hippi_hdr *hip;
0096
0097
0098
0099
0100
0101 skb->dev = dev;
0102 skb_reset_mac_header(skb);
0103 hip = (struct hippi_hdr *)skb_mac_header(skb);
0104 skb_pull(skb, HIPPI_HLEN);
0105
0106
0107
0108
0109
0110 return hip->snap.ethertype;
0111 }
0112
0113 EXPORT_SYMBOL(hippi_type_trans);
0114
0115
0116
0117
0118
0119 int hippi_mac_addr(struct net_device *dev, void *p)
0120 {
0121 struct sockaddr *addr = p;
0122 if (netif_running(dev))
0123 return -EBUSY;
0124 dev_addr_set(dev, addr->sa_data);
0125 return 0;
0126 }
0127 EXPORT_SYMBOL(hippi_mac_addr);
0128
0129 int hippi_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
0130 {
0131
0132 NEIGH_VAR_INIT(p, MCAST_PROBES, 0);
0133
0134
0135
0136
0137
0138 if (p->tbl->family != AF_INET6)
0139 NEIGH_VAR_INIT(p, UCAST_PROBES, 0);
0140 return 0;
0141 }
0142 EXPORT_SYMBOL(hippi_neigh_setup_dev);
0143
0144 static const struct header_ops hippi_header_ops = {
0145 .create = hippi_header,
0146 };
0147
0148
0149 static void hippi_setup(struct net_device *dev)
0150 {
0151 dev->header_ops = &hippi_header_ops;
0152
0153
0154
0155
0156
0157
0158 dev->type = ARPHRD_HIPPI;
0159 dev->hard_header_len = HIPPI_HLEN;
0160 dev->mtu = 65280;
0161 dev->min_mtu = 68;
0162 dev->max_mtu = 65280;
0163 dev->addr_len = HIPPI_ALEN;
0164 dev->tx_queue_len = 25 ;
0165 memset(dev->broadcast, 0xFF, HIPPI_ALEN);
0166
0167
0168
0169
0170
0171
0172 dev->flags = 0;
0173 }
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187 struct net_device *alloc_hippi_dev(int sizeof_priv)
0188 {
0189 return alloc_netdev(sizeof_priv, "hip%d", NET_NAME_UNKNOWN,
0190 hippi_setup);
0191 }
0192
0193 EXPORT_SYMBOL(alloc_hippi_dev);