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 002
   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                 stats->rx_errors++;
  58                 return 0;
  59         }
  60 
  61         stats->rx_packets++;
  62         skb->protocol=htons(ETH_P_IP);
  63         /* Spoof incoming device */
  64         skb->dev=dev;
  65 
  66         ip_rcv(skb, dev, NULL);
  67 
  68         return 1;
  69 }
  70 
  71 /*
  72  * We can't handle ARP so put some identification characters into the ARP
  73  * packet so that the transmit routine can identify it, and throw it away.
  74  */
  75 
  76 static int nr_header(unsigned char *buff, struct device *dev, unsigned short type,
     /* [previous][next][first][last][top][bottom][index][help] */
  77         void *daddr, void *saddr, unsigned len, struct sk_buff *skb)
  78 {
  79         if (type == ETH_P_ARP) {
  80                 *buff++ = 0xFF;         /* Mark it */
  81                 *buff++ = 0xFE;
  82                 return 37;
  83         }
  84 
  85         buff += 16;
  86         
  87         *buff++ = AX25_P_NETROM;
  88         
  89         memcpy(buff, (saddr != NULL) ? saddr : dev->dev_addr, dev->addr_len);
  90         buff[6] &= ~LAPB_C;
  91         buff[6] &= ~LAPB_E;
  92         buff[6] |= SSID_SPARE;
  93         buff += dev->addr_len;
  94 
  95         if (daddr != NULL)
  96                 memcpy(buff, daddr, dev->addr_len);
  97         buff[6] &= ~LAPB_C;
  98         buff[6] |= LAPB_E;
  99         buff[6] |= SSID_SPARE;
 100         buff += dev->addr_len;
 101 
 102         *buff++ = nr_default.ttl;
 103 
 104         *buff++ = NR_PROTO_IP;
 105         *buff++ = NR_PROTO_IP;
 106         *buff++ = 0;
 107         *buff++ = 0;
 108         *buff++ = NR_PROTOEXT;
 109 
 110         if (daddr != NULL)
 111                 return 37;
 112         
 113         return -37;     
 114 }
 115 
 116 static int nr_rebuild_header(void *buff, struct device *dev,
     /* [previous][next][first][last][top][bottom][index][help] */
 117         unsigned long raddr, struct sk_buff *skb)
 118 {
 119         unsigned char *bp = (unsigned char *)buff;
 120 
 121         if (arp_find(bp + 24, raddr, dev, dev->pa_addr, skb))
 122                 return 1;
 123 
 124         bp[23] &= ~LAPB_C;
 125         bp[23] &= ~LAPB_E;
 126         bp[23] |= SSID_SPARE;
 127         
 128         bp[30] &= ~LAPB_C;
 129         bp[30] |= LAPB_E;
 130         bp[30] |= SSID_SPARE;
 131 
 132         return 0;
 133 }
 134 
 135 static int nr_set_mac_address(struct device *dev, void *addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 136 {
 137         memcpy(dev->dev_addr, addr, dev->addr_len);
 138 
 139         return 0;
 140 }
 141 
 142 static int nr_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 143 {
 144         dev->tbusy = 0;
 145         dev->start = 1;
 146 
 147         return 0;
 148 }
 149 
 150 static int nr_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 151 {
 152         dev->tbusy = 1;
 153         dev->start = 0;
 154 
 155         return 0;
 156 }
 157 
 158 static int nr_xmit(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 159 {
 160         struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
 161         struct sk_buff *skbn;
 162 
 163         if (skb == NULL || dev == NULL)
 164                 return 0;
 165 
 166         if (!dev->start) {
 167                 printk("netrom: xmit call when iface is down\n");
 168                 return 1;
 169         }
 170 
 171         cli();
 172 
 173         if (dev->tbusy != 0) {
 174                 sti();
 175                 stats->tx_errors++;
 176                 return 1;
 177         }
 178 
 179         dev->tbusy = 1;
 180 
 181         sti();
 182 
 183         if (skb->data[0] != 0xFF && skb->data[1] != 0xFE) {
 184                 if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
 185                         dev->tbusy = 0;
 186                         stats->tx_errors++;
 187                         return 1;
 188                 }
 189 
 190                 if (!nr_route_frame(skbn, NULL)) {
 191                         skbn->free = 1;
 192                         kfree_skb(skbn, FREE_WRITE);
 193                         dev->tbusy = 0;
 194                         stats->tx_errors++;
 195                         return 1;
 196                 }
 197         }
 198 
 199         dev_kfree_skb(skb, FREE_WRITE);
 200 
 201         stats->tx_packets++;
 202 
 203         dev->tbusy = 0;
 204 
 205         mark_bh(NET_BH);
 206 
 207         return 0;
 208 }
 209 
 210 static struct enet_statistics *nr_get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 211 {
 212         return (struct enet_statistics *)dev->priv;
 213 }
 214 
 215 int nr_init(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 216 {
 217         int i;
 218 
 219         dev->mtu                = 236;          /* MTU                  */
 220         dev->tbusy              = 0;
 221         dev->hard_start_xmit    = nr_xmit;
 222         dev->open               = nr_open;
 223         dev->stop               = nr_close;
 224 
 225         dev->hard_header        = nr_header;
 226         dev->hard_header_len    = 37;
 227         dev->addr_len           = 7;
 228         dev->type               = ARPHRD_NETROM;
 229         dev->rebuild_header     = nr_rebuild_header;
 230         dev->set_mac_address    = nr_set_mac_address;
 231 
 232         /* New-style flags. */
 233         dev->flags              = 0;
 234         dev->family             = AF_INET;
 235 
 236         dev->pa_addr            = 0;
 237         dev->pa_brdaddr         = 0;
 238         dev->pa_mask            = 0;
 239         dev->pa_alen            = sizeof(unsigned long);
 240 
 241         dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL);
 242 
 243         memset(dev->priv, 0, sizeof(struct enet_statistics));
 244 
 245         dev->get_stats = nr_get_stats;
 246 
 247         /* Fill in the generic fields of the device structure. */
 248         for (i = 0; i < DEV_NUMBUFFS; i++)
 249                 skb_queue_head_init(&dev->buffs[i]);
 250 
 251         return 0;
 252 };
 253 
 254 #endif

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