root/net/netrom/nr_dev.c

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

DEFINITIONS

This source file includes following definitions.
  1. nr_rx_ip
  2. nr_header
  3. nr_set_mac_address
  4. nr_open
  5. nr_close
  6. nr_xmit
  7. nr_setup

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *
   4  * Copyright Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
   5  */
   6 #include <linux/module.h>
   7 #include <linux/proc_fs.h>
   8 #include <linux/kernel.h>
   9 #include <linux/interrupt.h>
  10 #include <linux/fs.h>
  11 #include <linux/types.h>
  12 #include <linux/sysctl.h>
  13 #include <linux/string.h>
  14 #include <linux/socket.h>
  15 #include <linux/errno.h>
  16 #include <linux/fcntl.h>
  17 #include <linux/in.h>
  18 #include <linux/if_ether.h>     /* For the statistics structure. */
  19 #include <linux/slab.h>
  20 #include <linux/uaccess.h>
  21 
  22 #include <asm/io.h>
  23 
  24 #include <linux/inet.h>
  25 #include <linux/netdevice.h>
  26 #include <linux/etherdevice.h>
  27 #include <linux/if_arp.h>
  28 #include <linux/skbuff.h>
  29 
  30 #include <net/ip.h>
  31 #include <net/arp.h>
  32 
  33 #include <net/ax25.h>
  34 #include <net/netrom.h>
  35 
  36 /*
  37  *      Only allow IP over NET/ROM frames through if the netrom device is up.
  38  */
  39 
  40 int nr_rx_ip(struct sk_buff *skb, struct net_device *dev)
  41 {
  42         struct net_device_stats *stats = &dev->stats;
  43 
  44         if (!netif_running(dev)) {
  45                 stats->rx_dropped++;
  46                 return 0;
  47         }
  48 
  49         stats->rx_packets++;
  50         stats->rx_bytes += skb->len;
  51 
  52         skb->protocol = htons(ETH_P_IP);
  53 
  54         /* Spoof incoming device */
  55         skb->dev      = dev;
  56         skb->mac_header = skb->network_header;
  57         skb_reset_network_header(skb);
  58         skb->pkt_type = PACKET_HOST;
  59 
  60         netif_rx(skb);
  61 
  62         return 1;
  63 }
  64 
  65 static int nr_header(struct sk_buff *skb, struct net_device *dev,
  66                      unsigned short type,
  67                      const void *daddr, const void *saddr, unsigned int len)
  68 {
  69         unsigned char *buff = skb_push(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN);
  70 
  71         memcpy(buff, (saddr != NULL) ? saddr : dev->dev_addr, dev->addr_len);
  72         buff[6] &= ~AX25_CBIT;
  73         buff[6] &= ~AX25_EBIT;
  74         buff[6] |= AX25_SSSID_SPARE;
  75         buff    += AX25_ADDR_LEN;
  76 
  77         if (daddr != NULL)
  78                 memcpy(buff, daddr, dev->addr_len);
  79         buff[6] &= ~AX25_CBIT;
  80         buff[6] |= AX25_EBIT;
  81         buff[6] |= AX25_SSSID_SPARE;
  82         buff    += AX25_ADDR_LEN;
  83 
  84         *buff++ = sysctl_netrom_network_ttl_initialiser;
  85 
  86         *buff++ = NR_PROTO_IP;
  87         *buff++ = NR_PROTO_IP;
  88         *buff++ = 0;
  89         *buff++ = 0;
  90         *buff++ = NR_PROTOEXT;
  91 
  92         if (daddr != NULL)
  93                 return 37;
  94 
  95         return -37;
  96 }
  97 
  98 static int __must_check nr_set_mac_address(struct net_device *dev, void *addr)
  99 {
 100         struct sockaddr *sa = addr;
 101         int err;
 102 
 103         if (!memcmp(dev->dev_addr, sa->sa_data, dev->addr_len))
 104                 return 0;
 105 
 106         if (dev->flags & IFF_UP) {
 107                 err = ax25_listen_register((ax25_address *)sa->sa_data, NULL);
 108                 if (err)
 109                         return err;
 110 
 111                 ax25_listen_release((ax25_address *)dev->dev_addr, NULL);
 112         }
 113 
 114         memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
 115 
 116         return 0;
 117 }
 118 
 119 static int nr_open(struct net_device *dev)
 120 {
 121         int err;
 122 
 123         err = ax25_listen_register((ax25_address *)dev->dev_addr, NULL);
 124         if (err)
 125                 return err;
 126 
 127         netif_start_queue(dev);
 128 
 129         return 0;
 130 }
 131 
 132 static int nr_close(struct net_device *dev)
 133 {
 134         ax25_listen_release((ax25_address *)dev->dev_addr, NULL);
 135         netif_stop_queue(dev);
 136         return 0;
 137 }
 138 
 139 static netdev_tx_t nr_xmit(struct sk_buff *skb, struct net_device *dev)
 140 {
 141         struct net_device_stats *stats = &dev->stats;
 142         unsigned int len = skb->len;
 143 
 144         if (!nr_route_frame(skb, NULL)) {
 145                 kfree_skb(skb);
 146                 stats->tx_errors++;
 147                 return NETDEV_TX_OK;
 148         }
 149 
 150         stats->tx_packets++;
 151         stats->tx_bytes += len;
 152 
 153         return NETDEV_TX_OK;
 154 }
 155 
 156 static const struct header_ops nr_header_ops = {
 157         .create = nr_header,
 158 };
 159 
 160 static const struct net_device_ops nr_netdev_ops = {
 161         .ndo_open               = nr_open,
 162         .ndo_stop               = nr_close,
 163         .ndo_start_xmit         = nr_xmit,
 164         .ndo_set_mac_address    = nr_set_mac_address,
 165 };
 166 
 167 void nr_setup(struct net_device *dev)
 168 {
 169         dev->mtu                = NR_MAX_PACKET_SIZE;
 170         dev->netdev_ops         = &nr_netdev_ops;
 171         dev->header_ops         = &nr_header_ops;
 172         dev->hard_header_len    = NR_NETWORK_LEN + NR_TRANSPORT_LEN;
 173         dev->addr_len           = AX25_ADDR_LEN;
 174         dev->type               = ARPHRD_NETROM;
 175 
 176         /* New-style flags. */
 177         dev->flags              = IFF_NOARP;
 178 }

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