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

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