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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* $Id: ifconfig_net.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
  2.  *
  3.  * This file is subject to the terms and conditions of the GNU General Public
  4.  * License.  See the file "COPYING" in the main directory of this archive
  5.  * for more details.
  6.  *
  7.  *  ifconfig_net - SGI's Persistent Network Device names.
  8.  *
  9.  * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
  10.  */
  11. #include <linux/types.h>
  12. #include <linux/config.h>
  13. #include <linux/slab.h>
  14. #include <linux/ctype.h>
  15. #include <linux/module.h>
  16. #include <linux/init.h>
  17. #include <linux/pci.h>
  18. #include <linux/netdevice.h>
  19. #include <linux/etherdevice.h>
  20. #include <linux/skbuff.h>
  21. #include <asm/sn/sgi.h>
  22. #include <linux/devfs_fs.h>
  23. #include <linux/devfs_fs_kernel.h>
  24. #include <asm/io.h>
  25. #include <asm/sn/iograph.h>
  26. #include <asm/sn/invent.h>
  27. #include <asm/sn/hcl.h>
  28. #include <asm/sn/labelcl.h>
  29. #include <asm/sn/ifconfig_net.h>
  30. #define SGI_IFCONFIG_NET "SGI-PERSISTENT NETWORK DEVICE NAME DRIVER"
  31. #define SGI_IFCONFIG_NET_VERSION "1.0"
  32. /*
  33.  * Some Global definitions.
  34.  */
  35. devfs_handle_t ifconfig_net_handle = NULL;
  36. unsigned long ifconfig_net_debug = 0;
  37. /*
  38.  * ifconfig_net_open - Opens the special device node "/devhw/.ifconfig_net".
  39.  */
  40. static int ifconfig_net_open(struct inode * inode, struct file * filp)
  41. {
  42. if (ifconfig_net_debug) {
  43.          printk("ifconfig_net_open called.n");
  44. }
  45.         return(0);
  46. }
  47. /*
  48.  * ifconfig_net_close - Closes the special device node "/devhw/.ifconfig_net".
  49.  */
  50. static int ifconfig_net_close(struct inode * inode, struct file * filp)
  51. {
  52. if (ifconfig_net_debug) {
  53.          printk("ifconfig_net_close called.n");
  54. }
  55.         return(0);
  56. }
  57. /*
  58.  * assign_ifname - Assign the next available interface name from the persistent list.
  59.  */
  60. void
  61. assign_ifname(struct net_device *dev,
  62.   struct ifname_num *ifname_num)
  63. {
  64. /*
  65.  * Handle eth devices.
  66.  */
  67.         if ( (memcmp(dev->name, "eth", 3) == 0) ) {
  68. if (ifname_num->next_eth != -1) {
  69. /*
  70.  * Assign it the next available eth interface number. 
  71.  */
  72. memset(dev->name, 0, strlen(dev->name));
  73. sprintf(dev->name, "eth%d", (int)ifname_num->next_eth);
  74. ifname_num->next_eth++;
  75.                 return;
  76.         }
  77. /*
  78.  * Handle fddi devices.
  79.  */
  80. if ( (memcmp(dev->name, "fddi", 4) == 0) ) {
  81. if (ifname_num->next_fddi != -1) {
  82. /*
  83.  * Assign it the next available fddi interface number.
  84.  */
  85. memset(dev->name, 0, strlen(dev->name));
  86. sprintf(dev->name, "fddi%d", (int)ifname_num->next_fddi);
  87. ifname_num->next_fddi++;
  88. }
  89. return;
  90. }
  91. /*
  92.  * Handle hip devices.
  93.  */
  94. if ( (memcmp(dev->name, "hip", 3) == 0) ) {
  95. if (ifname_num->next_hip != -1) {
  96. /*
  97.  * Assign it the next available hip interface number.
  98.  */
  99. memset(dev->name, 0, strlen(dev->name));
  100. sprintf(dev->name, "hip%d", (int)ifname_num->next_hip);
  101. ifname_num->next_hip++;
  102. }
  103. return;
  104. }
  105. /*
  106.  * Handle tr devices.
  107.  */
  108. if ( (memcmp(dev->name, "tr", 2) == 0) ) {
  109. if (ifname_num->next_tr != -1) {
  110. /*
  111.  * Assign it the next available tr interface number.
  112.  */
  113. memset(dev->name, 0, strlen(dev->name));
  114. sprintf(dev->name, "tr%d", (int)ifname_num->next_tr);
  115. ifname_num->next_tr++;
  116. }
  117. return;
  118. }
  119. /*
  120.  * Handle fc devices.
  121.  */
  122. if ( (memcmp(dev->name, "fc", 2) == 0) ) {
  123. if (ifname_num->next_fc != -1) {
  124. /*
  125.  * Assign it the next available fc interface number.
  126.  */
  127. memset(dev->name, 0, strlen(dev->name));
  128. sprintf(dev->name, "fc%d", (int)ifname_num->next_fc);
  129. ifname_num->next_fc++;
  130. }
  131. return;
  132. }
  133. }
  134. /*
  135.  * find_persistent_ifname: Returns the entry that was seen in previous boot.
  136.  */
  137. struct ifname_MAC *
  138. find_persistent_ifname(struct net_device *dev,
  139. struct ifname_MAC *ifname_MAC)
  140. {
  141. while (ifname_MAC->addr_len) {
  142. if (memcmp(dev->dev_addr, ifname_MAC->dev_addr, dev->addr_len) == 0)
  143. return(ifname_MAC);
  144. ifname_MAC++;
  145. }
  146. return(NULL);
  147. }
  148. /*
  149.  * ifconfig_net_ioctl: ifconfig_net driver ioctl interface.
  150.  */
  151. static int ifconfig_net_ioctl(struct inode * inode, struct file * file,
  152.         unsigned int cmd, unsigned long arg)
  153. {
  154. extern struct net_device *__dev_get_by_name(const char *);
  155. #ifdef CONFIG_NET
  156. struct net_device *dev;
  157. struct ifname_MAC *found;
  158. char temp[64];
  159. #endif
  160. struct ifname_MAC *ifname_MAC;
  161. struct ifname_MAC *new_devices, *temp_new_devices;
  162. struct ifname_num *ifname_num;
  163. unsigned long size;
  164. if (ifconfig_net_debug) {
  165. printk("HCL: hcl_ioctl called.n");
  166. }
  167. /*
  168.  * Read in the header and see how big of a buffer we really need to 
  169.  * allocate.
  170.  */
  171. ifname_num = (struct ifname_num *) kmalloc(sizeof(struct ifname_num), 
  172. GFP_KERNEL);
  173. copy_from_user( ifname_num, (char *) arg, sizeof(struct ifname_num));
  174. size = ifname_num->size;
  175. kfree(ifname_num);
  176. ifname_num = (struct ifname_num *) kmalloc(size, GFP_KERNEL);
  177. ifname_MAC = (struct ifname_MAC *) ((char *)ifname_num + (sizeof(struct ifname_num)) );
  178. copy_from_user( ifname_num, (char *) arg, size);
  179. new_devices =  kmalloc(size - sizeof(struct ifname_num), GFP_KERNEL);
  180. temp_new_devices = new_devices;
  181. memset(new_devices, 0, size - sizeof(struct ifname_num));
  182. #ifdef CONFIG_NET
  183. /*
  184.  * Go through the net device entries and make them persistent!
  185.  */
  186. for (dev = dev_base; dev != NULL; dev = dev->next) {
  187. /*
  188.  * Skip NULL entries or "lo"
  189.  */
  190. if ( (dev->addr_len == 0) || ( !strncmp(dev->name, "lo", strlen(dev->name))) ){
  191. continue;
  192. }
  193. /*
  194.  * See if we have a persistent interface name for this device.
  195.  */
  196. found = NULL;
  197. found = find_persistent_ifname(dev, ifname_MAC);
  198. if (found) {
  199. strcpy(dev->name, found->name);
  200. } else {
  201. /* Never seen this before .. */
  202. assign_ifname(dev, ifname_num);
  203. /* 
  204.  * Save the information for the next boot.
  205.  */
  206.   sprintf(temp,"%s %02x:%02x:%02x:%02x:%02x:%02xn", dev->name,
  207. dev->dev_addr[0],  dev->dev_addr[1],  dev->dev_addr[2],
  208. dev->dev_addr[3],  dev->dev_addr[4],  dev->dev_addr[5]);
  209. strcpy(temp_new_devices->name, dev->name);
  210. temp_new_devices->addr_len = dev->addr_len;
  211. memcpy(temp_new_devices->dev_addr, dev->dev_addr, dev->addr_len);
  212. temp_new_devices++;
  213. }
  214. }
  215. #endif
  216. /*
  217.  * Copy back to the User Buffer area any new devices encountered.
  218.  */
  219. copy_to_user((char *)arg + (sizeof(struct ifname_num)), new_devices, 
  220. size - sizeof(struct ifname_num));
  221. return(0);
  222. }
  223. struct file_operations ifconfig_net_fops = {
  224. ioctl:ifconfig_net_ioctl, /* ioctl */
  225. open:ifconfig_net_open, /* open */
  226. release:ifconfig_net_close /* release */
  227. };
  228. /*
  229.  * init_ifconfig_net() - Boot time initialization.  Ensure that it is called 
  230.  * after devfs has been initialized.
  231.  *
  232.  */
  233. #ifdef MODULE
  234. int init_module (void)
  235. #else
  236. int __init init_ifconfig_net(void)
  237. #endif
  238. {
  239. ifconfig_net_handle = NULL;
  240. ifconfig_net_handle = hwgraph_register(hwgraph_root, ".ifconfig_net",
  241. 0, DEVFS_FL_AUTO_DEVNUM,
  242. 0, 0,
  243. S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
  244. &ifconfig_net_fops, NULL);
  245. if (ifconfig_net_handle == NULL) {
  246. panic("Unable to create SGI PERSISTENT NETWORK DEVICE Name Driver.n");
  247. }
  248. return(0);
  249. }