wanmain.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:26k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2. * wanmain.c WAN Multiprotocol Router Module. Main code.
  3. *
  4. * This module is completely hardware-independent and provides
  5. * the following common services for the WAN Link Drivers:
  6. *  o WAN device managenment (registering, unregistering)
  7. *  o Network interface management
  8. *  o Physical connection management (dial-up, incoming calls)
  9. *  o Logical connection management (switched virtual circuits)
  10. *  o Protocol encapsulation/decapsulation
  11. *
  12. * Author: Gideon Hack
  13. *
  14. * Copyright: (c) 1995-1999 Sangoma Technologies Inc.
  15. *
  16. * This program is free software; you can redistribute it and/or
  17. * modify it under the terms of the GNU General Public License
  18. * as published by the Free Software Foundation; either version
  19. * 2 of the License, or (at your option) any later version.
  20. * ============================================================================
  21. * Nov 24, 2000  Nenad Corbic Updated for 2.4.X kernels 
  22. * Nov 07, 2000  Nenad Corbic Fixed the Mulit-Port PPP for kernels 2.2.16 and
  23. *   greater.
  24. * Aug 2,  2000  Nenad Corbic Block the Multi-Port PPP from running on
  25. *           kernels 2.2.16 or greater.  The SyncPPP 
  26. *           has changed.
  27. * Jul 13, 2000  Nenad Corbic Added SyncPPP support
  28. *  Added extra debugging in device_setup().
  29. * Oct 01, 1999  Gideon Hack     Update for s514 PCI card
  30. * Dec 27, 1996 Gene Kozin Initial version (based on Sangoma's WANPIPE)
  31. * Jan 16, 1997 Gene Kozin router_devlist made public
  32. * Jan 31, 1997  Alan Cox Hacked it about a bit for 2.1
  33. * Jun 27, 1997  Alan Cox realigned with vendor code
  34. * Oct 15, 1997  Farhan Thawar   changed wan_encapsulate to add a pad byte of 0
  35. * Apr 20, 1998 Alan Cox Fixed 2.1 symbols
  36. * May 17, 1998  K. Baranowski Fixed SNAP encapsulation in wan_encapsulate
  37. * Dec 15, 1998  Arnaldo Melo    support for firmwares of up to 128000 bytes
  38. *                               check wandev->setup return value
  39. * Dec 22, 1998  Arnaldo Melo    vmalloc/vfree used in device_setup to allocate
  40. *                               kernel memory and copy configuration data to
  41. *                               kernel space (for big firmwares)
  42. * Jun 02, 1999  Gideon Hack Updates for Linux 2.0.X and 2.2.X kernels.
  43. *****************************************************************************/
  44. #include <linux/version.h>
  45. #include <linux/config.h>
  46. #include <linux/stddef.h> /* offsetof(), etc. */
  47. #include <linux/errno.h> /* return codes */
  48. #include <linux/kernel.h>
  49. #include <linux/module.h> /* support for loadable modules */
  50. #include <linux/slab.h> /* kmalloc(), kfree() */
  51. #include <linux/mm.h> /* verify_area(), etc. */
  52. #include <linux/string.h> /* inline mem*, str* functions */
  53. #include <asm/byteorder.h> /* htons(), etc. */
  54. #include <linux/wanrouter.h> /* WAN router API definitions */
  55. #if defined(LINUX_2_4)
  56.  #include <linux/vmalloc.h> /* vmalloc, vfree */
  57.  #include <asm/uaccess.h>        /* copy_to/from_user */
  58.  #include <linux/init.h>         /* __initfunc et al. */
  59. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3)
  60.  #include <net/syncppp.h>
  61. #else
  62.  #include <../drivers/net/wan/syncppp.h>
  63. #endif
  64. #elif defined(LINUX_2_1) 
  65.  #define LINUX_2_1
  66.  #include <linux/vmalloc.h> /* vmalloc, vfree */
  67.  #include <asm/uaccess.h>        /* copy_to/from_user */
  68.  #include <linux/init.h>         /* __initfunc et al. */
  69.  #include <../drivers/net/syncppp.h>
  70. #else
  71.  #include <asm/segment.h> /* kernel <-> user copy */
  72. #endif
  73. #define KMEM_SAFETYZONE 8
  74. /***********FOR DEBUGGING PURPOSES*********************************************
  75. static void * dbg_kmalloc(unsigned int size, int prio, int line) {
  76. int i = 0;
  77. void * v = kmalloc(size+sizeof(unsigned int)+2*KMEM_SAFETYZONE*8,prio);
  78. char * c1 = v;
  79. c1 += sizeof(unsigned int);
  80. *((unsigned int *)v) = size;
  81. for (i = 0; i < KMEM_SAFETYZONE; i++) {
  82. c1[0] = 'D'; c1[1] = 'E'; c1[2] = 'A'; c1[3] = 'D';
  83. c1[4] = 'B'; c1[5] = 'E'; c1[6] = 'E'; c1[7] = 'F';
  84. c1 += 8;
  85. }
  86. c1 += size;
  87. for (i = 0; i < KMEM_SAFETYZONE; i++) {
  88. c1[0] = 'M'; c1[1] = 'U'; c1[2] = 'N'; c1[3] = 'G';
  89. c1[4] = 'W'; c1[5] = 'A'; c1[6] = 'L'; c1[7] = 'L';
  90. c1 += 8;
  91. }
  92. v = ((char *)v) + sizeof(unsigned int) + KMEM_SAFETYZONE*8;
  93. printk(KERN_INFO "line %d  kmalloc(%d,%d) = %pn",line,size,prio,v);
  94. return v;
  95. }
  96. static void dbg_kfree(void * v, int line) {
  97. unsigned int * sp = (unsigned int *)(((char *)v) - (sizeof(unsigned int) + KMEM_SAFETYZONE*8));
  98. unsigned int size = *sp;
  99. char * c1 = ((char *)v) - KMEM_SAFETYZONE*8;
  100. int i = 0;
  101. for (i = 0; i < KMEM_SAFETYZONE; i++) {
  102. if (   c1[0] != 'D' || c1[1] != 'E' || c1[2] != 'A' || c1[3] != 'D'
  103.     || c1[4] != 'B' || c1[5] != 'E' || c1[6] != 'E' || c1[7] != 'F') {
  104. printk(KERN_INFO "kmalloced block at %p has been corrupted (underrun)!n",v);
  105. printk(KERN_INFO " %4x: %2x %2x %2x %2x %2x %2x %2x %2xn", i*8,
  106.                 c1[0],c1[1],c1[2],c1[3],c1[4],c1[5],c1[6],c1[7] );
  107. }
  108. c1 += 8;
  109. }
  110. c1 += size;
  111. for (i = 0; i < KMEM_SAFETYZONE; i++) {
  112. if (   c1[0] != 'M' || c1[1] != 'U' || c1[2] != 'N' || c1[3] != 'G'
  113.     || c1[4] != 'W' || c1[5] != 'A' || c1[6] != 'L' || c1[7] != 'L'
  114.    ) {
  115. printk(KERN_INFO "kmalloced block at %p has been corrupted (overrun):n",v);
  116. printk(KERN_INFO " %4x: %2x %2x %2x %2x %2x %2x %2x %2xn", i*8,
  117.                 c1[0],c1[1],c1[2],c1[3],c1[4],c1[5],c1[6],c1[7] );
  118. }
  119. c1 += 8;
  120. }
  121. printk(KERN_INFO "line %d  kfree(%p)n",line,v);
  122. v = ((char *)v) - (sizeof(unsigned int) + KMEM_SAFETYZONE*8);
  123. kfree(v);
  124. }
  125. #define kmalloc(x,y) dbg_kmalloc(x,y,__LINE__)
  126. #define kfree(x) dbg_kfree(x,__LINE__)
  127. *****************************************************************************/
  128. /*
  129.  *  Function Prototypes 
  130.  */
  131. /* 
  132.  *  Kernel loadable module interface.
  133.  */
  134. #ifdef MODULE
  135. int init_module (void);
  136. void cleanup_module (void);
  137. #endif
  138. /* 
  139.  * WAN device IOCTL handlers 
  140.  */
  141. static int device_setup(wan_device_t *wandev, wandev_conf_t *u_conf);
  142. static int device_stat(wan_device_t *wandev, wandev_stat_t *u_stat);
  143. static int device_shutdown(wan_device_t *wandev);
  144. static int device_new_if(wan_device_t *wandev, wanif_conf_t *u_conf);
  145. static int device_del_if(wan_device_t *wandev, char *u_name);
  146.  
  147. /* 
  148.  * Miscellaneous 
  149.  */
  150. static wan_device_t *find_device (char *name);
  151. static int delete_interface (wan_device_t *wandev, char *name);
  152. void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags);
  153. void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags);
  154. /*
  155.  * Global Data
  156.  */
  157. static char fullname[] = "Sangoma WANPIPE Router";
  158. static char copyright[] = "(c) 1995-2000 Sangoma Technologies Inc.";
  159. static char modname[] = ROUTER_NAME; /* short module name */
  160. wan_device_t* router_devlist  = NULL; /* list of registered devices */
  161. static int devcnt  = 0;
  162. /* 
  163.  * Organize Unique Identifiers for encapsulation/decapsulation 
  164.  */
  165. static unsigned char oui_ether[] = { 0x00, 0x00, 0x00 };
  166. #if 0
  167. static unsigned char oui_802_2[] = { 0x00, 0x80, 0xC2 };
  168. #endif
  169. #ifndef MODULE
  170. int wanrouter_init(void)
  171. {
  172. int err;
  173. extern int wanpipe_init(void);
  174. extern int sdladrv_init(void);
  175. printk(KERN_INFO "%s v%u.%u %sn",
  176. fullname, ROUTER_VERSION, ROUTER_RELEASE, copyright);
  177. err = wanrouter_proc_init();
  178. if (err){
  179. printk(KERN_INFO "%s: can't create entry in proc filesystem!n", modname);
  180. }
  181.         /*
  182.          *      Initialise compiled in boards
  183.          */
  184. #ifdef CONFIG_VENDOR_SANGOMA
  185. sdladrv_init();
  186. wanpipe_init();
  187. #endif
  188.  
  189. return err;
  190. }
  191. #ifdef LINUX_2_4
  192. static void __exit wanrouter_cleanup (void)
  193. {
  194. wanrouter_proc_cleanup();
  195. }
  196. #endif
  197. #else
  198. /*
  199.  * Kernel Loadable Module Entry Points
  200.  */
  201. /*
  202.  *  Module 'insert' entry point.
  203.  *  o print announcement
  204.  *  o initialize static data
  205.  *  o create /proc/net/router directory and static entries
  206.  *
  207.  *  Return: 0 Ok
  208.  * < 0 error.
  209.  *  Context: process
  210.  */
  211. int init_module (void)
  212. {
  213. int err;
  214. printk(KERN_INFO "%s v%u.%u %sn",
  215. fullname, ROUTER_VERSION, ROUTER_RELEASE, copyright);
  216. err = wanrouter_proc_init();
  217. if (err){ 
  218. printk(KERN_INFO
  219. "%s: can't create entry in proc filesystem!n", modname);
  220. }
  221. return err;
  222. }
  223. /*
  224.  *  Module 'remove' entry point.
  225.  *  o delete /proc/net/router directory and static entries.
  226.  */
  227. void cleanup_module (void)
  228. {
  229. wanrouter_proc_cleanup();
  230. }
  231. #endif
  232. /*
  233.  *  Kernel APIs
  234.  */
  235. /*
  236.  *  Register WAN device.
  237.  *  o verify device credentials
  238.  *  o create an entry for the device in the /proc/net/router directory
  239.  *  o initialize internally maintained fields of the wan_device structure
  240.  *  o link device data space to a singly-linked list
  241.  *  o if it's the first device, then start kernel 'thread'
  242.  *  o increment module use count
  243.  *
  244.  *  Return:
  245.  * 0 Ok
  246.  * < 0 error.
  247.  *
  248.  *  Context: process
  249.  */
  250. int register_wan_device(wan_device_t *wandev)
  251. {
  252. int err, namelen;
  253. if ((wandev == NULL) || (wandev->magic != ROUTER_MAGIC) ||
  254.     (wandev->name == NULL))
  255. return -EINVAL;
  256.  
  257. namelen = strlen(wandev->name);
  258. if (!namelen || (namelen > WAN_DRVNAME_SZ))
  259. return -EINVAL;
  260. if (find_device(wandev->name) != NULL)
  261. return -EEXIST;
  262. #ifdef WANDEBUG
  263. printk(KERN_INFO "%s: registering WAN device %sn",
  264. modname, wandev->name);
  265. #endif
  266. /*
  267.  * Register /proc directory entry 
  268.  */
  269. err = wanrouter_proc_add(wandev);
  270. if (err) {
  271. printk(KERN_INFO
  272. "%s: can't create /proc/net/router/%s entry!n",
  273. modname, wandev->name);
  274. return err;
  275. }
  276. /*
  277.  * Initialize fields of the wan_device structure maintained by the
  278.  * router and update local data.
  279.  */
  280.  
  281. wandev->ndev = 0;
  282. wandev->dev  = NULL;
  283. wandev->next = router_devlist;
  284. router_devlist = wandev;
  285. ++devcnt;
  286.         MOD_INC_USE_COUNT; /* prevent module from unloading */
  287. return 0;
  288. }
  289. /*
  290.  * Unregister WAN device.
  291.  * o shut down device
  292.  * o unlink device data space from the linked list
  293.  * o delete device entry in the /proc/net/router directory
  294.  * o decrement module use count
  295.  *
  296.  * Return: 0 Ok
  297.  * <0 error.
  298.  * Context: process
  299.  */
  300. int unregister_wan_device(char *name)
  301. {
  302. wan_device_t *wandev, *prev;
  303. if (name == NULL)
  304. return -EINVAL;
  305. for (wandev = router_devlist, prev = NULL;
  306. wandev && strcmp(wandev->name, name);
  307. prev = wandev, wandev = wandev->next)
  308. ;
  309. if (wandev == NULL)
  310. return -ENODEV;
  311. #ifdef WANDEBUG
  312. printk(KERN_INFO "%s: unregistering WAN device %sn", modname, name);
  313. #endif
  314. if (wandev->state != WAN_UNCONFIGURED) {
  315. device_shutdown(wandev);
  316. }
  317. if (prev){
  318. prev->next = wandev->next;
  319. }else{
  320. router_devlist = wandev->next;
  321. }
  322. --devcnt;
  323. wanrouter_proc_delete(wandev);
  324.         MOD_DEC_USE_COUNT;
  325. return 0;
  326. }
  327. /*
  328.  * Encapsulate packet.
  329.  *
  330.  * Return: encapsulation header size
  331.  * < 0 - unsupported Ethertype
  332.  *
  333.  * Notes:
  334.  * 1. This function may be called on interrupt context.
  335.  */
  336. int wanrouter_encapsulate (struct sk_buff *skb, netdevice_t *dev,
  337. unsigned short type)
  338. {
  339. int hdr_len = 0;
  340. switch (type) {
  341. case ETH_P_IP: /* IP datagram encapsulation */
  342. hdr_len += 1;
  343. skb_push(skb, 1);
  344. skb->data[0] = NLPID_IP;
  345. break;
  346. case ETH_P_IPX: /* SNAP encapsulation */
  347. case ETH_P_ARP:
  348. hdr_len += 7;
  349. skb_push(skb, 7);
  350. skb->data[0] = 0;
  351. skb->data[1] = NLPID_SNAP;
  352. memcpy(&skb->data[2], oui_ether, sizeof(oui_ether));
  353. *((unsigned short*)&skb->data[5]) = htons(type);
  354. break;
  355. default: /* Unknown packet type */
  356. printk(KERN_INFO
  357. "%s: unsupported Ethertype 0x%04X on interface %s!n",
  358. modname, type, dev->name);
  359. hdr_len = -EINVAL;
  360. }
  361. return hdr_len;
  362. }
  363. /*
  364.  * Decapsulate packet.
  365.  *
  366.  * Return: Ethertype (in network order)
  367.  * 0 unknown encapsulation
  368.  *
  369.  * Notes:
  370.  * 1. This function may be called on interrupt context.
  371.  */
  372. unsigned short wanrouter_type_trans (struct sk_buff *skb, netdevice_t *dev)
  373. {
  374. int cnt = skb->data[0] ? 0 : 1; /* there may be a pad present */
  375. unsigned short ethertype;
  376. switch (skb->data[cnt]) {
  377. case NLPID_IP: /* IP datagramm */
  378. ethertype = htons(ETH_P_IP);
  379. cnt += 1;
  380. break;
  381.         case NLPID_SNAP: /* SNAP encapsulation */
  382. if (memcmp(&skb->data[cnt + 1], oui_ether, sizeof(oui_ether))){
  383.            printk(KERN_INFO
  384. "%s: unsupported SNAP OUI %02X-%02X-%02X "
  385. "on interface %s!n", modname,
  386. skb->data[cnt+1], skb->data[cnt+2],
  387. skb->data[cnt+3], dev->name);
  388. return 0;
  389. }
  390. ethertype = *((unsigned short*)&skb->data[cnt+4]);
  391. cnt += 6;
  392. break;
  393. /* add other protocols, e.g. CLNP, ESIS, ISIS, if needed */
  394. default:
  395. printk(KERN_INFO
  396. "%s: unsupported NLPID 0x%02X on interface %s!n",
  397. modname, skb->data[cnt], dev->name);
  398. return 0;
  399. }
  400. skb->protocol = ethertype;
  401. skb->pkt_type = PACKET_HOST; /* Physically point to point */
  402. skb_pull(skb, cnt);
  403. skb->mac.raw  = skb->data;
  404. return ethertype;
  405. }
  406. /*
  407.  * WAN device IOCTL.
  408.  * o find WAN device associated with this node
  409.  * o execute requested action or pass command to the device driver
  410.  */
  411. int wanrouter_ioctl(struct inode *inode, struct file *file,
  412. unsigned int cmd, unsigned long arg)
  413. {
  414. int err = 0;
  415. struct proc_dir_entry *dent;
  416. wan_device_t *wandev;
  417.       #if defined (LINUX_2_1) || defined (LINUX_2_4)
  418. if (!capable(CAP_NET_ADMIN)){
  419. return -EPERM;
  420. }
  421.       #endif
  422. if ((cmd >> 8) != ROUTER_IOCTL)
  423. return -EINVAL;
  424. dent = inode->u.generic_ip;
  425. if ((dent == NULL) || (dent->data == NULL))
  426. return -EINVAL;
  427. wandev = dent->data;
  428. if (wandev->magic != ROUTER_MAGIC)
  429. return -EINVAL;
  430. switch (cmd) {
  431. case ROUTER_SETUP:
  432. err = device_setup(wandev, (void*)arg);
  433. break;
  434. case ROUTER_DOWN:
  435. err = device_shutdown(wandev);
  436. break;
  437. case ROUTER_STAT:
  438. err = device_stat(wandev, (void*)arg);
  439. break;
  440. case ROUTER_IFNEW:
  441. err = device_new_if(wandev, (void*)arg);
  442. break;
  443. case ROUTER_IFDEL:
  444. err = device_del_if(wandev, (void*)arg);
  445. break;
  446. case ROUTER_IFSTAT:
  447. break;
  448. default:
  449. if ((cmd >= ROUTER_USER) &&
  450.     (cmd <= ROUTER_USER_MAX) &&
  451.     wandev->ioctl)
  452. err = wandev->ioctl(wandev, cmd, arg);
  453. else err = -EINVAL;
  454. }
  455. return err;
  456. }
  457. /*
  458.  * WAN Driver IOCTL Handlers
  459.  */
  460. /*
  461.  * Setup WAN link device.
  462.  * o verify user address space
  463.  * o allocate kernel memory and copy configuration data to kernel space
  464.  * o if configuration data includes extension, copy it to kernel space too
  465.  * o call driver's setup() entry point
  466.  */
  467. static int device_setup (wan_device_t *wandev, wandev_conf_t *u_conf)
  468. {
  469. void *data = NULL;
  470. wandev_conf_t *conf;
  471. int err = -EINVAL;
  472. if (wandev->setup == NULL){ /* Nothing to do ? */
  473. printk(KERN_INFO "%s: ERROR, No setup script: wandev->setup()n",
  474. wandev->name);
  475. return 0;
  476. }
  477.       #ifdef LINUX_2_0 
  478. err = verify_area (VERIFY_READ, u_conf, sizeof(wandev_conf_t));
  479. if(err){
  480. return err;
  481. }
  482.       #endif
  483. conf = kmalloc(sizeof(wandev_conf_t), GFP_KERNEL);
  484. if (conf == NULL){
  485. printk(KERN_INFO "%s: ERROR, Failed to allocate kernel memory !n",
  486. wandev->name);
  487. return -ENOBUFS;
  488. }
  489.       #if defined (LINUX_2_1) || defined (LINUX_2_4)
  490. if(copy_from_user(conf, u_conf, sizeof(wandev_conf_t))) {
  491. printk(KERN_INFO "%s: Failed to copy user config data to kernel space!n",
  492. wandev->name);
  493. kfree(conf);
  494. return -EFAULT;
  495. }
  496.       #else
  497. memcpy_fromfs ((void *)conf, (void *)u_conf, sizeof(wandev_conf_t));
  498.       #endif
  499. if (conf->magic != ROUTER_MAGIC){
  500. kfree(conf);
  501. printk(KERN_INFO "%s: ERROR, Invalid MAGIC Numbern",
  502. wandev->name);
  503.         return -EINVAL; 
  504. }
  505. if (conf->data_size && conf->data){
  506. if(conf->data_size > 128000 || conf->data_size < 0) {
  507. printk(KERN_INFO 
  508.     "%s: ERROR, Invalid firmware data size %i !n",
  509. wandev->name, conf->data_size);
  510. kfree(conf);
  511.         return -EINVAL;;
  512. }
  513. #if defined (LINUX_2_1) || defined (LINUX_2_4)
  514. data = vmalloc(conf->data_size);
  515. if (data) {
  516. if(!copy_from_user(data, conf->data, conf->data_size)){
  517. conf->data=data;
  518. err = wandev->setup(wandev,conf);
  519. }else{ 
  520. printk(KERN_INFO 
  521.      "%s: ERROR, Faild to copy from user data !n",
  522.        wandev->name);
  523. err = -EFAULT;
  524. }
  525. }else{ 
  526. printk(KERN_INFO 
  527.   "%s: ERROR, Faild allocate kernel memory !n",
  528. wandev->name);
  529. err = -ENOBUFS;
  530. }
  531. if (data){
  532. vfree(data);
  533. }
  534. #else
  535.                 err = verify_area(VERIFY_READ, conf->data, conf->data_size);
  536.                 if (!err) {
  537.                         data = kmalloc(conf->data_size, GFP_KERNEL);
  538.                         if (data) {
  539.                                 memcpy_fromfs(data, (void*)conf->data,
  540.                                         conf->data_size);
  541.                                 conf->data = data;
  542.                         }else{
  543. printk(KERN_INFO 
  544.     "%s: ERROR, Faild allocate kernel memory !n",wandev->name);
  545. err = -ENOMEM;
  546. }
  547.                 }else{
  548. printk(KERN_INFO 
  549.   "%s: ERROR, Faild to copy from user data !n",wandev->name);
  550. }
  551. if (!err){
  552. err = wandev->setup(wandev, conf);
  553. }
  554.          if (data){
  555. kfree(data);
  556. }
  557. #endif
  558. }else{
  559. printk(KERN_INFO 
  560.     "%s: ERROR, No firmware found ! Firmware size = %i !n",
  561. wandev->name, conf->data_size);
  562. }
  563. kfree(conf);
  564. return err;
  565. }
  566. /*
  567.  * Shutdown WAN device.
  568.  * o delete all not opened logical channels for this device
  569.  * o call driver's shutdown() entry point
  570.  */
  571.  
  572. static int device_shutdown (wan_device_t *wandev)
  573. {
  574. netdevice_t *dev;
  575. int err=0;
  576. if (wandev->state == WAN_UNCONFIGURED){
  577. return 0;
  578. }
  579. printk(KERN_INFO "n%s: Shutting Down!n",wandev->name);
  580. for (dev = wandev->dev; dev;) {
  581. if ((err=delete_interface(wandev, dev->name)) != 0){
  582. return err;
  583. }
  584. /* The above function deallocates the current dev
  585.  * structure. Therefore, we cannot use dev->priv
  586.  * as the next element: wandev->dev points to the
  587.  * next element */
  588. dev = wandev->dev;
  589. }
  590. if (wandev->ndev){
  591. return -EBUSY; /* there are opened interfaces  */
  592. }
  593. if (wandev->shutdown)
  594. err=wandev->shutdown(wandev);
  595. return err;
  596. }
  597. /*
  598.  * Get WAN device status & statistics.
  599.  */
  600. static int device_stat (wan_device_t *wandev, wandev_stat_t *u_stat)
  601. {
  602. wandev_stat_t stat;
  603.       #ifdef LINUX_2_0
  604. int err;
  605. err = verify_area(VERIFY_WRITE, u_stat, sizeof(wandev_stat_t));
  606.         if (err)
  607.                 return err;
  608.       #endif
  609. memset(&stat, 0, sizeof(stat));
  610. /* Ask device driver to update device statistics */
  611. if ((wandev->state != WAN_UNCONFIGURED) && wandev->update)
  612. wandev->update(wandev);
  613. /* Fill out structure */
  614. stat.ndev  = wandev->ndev;
  615. stat.state = wandev->state;
  616.       #if defined (LINUX_2_1) || defined (LINUX_2_4)
  617. if(copy_to_user(u_stat, &stat, sizeof(stat)))
  618. return -EFAULT;
  619.       #else
  620.         memcpy_tofs((void*)u_stat, (void*)&stat, sizeof(stat));
  621.       #endif
  622. return 0;
  623. }
  624. /*
  625.  * Create new WAN interface.
  626.  * o verify user address space
  627.  * o copy configuration data to kernel address space
  628.  * o allocate network interface data space
  629.  * o call driver's new_if() entry point
  630.  * o make sure there is no interface name conflict
  631.  * o register network interface
  632.  */
  633. static int device_new_if (wan_device_t *wandev, wanif_conf_t *u_conf)
  634. {
  635. wanif_conf_t conf;
  636. netdevice_t *dev=NULL;
  637. #ifdef CONFIG_WANPIPE_MULTPPP
  638. struct ppp_device *pppdev=NULL;
  639. #endif
  640. int err;
  641. if ((wandev->state == WAN_UNCONFIGURED) || (wandev->new_if == NULL))
  642. return -ENODEV;
  643. #if defined (LINUX_2_1) || defined (LINUX_2_4)
  644. if(copy_from_user(&conf, u_conf, sizeof(wanif_conf_t)))
  645. return -EFAULT;
  646. #else
  647.         err = verify_area(VERIFY_READ, u_conf, sizeof(wanif_conf_t));
  648.         if (err)
  649.                 return err;
  650.         memcpy_fromfs((void*)&conf, (void*)u_conf, sizeof(wanif_conf_t));
  651. #endif
  652. if (conf.magic != ROUTER_MAGIC)
  653. return -EINVAL;
  654. err = -EPROTONOSUPPORT;
  655. #ifdef CONFIG_WANPIPE_MULTPPP
  656. if (conf.config_id == WANCONFIG_MPPP){
  657. pppdev = kmalloc(sizeof(struct ppp_device), GFP_KERNEL);
  658. if (pppdev == NULL){
  659. return -ENOBUFS;
  660. }
  661. memset(pppdev, 0, sizeof(struct ppp_device));
  662. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,16)
  663. pppdev->dev = kmalloc(sizeof(netdevice_t), GFP_KERNEL);
  664. if (pppdev->dev == NULL){
  665. kfree(pppdev);
  666. return -ENOBUFS;
  667. }
  668. memset(pppdev->dev, 0, sizeof(netdevice_t));
  669. #endif
  670. err = wandev->new_if(wandev, (netdevice_t *)pppdev, &conf);
  671.       #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,16)
  672. dev = pppdev->dev;
  673.       #else
  674. dev = &pppdev->dev;
  675.       #endif
  676. }else{
  677. dev = kmalloc(sizeof(netdevice_t), GFP_KERNEL);
  678. if (dev == NULL){
  679. return -ENOBUFS;
  680. }
  681. memset(dev, 0, sizeof(netdevice_t));
  682. err = wandev->new_if(wandev, dev, &conf);
  683. }
  684. #else
  685. /* Sync PPP is disabled */
  686. if (conf.config_id != WANCONFIG_MPPP){
  687. dev = kmalloc(sizeof(netdevice_t), GFP_KERNEL);
  688. if (dev == NULL){
  689. return -ENOBUFS;
  690. }
  691. memset(dev, 0, sizeof(netdevice_t));
  692. err = wandev->new_if(wandev, dev, &conf);
  693. }else{
  694. printk(KERN_INFO "%s: Wanpipe Mulit-Port PPP support has not been compiled in!n",
  695. wandev->name);
  696. return err;
  697. }
  698. #endif
  699. if (!err) {
  700. /* Register network interface. This will invoke init()
  701.  * function supplied by the driver.  If device registered
  702.  * successfully, add it to the interface list.
  703.  */
  704. if (dev->name == NULL){
  705. err = -EINVAL;
  706. }else if (dev_get(dev->name)){
  707. err = -EEXIST; /* name already exists */
  708. }else{
  709. #ifdef WANDEBUG
  710. printk(KERN_INFO "%s: registering interface %s...n",
  711. modname, dev->name);
  712. #endif
  713. err = register_netdev(dev);
  714. if (!err) {
  715. netdevice_t *slave=NULL;
  716. unsigned long smp_flags=0;
  717. lock_adapter_irq(&wandev->lock, &smp_flags);
  718. if (wandev->dev == NULL){
  719. wandev->dev = dev;
  720. }else{
  721. for (slave=wandev->dev;
  722.      *((netdevice_t**)slave->priv);
  723.      slave=*((netdevice_t**)slave->priv));
  724. *((netdevice_t**)slave->priv) = dev;
  725. }
  726. ++wandev->ndev;
  727. unlock_adapter_irq(&wandev->lock, &smp_flags);
  728. return 0; /* done !!! */
  729. }
  730. }
  731. if (wandev->del_if)
  732. wandev->del_if(wandev, dev);
  733. }
  734. /* This code has moved from del_if() function */
  735. if (dev->priv){
  736. kfree(dev->priv);
  737. dev->priv=NULL;
  738. }
  739.       #ifdef CONFIG_WANPIPE_MULTPPP
  740. if (conf.config_id == WANCONFIG_MPPP){
  741. kfree(pppdev);
  742. }else{
  743. kfree(dev);
  744. }
  745.       #else
  746. /* Sync PPP is disabled */
  747. if (conf.config_id != WANCONFIG_MPPP){
  748. kfree(dev);
  749. }
  750.       #endif
  751. return err;
  752. }
  753. /*
  754.  * Delete WAN logical channel.
  755.  *  o verify user address space
  756.  *  o copy configuration data to kernel address space
  757.  */
  758. static int device_del_if (wan_device_t *wandev, char *u_name)
  759. {
  760. char name[WAN_IFNAME_SZ + 1];
  761.         int err = 0;
  762. if (wandev->state == WAN_UNCONFIGURED)
  763. return -ENODEV;
  764.       #ifdef LINUX_2_0
  765.         err = verify_area(VERIFY_READ, u_name, WAN_IFNAME_SZ);
  766.         if (err)
  767. return err;
  768.       #endif
  769. memset(name, 0, sizeof(name));
  770.       #if defined (LINUX_2_1) || defined (LINUX_2_4)
  771. if(copy_from_user(name, u_name, WAN_IFNAME_SZ))
  772. return -EFAULT;
  773.       #else
  774.         memcpy_fromfs((void*)name, (void*)u_name, WAN_IFNAME_SZ);
  775.       #endif
  776. err = delete_interface(wandev, name);
  777. if (err)
  778. return(err);
  779. /* If last interface being deleted, shutdown card
  780.  * This helps with administration at leaf nodes
  781.  * (You can tell if the person at the other end of the phone 
  782.  * has an interface configured) and avoids DoS vulnerabilities
  783.  * in binary driver files - this fixes a problem with the current
  784.  * Sangoma driver going into strange states when all the network
  785.  * interfaces are deleted and the link irrecoverably disconnected.
  786.  */ 
  787.         if (!wandev->ndev && wandev->shutdown){
  788.                 err = wandev->shutdown(wandev);
  789. }
  790. return err;
  791. }
  792. /*
  793.  * Miscellaneous Functions
  794.  */
  795. /*
  796.  * Find WAN device by name.
  797.  * Return pointer to the WAN device data space or NULL if device not found.
  798.  */
  799. static wan_device_t *find_device(char *name)
  800. {
  801. wan_device_t *wandev;
  802. for (wandev = router_devlist;wandev && strcmp(wandev->name, name);
  803. wandev = wandev->next);
  804. return wandev;
  805. }
  806. /*
  807.  * Delete WAN logical channel identified by its name.
  808.  * o find logical channel by its name
  809.  * o call driver's del_if() entry point
  810.  * o unregister network interface
  811.  * o unlink channel data space from linked list of channels
  812.  * o release channel data space
  813.  *
  814.  * Return: 0 success
  815.  * -ENODEV channel not found.
  816.  * -EBUSY interface is open
  817.  *
  818.  * Note: If (force != 0), then device will be destroyed even if interface
  819.  * associated with it is open. It's caller's responsibility to make
  820.  * sure that opened interfaces are not removed!
  821.  */
  822. static int delete_interface (wan_device_t *wandev, char *name)
  823. {
  824. netdevice_t *dev=NULL, *prev=NULL;
  825. unsigned long smp_flags=0;
  826. lock_adapter_irq(&wandev->lock, &smp_flags);
  827. dev = wandev->dev;
  828. prev = NULL;
  829. while (dev && strcmp(name, dev->name)) {
  830. netdevice_t **slave = dev->priv;
  831. prev = dev;
  832. dev = *slave;
  833. }
  834. unlock_adapter_irq(&wandev->lock, &smp_flags);
  835. if (dev == NULL){
  836. return -ENODEV; /* interface not found */
  837. }
  838.        #ifdef LINUX_2_4
  839. if (netif_running(dev)){
  840.        #else
  841. if (dev->start) {
  842.        #endif
  843. return -EBUSY; /* interface in use */
  844. }
  845. if (wandev->del_if)
  846. wandev->del_if(wandev, dev);
  847. lock_adapter_irq(&wandev->lock, &smp_flags);
  848. if (prev) {
  849. netdevice_t **prev_slave = prev->priv;
  850. netdevice_t **slave = dev->priv;
  851. *prev_slave = *slave;
  852. } else {
  853. netdevice_t **slave = dev->priv;
  854. wandev->dev = *slave;
  855. }
  856. --wandev->ndev;
  857. unlock_adapter_irq(&wandev->lock, &smp_flags);
  858. printk(KERN_INFO "%s: unregistering '%s'n", wandev->name, dev->name); 
  859. /* Due to new interface linking method using dev->priv,
  860.  * this code has moved from del_if() function.*/
  861. if (dev->priv){
  862. kfree(dev->priv);
  863. dev->priv=NULL;
  864. }
  865. unregister_netdev(dev);
  866.       #ifdef LINUX_2_4
  867. kfree(dev);
  868.       #else
  869. if (dev->name){
  870. kfree(dev->name);
  871. }
  872. kfree(dev);
  873.       #endif
  874. return 0;
  875. }
  876. void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags)
  877. {
  878.       #ifdef LINUX_2_0
  879. save_flags(*smp_flags);
  880. cli();
  881.       #else
  882.         spin_lock_irqsave(lock, *smp_flags);
  883.       #endif
  884. }
  885. void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags)
  886. {
  887.       #ifdef LINUX_2_0
  888. restore_flags(*smp_flags);
  889.       #else
  890. spin_unlock_irqrestore(lock, *smp_flags);
  891.       #endif
  892. }
  893. #if defined (LINUX_2_1) || defined (LINUX_2_4)
  894. EXPORT_SYMBOL(register_wan_device);
  895. EXPORT_SYMBOL(unregister_wan_device);
  896. EXPORT_SYMBOL(wanrouter_encapsulate);
  897. EXPORT_SYMBOL(wanrouter_type_trans);
  898. EXPORT_SYMBOL(lock_adapter_irq);
  899. EXPORT_SYMBOL(unlock_adapter_irq);
  900. #endif
  901. /*
  902.  * End
  903.  */