debugfs_key.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  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, prop, 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->prop); \
  23. return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
  24. }
  25. #define KEY_READ_D(name) KEY_READ(name, name, 20, "%d\n")
  26. #define KEY_READ_X(name) KEY_READ(name, name, 20, "0x%x\n")
  27. #define KEY_OPS(name) \
  28. static const struct file_operations key_ ##name## _ops = { \
  29. .read = key_##name##_read, \
  30. .open = mac80211_open_file_generic, \
  31. }
  32. #define KEY_FILE(name, format) \
  33. KEY_READ_##format(name) \
  34. KEY_OPS(name)
  35. #define KEY_CONF_READ(name, buflen, format_string) \
  36. KEY_READ(conf_##name, conf.name, buflen, format_string)
  37. #define KEY_CONF_READ_D(name) KEY_CONF_READ(name, 20, "%d\n")
  38. #define KEY_CONF_OPS(name) \
  39. static const struct file_operations key_ ##name## _ops = { \
  40. .read = key_conf_##name##_read, \
  41. .open = mac80211_open_file_generic, \
  42. }
  43. #define KEY_CONF_FILE(name, format) \
  44. KEY_CONF_READ_##format(name) \
  45. KEY_CONF_OPS(name)
  46. KEY_CONF_FILE(keylen, D);
  47. KEY_CONF_FILE(keyidx, D);
  48. KEY_CONF_FILE(hw_key_idx, D);
  49. KEY_FILE(flags, X);
  50. KEY_FILE(tx_rx_count, D);
  51. static ssize_t key_algorithm_read(struct file *file,
  52. char __user *userbuf,
  53. size_t count, loff_t *ppos)
  54. {
  55. char *alg;
  56. struct ieee80211_key *key = file->private_data;
  57. switch (key->conf.alg) {
  58. case ALG_WEP:
  59. alg = "WEP\n";
  60. break;
  61. case ALG_TKIP:
  62. alg = "TKIP\n";
  63. break;
  64. case ALG_CCMP:
  65. alg = "CCMP\n";
  66. break;
  67. default:
  68. return 0;
  69. }
  70. return simple_read_from_buffer(userbuf, count, ppos, alg, strlen(alg));
  71. }
  72. KEY_OPS(algorithm);
  73. static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf,
  74. size_t count, loff_t *ppos)
  75. {
  76. const u8 *tpn;
  77. char buf[20];
  78. int len;
  79. struct ieee80211_key *key = file->private_data;
  80. switch (key->conf.alg) {
  81. case ALG_WEP:
  82. len = scnprintf(buf, sizeof(buf), "\n");
  83. break;
  84. case ALG_TKIP:
  85. len = scnprintf(buf, sizeof(buf), "%08x %04x\n",
  86. key->u.tkip.iv32,
  87. key->u.tkip.iv16);
  88. break;
  89. case ALG_CCMP:
  90. tpn = key->u.ccmp.tx_pn;
  91. len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
  92. tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], tpn[5]);
  93. break;
  94. default:
  95. return 0;
  96. }
  97. return simple_read_from_buffer(userbuf, count, ppos, buf, len);
  98. }
  99. KEY_OPS(tx_spec);
  100. static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf,
  101. size_t count, loff_t *ppos)
  102. {
  103. struct ieee80211_key *key = file->private_data;
  104. char buf[14*NUM_RX_DATA_QUEUES+1], *p = buf;
  105. int i, len;
  106. const u8 *rpn;
  107. switch (key->conf.alg) {
  108. case ALG_WEP:
  109. len = scnprintf(buf, sizeof(buf), "\n");
  110. break;
  111. case ALG_TKIP:
  112. for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
  113. p += scnprintf(p, sizeof(buf)+buf-p,
  114. "%08x %04x\n",
  115. key->u.tkip.iv32_rx[i],
  116. key->u.tkip.iv16_rx[i]);
  117. len = p - buf;
  118. break;
  119. case ALG_CCMP:
  120. for (i = 0; i < NUM_RX_DATA_QUEUES; i++) {
  121. rpn = key->u.ccmp.rx_pn[i];
  122. p += scnprintf(p, sizeof(buf)+buf-p,
  123. "%02x%02x%02x%02x%02x%02x\n",
  124. rpn[0], rpn[1], rpn[2],
  125. rpn[3], rpn[4], rpn[5]);
  126. }
  127. len = p - buf;
  128. break;
  129. default:
  130. return 0;
  131. }
  132. return simple_read_from_buffer(userbuf, count, ppos, buf, len);
  133. }
  134. KEY_OPS(rx_spec);
  135. static ssize_t key_replays_read(struct file *file, char __user *userbuf,
  136. size_t count, loff_t *ppos)
  137. {
  138. struct ieee80211_key *key = file->private_data;
  139. char buf[20];
  140. int len;
  141. if (key->conf.alg != ALG_CCMP)
  142. return 0;
  143. len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays);
  144. return simple_read_from_buffer(userbuf, count, ppos, buf, len);
  145. }
  146. KEY_OPS(replays);
  147. static ssize_t key_key_read(struct file *file, char __user *userbuf,
  148. size_t count, loff_t *ppos)
  149. {
  150. struct ieee80211_key *key = file->private_data;
  151. int i, res, bufsize = 2 * key->conf.keylen + 2;
  152. char *buf = kmalloc(bufsize, GFP_KERNEL);
  153. char *p = buf;
  154. for (i = 0; i < key->conf.keylen; i++)
  155. p += scnprintf(p, bufsize + buf - p, "%02x", key->conf.key[i]);
  156. p += scnprintf(p, bufsize+buf-p, "\n");
  157. res = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
  158. kfree(buf);
  159. return res;
  160. }
  161. KEY_OPS(key);
  162. #define DEBUGFS_ADD(name) \
  163. key->debugfs.name = debugfs_create_file(#name, 0400,\
  164. key->debugfs.dir, key, &key_##name##_ops);
  165. void ieee80211_debugfs_key_add(struct ieee80211_local *local,
  166. struct ieee80211_key *key)
  167. {
  168. static int keycount;
  169. char buf[20];
  170. if (!local->debugfs.keys)
  171. return;
  172. sprintf(buf, "%d", keycount);
  173. keycount++;
  174. key->debugfs.dir = debugfs_create_dir(buf,
  175. local->debugfs.keys);
  176. if (!key->debugfs.dir)
  177. return;
  178. DEBUGFS_ADD(keylen);
  179. DEBUGFS_ADD(flags);
  180. DEBUGFS_ADD(keyidx);
  181. DEBUGFS_ADD(hw_key_idx);
  182. DEBUGFS_ADD(tx_rx_count);
  183. DEBUGFS_ADD(algorithm);
  184. DEBUGFS_ADD(tx_spec);
  185. DEBUGFS_ADD(rx_spec);
  186. DEBUGFS_ADD(replays);
  187. DEBUGFS_ADD(key);
  188. };
  189. #define DEBUGFS_DEL(name) \
  190. debugfs_remove(key->debugfs.name); key->debugfs.name = NULL;
  191. void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
  192. {
  193. if (!key)
  194. return;
  195. DEBUGFS_DEL(keylen);
  196. DEBUGFS_DEL(flags);
  197. DEBUGFS_DEL(keyidx);
  198. DEBUGFS_DEL(hw_key_idx);
  199. DEBUGFS_DEL(tx_rx_count);
  200. DEBUGFS_DEL(algorithm);
  201. DEBUGFS_DEL(tx_spec);
  202. DEBUGFS_DEL(rx_spec);
  203. DEBUGFS_DEL(replays);
  204. DEBUGFS_DEL(key);
  205. debugfs_remove(key->debugfs.stalink);
  206. key->debugfs.stalink = NULL;
  207. debugfs_remove(key->debugfs.dir);
  208. key->debugfs.dir = NULL;
  209. }
  210. void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata)
  211. {
  212. char buf[50];
  213. if (!sdata->debugfsdir)
  214. return;
  215. sprintf(buf, "../keys/%d", sdata->default_key->conf.keyidx);
  216. sdata->debugfs.default_key =
  217. debugfs_create_symlink("default_key", sdata->debugfsdir, buf);
  218. }
  219. void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata)
  220. {
  221. if (!sdata)
  222. return;
  223. debugfs_remove(sdata->debugfs.default_key);
  224. sdata->debugfs.default_key = NULL;
  225. }
  226. void ieee80211_debugfs_key_sta_link(struct ieee80211_key *key,
  227. struct sta_info *sta)
  228. {
  229. char buf[50];
  230. if (!key->debugfs.dir)
  231. return;
  232. sprintf(buf, "../../stations/" MAC_FMT, MAC_ARG(sta->addr));
  233. key->debugfs.stalink =
  234. debugfs_create_symlink("station", key->debugfs.dir, buf);
  235. }
  236. void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,
  237. struct sta_info *sta)
  238. {
  239. debugfs_remove(key->debugfs.stalink);
  240. key->debugfs.stalink = NULL;
  241. }