~ubuntu-branches/ubuntu/natty/linux-backports-modules-2.6.38/natty-updates

« back to all changes in this revision

Viewing changes to updates/compat-wireless-2.6.37/net/mac80211/debugfs_key.c

  • Committer: Bazaar Package Importer
  • Author(s): Tim Gardner, Tim Gardner
  • Date: 2011-06-08 10:44:09 UTC
  • Revision ID: james.westby@ubuntu.com-20110608104409-fnl8carkdo15bwsz
Tags: 2.6.38-10.6
[ Tim Gardner ]

Shorten compat-wireless package name to cw to accomodate
CDROM file name length restrictions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 
11
 
#include <linux/kobject.h>
12
 
#include <linux/slab.h>
13
 
#include "ieee80211_i.h"
14
 
#include "key.h"
15
 
#include "debugfs.h"
16
 
#include "debugfs_key.h"
17
 
 
18
 
#define KEY_READ(name, prop, buflen, format_string)                     \
19
 
static ssize_t key_##name##_read(struct file *file,                     \
20
 
                                 char __user *userbuf,                  \
21
 
                                 size_t count, loff_t *ppos)            \
22
 
{                                                                       \
23
 
        char buf[buflen];                                               \
24
 
        struct ieee80211_key *key = file->private_data;                 \
25
 
        int res = scnprintf(buf, buflen, format_string, key->prop);     \
26
 
        return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
27
 
}
28
 
#define KEY_READ_D(name) KEY_READ(name, name, 20, "%d\n")
29
 
#define KEY_READ_X(name) KEY_READ(name, name, 20, "0x%x\n")
30
 
 
31
 
#define KEY_OPS(name)                                                   \
32
 
static const struct file_operations key_ ##name## _ops = {              \
33
 
        .read = key_##name##_read,                                      \
34
 
        .open = mac80211_open_file_generic,                             \
35
 
        .llseek = generic_file_llseek,                                  \
36
 
}
37
 
 
38
 
#define KEY_FILE(name, format)                                          \
39
 
                 KEY_READ_##format(name)                                \
40
 
                 KEY_OPS(name)
41
 
 
42
 
#define KEY_CONF_READ(name, buflen, format_string)                      \
43
 
        KEY_READ(conf_##name, conf.name, buflen, format_string)
44
 
#define KEY_CONF_READ_D(name) KEY_CONF_READ(name, 20, "%d\n")
45
 
 
46
 
#define KEY_CONF_OPS(name)                                              \
47
 
static const struct file_operations key_ ##name## _ops = {              \
48
 
        .read = key_conf_##name##_read,                                 \
49
 
        .open = mac80211_open_file_generic,                             \
50
 
        .llseek = generic_file_llseek,                                  \
51
 
}
52
 
 
53
 
#define KEY_CONF_FILE(name, format)                                     \
54
 
                 KEY_CONF_READ_##format(name)                           \
55
 
                 KEY_CONF_OPS(name)
56
 
 
57
 
KEY_CONF_FILE(keylen, D);
58
 
KEY_CONF_FILE(keyidx, D);
59
 
KEY_CONF_FILE(hw_key_idx, D);
60
 
KEY_FILE(flags, X);
61
 
KEY_FILE(tx_rx_count, D);
62
 
KEY_READ(ifindex, sdata->name, IFNAMSIZ + 2, "%s\n");
63
 
KEY_OPS(ifindex);
64
 
 
65
 
static ssize_t key_algorithm_read(struct file *file,
66
 
                                  char __user *userbuf,
67
 
                                  size_t count, loff_t *ppos)
68
 
{
69
 
        char buf[15];
70
 
        struct ieee80211_key *key = file->private_data;
71
 
        u32 c = key->conf.cipher;
72
 
 
73
 
        sprintf(buf, "%.2x-%.2x-%.2x:%d\n",
74
 
                c >> 24, (c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff);
75
 
        return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf));
76
 
}
77
 
KEY_OPS(algorithm);
78
 
 
79
 
static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf,
80
 
                                size_t count, loff_t *ppos)
81
 
{
82
 
        const u8 *tpn;
83
 
        char buf[20];
84
 
        int len;
85
 
        struct ieee80211_key *key = file->private_data;
86
 
 
87
 
        switch (key->conf.cipher) {
88
 
        case WLAN_CIPHER_SUITE_WEP40:
89
 
        case WLAN_CIPHER_SUITE_WEP104:
90
 
                len = scnprintf(buf, sizeof(buf), "\n");
91
 
                break;
92
 
        case WLAN_CIPHER_SUITE_TKIP:
93
 
                len = scnprintf(buf, sizeof(buf), "%08x %04x\n",
94
 
                                key->u.tkip.tx.iv32,
95
 
                                key->u.tkip.tx.iv16);
96
 
                break;
97
 
        case WLAN_CIPHER_SUITE_CCMP:
98
 
                tpn = key->u.ccmp.tx_pn;
99
 
                len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
100
 
                                tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], tpn[5]);
101
 
                break;
