libipw_module.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /*******************************************************************************
  2. Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
  3. Portions of this file are based on the WEP enablement code provided by the
  4. Host AP project hostap-drivers v0.1.3
  5. Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
  6. <j@w1.fi>
  7. Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
  8. This program is free software; you can redistribute it and/or modify it
  9. under the terms of version 2 of the GNU General Public License as
  10. published by the Free Software Foundation.
  11. This program is distributed in the hope that it will be useful, but WITHOUT
  12. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  14. more details.
  15. You should have received a copy of the GNU General Public License along with
  16. this program; if not, write to the Free Software Foundation, Inc., 59
  17. Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. The full GNU General Public License is included in this distribution in the
  19. file called LICENSE.
  20. Contact Information:
  21. Intel Linux Wireless <ilw@linux.intel.com>
  22. Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  23. *******************************************************************************/
  24. #include <linux/compiler.h>
  25. #include <linux/errno.h>
  26. #include <linux/if_arp.h>
  27. #include <linux/in6.h>
  28. #include <linux/in.h>
  29. #include <linux/ip.h>
  30. #include <linux/kernel.h>
  31. #include <linux/module.h>
  32. #include <linux/netdevice.h>
  33. #include <linux/proc_fs.h>
  34. #include <linux/skbuff.h>
  35. #include <linux/slab.h>
  36. #include <linux/tcp.h>
  37. #include <linux/types.h>
  38. #include <linux/wireless.h>
  39. #include <linux/etherdevice.h>
  40. #include <asm/uaccess.h>
  41. #include <net/net_namespace.h>
  42. #include <net/arp.h>
  43. #include "libipw.h"
  44. #define DRV_DESCRIPTION "802.11 data/management/control stack"
  45. #define DRV_NAME "libipw"
  46. #define DRV_PROCNAME "ieee80211"
  47. #define DRV_VERSION LIBIPW_VERSION
  48. #define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>"
  49. MODULE_VERSION(DRV_VERSION);
  50. MODULE_DESCRIPTION(DRV_DESCRIPTION);
  51. MODULE_AUTHOR(DRV_COPYRIGHT);
  52. MODULE_LICENSE("GPL");
  53. static struct cfg80211_ops libipw_config_ops = { };
  54. static void *libipw_wiphy_privid = &libipw_wiphy_privid;
  55. static int libipw_networks_allocate(struct libipw_device *ieee)
  56. {
  57. int i, j;
  58. for (i = 0; i < MAX_NETWORK_COUNT; i++) {
  59. ieee->networks[i] = kzalloc(sizeof(struct libipw_network),
  60. GFP_KERNEL);
  61. if (!ieee->networks[i]) {
  62. LIBIPW_ERROR("Out of memory allocating beacons\n");
  63. for (j = 0; j < i; j++)
  64. kfree(ieee->networks[j]);
  65. return -ENOMEM;
  66. }
  67. }
  68. return 0;
  69. }
  70. static inline void libipw_networks_free(struct libipw_device *ieee)
  71. {
  72. int i;
  73. for (i = 0; i < MAX_NETWORK_COUNT; i++)
  74. kfree(ieee->networks[i]);
  75. }
  76. void libipw_networks_age(struct libipw_device *ieee,
  77. unsigned long age_secs)
  78. {
  79. struct libipw_network *network = NULL;
  80. unsigned long flags;
  81. unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);
  82. spin_lock_irqsave(&ieee->lock, flags);
  83. list_for_each_entry(network, &ieee->network_list, list) {
  84. network->last_scanned -= age_jiffies;
  85. }
  86. spin_unlock_irqrestore(&ieee->lock, flags);
  87. }
  88. EXPORT_SYMBOL(libipw_networks_age);
  89. static void libipw_networks_initialize(struct libipw_device *ieee)
  90. {
  91. int i;
  92. INIT_LIST_HEAD(&ieee->network_free_list);
  93. INIT_LIST_HEAD(&ieee->network_list);
  94. for (i = 0; i < MAX_NETWORK_COUNT; i++)
  95. list_add_tail(&ieee->networks[i]->list,
  96. &ieee->network_free_list);
  97. }
  98. int libipw_change_mtu(struct net_device *dev, int new_mtu)
  99. {
  100. if ((new_mtu < 68) || (new_mtu > LIBIPW_DATA_LEN))
  101. return -EINVAL;
  102. dev->mtu = new_mtu;
  103. return 0;
  104. }
  105. EXPORT_SYMBOL(libipw_change_mtu);
  106. struct net_device *alloc_libipw(int sizeof_priv, int monitor)
  107. {
  108. struct libipw_device *ieee;
  109. struct net_device *dev;
  110. int err;
  111. LIBIPW_DEBUG_INFO("Initializing...\n");
  112. dev = alloc_etherdev(sizeof(struct libipw_device) + sizeof_priv);
  113. if (!dev)
  114. goto failed;
  115. ieee = netdev_priv(dev);
  116. ieee->dev = dev;
  117. if (!monitor) {
  118. ieee->wdev.wiphy = wiphy_new(&libipw_config_ops, 0);
  119. if (!ieee->wdev.wiphy) {
  120. LIBIPW_ERROR("Unable to allocate wiphy.\n");
  121. goto failed_free_netdev;
  122. }
  123. ieee->dev->ieee80211_ptr = &ieee->wdev;
  124. ieee->wdev.iftype = NL80211_IFTYPE_STATION;
  125. /* Fill-out wiphy structure bits we know... Not enough info
  126. here to call set_wiphy_dev or set MAC address or channel info
  127. -- have to do that in ->ndo_init... */
  128. ieee->wdev.wiphy->privid = libipw_wiphy_privid;
  129. ieee->wdev.wiphy->max_scan_ssids = 1;
  130. ieee->wdev.wiphy->max_scan_ie_len = 0;
  131. ieee->wdev.wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
  132. | BIT(NL80211_IFTYPE_ADHOC);
  133. }
  134. err = libipw_networks_allocate(ieee);
  135. if (err) {
  136. LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err);
  137. goto failed_free_wiphy;
  138. }
  139. libipw_networks_initialize(ieee);
  140. /* Default fragmentation threshold is maximum payload size */
  141. ieee->fts = DEFAULT_FTS;
  142. ieee->rts = DEFAULT_FTS;
  143. ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
  144. ieee->open_wep = 1;
  145. /* Default to enabling full open WEP with host based encrypt/decrypt */
  146. ieee->host_encrypt = 1;
  147. ieee->host_decrypt = 1;
  148. ieee->host_mc_decrypt = 1;
  149. /* Host fragmentation in Open mode. Default is enabled.
  150. * Note: host fragmentation is always enabled if host encryption
  151. * is enabled. For cards can do hardware encryption, they must do
  152. * hardware fragmentation as well. So we don't need a variable
  153. * like host_enc_frag. */
  154. ieee->host_open_frag = 1;
  155. ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
  156. spin_lock_init(&ieee->lock);
  157. lib80211_crypt_info_init(&ieee->crypt_info, dev->name, &ieee->lock);
  158. ieee->wpa_enabled = 0;
  159. ieee->drop_unencrypted = 0;
  160. ieee->privacy_invoked = 0;
  161. return dev;
  162. failed_free_wiphy:
  163. if (!monitor)
  164. wiphy_free(ieee->wdev.wiphy);
  165. failed_free_netdev:
  166. free_netdev(dev);
  167. failed:
  168. return NULL;
  169. }
  170. EXPORT_SYMBOL(alloc_libipw);
  171. void free_libipw(struct net_device *dev, int monitor)
  172. {
  173. struct libipw_device *ieee = netdev_priv(dev);
  174. lib80211_crypt_info_free(&ieee->crypt_info);
  175. libipw_networks_free(ieee);
  176. /* free cfg80211 resources */
  177. if (!monitor)
  178. wiphy_free(ieee->wdev.wiphy);
  179. free_netdev(dev);
  180. }
  181. EXPORT_SYMBOL(free_libipw);
  182. #ifdef CONFIG_LIBIPW_DEBUG
  183. static int debug = 0;
  184. u32 libipw_debug_level = 0;
  185. EXPORT_SYMBOL_GPL(libipw_debug_level);
  186. static struct proc_dir_entry *libipw_proc = NULL;
  187. static int debug_level_proc_show(struct seq_file *m, void *v)
  188. {
  189. seq_printf(m, "0x%08X\n", libipw_debug_level);
  190. return 0;
  191. }
  192. static int debug_level_proc_open(struct inode *inode, struct file *file)
  193. {
  194. return single_open(file, debug_level_proc_show, NULL);
  195. }
  196. static ssize_t debug_level_proc_write(struct file *file,
  197. const char __user *buffer, size_t count, loff_t *pos)
  198. {
  199. char buf[] = "0x00000000\n";
  200. size_t len = min(sizeof(buf) - 1, count);
  201. unsigned long val;
  202. if (copy_from_user(buf, buffer, len))
  203. return count;
  204. buf[len] = 0;
  205. if (sscanf(buf, "%li", &val) != 1)
  206. printk(KERN_INFO DRV_NAME
  207. ": %s is not in hex or decimal form.\n", buf);
  208. else
  209. libipw_debug_level = val;
  210. return strnlen(buf, len);
  211. }
  212. static const struct file_operations debug_level_proc_fops = {
  213. .owner = THIS_MODULE,
  214. .open = debug_level_proc_open,
  215. .read = seq_read,
  216. .llseek = seq_lseek,
  217. .release = single_release,
  218. .write = debug_level_proc_write,
  219. };
  220. #endif /* CONFIG_LIBIPW_DEBUG */
  221. static int __init libipw_init(void)
  222. {
  223. #ifdef CONFIG_LIBIPW_DEBUG
  224. struct proc_dir_entry *e;
  225. libipw_debug_level = debug;
  226. libipw_proc = proc_mkdir(DRV_PROCNAME, init_net.proc_net);
  227. if (libipw_proc == NULL) {
  228. LIBIPW_ERROR("Unable to create " DRV_PROCNAME
  229. " proc directory\n");
  230. return -EIO;
  231. }
  232. e = proc_create("debug_level", S_IRUGO | S_IWUSR, libipw_proc,
  233. &debug_level_proc_fops);
  234. if (!e) {
  235. remove_proc_entry(DRV_PROCNAME, init_net.proc_net);
  236. libipw_proc = NULL;
  237. return -EIO;
  238. }
  239. #endif /* CONFIG_LIBIPW_DEBUG */
  240. printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
  241. printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
  242. return 0;
  243. }
  244. static void __exit libipw_exit(void)
  245. {
  246. #ifdef CONFIG_LIBIPW_DEBUG
  247. if (libipw_proc) {
  248. remove_proc_entry("debug_level", libipw_proc);
  249. remove_proc_entry(DRV_PROCNAME, init_net.proc_net);
  250. libipw_proc = NULL;
  251. }
  252. #endif /* CONFIG_LIBIPW_DEBUG */
  253. }
  254. #ifdef CONFIG_LIBIPW_DEBUG
  255. #include <linux/moduleparam.h>
  256. module_param(debug, int, 0444);
  257. MODULE_PARM_DESC(debug, "debug output mask");
  258. #endif /* CONFIG_LIBIPW_DEBUG */
  259. module_exit(libipw_exit);
  260. module_init(libipw_init);