bpqether.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:15k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * G8BPQ compatible "AX.25 via ethernet" driver release 004
  3.  *
  4.  * This code REQUIRES 2.0.0 or higher/ NET3.029
  5.  *
  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.
  11.  *
  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
  15.  *
  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
  26.  *
  27.  * This driver can use any ethernet destination address, and can be
  28.  * limited to accept frames from one dedicated ethernet card only.
  29.  *
  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).
  35.  *
  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/...
  41.  *
  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.
  55.  */
  56. #include <linux/config.h>
  57. #include <linux/errno.h>
  58. #include <linux/types.h>
  59. #include <linux/socket.h>
  60. #include <linux/in.h>
  61. #include <linux/kernel.h>
  62. #include <linux/string.h>
  63. #include <linux/net.h>
  64. #include <net/ax25.h>
  65. #include <linux/inet.h>
  66. #include <linux/netdevice.h>
  67. #include <linux/if_ether.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/netfilter.h>
  80. #include <linux/module.h>
  81. #include <linux/init.h>
  82. #include <linux/rtnetlink.h>
  83. #include <net/ip.h>
  84. #include <net/arp.h>
  85. #include <linux/bpqether.h>
  86. static char banner[] __initdata = KERN_INFO "AX.25: bpqether driver version 004n";
  87. static unsigned char ax25_bcast[AX25_ADDR_LEN] =
  88. {'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, '0' << 1};
  89. static unsigned char ax25_defaddr[AX25_ADDR_LEN] =
  90. {'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1, '1' << 1};
  91. static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
  92. static char bpq_eth_addr[6];
  93. static int bpq_rcv(struct sk_buff *, struct net_device *, struct packet_type *);
  94. static int bpq_device_event(struct notifier_block *, unsigned long, void *);
  95. static char *bpq_print_ethaddr(unsigned char *);
  96. static struct packet_type bpq_packet_type = {
  97. type: __constant_htons(ETH_P_BPQ),
  98. func: bpq_rcv,
  99. };
  100. static struct notifier_block bpq_dev_notifier = {
  101. notifier_call: bpq_device_event,
  102. };
  103. #define MAXBPQDEV 100
  104. static struct bpqdev {
  105. struct bpqdev *next;
  106. char   ethname[14]; /* ether device name */
  107. struct net_device *ethdev; /* link to ethernet device */
  108. struct net_device axdev; /* bpq device (bpq#) */
  109. struct net_device_stats stats; /* some statistics */
  110. char   dest_addr[6]; /* ether destination address */
  111. char   acpt_addr[6]; /* accept ether frames from this address only */
  112. } *bpq_devices;
  113. /* ------------------------------------------------------------------------ */
  114. /*
  115.  * Get the ethernet device for a BPQ device
  116.  */
  117. static inline struct net_device *bpq_get_ether_dev(struct net_device *dev)
  118. {
  119. struct bpqdev *bpq = (struct bpqdev *) dev->priv;
  120. return bpq ? bpq->ethdev : NULL;
  121. }
  122. /*
  123.  * Get the BPQ device for the ethernet device
  124.  */
  125. static inline struct net_device *bpq_get_ax25_dev(struct net_device *dev)
  126. {
  127. struct bpqdev *bpq;
  128. for (bpq = bpq_devices; bpq != NULL; bpq = bpq->next)
  129. if (bpq->ethdev == dev)
  130. return &bpq->axdev;
  131. return NULL;
  132. }
  133. static inline int dev_is_ethdev(struct net_device *dev)
  134. {
  135. return (
  136. dev->type == ARPHRD_ETHER
  137. && strncmp(dev->name, "dummy", 5)
  138. );
  139. }
  140. /*
  141.  * Sanity check: remove all devices that ceased to exists and
  142.  * return '1' if the given BPQ device was affected.
  143.  */
  144. static int bpq_check_devices(struct net_device *dev)
  145. {
  146. struct bpqdev *bpq, *bpq_prev, *bpq_next;
  147. int result = 0;
  148. unsigned long flags;
  149. save_flags(flags);
  150. cli();
  151. bpq_prev = NULL;
  152. for (bpq = bpq_devices; bpq != NULL; bpq = bpq_next) {
  153. bpq_next = bpq->next;
  154. if (!dev_get(bpq->ethname)) {
  155. if (bpq_prev)
  156. bpq_prev->next = bpq->next;
  157. else
  158. bpq_devices = bpq->next;
  159. if (&bpq->axdev == dev)
  160. result = 1;
  161. /* We should be locked, call 
  162.  * unregister_netdevice directly 
  163.  */
  164. unregister_netdevice(&bpq->axdev);
  165. kfree(bpq);
  166. }
  167. else
  168. bpq_prev = bpq;
  169. }
  170. restore_flags(flags);
  171. return result;
  172. }
  173. /* ------------------------------------------------------------------------ */
  174. /*
  175.  * Receive an AX.25 frame via an ethernet interface.
  176.  */
  177. static int bpq_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype)
  178. {
  179. int len;
  180. char * ptr;
  181. struct ethhdr *eth = (struct ethhdr *)skb->mac.raw;
  182. struct bpqdev *bpq;
  183. skb->sk = NULL; /* Initially we don't know who it's for */
  184. dev = bpq_get_ax25_dev(dev);
  185. if (dev == NULL || !netif_running(dev)) {
  186. kfree_skb(skb);
  187. return 0;
  188. }
  189. /*
  190.  * if we want to accept frames from just one ethernet device
  191.  * we check the source address of the sender.
  192.  */
  193. bpq = (struct bpqdev *)dev->priv;
  194. if (!(bpq->acpt_addr[0] & 0x01) && memcmp(eth->h_source, bpq->acpt_addr, ETH_ALEN)) {
  195. printk(KERN_DEBUG "bpqether: wrong dest %sn", bpq_print_ethaddr(eth->h_source));
  196. kfree_skb(skb);
  197. return 0;
  198. }
  199. len = skb->data[0] + skb->data[1] * 256 - 5;
  200. skb_pull(skb, 2); /* Remove the length bytes */
  201. skb_trim(skb, len); /* Set the length of the data */
  202. bpq->stats.rx_packets++;
  203. bpq->stats.rx_bytes += len;
  204. ptr = skb_push(skb, 1);
  205. *ptr = 0;
  206. skb->dev = dev;
  207. skb->protocol = htons(ETH_P_AX25);
  208. skb->mac.raw = skb->data;
  209. skb->pkt_type = PACKET_HOST;
  210. netif_rx(skb);
  211. return 0;
  212. }
  213. /*
  214.  *  Send an AX.25 frame via an ethernet interface
  215.  */
  216. static int bpq_xmit(struct sk_buff *skb, struct net_device *dev)
  217. {
  218. struct sk_buff *newskb;
  219. unsigned char *ptr;
  220. struct bpqdev *bpq;
  221. int size;
  222. /*
  223.  * Just to be *really* sure not to send anything if the interface
  224.  * is down, the ethernet device may have gone.
  225.  */
  226. if (!netif_running(dev)) {
  227. bpq_check_devices(dev);
  228. kfree_skb(skb);
  229. return -ENODEV;
  230. }
  231. skb_pull(skb, 1);
  232. size = skb->len;
  233. /*
  234.  * The AX.25 code leaves enough room for the ethernet header, but
  235.  * sendto() does not.
  236.  */
  237. if (skb_headroom(skb) < AX25_BPQ_HEADER_LEN) { /* Ough! */
  238. if ((newskb = skb_realloc_headroom(skb, AX25_BPQ_HEADER_LEN)) == NULL) {
  239. printk(KERN_WARNING "bpqether: out of memoryn");
  240. kfree_skb(skb);
  241. return -ENOMEM;
  242. }
  243. if (skb->sk != NULL)
  244. skb_set_owner_w(newskb, skb->sk);
  245. kfree_skb(skb);
  246. skb = newskb;
  247. }
  248. skb->protocol = htons(ETH_P_AX25);
  249. ptr = skb_push(skb, 2);
  250. *ptr++ = (size + 5) % 256;
  251. *ptr++ = (size + 5) / 256;
  252. bpq = (struct bpqdev *)dev->priv;
  253. if ((dev = bpq_get_ether_dev(dev)) == NULL) {
  254. bpq->stats.tx_dropped++;
  255. kfree_skb(skb);
  256. return -ENODEV;
  257. }
  258. skb->dev = dev;
  259. skb->nh.raw = skb->data;
  260. dev->hard_header(skb, dev, ETH_P_BPQ, bpq->dest_addr, NULL, 0);
  261. bpq->stats.tx_packets++;
  262. bpq->stats.tx_bytes+=skb->len;
  263.   
  264. dev_queue_xmit(skb);
  265. netif_wake_queue(dev);
  266. return 0;
  267. }
  268. /*
  269.  * Statistics
  270.  */
  271. static struct net_device_stats *bpq_get_stats(struct net_device *dev)
  272. {
  273. struct bpqdev *bpq = (struct bpqdev *) dev->priv;
  274. return &bpq->stats;
  275. }
  276. /*
  277.  * Set AX.25 callsign
  278.  */
  279. static int bpq_set_mac_address(struct net_device *dev, void *addr)
  280. {
  281.     struct sockaddr *sa = (struct sockaddr *)addr;
  282.     memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
  283.     return 0;
  284. }
  285. /* Ioctl commands
  286.  *
  287.  * SIOCSBPQETHOPT reserved for enhancements
  288.  * SIOCSBPQETHADDR set the destination and accepted
  289.  * source ethernet address (broadcast
  290.  * or multicast: accept all)
  291.  */
  292. static int bpq_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
  293. {
  294. struct bpq_ethaddr *ethaddr = (struct bpq_ethaddr *)ifr->ifr_data;
  295. struct bpqdev *bpq = dev->priv;
  296. struct bpq_req req;
  297. if (!capable(CAP_NET_ADMIN))
  298. return -EPERM;
  299. if (bpq == NULL) /* woops! */
  300. return -ENODEV;
  301. switch (cmd) {
  302. case SIOCSBPQETHOPT:
  303. if (copy_from_user(&req, ifr->ifr_data, sizeof(struct bpq_req)))
  304. return -EFAULT;
  305. switch (req.cmd) {
  306. case SIOCGBPQETHPARAM:
  307. case SIOCSBPQETHPARAM:
  308. default:
  309. return -EINVAL;
  310. }
  311. break;
  312. case SIOCSBPQETHADDR:
  313. if (copy_from_user(bpq->dest_addr, ethaddr->destination, ETH_ALEN))
  314. return -EFAULT;
  315. if (copy_from_user(bpq->acpt_addr, ethaddr->accept, ETH_ALEN))
  316. return -EFAULT;
  317. break;
  318. default:
  319. return -EINVAL;
  320. }
  321. return 0;
  322. }
  323. /*
  324.  * open/close a device
  325.  */
  326. static int bpq_open(struct net_device *dev)
  327. {
  328. if (bpq_check_devices(dev))
  329. return -ENODEV; /* oops, it's gone */
  330. MOD_INC_USE_COUNT;
  331. netif_start_queue(dev);
  332. return 0;
  333. }
  334. static int bpq_close(struct net_device *dev)
  335. {
  336. netif_stop_queue(dev);
  337. MOD_DEC_USE_COUNT;
  338. return 0;
  339. }
  340. /*
  341.  * currently unused
  342.  */
  343. static int bpq_dev_init(struct net_device *dev)
  344. {
  345. return 0;
  346. }
  347. /* ------------------------------------------------------------------------ */
  348. /*
  349.  * Proc filesystem
  350.  */
  351. static char * bpq_print_ethaddr(unsigned char *e)
  352. {
  353. static char buf[18];
  354. sprintf(buf, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
  355. e[0], e[1], e[2], e[3], e[4], e[5]);
  356. return buf;
  357. }
  358. static int bpq_get_info(char *buffer, char **start, off_t offset, int length)
  359. {
  360. struct bpqdev *bpqdev;
  361. int len     = 0;
  362. off_t pos   = 0;
  363. off_t begin = 0;
  364. cli();
  365. len += sprintf(buffer, "dev   ether      destination        accept fromn");
  366. for (bpqdev = bpq_devices; bpqdev != NULL; bpqdev = bpqdev->next) {
  367. len += sprintf(buffer + len, "%-5s %-10s %s  ",
  368. bpqdev->axdev.name, bpqdev->ethname,
  369. bpq_print_ethaddr(bpqdev->dest_addr));
  370. len += sprintf(buffer + len, "%sn",
  371. (bpqdev->acpt_addr[0] & 0x01) ? "*" : bpq_print_ethaddr(bpqdev->acpt_addr));
  372. pos = begin + len;
  373. if (pos < offset) {
  374. len   = 0;
  375. begin = pos;
  376. }
  377. if (pos > offset + length)
  378. break;
  379. }
  380. sti();
  381. *start = buffer + (offset - begin);
  382. len   -= (offset - begin);
  383. if (len > length) len = length;
  384. return len;
  385. }
  386. /* ------------------------------------------------------------------------ */
  387. /*
  388.  * Setup a new device.
  389.  */
  390. static int bpq_new_device(struct net_device *dev)
  391. {
  392. int k;
  393. struct bpqdev *bpq, *bpq2;
  394. if ((bpq = kmalloc(sizeof(struct bpqdev), GFP_KERNEL)) == NULL)
  395. return -ENOMEM;
  396. memset(bpq, 0, sizeof(struct bpqdev));
  397. bpq->ethdev = dev;
  398. bpq->ethname[sizeof(bpq->ethname)-1] = '';
  399. strncpy(bpq->ethname, dev->name, sizeof(bpq->ethname)-1);
  400. memcpy(bpq->dest_addr, bcast_addr, sizeof(bpq_eth_addr));
  401. memcpy(bpq->acpt_addr, bcast_addr, sizeof(bpq_eth_addr));
  402. dev = &bpq->axdev;
  403. for (k = 0; k < MAXBPQDEV; k++) {
  404. struct net_device *odev;
  405. sprintf(dev->name, "bpq%d", k);
  406. if ((odev = __dev_get_by_name(dev->name)) == NULL || bpq_check_devices(odev))
  407. break;
  408. }
  409. if (k == MAXBPQDEV) {
  410. kfree(bpq);
  411. return -ENODEV;
  412. }
  413. dev->priv = (void *)bpq; /* pointer back */
  414. dev->init = bpq_dev_init;
  415. /* We should be locked, call register_netdevice() directly. */
  416. if (register_netdevice(dev) != 0) {
  417. kfree(bpq);
  418.                 return -EIO;
  419.         }
  420. dev->hard_start_xmit = bpq_xmit;
  421. dev->open      = bpq_open;
  422. dev->stop      = bpq_close;
  423. dev->set_mac_address = bpq_set_mac_address;
  424. dev->get_stats      = bpq_get_stats;
  425. dev->do_ioctl      = bpq_ioctl;
  426. memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN);
  427. memcpy(dev->dev_addr,  ax25_defaddr, AX25_ADDR_LEN);
  428. dev->flags      = 0;
  429. #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
  430. dev->hard_header     = ax25_encapsulate;
  431. dev->rebuild_header  = ax25_rebuild_header;
  432. #endif
  433. dev->type            = ARPHRD_AX25;
  434. dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
  435. dev->mtu             = AX25_DEF_PACLEN;
  436. dev->addr_len        = AX25_ADDR_LEN;
  437. cli();
  438. if (bpq_devices == NULL) {
  439. bpq_devices = bpq;
  440. } else {
  441. for (bpq2 = bpq_devices; bpq2->next != NULL; bpq2 = bpq2->next);
  442. bpq2->next = bpq;
  443. }
  444. sti();
  445. return 0;
  446. }
  447. /*
  448.  * Handle device status changes.
  449.  */
  450. static int bpq_device_event(struct notifier_block *this,unsigned long event, void *ptr)
  451. {
  452. struct net_device *dev = (struct net_device *)ptr;
  453. if (!dev_is_ethdev(dev))
  454. return NOTIFY_DONE;
  455. bpq_check_devices(NULL);
  456. switch (event) {
  457. case NETDEV_UP: /* new ethernet device -> new BPQ interface */
  458. if (bpq_get_ax25_dev(dev) == NULL)
  459. bpq_new_device(dev);
  460. break;
  461. case NETDEV_DOWN: /* ethernet device closed -> close BPQ interface */
  462. if ((dev = bpq_get_ax25_dev(dev)) != NULL)
  463. dev_close(dev);
  464. break;
  465. default:
  466. break;
  467. }
  468. return NOTIFY_DONE;
  469. }
  470. /* ------------------------------------------------------------------------ */
  471. /*
  472.  * Initialize driver. To be called from af_ax25 if not compiled as a
  473.  * module
  474.  */
  475. static int __init bpq_init_driver(void)
  476. {
  477. struct net_device *dev;
  478. dev_add_pack(&bpq_packet_type);
  479. register_netdevice_notifier(&bpq_dev_notifier);
  480. printk(banner);
  481. proc_net_create("bpqether", 0, bpq_get_info);
  482. read_lock_bh(&dev_base_lock);
  483. for (dev = dev_base; dev != NULL; dev = dev->next) {
  484. if (dev_is_ethdev(dev)) {
  485. read_unlock_bh(&dev_base_lock);
  486. bpq_new_device(dev);
  487. read_lock_bh(&dev_base_lock);
  488. }
  489. }
  490. read_unlock_bh(&dev_base_lock);
  491. return 0;
  492. }
  493. static void __exit bpq_cleanup_driver(void)
  494. {
  495. struct bpqdev *bpq;
  496. dev_remove_pack(&bpq_packet_type);
  497. unregister_netdevice_notifier(&bpq_dev_notifier);
  498. proc_net_remove("bpqether");
  499. for (bpq = bpq_devices; bpq != NULL; bpq = bpq->next)
  500. unregister_netdev(&bpq->axdev);
  501. }
  502. MODULE_AUTHOR("Joerg Reuter DL1BKE <jreuter@yaina.de>");
  503. MODULE_DESCRIPTION("Transmit and receive AX.25 packets over Ethernet");
  504. MODULE_LICENSE("GPL");
  505. module_init(bpq_init_driver);
  506. module_exit(bpq_cleanup_driver);