root/net/netrom/nr_dev.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nr_rx_ip
  2. nr_header
  3. nr_rebuild_header
  4. nr_set_mac_address
  5. nr_open
  6. nr_close
  7. nr_xmit
  8. nr_get_stats
  9. nr_init

   1 /*
   2  *      NET/ROM release 003
   3  *
   4  *      This is ALPHA test software. This code may break your machine, randomly fail to work with new 
   5  *      releases, misbehave and/or generally screw up. It might even work. 
   6  *
   7  *      This code REQUIRES 1.3.0 or higher/ NET3.029
   8  *
   9  *      This module:
  10  *              This module is free software; you can redistribute it and/or
  11  *              modify it under the terms of the GNU General Public License
  12  *              as published by the Free Software Foundation; either version
  13  *              2 of the License, or (at your option) any later version.
  14  *
  15  *      History
  16  *      NET/ROM 001     Jonathan(G4KLX) Cloned from loopback.c
  17  */
  18 
  19 #include <linux/config.h>
  20 #ifdef CONFIG_NETROM
  21 #include <linux/kernel.h>
  22 #include <linux/sched.h>
  23 #include <linux/interrupt.h>
  24 #include <linux/fs.h>
  25 #include <linux/types.h>
  26 #include <linux/string.h>
  27 #include <linux/socket.h>
  28 #include <linux/errno.h>
  29 #include <linux/fcntl.h>
  30 #include <linux/in.h>
  31 #include <linux/if_ether.h>     /* For the statistics structure. */
  32 
  33 #include <asm/system.h>
  34 #include <asm/segment.h>
  35 #include <asm/io.h>
  36 
  37 #include <linux/inet.h>
  38 #include <linux/netdevice.h>
  39 #include <linux/etherdevice.h>
  40 #include <linux/skbuff.h>
  41 
  42 #include <net/ip.h>
  43 #include <net/arp.h>
  44 
  45 #include <net/ax25.h>
  46 #include <net/netrom.h>
  47 
  48 /*
  49  *      Only allow IP over NET/ROM frames through if the netrom device is up.
  50  */
  51 
  52 int nr_rx_ip(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
  53 {
  54         struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
  55 
  56         if (!dev->start) 
  57         {
  58                 stats->rx_errors++;
  59                 return 0;
  60         }
  61 
  62         stats->rx_packets++;
  63         skb->protocol = htons(ETH_P_IP);
  64 
  65         /* Spoof incoming device */
  66         skb->dev = dev;
  67 
  68         skb->h.raw = skb->data;
  69         ip_rcv(skb, skb->dev, NULL);
  70 
  71         return 1;
  72 }
  73 
  74 static int nr_header(struct sk_buff *skb, struct device *dev, unsigned short type,
     /* [previous][next][first][last][top][bottom][index][help] */
  75         void *daddr, void *saddr, unsigned len)
  76 {
  77         unsigned char *buff = skb_push(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN);
  78 
  79         memcpy(buff, (saddr != NULL) ? saddr : dev->dev_addr, dev->addr_len);
  80         buff[6] &= ~LAPB_C;
  81         buff[6] &= ~LAPB_E;
  82         buff[6] |= SSID_SPARE;
  83         buff    += AX25_ADDR_LEN;
  84 
  85         if (daddr != NULL)
  86                 memcpy(buff, daddr, dev->addr_len);
  87         buff[6] &= ~LAPB_C;
  88         buff[6] |= LAPB_E;
  89         buff[6] |= SSID_SPARE;
  90         buff    += AX25_ADDR_LEN;
  91 
  92         *buff++ = nr_default.ttl;
  93 
  94         *buff++ = NR_PROTO_IP;
  95         *buff++ = NR_PROTO_IP;
  96         *buff++ = 0;
  97         *buff++ = 0;
  98         *buff++ = NR_PROTOEXT;
  99 
 100         if (daddr != NULL)
 101                 return 37;
 102         
 103         return -37;     
 104 }
 105 
 106 static int nr_rebuild_header(void *buff, struct device *dev,
     /* [previous][next][first][last][top][bottom][index][help] */
 107         unsigned long raddr, struct sk_buff *skb)
 108 {
 109         struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
 110         unsigned char *bp = (unsigned char *)buff;
 111 
 112         skb_device_unlock(skb);
 113 
 114         if (!arp_query(bp + 7, raddr, ARPHRD_NETROM)) {
 115                 skb->free = 1;
 116                 kfree_skb(skb, FREE_WRITE);
 117                 return 1;
 118         }
 119 
 120         bp[6] &= ~LAPB_C;
 121         bp[6] &= ~LAPB_E;
 122         bp[6] |= SSID_SPARE;
 123         bp    += AX25_ADDR_LEN;
 124         
 125         bp[6] &= ~LAPB_C;
 126         bp[6] |= LAPB_E;
 127         bp[6] |= SSID_SPARE;
 128 
 129         if (!nr_route_frame(skb, NULL)) {
 130                 skb->free = 1;
 131                 kfree_skb(skb, FREE_WRITE);
 132                 stats->tx_errors++;
 133         }
 134 
 135         stats->tx_packets++;
 136 
 137         return 1;
 138 }
 139 
 140 static int nr_set_mac_address(struct device *dev, void *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 141 {
 142         memcpy(dev->dev_addr, addr, dev->addr_len);
 143 
 144         return 0;
 145 }
 146 
 147 static int nr_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 148 {
 149         dev->tbusy = 0;
 150         dev->start = 1;
 151 
 152         return 0;
 153 }
 154 
 155 static int nr_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 156 {
 157         dev->tbusy = 1;
 158         dev->start = 0;
 159 
 160         return 0;
 161 }
 162 
 163 static int nr_xmit(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 164 {
 165         struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
 166 
 167         if (skb == NULL || dev == NULL)
 168                 return 0;
 169 
 170         if (!dev->start) {
 171                 printk("netrom: xmit call when iface is down\n");
 172                 return 1;
 173         }
 174 
 175         cli();
 176 
 177         if (dev->tbusy != 0) {
 178                 sti();
 179                 stats->tx_errors++;
 180                 return 1;
 181         }
 182 
 183         dev->tbusy = 1;
 184 
 185         sti();
 186 
 187         dev_kfree_skb(skb, FREE_WRITE);
 188 
 189         stats->tx_errors++;
 190 
 191         dev->tbusy = 0;
 192 
 193         mark_bh(NET_BH);
 194 
 195         return 0;
 196 }
 197 
 198 static struct enet_statistics *nr_get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 199 {
 200         return (struct enet_statistics *)dev->priv;
 201 }
 202 
 203 int nr_init(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 204 {
 205         int i;
 206 
 207         dev->mtu                = 236;          /* MTU                  */
 208         dev->tbusy              = 0;
 209         dev->hard_start_xmit    = nr_xmit;
 210         dev->open               = nr_open;
 211         dev->stop               = nr_close;
 212 
 213         dev->hard_header        = nr_header;
 214         dev->hard_header_len    = AX25_BPQ_HEADER_LEN + AX25_MAX_HEADER_LEN + 2 + NR_NETWORK_LEN + NR_TRANSPORT_LEN;
 215         dev->addr_len           = AX25_ADDR_LEN;
 216         dev->type               = ARPHRD_NETROM;
 217         dev->rebuild_header     = nr_rebuild_header;
 218         dev->set_mac_address    = nr_set_mac_address;
 219 
 220         /* New-style flags. */
 221         dev->flags              = 0;
 222         dev->family             = AF_INET;
 223 
 224         dev->pa_addr            = 0;
 225         dev->pa_brdaddr         = 0;
 226         dev->pa_mask            = 0;
 227         dev->pa_alen            = sizeof(unsigned long);
 228 
 229         dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL);
 230 
 231         memset(dev->priv, 0, sizeof(struct enet_statistics));
 232 
 233         dev->get_stats = nr_get_stats;
 234 
 235         /* Fill in the generic fields of the device structure. */
 236         for (i = 0; i < DEV_NUMBUFFS; i++)
 237                 skb_queue_head_init(&dev->buffs[i]);
 238 
 239         return 0;
 240 };
 241 
 242 #endif

/* [previous][next][first][last][top][bottom][index][help] */