102
 
        case WLAN_CIPHER_SUITE_AES_CMAC:
103
 
                tpn = key->u.aes_cmac.tx_pn;
104
 
                len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n",
105
 
                                tpn[0], tpn[1], tpn[2], tpn[3], tpn[4],
106
 
                                tpn[5]);
107
 
                break;
108
 
        default:
109
 
                return 0;
110
 
        }
111
 
        return simple_read_from_buffer(userbuf, count, ppos, buf, len);
112
 
}
113
 
KEY_OPS(tx_spec);
114
 
 
115
 
static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf,
116
 
                                size_t count, loff_t *ppos)
117
 
{
118
 
        struct ieee80211_key *key = file->private_data;
119
 
        char buf[14*NUM_RX_DATA_QUEUES+1], *p = buf;
120
 
        int i, len;
121
 
        const u8 *rpn;
122
 
 
123
 
        switch (key->conf.cipher) {
124
 
        case WLAN_CIPHER_SUITE_WEP40:
125
 
        case WLAN_CIPHER_SUITE_WEP104:
126
 
                len = scnprintf(buf, sizeof(buf), "\n");
127
 
                break;
128
 
        case WLAN_CIPHER_SUITE_TKIP:
129
 
                for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
130
 
                        p += scnprintf(p, sizeof(buf)+buf-p,
131
 
                                       "%08x %04x\n",
132
 
                                       key->u.tkip.rx[i].iv32,
133
 
                                       key->u.tkip.rx[i].iv16);
134
 
                len = p - buf;
135
 
                break;
136
 
        case WLAN_CIPHER_SUITE_CCMP:
137
 
                for (i = 0; i < NUM_RX_DATA_QUEUES + 1; i++) {
138
 
                        rpn = key->u.ccmp.rx_pn[i];
139
 
                        p += scnprintf(p, sizeof(buf)+buf-p,
140
 
                                       "%02x%02x%02x%02x%02x%02x\n",
141
 
                                       rpn[0], rpn[1], rpn[2],
142
 
                                       rpn[3], rpn[4], rpn[5]);
143
 
                }
144
 
                len = p - buf;
145
 
                break;
146
 
        case WLAN_CIPHER_SUITE_AES_CMAC:
147
 
                rpn = key->u.aes_cmac.rx_pn;
148
 
                p += scnprintf(p, sizeof(buf)+buf-p,
149
 
                               "%02x%02x%02x%02x%02x%02x\n",
150
 
                               rpn[0], rpn[1], rpn[2],
151
 
                               rpn[3], rpn[4], rpn[5]);
152
 
                len = p - buf;
153
 
                break;
154
 
        default:
155
 
                return 0;
156
 
        }
157
 
        return simple_read_from_buffer(userbuf, count, ppos, buf, len);
158
 
}
159
 
KEY_OPS(rx_spec);
160
 
 
161
 
static ssize_t key_replays_read(struct file *file, char __user *userbuf,
162
 
                                size_t count, loff_t *ppos)
163
 
{
164
 
        struct ieee80211_key *key = file->private_data;
165
 
        char buf[20];
166
 
        int len;
167
 
 
168
 
        switch (key->conf.cipher) {
169
 
        case WLAN_CIPHER_SUITE_CCMP:
170
 
                len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays);
171
 
                break;
172
 
        case WLAN_CIPHER_SUITE_AES_CMAC:
173
 
                len = scnprintf(buf, sizeof(buf), "%u\n",
174
 
                                key->u.aes_cmac.replays);
175
 
                break;
176
 
        default:
177
 
                return 0;
178
 
        }
179
 
        return simple_read_from_buffer(userbuf, count, ppos, buf, len);
180
 
}
181
 
KEY_OPS(replays);
182
 
 
183
 
static ssize_t key_icverrors_read(struct file *file, char __user *userbuf,
184
 
                                  size_t count, loff_t *ppos)
185
 
{
186
 
        struct ieee80211_key *key = file->private_data;
187
 
        char buf[20];
188
 
        int len;
189
 
 
190
 
        switch (key->conf.cipher) {
191
 
        case WLAN_CIPHER_SUITE_AES_CMAC:
192
 
                len = scnprintf(buf, sizeof(buf), "%u\n",
193
 
                                key->u.aes_cmac.icverrors);
194
 
                break;
195
 
        default:
196
 
                return 0;
197
 
        }
198
 
        return simple_read_from_buffer(userbuf, count, ppos, buf, len);
199
 
}
200
 
KEY_OPS(icverrors);
201
 
 
202
 
static ssize_t key_key_read(struct file *file, char __user *userbuf,
203
 
                            size_t count, loff_t *ppos)
204
 
{
205
 
        struct ieee80211_key *key = file->private_data;
206
 
        int i, bufsize = 2 * key->conf.keylen + 2;
207
 
        char *buf = kmalloc(bufsize, GFP_KERNEL);
208
 
        char *p = buf;
209
 
        ssize_t res;
210
 
 
211
 
        if (!buf)
212
 
                return -ENOMEM;
213
 
 
214
 
        for (i = 0; i < key->conf.keylen; i++)
215
 
                p += scnprintf(p, bufsize + buf - p, "%02x", key->conf.key[i]);
216
 
        p += scnprintf(p, bufsize+buf-p, "\n");
217
 
        res = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
218
 
        kfree(buf);
219
 
        return res;
220
 
}
221
 
