Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * INET     An implementation of the TCP/IP protocol suite for the LINUX
0004  *      operating system.  INET is implemented using the  BSD Socket
0005  *      interface as the means of communication with the user level.
0006  *
0007  *      HIPPI-type device handling.
0008  *
0009  * Version: @(#)hippi.c 1.0.0   05/29/97
0010  *
0011  * Authors: Ross Biro
0012  *      Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
0013  *      Mark Evans, <evansmp@uhura.aston.ac.uk>
0014  *      Florian  La Roche, <rzsfl@rz.uni-sb.de>
0015  *      Alan Cox, <gw4pts@gw4pts.ampr.org>
0016  *      Jes Sorensen, <Jes.Sorensen@cern.ch>
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  * Create the HIPPI MAC header for an arbitrary protocol layer
0037  *
0038  * saddr=NULL   means use device source address
0039  * daddr=NULL   means leave destination address (eg unresolved arp)
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      * Due to the stupidity of the little endian byte-order we
0056      * have to set the fp field this way.
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;    /* only HIPPI 800 for the time being */
0062     hip->le.message_type    = 0;    /* Data PDU */
0063 
0064     hip->le.dest_addr_type  = 2;    /* 12 bit SC address */
0065     hip->le.src_addr_type   = 2;    /* 12 bit SC address */
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  *  Determine the packet's protocol ID.
0091  */
0092 
0093 __be16 hippi_type_trans(struct sk_buff *skb, struct net_device *dev)
0094 {
0095     struct hippi_hdr *hip;
0096 
0097     /*
0098      * This is actually wrong ... question is if we really should
0099      * set the raw address here.
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      * No fancy promisc stuff here now.
0108      */
0109 
0110     return hip->snap.ethertype;
0111 }
0112 
0113 EXPORT_SYMBOL(hippi_type_trans);
0114 
0115 /*
0116  * For HIPPI we will actually use the lower 4 bytes of the hardware
0117  * address as the I-FIELD rather than the actual hardware address.
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     /* Never send broadcast/multicast ARP messages */
0132     NEIGH_VAR_INIT(p, MCAST_PROBES, 0);
0133 
0134     /* In IPv6 unicast probes are valid even on NBMA,
0135     * because they are encapsulated in normal IPv6 protocol.
0136     * Should be a generic flag.
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      * We don't support HIPPI `ARP' for the time being, and probably
0155      * never will unless someone else implements it. However we
0156      * still need a fake ARPHRD to make ifconfig and friends play ball.
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 /* 5 */;
0165     memset(dev->broadcast, 0xFF, HIPPI_ALEN);
0166 
0167 
0168     /*
0169      * HIPPI doesn't support broadcast+multicast and we only use
0170      * static ARP tables. ARP is disabled by hippi_neigh_setup_dev.
0171      */
0172     dev->flags = 0;
0173 }
0174 
0175 /**
0176  * alloc_hippi_dev - Register HIPPI device
0177  * @sizeof_priv: Size of additional driver-private structure to be allocated
0178  *  for this HIPPI device
0179  *
0180  * Fill in the fields of the device structure with HIPPI-generic values.
0181  *
0182  * Constructs a new net device, complete with a private data area of
0183  * size @sizeof_priv.  A 32-byte (not bit) alignment is enforced for
0184  * this private data area.
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);