Import 2.3.10pre5
[davej-history.git] / drivers / net / hamradio / bpqether.c
blob18a7bce2381146a8c83ff2bfe672d0609c211765
1 /*
2 * G8BPQ compatible "AX.25 via ethernet" driver release 003
4 * This code REQUIRES 2.0.0 or higher/ NET3.029
6 * This module:
7 * This module is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
12 * This is a "pseudo" network driver to allow AX.25 over Ethernet
13 * using G8BPQ encapsulation. It has been extracted from the protocol
14 * implementation because
16 * - things got unreadable within the protocol stack
17 * - to cure the protocol stack from "feature-ism"
18 * - a protocol implementation shouldn't need to know on
19 * which hardware it is running
20 * - user-level programs like the AX.25 utilities shouldn't
21 * need to know about the hardware.
22 * - IP over ethernet encapsulated AX.25 was impossible
23 * - rxecho.c did not work
24 * - to have room for extensions
25 * - it just deserves to "live" as an own driver
27 * This driver can use any ethernet destination address, and can be
28 * limited to accept frames from one dedicated ethernet card only.
30 * Note that the driver sets up the BPQ devices automagically on
31 * startup or (if started before the "insmod" of an ethernet device)
32 * on "ifconfig up". It hopefully will remove the BPQ on "rmmod"ing
33 * the ethernet device (in fact: as soon as another ethernet or bpq
34 * device gets "ifconfig"ured).
36 * I have heard that several people are thinking of experiments
37 * with highspeed packet radio using existing ethernet cards.
38 * Well, this driver is prepared for this purpose, just add
39 * your tx key control and a txdelay / tailtime algorithm,
40 * probably some buffering, and /voila/...
42 * History
43 * BPQ 001 Joerg(DL1BKE) Extracted BPQ code from AX.25
44 * protocol stack and added my own
45 * yet existing patches
46 * BPQ 002 Joerg(DL1BKE) Scan network device list on
47 * startup.
48 * BPQ 003 Joerg(DL1BKE) Ethernet destination address
49 * and accepted source address
50 * can be configured by an ioctl()
51 * call.
52 * Fixed to match Linux networking
53 * changes - 2.1.15.
54 * BPQ 004 Joerg(DL1BKE) Fixed to not lock up on ifconfig.
57 #include <linux/config.h>
58 #include <linux/errno.h>
59 #include <linux/types.h>
60 #include <linux/socket.h>
61 #include <linux/in.h>
62 #include <linux/kernel.h>
63 #include <linux/string.h>
64 #include <linux/net.h>
65 #include <net/ax25.h>
66 #include <linux/inet.h>
67 #include <linux/netdevice.h>
68 #include <linux/if_arp.h>
69 #include <linux/skbuff.h>
70 #include <net/sock.h>
71 #include <asm/segment.h>
72 #include <asm/system.h>
73 #include <asm/uaccess.h>
74 #include <linux/mm.h>
75 #include <linux/interrupt.h>
76 #include <linux/notifier.h>
77 #include <linux/proc_fs.h>
78 #include <linux/stat.h>
79 #include <linux/firewall.h>
80 #include <linux/module.h>
81 #include <linux/init.h>
82 #include <linux/rtnetlink.h>
84 #include <net/ip.h>
85 #include <net/arp.h>
87 #include <linux/bpqether.h>
89 static unsigned char ax25_bcast[AX25_ADDR_LEN] =
90 {'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, '0' << 1};
91 static unsigned char ax25_defaddr[AX25_ADDR_LEN] =
92 {'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1, '1' << 1};
94 static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
96 static char bpq_eth_addr[6];
98 static int bpq_rcv(struct sk_buff *, struct device *, struct packet_type *);
99 static int bpq_device_event(struct notifier_block *, unsigned long, void *);
100 static char *bpq_print_ethaddr(unsigned char *);
102 static struct packet_type bpq_packet_type = {
103 0, /* ntohs(ETH_P_BPQ),*/
104 0, /* copy */
105 bpq_rcv,
106 NULL,
107 NULL,
110 static struct notifier_block bpq_dev_notifier = {
111 bpq_device_event,
116 #define MAXBPQDEV 100
118 static struct bpqdev {
119 struct bpqdev *next;
120 char ethname[14]; /* ether device name */
121 struct device *ethdev; /* link to ethernet device */
122 struct device axdev; /* bpq device (bpq#) */
123 struct net_device_stats stats; /* some statistics */
124 char dest_addr[6]; /* ether destination address */
125 char acpt_addr[6]; /* accept ether frames from this address only */
126 } *bpq_devices = NULL;
129 /* ------------------------------------------------------------------------ */
133 * Get the ethernet device for a BPQ device
135 static __inline__ struct device *bpq_get_ether_dev(struct device *dev)
137 struct bpqdev *bpq;
139 bpq = (struct bpqdev *)dev->priv;
141 return (bpq != NULL) ? bpq->ethdev : NULL;
145 * Get the BPQ device for the ethernet device
147 static __inline__ struct device *bpq_get_ax25_dev(struct device *dev)
149 struct bpqdev *bpq;
151 for (bpq = bpq_devices; bpq != NULL; bpq = bpq->next)
152 if (bpq->ethdev == dev)
153 return &bpq->axdev;
155 return NULL;
158 static __inline__ int dev_is_ethdev(struct device *dev)
160 return (
161 dev->type == ARPHRD_ETHER
162 && strncmp(dev->name, "dummy", 5)
167 * Sanity check: remove all devices that ceased to exists and
168 * return '1' if the given BPQ device was affected.
170 static int bpq_check_devices(struct device *dev)
172 struct bpqdev *bpq, *bpq_prev;
173 int result = 0;
174 unsigned long flags;
176 save_flags(flags);
177 cli();
179 bpq_prev = NULL;
181 for (bpq = bpq_devices; bpq != NULL; bpq = bpq->next) {
182 if (!dev_get(bpq->ethname)) {
183 if (bpq_prev)
184 bpq_prev->next = bpq->next;
185 else
186 bpq_devices = bpq->next;
188 if (&bpq->axdev == dev)
189 result = 1;
191 /* We should be locked, call
192 * unregister_netdevice directly
195 unregister_netdevice(&bpq->axdev);
196 kfree(bpq);
199 bpq_prev = bpq;
202 restore_flags(flags);
204 return result;
208 /* ------------------------------------------------------------------------ */
212 * Receive an AX.25 frame via an ethernet interface.
214 static int bpq_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *ptype)
216 int len;
217 char * ptr;
218 struct ethhdr *eth = (struct ethhdr *)skb->mac.raw;
219 struct bpqdev *bpq;
221 skb->sk = NULL; /* Initially we don't know who it's for */
223 dev = bpq_get_ax25_dev(dev);
225 if (dev == NULL || dev->start == 0) {
226 kfree_skb(skb);
227 return 0;
231 * if we want to accept frames from just one ethernet device
232 * we check the source address of the sender.
235 bpq = (struct bpqdev *)dev->priv;
237 if (!(bpq->acpt_addr[0] & 0x01) && memcmp(eth->h_source, bpq->acpt_addr, ETH_ALEN)) {
238 printk(KERN_DEBUG "bpqether: wrong dest %s\n", bpq_print_ethaddr(eth->h_source));
239 kfree_skb(skb);
240 return 0;
243 len = skb->data[0] + skb->data[1] * 256 - 5;
245 skb_pull(skb, 2); /* Remove the length bytes */
246 skb_trim(skb, len); /* Set the length of the data */
248 ((struct bpqdev *)dev->priv)->stats.rx_packets++;
249 ((struct bpqdev *)dev->priv)->stats.rx_bytes+=len;
251 ptr = skb_push(skb, 1);
252 *ptr = 0;
254 skb->dev = dev;
255 skb->protocol = htons(ETH_P_AX25);
256 skb->mac.raw = skb->data;
257 skb->pkt_type = PACKET_HOST;
259 netif_rx(skb);
261 return 0;
265 * Send an AX.25 frame via an ethernet interface
267 static int bpq_xmit(struct sk_buff *skb, struct device *dev)
269 struct sk_buff *newskb;
270 unsigned char *ptr;
271 struct bpqdev *bpq;
272 int size;
275 * Just to be *really* sure not to send anything if the interface
276 * is down, the ethernet device may have gone.
278 if (!dev->start) {
279 bpq_check_devices(dev);
280 kfree_skb(skb);
281 return -ENODEV;
284 skb_pull(skb, 1);
285 size = skb->len;
288 * The AX.25 code leaves enough room for the ethernet header, but
289 * sendto() does not.
291 if (skb_headroom(skb) < AX25_BPQ_HEADER_LEN) { /* Ough! */
292 if ((newskb = skb_realloc_headroom(skb, AX25_BPQ_HEADER_LEN)) == NULL) {
293 printk(KERN_WARNING "bpqether: out of memory\n");
294 kfree_skb(skb);
295 return -ENOMEM;
298 if (skb->sk != NULL)
299 skb_set_owner_w(newskb, skb->sk);
301 kfree_skb(skb);
302 skb = newskb;
305 skb->protocol = htons(ETH_P_AX25);
307 ptr = skb_push(skb, 2);
309 *ptr++ = (size + 5) % 256;
310 *ptr++ = (size + 5) / 256;
312 bpq = (struct bpqdev *)dev->priv;
314 if ((dev = bpq_get_ether_dev(dev)) == NULL) {
315 bpq->stats.tx_dropped++;
316 kfree_skb(skb);
317 return -ENODEV;
320 skb->dev = dev;
321 skb->nh.raw = skb->data;
322 dev->hard_header(skb, dev, ETH_P_BPQ, bpq->dest_addr, NULL, 0);
323 bpq->stats.tx_packets++;
324 bpq->stats.tx_bytes+=skb->len;
326 dev_queue_xmit(skb);
328 return 0;
332 * Statistics
334 static struct net_device_stats *bpq_get_stats(struct device *dev)
336 struct bpqdev *bpq;
338 bpq = (struct bpqdev *)dev->priv;
340 return &bpq->stats;
344 * Set AX.25 callsign
346 static int bpq_set_mac_address(struct device *dev, void *addr)
348 struct sockaddr *sa = (struct sockaddr *)addr;
350 memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
352 return 0;
355 /* Ioctl commands
357 * SIOCSBPQETHOPT reserved for enhancements
358 * SIOCSBPQETHADDR set the destination and accepted
359 * source ethernet address (broadcast
360 * or multicast: accept all)
362 static int bpq_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
364 int err;
365 struct bpq_ethaddr *ethaddr = (struct bpq_ethaddr *)ifr->ifr_data;
366 struct bpqdev *bpq = dev->priv;
367 struct bpq_req req;
369 if (!suser())
370 return -EPERM;
372 if (bpq == NULL) /* woops! */
373 return -ENODEV;
375 switch (cmd) {
376 case SIOCSBPQETHOPT:
377 if ((err = verify_area(VERIFY_WRITE, ifr->ifr_data, sizeof(struct bpq_req))) != 0)
378 return err;
379 copy_from_user(&req, ifr->ifr_data, sizeof(struct bpq_req));
380 switch (req.cmd) {
381 case SIOCGBPQETHPARAM:
382 case SIOCSBPQETHPARAM:
383 default:
384 return -EINVAL;
387 break;
389 case SIOCSBPQETHADDR:
390 if ((err = verify_area(VERIFY_READ, ethaddr, sizeof(struct bpq_ethaddr))) != 0)
391 return err;
392 copy_from_user(bpq->dest_addr, ethaddr->destination, ETH_ALEN);
393 copy_from_user(bpq->acpt_addr, ethaddr->accept, ETH_ALEN);
394 break;
396 default:
397 return -EINVAL;
400 return 0;
404 * open/close a device
406 static int bpq_open(struct device *dev)
408 if (bpq_check_devices(dev))
409 return -ENODEV; /* oops, it's gone */
411 dev->tbusy = 0;
412 dev->start = 1;
414 MOD_INC_USE_COUNT;
416 return 0;
419 static int bpq_close(struct device *dev)
421 dev->tbusy = 1;
422 dev->start = 0;
424 MOD_DEC_USE_COUNT;
426 return 0;
430 * currently unused
432 static int bpq_dev_init(struct device *dev)
434 return 0;
438 /* ------------------------------------------------------------------------ */
442 * Proc filesystem
444 static char * bpq_print_ethaddr(unsigned char *e)
446 static char buf[18];
448 sprintf(buf, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
449 e[0], e[1], e[2], e[3], e[4], e[5]);
451 return buf;
454 int bpq_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
456 struct bpqdev *bpqdev;
457 int len = 0;
458 off_t pos = 0;
459 off_t begin = 0;
461 cli();
463 len += sprintf(buffer, "dev ether destination accept from\n");
465 for (bpqdev = bpq_devices; bpqdev != NULL; bpqdev = bpqdev->next) {
466 len += sprintf(buffer + len, "%-5s %-10s %s ",
467 bpqdev->axdev.name, bpqdev->ethname,
468 bpq_print_ethaddr(bpqdev->dest_addr));
470 len += sprintf(buffer + len, "%s\n",
471 (bpqdev->acpt_addr[0] & 0x01) ? "*" : bpq_print_ethaddr(bpqdev->acpt_addr));
473 pos = begin + len;
475 if (pos < offset) {
476 len = 0;
477 begin = pos;
480 if (pos > offset + length)
481 break;
484 sti();
486 *start = buffer + (offset - begin);
487 len -= (offset - begin);
489 if (len > length) len = length;
491 return len;
495 /* ------------------------------------------------------------------------ */
499 * Setup a new device.
501 static int bpq_new_device(struct device *dev)
503 int k;
504 unsigned char *buf;
505 struct bpqdev *bpq, *bpq2;
507 if ((bpq = kmalloc(sizeof(struct bpqdev), GFP_KERNEL)) == NULL)
508 return -ENOMEM;
510 memset(bpq, 0, sizeof(struct bpqdev));
512 bpq->ethdev = dev;
514 bpq->ethname[sizeof(bpq->ethname)-1] = '\0';
515 strncpy(bpq->ethname, dev->name, sizeof(bpq->ethname)-1);
517 memcpy(bpq->dest_addr, bcast_addr, sizeof(bpq_eth_addr));
518 memcpy(bpq->acpt_addr, bcast_addr, sizeof(bpq_eth_addr));
520 dev = &bpq->axdev;
521 buf = kmalloc(14, GFP_KERNEL);
523 for (k = 0; k < MAXBPQDEV; k++) {
524 struct device *odev;
526 sprintf(buf, "bpq%d", k);
528 if ((odev = dev_get(buf)) == NULL || bpq_check_devices(odev))
529 break;
532 if (k == MAXBPQDEV) {
533 kfree(bpq);
534 return -ENODEV;
537 dev->priv = (void *)bpq; /* pointer back */
538 dev->name = buf;
539 dev->init = bpq_dev_init;
541 /* We should be locked, call register_netdevice() directly. */
543 if (register_netdevice(dev) != 0) {
544 kfree(bpq);
545 return -EIO;
548 dev_init_buffers(dev);
550 dev->hard_start_xmit = bpq_xmit;
551 dev->open = bpq_open;
552 dev->stop = bpq_close;
553 dev->set_mac_address = bpq_set_mac_address;
554 dev->get_stats = bpq_get_stats;
555 dev->do_ioctl = bpq_ioctl;
557 memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN);
558 memcpy(dev->dev_addr, ax25_defaddr, AX25_ADDR_LEN);
560 dev->flags = 0;
562 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
563 dev->hard_header = ax25_encapsulate;
564 dev->rebuild_header = ax25_rebuild_header;
565 #endif
567 dev->type = ARPHRD_AX25;
568 dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
569 dev->mtu = AX25_DEF_PACLEN;
570 dev->addr_len = AX25_ADDR_LEN;
572 cli();
574 if (bpq_devices == NULL) {
575 bpq_devices = bpq;
576 } else {
577 for (bpq2 = bpq_devices; bpq2->next != NULL; bpq2 = bpq2->next);
578 bpq2->next = bpq;
581 sti();
583 return 0;
588 * Handle device status changes.
590 static int bpq_device_event(struct notifier_block *this,unsigned long event, void *ptr)
592 struct device *dev = (struct device *)ptr;
594 if (!dev_is_ethdev(dev))
595 return NOTIFY_DONE;
597 bpq_check_devices(NULL);
599 switch (event) {
600 case NETDEV_UP: /* new ethernet device -> new BPQ interface */
601 if (bpq_get_ax25_dev(dev) == NULL)
602 bpq_new_device(dev);
603 break;
605 case NETDEV_DOWN: /* ethernet device closed -> close BPQ interface */
606 if ((dev = bpq_get_ax25_dev(dev)) != NULL)
607 dev_close(dev);
608 break;
610 default:
611 break;
614 return NOTIFY_DONE;
618 /* ------------------------------------------------------------------------ */
621 * Initialize driver. To be called from af_ax25 if not compiled as a
622 * module
624 int __init bpq_init(void)
626 struct device *dev;
628 bpq_packet_type.type = htons(ETH_P_BPQ);
629 dev_add_pack(&bpq_packet_type);
631 register_netdevice_notifier(&bpq_dev_notifier);
633 printk(KERN_INFO "AX.25 ethernet driver version 0.01\n");
635 #ifdef CONFIG_PROC_FS
636 proc_net_register(&(struct proc_dir_entry) {
637 PROC_NET_AX25_BPQETHER, 8, "bpqether",
638 S_IFREG | S_IRUGO, 1, 0, 0,
639 0, &proc_net_inode_operations,
640 bpq_get_info
642 #endif
644 read_lock_bh(&dev_base_lock);
645 for (dev = dev_base; dev != NULL; dev = dev->next) {
646 if (dev_is_ethdev(dev)) {
647 read_unlock_bh(&dev_base_lock);
648 bpq_new_device(dev);
649 read_lock_bh(&dev_base_lock);
652 read_unlock_bh(&dev_base_lock);
653 out:
654 return 0;
657 #ifdef MODULE
658 EXPORT_NO_SYMBOLS;
660 MODULE_AUTHOR("Joerg Reuter DL1BKE <jreuter@lykos.oche.de>");
661 MODULE_DESCRIPTION("Transmit and receive AX.25 packets over Ethernet");
663 int init_module(void)
665 return bpq_init();
668 void cleanup_module(void)
670 struct bpqdev *bpq;
672 dev_remove_pack(&bpq_packet_type);
674 unregister_netdevice_notifier(&bpq_dev_notifier);
676 #ifdef CONFIG_PROC_FS
677 proc_net_unregister(PROC_NET_AX25_BPQETHER);
678 #endif
680 for (bpq = bpq_devices; bpq != NULL; bpq = bpq->next)
681 unregister_netdev(&bpq->axdev);
683 #endif