debugfs_key.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /*
  2. * Copyright 2003-2005 Devicescape Software, Inc.
  3. * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
  4. * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. #include <linux/kobject.h>
  11. #include "ieee80211_i.h"
  12. #include "ieee80211_key.h"
  13. #include "debugfs.h"
  14. #include "debugfs_key.h"
  15. #define KEY_READ(name, buflen, format_string) \
  16. static ssize_t key_##name##_read(struct file *file, \
  17. char __user *userbuf, \
  18. size_t count, loff_t *ppos) \
  19. { \
  20. char buf[buflen]; \
  21. struct ieee80211_key *key = file->private_data; \
  22. int res = scnprintf(buf, buflen, format_string, key->name); \
  23. return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
  24. }
  25. #define KEY_READ_D(name) KEY_READ(name, 20, "%d\n")
  26. #define KEY_OPS(name) \
  27. static const struct file_operations key_ ##name## _ops = { \
  28. .read = key_##name##_read, \
  29. .open = mac80211_open_file_generic, \
  30. }
  31. #define KEY_FILE(name, format) \
  32. KEY_READ_##format(name) \
  33. KEY_OPS(name)
  34. KEY_FILE(keylen, D);
  35. KEY_FILE(force_sw_encrypt, D);
  36. KEY_FILE(keyidx, D);
  37. KEY_FILE(hw_key_idx, D);
  38. KEY_FILE(tx_rx_count, D);
  39. static ssize_t key_algorithm_read(struct file *file,
  40. char __user *userbuf,
  41. size_t count, loff_t *ppos)
  42. {
  43. char *alg;
  44. struct ieee80211_key *key = file->private_data;
  45. switch (key->alg) {
  46. case ALG_WEP:
  47. alg = "WEP\n";
  48. break;
  49. case ALG_TKIP:
  50. alg = "TKIP\n";
  51. break;
  52. case ALG_CCMP:
  53. alg = "CCMP\n";
  54. break;
  55. default:
  56. return 0;
  57. }
  58. return simple_read_from_buffer(userbuf, count, ppos, alg, strlen(alg));
  59. }
  60. KEY_OPS(algorithm);
  61. static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf,
  62. size_t count, loff_t *ppos)
  63. {
  64. const u8 *tpn;
  65. char buf[20];
  66. int len;
  67. struct ieee80211_key *key = file->private_data;
  68. switch (key->alg) {
  69. case ALG_WEP:
  70. len = scnprintf(buf, sizeof(buf), "\n");
  71. case ALG_TKIP:
  72. len = scnprintf(buf, sizeof(buf), "%08x %04x\n",
  73. key->u.tkip.iv32,
  74. key->u.tkip.iv16);
  75. case ALG_CCMP:
  76. tpn = key->u.ccmp.tx_pn;
  77. len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
  78. tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], tpn[5]);
  79. default:
  80. return 0;
  81. }
  82. return simple_read_from_buffer(userbuf, count, ppos, buf, len);
  83. }
  84. KEY_OPS(tx_spec);
  85. static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf,
  86. size_t count, loff_t *ppos)
  87. {
  88. struct ieee80211_key *key = file->private_data;
  89. char buf[14*NUM_RX_DATA_QUEUES+1], *p = buf;
  90. int i, len;
  91. const u8 *rpn;
  92. switch (key->alg) {
  93. case ALG_WEP:
  94. len = scnprintf(buf, sizeof(buf), "\n");
  95. case ALG_TKIP:
  96. for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
  97. p += scnprintf(p, sizeof(buf)+buf-p,
  98. "%08x %04x\n",
  99. key->u.tkip.iv32_rx[i],
  100. key->u.tkip.iv16_rx[i]);
  101. len = p - buf;
  102. case ALG_CCMP:
  103. for (i = 0; i < NUM_RX_DATA_QUEUES; i++) {
  104. rpn = key->u.ccmp.rx_pn[i];
  105. p += scnprintf(p, sizeof(buf)+buf-p,
  106. "%02x%02x%02x%02x%02x%02x\n",
  107. rpn[0], rpn[1], rpn[2],
  108. rpn[3], rpn[4], rpn[5]);
  109. }
  110. len = p - buf;
  111. default:
  112. return 0;
  113. }
  114. return simple_read_from_buffer(userbuf, count, ppos, buf, len);
  115. }
  116. KEY_OPS(rx_spec);
  117. static ssize_t key_replays_read(struct file *file, char __user *userbuf,
  118. size_t count, loff_t *ppos)
  119. {
  120. struct ieee80211_key *key = file->private_data;
  121. char buf[20];
  122. int len;
  123. if (key->alg != ALG_CCMP)
  124. return 0;
  125. len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays);
  126. return simple_read_from_buffer(userbuf, count, ppos, buf, len);
  127. }
  128. KEY_OPS(replays);
  129. static ssize_t key_key_read(struct file *file, char __user *userbuf,
  130. size_t count, loff_t *ppos)
  131. {
  132. struct ieee80211_key *key = file->private_data;
  133. int i, res, bufsize = 2*key->keylen+2;
  134. char *buf = kmalloc(bufsize, GFP_KERNEL);
  135. char *p = buf;
  136. for (i = 0; i < key->keylen; i++)
  137. p += scnprintf(p, bufsize+buf-p, "%02x", key->key[i]);
  138. p += scnprintf(p, bufsize+buf-p, "\n");
  139. res = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
  140. kfree(buf);
  141. return res;
  142. }
  143. KEY_OPS(key);
  144. #define DEBUGFS_ADD(name) \
  145. key->debugfs.name = debugfs_create_file(#name, 0400,\
  146. key->debugfs.dir, key, &key_##name##_ops);
  147. void ieee80211_debugfs_key_add(struct ieee80211_local *local,
  148. struct ieee80211_key *key)
  149. {
  150. char buf[20];
  151. if (!local->debugfs.keys)
  152. return;
  153. sprintf(buf, "%d", key->keyidx);
  154. key->debugfs.dir = debugfs_create_dir(buf,
  155. local->debugfs.keys);
  156. if (!key->debugfs.dir)
  157. return;
  158. DEBUGFS_ADD(keylen);
  159. DEBUGFS_ADD(force_sw_encrypt);
  160. DEBUGFS_ADD(keyidx);
  161. DEBUGFS_ADD(hw_key_idx);
  162. DEBUGFS_ADD(tx_rx_count);
  163. DEBUGFS_ADD(algorithm);
  164. DEBUGFS_ADD(tx_spec);
  165. DEBUGFS_ADD(rx_spec);
  166. DEBUGFS_ADD(replays);
  167. DEBUGFS_ADD(key);
  168. };
  169. #define DEBUGFS_DEL(name) \
  170. debugfs_remove(key->debugfs.name); key->debugfs.name = NULL;
  171. void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
  172. {
  173. if (!key)
  174. return;
  175. DEBUGFS_DEL(keylen);
  176. DEBUGFS_DEL(force_sw_encrypt);
  177. DEBUGFS_DEL(keyidx);
  178. DEBUGFS_DEL(hw_key_idx);
  179. DEBUGFS_DEL(tx_rx_count);
  180. DEBUGFS_DEL(algorithm);
  181. DEBUGFS_DEL(tx_spec);
  182. DEBUGFS_DEL(rx_spec);
  183. DEBUGFS_DEL(replays);
  184. DEBUGFS_DEL(key);
  185. debugfs_remove(key->debugfs.stalink);
  186. key->debugfs.stalink = NULL;
  187. debugfs_remove(key->debugfs.dir);
  188. key->debugfs.dir = NULL;
  189. }
  190. void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata)
  191. {
  192. char buf[50];
  193. if (!sdata->debugfsdir)
  194. return;
  195. sprintf(buf, "../keys/%d", sdata->default_key->keyidx);
  196. sdata->debugfs.default_key =
  197. debugfs_create_symlink("default_key", sdata->debugfsdir, buf);
  198. }
  199. void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata)
  200. {
  201. if (!sdata)
  202. return;
  203. debugfs_remove(sdata->debugfs.default_key);
  204. sdata->debugfs.default_key = NULL;
  205. }
  206. void ieee80211_debugfs_key_sta_link(struct ieee80211_key *key,
  207. struct sta_info *sta)
  208. {
  209. char buf[50];
  210. if (!key->debugfs.dir)
  211. return;
  212. sprintf(buf, "../sta/" MAC_FMT, MAC_ARG(sta->addr));
  213. key->debugfs.stalink =
  214. debugfs_create_symlink("station", key->debugfs.dir, buf);
  215. }
  216. void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,
  217. struct sta_info *sta)
  218. {
  219. debugfs_remove(key->debugfs.stalink);
  220. key->debugfs.stalink = NULL;
  221. }