2 * "LAPB via ethernet" driver release 001
4 * This code REQUIRES 2.1.15 or higher/ NET3.038
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 LAPB over Ethernet.
14 * This driver can use any ethernet destination address, and can be
15 * limited to accept frames from one dedicated ethernet card only.
18 * LAPBETH 001 Jonathan Naylor Cloned from bpqether.c
21 #include <linux/errno.h>
22 #include <linux/types.h>
23 #include <linux/socket.h>
25 #include <linux/kernel.h>
26 #include <linux/string.h>
27 #include <linux/net.h>
28 #include <linux/inet.h>
29 #include <linux/netdevice.h>
30 #include <linux/if_arp.h>
31 #include <linux/skbuff.h>
33 #include <asm/segment.h>
34 #include <asm/system.h>
35 #include <asm/uaccess.h>
37 #include <linux/interrupt.h>
38 #include <linux/notifier.h>
39 #include <linux/proc_fs.h>
40 #include <linux/stat.h>
41 #include <linux/netfilter.h>
42 #include <linux/module.h>
43 #include <linux/lapb.h>
44 #include <linux/init.h>
46 static char bcast_addr
[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
48 static int lapbeth_rcv(struct sk_buff
*, struct net_device
*, struct packet_type
*);
49 static int lapbeth_device_event(struct notifier_block
*, unsigned long, void *);
51 static struct packet_type lapbeth_packet_type
= {
52 0, /* ntohs(ETH_P_DEC),*/
59 static struct notifier_block lapbeth_dev_notifier
= {
65 #define MAXLAPBDEV 100
67 static struct lapbethdev
{
68 struct lapbethdev
*next
;
69 char ethname
[14]; /* ether device name */
70 struct net_device
*ethdev
; /* link to ethernet device */
71 struct net_device axdev
; /* lapbeth device (lapb#) */
72 struct net_device_stats stats
; /* some statistics */
73 } *lapbeth_devices
= NULL
;
76 /* ------------------------------------------------------------------------ */
80 * Get the ethernet device for a LAPB device
82 static __inline__
struct net_device
*lapbeth_get_ether_dev(struct net_device
*dev
)
84 struct lapbethdev
*lapbeth
;
86 lapbeth
= (struct lapbethdev
*)dev
->priv
;
88 return (lapbeth
!= NULL
) ? lapbeth
->ethdev
: NULL
;
92 * Get the LAPB device for the ethernet device
94 static __inline__
struct net_device
*lapbeth_get_x25_dev(struct net_device
*dev
)
96 struct lapbethdev
*lapbeth
;
98 for (lapbeth
= lapbeth_devices
; lapbeth
!= NULL
; lapbeth
= lapbeth
->next
)
99 if (lapbeth
->ethdev
== dev
)
100 return &lapbeth
->axdev
;
105 static __inline__
int dev_is_ethdev(struct net_device
*dev
)
108 dev
->type
== ARPHRD_ETHER
109 && strncmp(dev
->name
, "dummy", 5)
114 * Sanity check: remove all devices that ceased to exists and
115 * return '1' if the given LAPB device was affected.
117 static int lapbeth_check_devices(struct net_device
*dev
)
119 struct lapbethdev
*lapbeth
, *lapbeth_prev
;
128 for (lapbeth
= lapbeth_devices
; lapbeth
!= NULL
; lapbeth
= lapbeth
->next
) {
129 if (!dev_get(lapbeth
->ethname
)) {
131 lapbeth_prev
->next
= lapbeth
->next
;
133 lapbeth_devices
= lapbeth
->next
;
135 if (&lapbeth
->axdev
== dev
)
138 unregister_netdev(&lapbeth
->axdev
);
142 lapbeth_prev
= lapbeth
;
145 restore_flags(flags
);
151 /* ------------------------------------------------------------------------ */
155 * Receive a LAPB frame via an ethernet interface.
157 static int lapbeth_rcv(struct sk_buff
*skb
, struct net_device
*dev
, struct packet_type
*ptype
)
160 struct lapbethdev
*lapbeth
;
162 skb
->sk
= NULL
; /* Initially we don't know who it's for */
164 dev
= lapbeth_get_x25_dev(dev
);
166 if (dev
== NULL
|| dev
->start
== 0) {
171 lapbeth
= (struct lapbethdev
*)dev
->priv
;
173 lapbeth
->stats
.rx_packets
++;
175 len
= skb
->data
[0] + skb
->data
[1] * 256;
177 skb_pull(skb
, 2); /* Remove the length bytes */
178 skb_trim(skb
, len
); /* Set the length of the data */
180 if ((err
= lapb_data_received(lapbeth
, skb
)) != LAPB_OK
) {
182 printk(KERN_DEBUG
"lapbether: lapb_data_received err - %d\n", err
);
188 static void lapbeth_data_indication(void *token
, struct sk_buff
*skb
)
190 struct lapbethdev
*lapbeth
= (struct lapbethdev
*)token
;
193 ptr
= skb_push(skb
, 1);
196 skb
->dev
= &lapbeth
->axdev
;
197 skb
->protocol
= htons(ETH_P_X25
);
198 skb
->mac
.raw
= skb
->data
;
199 skb
->pkt_type
= PACKET_HOST
;
205 * Send a LAPB frame via an ethernet interface
207 static int lapbeth_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
209 struct lapbethdev
*lapbeth
;
212 lapbeth
= (struct lapbethdev
*)dev
->priv
;
215 * Just to be *really* sure not to send anything if the interface
216 * is down, the ethernet device may have gone.
219 lapbeth_check_devices(dev
);
224 switch (skb
->data
[0]) {
228 if ((err
= lapb_connect_request(lapbeth
)) != LAPB_OK
)
229 printk(KERN_ERR
"lapbeth: lapb_connect_request error - %d\n", err
);
233 if ((err
= lapb_disconnect_request(lapbeth
)) != LAPB_OK
)
234 printk(KERN_ERR
"lapbeth: lapb_disconnect_request err - %d\n", err
);
244 if ((err
= lapb_data_request(lapbeth
, skb
)) != LAPB_OK
) {
245 printk(KERN_ERR
"lapbeth: lapb_data_request error - %d\n", err
);
253 static void lapbeth_data_transmit(void *token
, struct sk_buff
*skb
)
255 struct lapbethdev
*lapbeth
= (struct lapbethdev
*)token
;
257 struct net_device
*dev
;
260 skb
->protocol
= htons(ETH_P_X25
);
264 ptr
= skb_push(skb
, 2);
269 lapbeth
->stats
.tx_packets
++;
271 skb
->dev
= dev
= lapbeth
->ethdev
;
273 dev
->hard_header(skb
, dev
, ETH_P_DEC
, bcast_addr
, NULL
, 0);
278 static void lapbeth_connected(void *token
, int reason
)
280 struct lapbethdev
*lapbeth
= (struct lapbethdev
*)token
;
284 if ((skb
= dev_alloc_skb(1)) == NULL
) {
285 printk(KERN_ERR
"lapbeth: out of memory\n");
289 ptr
= skb_put(skb
, 1);
292 skb
->dev
= &lapbeth
->axdev
;
293 skb
->protocol
= htons(ETH_P_X25
);
294 skb
->mac
.raw
= skb
->data
;
295 skb
->pkt_type
= PACKET_HOST
;
300 static void lapbeth_disconnected(void *token
, int reason
)
302 struct lapbethdev
*lapbeth
= (struct lapbethdev
*)token
;
306 if ((skb
= dev_alloc_skb(1)) == NULL
) {
307 printk(KERN_ERR
"lapbeth: out of memory\n");
311 ptr
= skb_put(skb
, 1);
314 skb
->dev
= &lapbeth
->axdev
;
315 skb
->protocol
= htons(ETH_P_X25
);
316 skb
->mac
.raw
= skb
->data
;
317 skb
->pkt_type
= PACKET_HOST
;
325 static struct net_device_stats
*lapbeth_get_stats(struct net_device
*dev
)
327 struct lapbethdev
*lapbeth
;
329 lapbeth
= (struct lapbethdev
*)dev
->priv
;
331 return &lapbeth
->stats
;
337 static int lapbeth_set_mac_address(struct net_device
*dev
, void *addr
)
339 struct sockaddr
*sa
= (struct sockaddr
*)addr
;
341 memcpy(dev
->dev_addr
, sa
->sa_data
, dev
->addr_len
);
346 static int lapbeth_ioctl(struct net_device
*dev
, struct ifreq
*ifr
, int cmd
)
352 * open/close a device
354 static int lapbeth_open(struct net_device
*dev
)
356 struct lapb_register_struct lapbeth_callbacks
;
357 struct lapbethdev
*lapbeth
;
360 if (lapbeth_check_devices(dev
))
361 return -ENODEV
; /* oops, it's gone */
366 lapbeth
= (struct lapbethdev
*)dev
->priv
;
368 lapbeth_callbacks
.connect_confirmation
= lapbeth_connected
;
369 lapbeth_callbacks
.connect_indication
= lapbeth_connected
;
370 lapbeth_callbacks
.disconnect_confirmation
= lapbeth_disconnected
;
371 lapbeth_callbacks
.disconnect_indication
= lapbeth_disconnected
;
372 lapbeth_callbacks
.data_indication
= lapbeth_data_indication
;
373 lapbeth_callbacks
.data_transmit
= lapbeth_data_transmit
;
375 if ((err
= lapb_register(lapbeth
, &lapbeth_callbacks
)) != LAPB_OK
) {
376 printk(KERN_ERR
"lapbeth: lapb_register error - %d\n", err
);
387 static int lapbeth_close(struct net_device
*dev
)
389 struct lapbethdev
*lapbeth
;
395 lapbeth
= (struct lapbethdev
*)dev
->priv
;
397 if ((err
= lapb_unregister(lapbeth
)) != LAPB_OK
)
398 printk(KERN_ERR
"lapbeth: lapb_unregister error - %d\n", err
);
405 static int lapbeth_dev_init(struct net_device
*dev
)
410 /* ------------------------------------------------------------------------ */
413 * Setup a new device.
415 static int lapbeth_new_device(struct net_device
*dev
)
419 struct lapbethdev
*lapbeth
, *lapbeth2
;
421 if ((lapbeth
= kmalloc(sizeof(struct lapbethdev
), GFP_KERNEL
)) == NULL
)
424 memset(lapbeth
, 0, sizeof(struct lapbethdev
));
426 lapbeth
->ethdev
= dev
;
428 lapbeth
->ethname
[sizeof(lapbeth
->ethname
)-1] = '\0';
429 strncpy(lapbeth
->ethname
, dev
->name
, sizeof(lapbeth
->ethname
)-1);
431 dev
= &lapbeth
->axdev
;
432 buf
= kmalloc(14, GFP_KERNEL
);
434 for (k
= 0; k
< MAXLAPBDEV
; k
++) {
435 struct net_device
*odev
;
437 sprintf(buf
, "lapb%d", k
);
439 if ((odev
= __dev_get_by_name(buf
)) == NULL
|| lapbeth_check_devices(odev
))
443 if (k
== MAXLAPBDEV
) {
448 dev
->priv
= (void *)lapbeth
; /* pointer back */
450 dev
->init
= lapbeth_dev_init
;
452 if (register_netdev(dev
) != 0) {
457 dev_init_buffers(dev
);
459 dev
->hard_start_xmit
= lapbeth_xmit
;
460 dev
->open
= lapbeth_open
;
461 dev
->stop
= lapbeth_close
;
462 dev
->set_mac_address
= lapbeth_set_mac_address
;
463 dev
->get_stats
= lapbeth_get_stats
;
464 dev
->do_ioctl
= lapbeth_ioctl
;
468 dev
->type
= ARPHRD_X25
;
469 dev
->hard_header_len
= 3;
475 if (lapbeth_devices
== NULL
) {
476 lapbeth_devices
= lapbeth
;
478 for (lapbeth2
= lapbeth_devices
; lapbeth2
->next
!= NULL
; lapbeth2
= lapbeth2
->next
);
479 lapbeth2
->next
= lapbeth
;
489 * Handle device status changes.
491 static int lapbeth_device_event(struct notifier_block
*this,unsigned long event
, void *ptr
)
493 struct net_device
*dev
= (struct net_device
*)ptr
;
495 if (!dev_is_ethdev(dev
))
498 lapbeth_check_devices(NULL
);
501 case NETDEV_UP
: /* new ethernet device -> new LAPB interface */
502 if (lapbeth_get_x25_dev(dev
) == NULL
)
503 lapbeth_new_device(dev
);
506 case NETDEV_DOWN
: /* ethernet device closed -> close LAPB interface */
507 if ((dev
= lapbeth_get_x25_dev(dev
)) != NULL
)
519 /* ------------------------------------------------------------------------ */
522 * Initialize driver. To be called from af_ax25 if not compiled as a
525 int lapbeth_init(void)
527 struct net_device
*dev
;
529 lapbeth_packet_type
.type
= htons(ETH_P_DEC
);
530 dev_add_pack(&lapbeth_packet_type
);
532 register_netdevice_notifier(&lapbeth_dev_notifier
);
534 printk(KERN_INFO
"LAPB Ethernet driver version 0.01\n");
536 read_lock_bh(&dev_base_lock
);
537 for (dev
= dev_base
; dev
!= NULL
; dev
= dev
->next
) {
538 if (dev_is_ethdev(dev
)) {
539 read_unlock_bh(&dev_base_lock
);
540 lapbeth_new_device(dev
);
541 read_lock_bh(&dev_base_lock
);
544 read_unlock_bh(&dev_base_lock
);
552 MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>");
553 MODULE_DESCRIPTION("The unofficial LAPB over Ethernet driver");
555 int init_module(void)
557 return lapbeth_init();
560 void cleanup_module(void)
562 struct lapbethdev
*lapbeth
;
564 dev_remove_pack(&lapbeth_packet_type
);
566 unregister_netdevice_notifier(&lapbeth_dev_notifier
);
568 for (lapbeth
= lapbeth_devices
; lapbeth
!= NULL
; lapbeth
= lapbeth
->next
)
569 unregister_netdev(&lapbeth
->axdev
);