libipw_module.c 7.6 KB

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