KEY_OPS(key);
222
 
 
223
 
#define DEBUGFS_ADD(name) \
224
 
        debugfs_create_file(#name, 0400, key->debugfs.dir, \
225
 
                            key, &key_##name##_ops);
226
 
 
227
 
void ieee80211_debugfs_key_add(struct ieee80211_key *key)
228
 
  {
229
 
        static int keycount;
230
 
        char buf[50];
231
 
        struct sta_info *sta;
232
 
 
233
 
        if (!key->local->debugfs.keys)
234
 
                return;
235
 
 
236
 
        sprintf(buf, "%d", keycount);
237
 
        key->debugfs.cnt = keycount;
238
 
        keycount++;
239
 
        key->debugfs.dir = debugfs_create_dir(buf,
240
 
                                        key->local->debugfs.keys);
241
 
 
242
 
        if (!key->debugfs.dir)
243
 
                return;
244
 
 
245
 
        rcu_read_lock();
246
 
        sta = rcu_dereference(key->sta);
247
 
        if (sta)
248
 
                sprintf(buf, "../../stations/%pM", sta->sta.addr);
249
 
        rcu_read_unlock();
250
 
 
251
 
        /* using sta as a boolean is fine outside RCU lock */
252
 
        if (sta)
253
 
                key->debugfs.stalink =
254
 
                        debugfs_create_symlink("station", key->debugfs.dir, buf);
255
 
 
256
 
        DEBUGFS_ADD(keylen);
257
 
        DEBUGFS_ADD(flags);
258
 
        DEBUGFS_ADD(keyidx);
259
 
        DEBUGFS_ADD(hw_key_idx);
260
 
        DEBUGFS_ADD(tx_rx_count);
261
 
        DEBUGFS_ADD(algorithm);
262
 
        DEBUGFS_ADD(tx_spec);
263
 
        DEBUGFS_ADD(rx_spec);
264
 
        DEBUGFS_ADD(replays);
265
 
        DEBUGFS_ADD(icverrors);
266
 
        DEBUGFS_ADD(key);
267
 
        DEBUGFS_ADD(ifindex);
268
 
};
269
 
 
270
 
void ieee80211_debugfs_key_remove(struct ieee80211_key *key)
271
 
{
272
 
        if (!key)
273
 
                return;
274
 
 
275
 
        debugfs_remove_recursive(key->debugfs.dir);
276
 
        key->debugfs.dir = NULL;
277
 
}
278
 
void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata)
279
 
{
280
 
        char buf[50];
281
 
        struct ieee80211_key *key;
282
 
 
283
 
        if (!sdata->debugfs.dir)
284
 
                return;
285
 
 
286
 
        /* this is running under the key lock */
287
 
 
288
 
        key = sdata->default_key;
289
 
        if (key) {
290
 
                sprintf(buf, "../keys/%d", key->debugfs.cnt);
291
 
                sdata->debugfs.default_key =
292
 
                        debugfs_create_symlink("default_key",
293
 
                                               sdata->debugfs.dir, buf);
294
 
        } else
295
 
                ieee80211_debugfs_key_remove_default(sdata);
296
 
}
297
 
 
298
 
void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata)
299
 
{
300
 
        if (!sdata)
301
 
                return;
302
 
 
303
 
        debugfs_remove(sdata->debugfs.default_key);
304
 
        sdata->debugfs.default_key = NULL;
305
 
}
306
 
 
307
 
void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata)
308
 
{
309
 
        char buf[50];
310
 
        struct ieee80211_key *key;
311
 
 
312
 
        if (!sdata->debugfs.dir)
313
 
                return;
314
 
 
315
 
        /* this is running under the key lock */
316
 
 
317
 
        key = sdata->default_mgmt_key;
318
 
        if (key) {
319
 
                sprintf(buf, "../keys/%d", key->debugfs.cnt);
320
 
                sdata->debugfs.default_mgmt_key =
321
 
                        debugfs_create_symlink("default_mgmt_key",
322
 
                                               sdata->debugfs.dir, buf);
323
 
        } else
324
 
                ieee80211_debugfs_key_remove_mgmt_default(sdata);
325
 
}
326
 
 
327
 
void ieee80211_debugfs_key_remove_mgmt_default(struct ieee80211_sub_if_data *sdata)
328
 
{
329
 
        if (!sdata)
330
 
                return;
331
 
 
332
 
        debugfs_remove(sdata->debugfs.default_mgmt_key);
333
 
        sdata->debugfs.default_mgmt_key = NULL;
334
 
}
335
 
 
336
 
void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,
337
 
                                   struct sta_info *sta)
338
 
{
339
 
        debugfs_remove(key->debugfs.stalink);
340
 
        key->debugfs.stalink = NULL;
341
 
}