~ubuntu-branches/ubuntu/saucy/wpasupplicant/saucy

« back to all changes in this revision

Viewing changes to src/drivers/driver_atheros.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathieu Trudel-Lapierre
  • Date: 2010-11-22 09:43:43 UTC
  • mfrom: (1.1.16 upstream)
  • Revision ID: james.westby@ubuntu.com-20101122094343-qgsxaojvmswfri77
Tags: 0.7.3-0ubuntu1
* Get wpasupplicant 0.7.3 from Debian's SVN. Leaving 0.7.3-1 as unreleased
  for now.
* Build-Depend on debhelper 8, since the packaging from Debian uses compat 8.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * hostapd / Driver interaction with Atheros driver
 
3
 * Copyright (c) 2004, Sam Leffler <sam@errno.com>
 
4
 * Copyright (c) 2004, Video54 Technologies
 
5
 * Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi>
 
6
 * Copyright (c) 2009, Atheros Communications
 
7
 *
 
8
 * This program is free software; you can redistribute it and/or modify
 
9
 * it under the terms of the GNU General Public License version 2 as
 
10
 * published by the Free Software Foundation.
 
11
 *
 
12
 * Alternatively, this software may be distributed under the terms of BSD
 
13
 * license.
 
14
 *
 
15
 * See README and COPYING for more details.
 
16
 */
 
17
 
 
18
#include "includes.h"
 
19
#include <net/if.h>
 
20
#include <sys/ioctl.h>
 
21
 
 
22
#include "common.h"
 
23
#ifndef _BYTE_ORDER
 
24
#ifdef WORDS_BIGENDIAN
 
25
#define _BYTE_ORDER _BIG_ENDIAN
 
26
#else
 
27
#define _BYTE_ORDER _LITTLE_ENDIAN
 
28
#endif
 
29
#endif /* _BYTE_ORDER */
 
30
 
 
31
/*
 
32
 * Note, the ATH_WPS_IE setting must match with the driver build.. If the
 
33
 * driver does not include this, the IEEE80211_IOCTL_GETWPAIE ioctl will fail.
 
34
 */
 
35
#define ATH_WPS_IE
 
36
 
 
37
#include "os/linux/include/ieee80211_external.h"
 
38
 
 
39
 
 
40
#ifdef CONFIG_WPS
 
41
#include <netpacket/packet.h>
 
42
 
 
43
#ifndef ETH_P_80211_RAW
 
44
#define ETH_P_80211_RAW 0x0019
 
45
#endif
 
46
#endif /* CONFIG_WPS */
 
47
 
 
48
#include "wireless_copy.h"
 
49
 
 
50
#include "driver.h"
 
51
#include "eloop.h"
 
52
#include "priv_netlink.h"
 
53
#include "l2_packet/l2_packet.h"
 
54
#include "common/ieee802_11_defs.h"
 
55
#include "netlink.h"
 
56
#include "linux_ioctl.h"
 
57
 
 
58
 
 
59
struct madwifi_driver_data {
 
60
        struct hostapd_data *hapd;              /* back pointer */
 
61
 
 
62
        char    iface[IFNAMSIZ + 1];
 
63
        int     ifindex;
 
64
        struct l2_packet_data *sock_xmit;       /* raw packet xmit socket */
 
65
        struct l2_packet_data *sock_recv;       /* raw packet recv socket */
 
66
        int     ioctl_sock;                     /* socket for ioctl() use */
 
67
        struct netlink_data *netlink;
 
68
        int     we_version;
 
69
        u8      acct_mac[ETH_ALEN];
 
70
        struct hostap_sta_driver_data acct_data;
 
71
 
 
72
        struct l2_packet_data *sock_raw; /* raw 802.11 management frames */
 
73
};
 
74
 
 
75
static int madwifi_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
 
76
                              int reason_code);
 
77
static int madwifi_set_privacy(void *priv, int enabled);
 
78
 
 
79
static const char * athr_get_ioctl_name(int op)
 
80
{
 
81
        switch (op) {
 
82
        case IEEE80211_IOCTL_SETPARAM:
 
83
                return "SETPARAM";
 
84
        case IEEE80211_IOCTL_GETPARAM:
 
85
                return "GETPARAM";
 
86
        case IEEE80211_IOCTL_SETKEY:
 
87
                return "SETKEY";
 
88
        case IEEE80211_IOCTL_SETWMMPARAMS:
 
89
                return "SETWMMPARAMS";
 
90
        case IEEE80211_IOCTL_DELKEY:
 
91
                return "DELKEY";
 
92
        case IEEE80211_IOCTL_GETWMMPARAMS:
 
93
                return "GETWMMPARAMS";
 
94
        case IEEE80211_IOCTL_SETMLME:
 
95
                return "SETMLME";
 
96
        case IEEE80211_IOCTL_GETCHANINFO:
 
97
                return "GETCHANINFO";
 
98
        case IEEE80211_IOCTL_SETOPTIE:
 
99
                return "SETOPTIE";
 
100
        case IEEE80211_IOCTL_GETOPTIE:
 
101
                return "GETOPTIE";
 
102
        case IEEE80211_IOCTL_ADDMAC:
 
103
                return "ADDMAC";
 
104
        case IEEE80211_IOCTL_DELMAC:
 
105
                return "DELMAC";
 
106
        case IEEE80211_IOCTL_GETCHANLIST:
 
107
                return "GETCHANLIST";
 
108
        case IEEE80211_IOCTL_SETCHANLIST:
 
109
                return "SETCHANLIST";
 
110
        case IEEE80211_IOCTL_KICKMAC:
 
111
                return "KICKMAC";
 
112
        case IEEE80211_IOCTL_CHANSWITCH:
 
113
                return "CHANSWITCH";
 
114
        case IEEE80211_IOCTL_GETMODE:
 
115
                return "GETMODE";
 
116
        case IEEE80211_IOCTL_SETMODE:
 
117
                return "SETMODE";
 
118
        case IEEE80211_IOCTL_GET_APPIEBUF:
 
119
                return "GET_APPIEBUF";
 
120
        case IEEE80211_IOCTL_SET_APPIEBUF:
 
121
                return "SET_APPIEBUF";
 
122
        case IEEE80211_IOCTL_SET_ACPARAMS:
 
123
                return "SET_ACPARAMS";
 
124
        case IEEE80211_IOCTL_FILTERFRAME:
 
125
                return "FILTERFRAME";
 
126
        case IEEE80211_IOCTL_SET_RTPARAMS:
 
127
                return "SET_RTPARAMS";
 
128
        case IEEE80211_IOCTL_SENDADDBA:
 
129
                return "SENDADDBA";
 
130
        case IEEE80211_IOCTL_GETADDBASTATUS:
 
131
                return "GETADDBASTATUS";
 
132
        case IEEE80211_IOCTL_SENDDELBA:
 
133
                return "SENDDELBA";
 
134
        case IEEE80211_IOCTL_SET_MEDENYENTRY:
 
135
                return "SET_MEDENYENTRY";
 
136
        case IEEE80211_IOCTL_SET_ADDBARESP:
 
137
                return "SET_ADDBARESP";
 
138
        case IEEE80211_IOCTL_GET_MACADDR:
 
139
                return "GET_MACADDR";
 
140
        case IEEE80211_IOCTL_SET_HBRPARAMS:
 
141
                return "SET_HBRPARAMS";
 
142
        case IEEE80211_IOCTL_SET_RXTIMEOUT:
 
143
                return "SET_RXTIMEOUT";
 
144
        case IEEE80211_IOCTL_STA_STATS:
 
145
                return "STA_STATS";
 
146
        case IEEE80211_IOCTL_GETWPAIE:
 
147
                return "GETWPAIE";
 
148
        default:
 
149
                return "??";
 
150
        }
 
151
}
 
152
 
 
153
 
 
154
static const char * athr_get_param_name(int op)
 
155
{
 
156
        switch (op) {
 
157
        case IEEE80211_IOC_MCASTCIPHER:
 
158
                return "MCASTCIPHER";
 
159
        case IEEE80211_PARAM_MCASTKEYLEN:
 
160
                return "MCASTKEYLEN";
 
161
        case IEEE80211_PARAM_UCASTCIPHERS:
 
162
                return "UCASTCIPHERS";
 
163
        case IEEE80211_PARAM_KEYMGTALGS:
 
164
                return "KEYMGTALGS";
 
165
        case IEEE80211_PARAM_RSNCAPS:
 
166
                return "RSNCAPS";
 
167
        case IEEE80211_PARAM_WPA:
 
168
                return "WPA";
 
169
        case IEEE80211_PARAM_AUTHMODE:
 
170
                return "AUTHMODE";
 
171
        case IEEE80211_PARAM_PRIVACY:
 
172
                return "PRIVACY";
 
173
        case IEEE80211_PARAM_COUNTERMEASURES:
 
174
                return "COUNTERMEASURES";
 
175
        default:
 
176
                return "??";
 
177
        }
 
178
}
 
179
 
 
180
 
 
181
static int
 
182
set80211priv(struct madwifi_driver_data *drv, int op, void *data, int len)
 
183
{
 
184
        struct iwreq iwr;
 
185
        int do_inline = len < IFNAMSIZ;
 
186
 
 
187
        /* Certain ioctls must use the non-inlined method */
 
188
        if (op == IEEE80211_IOCTL_SET_APPIEBUF ||
 
189
            op == IEEE80211_IOCTL_FILTERFRAME)
 
190
                do_inline = 0;
 
191
 
 
192
        memset(&iwr, 0, sizeof(iwr));
 
193
        os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
 
194
        if (do_inline) {
 
195
                /*
 
196
                 * Argument data fits inline; put it there.
 
197
                 */
 
198
                memcpy(iwr.u.name, data, len);
 
199
        } else {
 
200
                /*
 
201
                 * Argument data too big for inline transfer; setup a
 
202
                 * parameter block instead; the kernel will transfer
 
203
                 * the data for the driver.
 
204
                 */
 
205
                iwr.u.data.pointer = data;
 
206
                iwr.u.data.length = len;
 
207
        }
 
208
 
 
209
        if (ioctl(drv->ioctl_sock, op, &iwr) < 0) {
 
210
                wpa_printf(MSG_DEBUG, "atheros: %s: %s: ioctl op=0x%x "
 
211
                           "(%s) len=%d failed: %d (%s)",
 
212
                           __func__, drv->iface, op,
 
213
                           athr_get_ioctl_name(op),
 
214
                           len, errno, strerror(errno));
 
215
                return -1;
 
216
        }
 
217
        return 0;
 
218
}
 
219
 
 
220
static int
 
221
set80211param(struct madwifi_driver_data *drv, int op, int arg)
 
222
{
 
223
        struct iwreq iwr;
 
224
 
 
225
        memset(&iwr, 0, sizeof(iwr));
 
226
        os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
 
227
        iwr.u.mode = op;
 
228
        memcpy(iwr.u.name+sizeof(__u32), &arg, sizeof(arg));
 
229
 
 
230
        if (ioctl(drv->ioctl_sock, IEEE80211_IOCTL_SETPARAM, &iwr) < 0) {
 
231
                perror("ioctl[IEEE80211_IOCTL_SETPARAM]");
 
232
                wpa_printf(MSG_DEBUG, "%s: %s: Failed to set parameter (op %d "
 
233
                           "(%s) arg %d)", __func__, drv->iface, op,
 
234
                           athr_get_param_name(op), arg);
 
235
                return -1;
 
236
        }
 
237
        return 0;
 
238
}
 
239
 
 
240
#ifndef CONFIG_NO_STDOUT_DEBUG
 
241
static const char *
 
242
ether_sprintf(const u8 *addr)
 
243
{
 
244
        static char buf[sizeof(MACSTR)];
 
245
 
 
246
        if (addr != NULL)
 
247
                snprintf(buf, sizeof(buf), MACSTR, MAC2STR(addr));
 
248
        else
 
249
                snprintf(buf, sizeof(buf), MACSTR, 0,0,0,0,0,0);
 
250
        return buf;
 
251
}
 
252
#endif /* CONFIG_NO_STDOUT_DEBUG */
 
253
 
 
254
/*
 
255
 * Configure WPA parameters.
 
256
 */
 
257
static int
 
258
madwifi_configure_wpa(struct madwifi_driver_data *drv,
 
259
                      struct wpa_bss_params *params)
 
260
{
 
261
        int v;
 
262
 
 
263
        switch (params->wpa_group) {
 
264
        case WPA_CIPHER_CCMP:
 
265
                v = IEEE80211_CIPHER_AES_CCM;
 
266
                break;
 
267
        case WPA_CIPHER_TKIP:
 
268
                v = IEEE80211_CIPHER_TKIP;
 
269
                break;
 
270
        case WPA_CIPHER_WEP104:
 
271
                v = IEEE80211_CIPHER_WEP;
 
272
                break;
 
273
        case WPA_CIPHER_WEP40:
 
274
                v = IEEE80211_CIPHER_WEP;
 
275
                break;
 
276
        case WPA_CIPHER_NONE:
 
277
                v = IEEE80211_CIPHER_NONE;
 
278
                break;
 
279
        default:
 
280
                wpa_printf(MSG_ERROR, "Unknown group key cipher %u",
 
281
                           params->wpa_group);
 
282
                return -1;
 
283
        }
 
284
        wpa_printf(MSG_DEBUG, "%s: group key cipher=%d", __func__, v);
 
285
        if (set80211param(drv, IEEE80211_PARAM_MCASTCIPHER, v)) {
 
286
                printf("Unable to set group key cipher to %u\n", v);
 
287
                return -1;
 
288
        }
 
289
        if (v == IEEE80211_CIPHER_WEP) {
 
290
                /* key length is done only for specific ciphers */
 
291
                v = (params->wpa_group == WPA_CIPHER_WEP104 ? 13 : 5);
 
292
                if (set80211param(drv, IEEE80211_PARAM_MCASTKEYLEN, v)) {
 
293
                        printf("Unable to set group key length to %u\n", v);
 
294
                        return -1;
 
295
                }
 
296
        }
 
297
 
 
298
        v = 0;
 
299
        if (params->wpa_pairwise & WPA_CIPHER_CCMP)
 
300
                v |= 1<<IEEE80211_CIPHER_AES_CCM;
 
301
        if (params->wpa_pairwise & WPA_CIPHER_TKIP)
 
302
                v |= 1<<IEEE80211_CIPHER_TKIP;
 
303
        if (params->wpa_pairwise & WPA_CIPHER_NONE)
 
304
                v |= 1<<IEEE80211_CIPHER_NONE;
 
305
        wpa_printf(MSG_DEBUG, "%s: pairwise key ciphers=0x%x", __func__, v);
 
306
        if (set80211param(drv, IEEE80211_PARAM_UCASTCIPHERS, v)) {
 
307
                printf("Unable to set pairwise key ciphers to 0x%x\n", v);
 
308
                return -1;
 
309
        }
 
310
 
 
311
        wpa_printf(MSG_DEBUG, "%s: key management algorithms=0x%x",
 
312
                   __func__, params->wpa_key_mgmt);
 
313
        if (set80211param(drv, IEEE80211_PARAM_KEYMGTALGS,
 
314
                          params->wpa_key_mgmt)) {
 
315
                printf("Unable to set key management algorithms to 0x%x\n",
 
316
                        params->wpa_key_mgmt);
 
317
                return -1;
 
318
        }
 
319
 
 
320
        v = 0;
 
321
        if (params->rsn_preauth)
 
322
                v |= BIT(0);
 
323
        wpa_printf(MSG_DEBUG, "%s: rsn capabilities=0x%x",
 
324
                   __func__, params->rsn_preauth);
 
325
        if (set80211param(drv, IEEE80211_PARAM_RSNCAPS, v)) {
 
326
                printf("Unable to set RSN capabilities to 0x%x\n", v);
 
327
                return -1;
 
328
        }
 
329
 
 
330
        wpa_printf(MSG_DEBUG, "%s: enable WPA=0x%x", __func__, params->wpa);
 
331
        if (set80211param(drv, IEEE80211_PARAM_WPA, params->wpa)) {
 
332
                printf("Unable to set WPA to %u\n", params->wpa);
 
333
                return -1;
 
334
        }
 
335
        return 0;
 
336
}
 
337
 
 
338
static int
 
339
madwifi_set_ieee8021x(void *priv, struct wpa_bss_params *params)
 
340
{
 
341
        struct madwifi_driver_data *drv = priv;
 
342
 
 
343
        wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, params->enabled);
 
344
 
 
345
        if (!params->enabled) {
 
346
                /* XXX restore state */
 
347
                if (set80211param(priv, IEEE80211_PARAM_AUTHMODE,
 
348
                                  IEEE80211_AUTH_AUTO) < 0)
 
349
                        return -1;
 
350
                /* IEEE80211_AUTH_AUTO ends up enabling Privacy; clear that */
 
351
                return madwifi_set_privacy(drv, 0);
 
352
        }
 
353
        if (!params->wpa && !params->ieee802_1x) {
 
354
                hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER,
 
355
                        HOSTAPD_LEVEL_WARNING, "No 802.1X or WPA enabled!");
 
356
                return -1;
 
357
        }
 
358
        if (params->wpa && madwifi_configure_wpa(drv, params) != 0) {
 
359
                hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER,
 
360
                        HOSTAPD_LEVEL_WARNING, "Error configuring WPA state!");
 
361
                return -1;
 
362
        }
 
363
        if (set80211param(priv, IEEE80211_PARAM_AUTHMODE,
 
364
                (params->wpa ? IEEE80211_AUTH_WPA : IEEE80211_AUTH_8021X))) {
 
365
                hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER,
 
366
                        HOSTAPD_LEVEL_WARNING, "Error enabling WPA/802.1X!");
 
367
                return -1;
 
368
        }
 
369
 
 
370
        return 0;
 
371
}
 
372
 
 
373
static int
 
374
madwifi_set_privacy(void *priv, int enabled)
 
375
{
 
376
        struct madwifi_driver_data *drv = priv;
 
377
 
 
378
        wpa_printf(MSG_DEBUG, "%s: enabled=%d", __func__, enabled);
 
379
 
 
380
        return set80211param(drv, IEEE80211_PARAM_PRIVACY, enabled);
 
381
}
 
382
 
 
383
static int
 
384
madwifi_set_sta_authorized(void *priv, const u8 *addr, int authorized)
 
385
{
 
386
        struct madwifi_driver_data *drv = priv;
 
387
        struct ieee80211req_mlme mlme;
 
388
        int ret;
 
389
 
 
390
        wpa_printf(MSG_DEBUG, "%s: addr=%s authorized=%d",
 
391
                   __func__, ether_sprintf(addr), authorized);
 
392
 
 
393
        if (authorized)
 
394
                mlme.im_op = IEEE80211_MLME_AUTHORIZE;
 
395
        else
 
396
                mlme.im_op = IEEE80211_MLME_UNAUTHORIZE;
 
397
        mlme.im_reason = 0;
 
398
        memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
 
399
        ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme));
 
400
        if (ret < 0) {
 
401
                wpa_printf(MSG_DEBUG, "%s: Failed to %sauthorize STA " MACSTR,
 
402
                           __func__, authorized ? "" : "un", MAC2STR(addr));
 
403
        }
 
404
 
 
405
        return ret;
 
406
}
 
407
 
 
408
static int
 
409
madwifi_sta_set_flags(void *priv, const u8 *addr,
 
410
                      int total_flags, int flags_or, int flags_and)
 
411
{
 
412
        /* For now, only support setting Authorized flag */
 
413
        if (flags_or & WPA_STA_AUTHORIZED)
 
414
                return madwifi_set_sta_authorized(priv, addr, 1);
 
415
        if (!(flags_and & WPA_STA_AUTHORIZED))
 
416
                return madwifi_set_sta_authorized(priv, addr, 0);
 
417
        return 0;
 
418
}
 
419
 
 
420
static int
 
421
madwifi_del_key(void *priv, const u8 *addr, int key_idx)
 
422
{
 
423
        struct madwifi_driver_data *drv = priv;
 
424
        struct ieee80211req_del_key wk;
 
425
        int ret;
 
426
 
 
427
        wpa_printf(MSG_DEBUG, "%s: addr=%s key_idx=%d",
 
428
                   __func__, ether_sprintf(addr), key_idx);
 
429
 
 
430
        memset(&wk, 0, sizeof(wk));
 
431
        if (addr != NULL) {
 
432
                memcpy(wk.idk_macaddr, addr, IEEE80211_ADDR_LEN);
 
433
                wk.idk_keyix = (u8) IEEE80211_KEYIX_NONE;
 
434
        } else {
 
435
                wk.idk_keyix = key_idx;
 
436
        }
 
437
 
 
438
        ret = set80211priv(drv, IEEE80211_IOCTL_DELKEY, &wk, sizeof(wk));
 
439
        if (ret < 0) {
 
440
                wpa_printf(MSG_DEBUG, "%s: Failed to delete key (addr %s"
 
441
                           " key_idx %d)", __func__, ether_sprintf(addr),
 
442
                           key_idx);
 
443
        }
 
444
 
 
445
        return ret;
 
446
}
 
447
 
 
448
static int
 
449
madwifi_set_key(const char *ifname, void *priv, enum wpa_alg alg,
 
450
                const u8 *addr, int key_idx, int set_tx, const u8 *seq,
 
451
                size_t seq_len, const u8 *key, size_t key_len)
 
452
{
 
453
        struct madwifi_driver_data *drv = priv;
 
454
        struct ieee80211req_key wk;
 
455
        u_int8_t cipher;
 
456
        int ret;
 
457
 
 
458
        if (alg == WPA_ALG_NONE)
 
459
                return madwifi_del_key(drv, addr, key_idx);
 
460
 
 
461
        wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%s key_idx=%d",
 
462
                   __func__, alg, ether_sprintf(addr), key_idx);
 
463
 
 
464
        switch (alg) {
 
465
        case WPA_ALG_WEP:
 
466
                cipher = IEEE80211_CIPHER_WEP;
 
467
                break;
 
468
        case WPA_ALG_TKIP:
 
469
                cipher = IEEE80211_CIPHER_TKIP;
 
470
                break;
 
471
        case WPA_ALG_CCMP:
 
472
                cipher = IEEE80211_CIPHER_AES_CCM;
 
473
                break;
 
474
        default:
 
475
                printf("%s: unknown/unsupported algorithm %d\n",
 
476
                        __func__, alg);
 
477
                return -1;
 
478
        }
 
479
 
 
480
        if (key_len > sizeof(wk.ik_keydata)) {
 
481
                printf("%s: key length %lu too big\n", __func__,
 
482
                       (unsigned long) key_len);
 
483
                return -3;
 
484
        }
 
485
 
 
486
        memset(&wk, 0, sizeof(wk));
 
487
        wk.ik_type = cipher;
 
488
        wk.ik_flags = IEEE80211_KEY_RECV | IEEE80211_KEY_XMIT;
 
489
        if (addr == NULL) {
 
490
                memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
 
491
                wk.ik_keyix = key_idx;
 
492
                wk.ik_flags |= IEEE80211_KEY_DEFAULT;
 
493
        } else {
 
494
                memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
 
495
                wk.ik_keyix = IEEE80211_KEYIX_NONE;
 
496
        }
 
497
        wk.ik_keylen = key_len;
 
498
        memcpy(wk.ik_keydata, key, key_len);
 
499
 
 
500
        ret = set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk));
 
501
        if (ret < 0) {
 
502
                wpa_printf(MSG_DEBUG, "%s: Failed to set key (addr %s"
 
503
                           " key_idx %d alg %d key_len %lu set_tx %d)",
 
504
                           __func__, ether_sprintf(wk.ik_macaddr), key_idx,
 
505
                           alg, (unsigned long) key_len, set_tx);
 
506
        }
 
507
 
 
508
        return ret;
 
509
}
 
510
 
 
511
 
 
512
static int
 
513
madwifi_get_seqnum(const char *ifname, void *priv, const u8 *addr, int idx,
 
514
                   u8 *seq)
 
515
{
 
516
        struct madwifi_driver_data *drv = priv;
 
517
        struct ieee80211req_key wk;
 
518
 
 
519
        wpa_printf(MSG_DEBUG, "%s: addr=%s idx=%d",
 
520
                   __func__, ether_sprintf(addr), idx);
 
521
 
 
522
        memset(&wk, 0, sizeof(wk));
 
523
        if (addr == NULL)
 
524
                memset(wk.ik_macaddr, 0xff, IEEE80211_ADDR_LEN);
 
525
        else
 
526
                memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN);
 
527
        wk.ik_keyix = idx;
 
528
 
 
529
        if (set80211priv(drv, IEEE80211_IOCTL_GETKEY, &wk, sizeof(wk))) {
 
530
                wpa_printf(MSG_DEBUG, "%s: Failed to get encryption data "
 
531
                           "(addr " MACSTR " key_idx %d)",
 
532
                           __func__, MAC2STR(wk.ik_macaddr), idx);
 
533
                return -1;
 
534
        }
 
535
 
 
536
#ifdef WORDS_BIGENDIAN
 
537
        {
 
538
                /*
 
539
                 * wk.ik_keytsc is in host byte order (big endian), need to
 
540
                 * swap it to match with the byte order used in WPA.
 
541
                 */
 
542
                int i;
 
543
#ifndef WPA_KEY_RSC_LEN
 
544
#define WPA_KEY_RSC_LEN 8
 
545
#endif
 
546
                u8 tmp[WPA_KEY_RSC_LEN];
 
547
                memcpy(tmp, &wk.ik_keytsc, sizeof(wk.ik_keytsc));
 
548
                for (i = 0; i < WPA_KEY_RSC_LEN; i++) {
 
549
                        seq[i] = tmp[WPA_KEY_RSC_LEN - i - 1];
 
550
                }
 
551
        }
 
552
#else /* WORDS_BIGENDIAN */
 
553
        memcpy(seq, &wk.ik_keytsc, sizeof(wk.ik_keytsc));
 
554
#endif /* WORDS_BIGENDIAN */
 
555
        return 0;
 
556
}
 
557
 
 
558
 
 
559
static int
 
560
madwifi_flush(void *priv)
 
561
{
 
562
        u8 allsta[IEEE80211_ADDR_LEN];
 
563
        memset(allsta, 0xff, IEEE80211_ADDR_LEN);
 
564
        return madwifi_sta_deauth(priv, NULL, allsta,
 
565
                                  IEEE80211_REASON_AUTH_LEAVE);
 
566
}
 
567
 
 
568
 
 
569
static int
 
570
madwifi_read_sta_driver_data(void *priv, struct hostap_sta_driver_data *data,
 
571
                             const u8 *addr)
 
572
{
 
573
        struct madwifi_driver_data *drv = priv;
 
574
        struct ieee80211req_sta_stats stats;
 
575
 
 
576
        memset(data, 0, sizeof(*data));
 
577
 
 
578
        /*
 
579
         * Fetch statistics for station from the system.
 
580
         */
 
581
        memset(&stats, 0, sizeof(stats));
 
582
        memcpy(stats.is_u.macaddr, addr, IEEE80211_ADDR_LEN);
 
583
        if (set80211priv(drv, IEEE80211_IOCTL_STA_STATS,
 
584
                         &stats, sizeof(stats))) {
 
585
                wpa_printf(MSG_DEBUG, "%s: Failed to fetch STA stats (addr "
 
586
                           MACSTR ")", __func__, MAC2STR(addr));
 
587
                if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) {
 
588
                        memcpy(data, &drv->acct_data, sizeof(*data));
 
589
                        return 0;
 
590
                }
 
591
 
 
592
                printf("Failed to get station stats information element.\n");
 
593
                return -1;
 
594
        }
 
595
 
 
596
        data->rx_packets = stats.is_stats.ns_rx_data;
 
597
        data->rx_bytes = stats.is_stats.ns_rx_bytes;
 
598
        data->tx_packets = stats.is_stats.ns_tx_data;
 
599
        data->tx_bytes = stats.is_stats.ns_tx_bytes;
 
600
        return 0;
 
601
}
 
602
 
 
603
 
 
604
static int
 
605
madwifi_sta_clear_stats(void *priv, const u8 *addr)
 
606
{
 
607
        struct madwifi_driver_data *drv = priv;
 
608
        struct ieee80211req_mlme mlme;
 
609
        int ret;
 
610
 
 
611
        wpa_printf(MSG_DEBUG, "%s: addr=%s", __func__, ether_sprintf(addr));
 
612
 
 
613
        mlme.im_op = IEEE80211_MLME_CLEAR_STATS;
 
614
        memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
 
615
        ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme,
 
616
                           sizeof(mlme));
 
617
        if (ret < 0) {
 
618
                wpa_printf(MSG_DEBUG, "%s: Failed to clear STA stats (addr "
 
619
                           MACSTR ")", __func__, MAC2STR(addr));
 
620
        }
 
621
 
 
622
        return ret;
 
623
}
 
624
 
 
625
 
 
626
static int
 
627
madwifi_set_opt_ie(void *priv, const u8 *ie, size_t ie_len)
 
628
{
 
629
        /*
 
630
         * Do nothing; we setup parameters at startup that define the
 
631
         * contents of the beacon information element.
 
632
         */
 
633
        return 0;
 
634
}
 
635
 
 
636
static int
 
637
madwifi_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
 
638
                   int reason_code)
 
639
{
 
640
        struct madwifi_driver_data *drv = priv;
 
641
        struct ieee80211req_mlme mlme;
 
642
        int ret;
 
643
 
 
644
        wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d",
 
645
                   __func__, ether_sprintf(addr), reason_code);
 
646
 
 
647
        mlme.im_op = IEEE80211_MLME_DEAUTH;
 
648
        mlme.im_reason = reason_code;
 
649
        memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
 
650
        ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme));
 
651
        if (ret < 0) {
 
652
                wpa_printf(MSG_DEBUG, "%s: Failed to deauth STA (addr " MACSTR
 
653
                           " reason %d)",
 
654
                           __func__, MAC2STR(addr), reason_code);
 
655
        }
 
656
 
 
657
        return ret;
 
658
}
 
659
 
 
660
static int
 
661
madwifi_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
 
662
                     int reason_code)
 
663
{
 
664
        struct madwifi_driver_data *drv = priv;
 
665
        struct ieee80211req_mlme mlme;
 
666
        int ret;
 
667
 
 
668
        wpa_printf(MSG_DEBUG, "%s: addr=%s reason_code=%d",
 
669
                   __func__, ether_sprintf(addr), reason_code);
 
670
 
 
671
        mlme.im_op = IEEE80211_MLME_DISASSOC;
 
672
        mlme.im_reason = reason_code;
 
673
        memcpy(mlme.im_macaddr, addr, IEEE80211_ADDR_LEN);
 
674
        ret = set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme));
 
675
        if (ret < 0) {
 
676
                wpa_printf(MSG_DEBUG, "%s: Failed to disassoc STA (addr "
 
677
                           MACSTR " reason %d)",
 
678
                           __func__, MAC2STR(addr), reason_code);
 
679
        }
 
680
 
 
681
        return ret;
 
682
}
 
683
 
 
684
#ifdef CONFIG_WPS
 
685
static void madwifi_raw_receive(void *ctx, const u8 *src_addr, const u8 *buf,
 
686
                                size_t len)
 
687
{
 
688
        struct madwifi_driver_data *drv = ctx;
 
689
        const struct ieee80211_mgmt *mgmt;
 
690
        u16 fc;
 
691
        union wpa_event_data event;
 
692
 
 
693
        /* Send Probe Request information to WPS processing */
 
694
 
 
695
        if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req))
 
696
                return;
 
697
        mgmt = (const struct ieee80211_mgmt *) buf;
 
698
 
 
699
        fc = le_to_host16(mgmt->frame_control);
 
700
        if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT ||
 
701
            WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_PROBE_REQ)
 
702
                return;
 
703
 
 
704
        os_memset(&event, 0, sizeof(event));
 
705
        event.rx_probe_req.sa = mgmt->sa;
 
706
        event.rx_probe_req.ie = mgmt->u.probe_req.variable;
 
707
        event.rx_probe_req.ie_len =
 
708
                len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req));
 
709
        wpa_supplicant_event(drv->hapd, EVENT_RX_PROBE_REQ, &event);
 
710
}
 
711
#endif /* CONFIG_WPS */
 
712
 
 
713
static int madwifi_receive_probe_req(struct madwifi_driver_data *drv)
 
714
{
 
715
        int ret = 0;
 
716
#ifdef CONFIG_WPS
 
717
        struct ieee80211req_set_filter filt;
 
718
 
 
719
        wpa_printf(MSG_DEBUG, "%s Enter", __func__);
 
720
        filt.app_filterype = IEEE80211_FILTER_TYPE_PROBE_REQ;
 
721
 
 
722
        ret = set80211priv(drv, IEEE80211_IOCTL_FILTERFRAME, &filt,
 
723
                           sizeof(struct ieee80211req_set_filter));
 
724
        if (ret)
 
725
                return ret;
 
726
 
 
727
        drv->sock_raw = l2_packet_init(drv->iface, NULL, ETH_P_80211_RAW,
 
728
                                       madwifi_raw_receive, drv, 1);
 
729
        if (drv->sock_raw == NULL)
 
730
                return -1;
 
731
#endif /* CONFIG_WPS */
 
732
        return ret;
 
733
}
 
734
 
 
735
#ifdef CONFIG_WPS
 
736
static int
 
737
madwifi_set_wps_ie(void *priv, const u8 *ie, size_t len, u32 frametype)
 
738
{
 
739
        struct madwifi_driver_data *drv = priv;
 
740
        u8 buf[256];
 
741
        struct ieee80211req_getset_appiebuf *beac_ie;
 
742
 
 
743
        wpa_printf(MSG_DEBUG, "%s buflen = %lu", __func__,
 
744
                   (unsigned long) len);
 
745
 
 
746
        beac_ie = (struct ieee80211req_getset_appiebuf *) buf;
 
747
        beac_ie->app_frmtype = frametype;
 
748
        beac_ie->app_buflen = len;
 
749
        memcpy(&(beac_ie->app_buf[0]), ie, len);
 
750
 
 
751
        return set80211priv(drv, IEEE80211_IOCTL_SET_APPIEBUF, beac_ie,
 
752
                            sizeof(struct ieee80211req_getset_appiebuf) + len);
 
753
}
 
754
 
 
755
static int
 
756
madwifi_set_ap_wps_ie(void *priv, const struct wpabuf *beacon,
 
757
                      const struct wpabuf *proberesp)
 
758
{
 
759
        if (madwifi_set_wps_ie(priv, beacon ? wpabuf_head(beacon) : NULL,
 
760
                               beacon ? wpabuf_len(beacon) : 0,
 
761
                               IEEE80211_APPIE_FRAME_BEACON))
 
762
                return -1;
 
763
        return madwifi_set_wps_ie(priv,
 
764
                                  proberesp ? wpabuf_head(proberesp) : NULL,
 
765
                                  proberesp ? wpabuf_len(proberesp): 0,
 
766
                                  IEEE80211_APPIE_FRAME_PROBE_RESP);
 
767
}
 
768
#else /* CONFIG_WPS */
 
769
#define madwifi_set_ap_wps_ie NULL
 
770
#endif /* CONFIG_WPS */
 
771
 
 
772
static void
 
773
madwifi_new_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN])
 
774
{
 
775
        struct hostapd_data *hapd = drv->hapd;
 
776
        struct ieee80211req_wpaie ie;
 
777
        int ielen = 0;
 
778
        u8 *iebuf = NULL;
 
779
 
 
780
        /*
 
781
         * Fetch negotiated WPA/RSN parameters from the system.
 
782
         */
 
783
        memset(&ie, 0, sizeof(ie));
 
784
        memcpy(ie.wpa_macaddr, addr, IEEE80211_ADDR_LEN);
 
785
        if (set80211priv(drv, IEEE80211_IOCTL_GETWPAIE, &ie, sizeof(ie))) {
 
786
                /*
 
787
                 * See ATH_WPS_IE comment in the beginning of the file for a
 
788
                 * possible cause for the failure..
 
789
                 */
 
790
                wpa_printf(MSG_DEBUG, "%s: Failed to get WPA/RSN IE: %s",
 
791
                           __func__, strerror(errno));
 
792
                goto no_ie;
 
793
        }
 
794
        wpa_hexdump(MSG_MSGDUMP, "madwifi req WPA IE",
 
795
                    ie.wpa_ie, IEEE80211_MAX_OPT_IE);
 
796
        wpa_hexdump(MSG_MSGDUMP, "madwifi req RSN IE",
 
797
                    ie.rsn_ie, IEEE80211_MAX_OPT_IE);
 
798
        iebuf = ie.wpa_ie;
 
799
        /* madwifi seems to return some random data if WPA/RSN IE is not set.
 
800
         * Assume the IE was not included if the IE type is unknown. */
 
801
        if (iebuf[0] != WLAN_EID_VENDOR_SPECIFIC)
 
802
                iebuf[1] = 0;
 
803
        if (iebuf[1] == 0 && ie.rsn_ie[1] > 0) {
 
804
                /* madwifi-ng svn #1453 added rsn_ie. Use it, if wpa_ie was not
 
805
                 * set. This is needed for WPA2. */
 
806
                iebuf = ie.rsn_ie;
 
807
                if (iebuf[0] != WLAN_EID_RSN)
 
808
                        iebuf[1] = 0;
 
809
        }
 
810
 
 
811
        ielen = iebuf[1];
 
812
        if (ielen == 0)
 
813
                iebuf = NULL;
 
814
        else
 
815
                ielen += 2;
 
816
 
 
817
no_ie:
 
818
        drv_event_assoc(hapd, addr, iebuf, ielen);
 
819
 
 
820
        if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) {
 
821
                /* Cached accounting data is not valid anymore. */
 
822
                memset(drv->acct_mac, 0, ETH_ALEN);
 
823
                memset(&drv->acct_data, 0, sizeof(drv->acct_data));
 
824
        }
 
825
}
 
826
 
 
827
static void
 
828
madwifi_wireless_event_wireless_custom(struct madwifi_driver_data *drv,
 
829
                                       char *custom, char *end)
 
830
{
 
831
        wpa_printf(MSG_DEBUG, "Custom wireless event: '%s'", custom);
 
832
 
 
833
        if (strncmp(custom, "MLME-MICHAELMICFAILURE.indication", 33) == 0) {
 
834
                char *pos;
 
835
                u8 addr[ETH_ALEN];
 
836
                pos = strstr(custom, "addr=");
 
837
                if (pos == NULL) {
 
838
                        wpa_printf(MSG_DEBUG,
 
839
                                   "MLME-MICHAELMICFAILURE.indication "
 
840
                                   "without sender address ignored");
 
841
                        return;
 
842
                }
 
843
                pos += 5;
 
844
                if (hwaddr_aton(pos, addr) == 0) {
 
845
                        union wpa_event_data data;
 
846
                        os_memset(&data, 0, sizeof(data));
 
847
                        data.michael_mic_failure.unicast = 1;
 
848
                        data.michael_mic_failure.src = addr;
 
849
                        wpa_supplicant_event(drv->hapd,
 
850
                                             EVENT_MICHAEL_MIC_FAILURE, &data);
 
851
                } else {
 
852
                        wpa_printf(MSG_DEBUG,
 
853
                                   "MLME-MICHAELMICFAILURE.indication "
 
854
                                   "with invalid MAC address");
 
855
                }
 
856
        } else if (strncmp(custom, "STA-TRAFFIC-STAT", 16) == 0) {
 
857
                char *key, *value;
 
858
                u32 val;
 
859
                key = custom;
 
860
                while ((key = strchr(key, '\n')) != NULL) {
 
861
                        key++;
 
862
                        value = strchr(key, '=');
 
863
                        if (value == NULL)
 
864
                                continue;
 
865
                        *value++ = '\0';
 
866
                        val = strtoul(value, NULL, 10);
 
867
                        if (strcmp(key, "mac") == 0)
 
868
                                hwaddr_aton(value, drv->acct_mac);
 
869
                        else if (strcmp(key, "rx_packets") == 0)
 
870
                                drv->acct_data.rx_packets = val;
 
871
                        else if (strcmp(key, "tx_packets") == 0)
 
872
                                drv->acct_data.tx_packets = val;
 
873
                        else if (strcmp(key, "rx_bytes") == 0)
 
874
                                drv->acct_data.rx_bytes = val;
 
875
                        else if (strcmp(key, "tx_bytes") == 0)
 
876
                                drv->acct_data.tx_bytes = val;
 
877
                        key = value;
 
878
                }
 
879
#ifdef CONFIG_WPS
 
880
        } else if (strncmp(custom, "PUSH-BUTTON.indication", 22) == 0) {
 
881
                /* Some atheros kernels send push button as a wireless event */
 
882
                /* PROBLEM! this event is received for ALL BSSs ...
 
883
                 * so all are enabled for WPS... ugh.
 
884
                 */
 
885
                wpa_supplicant_event(drv->hapd, EVENT_WPS_BUTTON_PUSHED, NULL);
 
886
        } else if (strncmp(custom, "Manage.prob_req ", 16) == 0) {
 
887
                /*
 
888
                 * Atheros driver uses a hack to pass Probe Request frames as a
 
889
                 * binary data in the custom wireless event. The old way (using
 
890
                 * packet sniffing) didn't work when bridging.
 
891
                 * Format: "Manage.prob_req <frame len>" | zero padding | frame
 
892
                 */
 
893
#define WPS_FRAM_TAG_SIZE 30 /* hardcoded in driver */
 
894
                int len = atoi(custom + 16);
 
895
                if (len < 0 || custom + WPS_FRAM_TAG_SIZE + len > end) {
 
896
                        wpa_printf(MSG_DEBUG, "Invalid Manage.prob_req event "
 
897
                                   "length %d", len);
 
898
                        return;
 
899
                }
 
900
                madwifi_raw_receive(drv, NULL,
 
901
                                    (u8 *) custom + WPS_FRAM_TAG_SIZE, len);
 
902
#endif /* CONFIG_WPS */
 
903
        }
 
904
}
 
905
 
 
906
static void
 
907
madwifi_wireless_event_wireless(struct madwifi_driver_data *drv,
 
908
                                char *data, int len)
 
909
{
 
910
        struct iw_event iwe_buf, *iwe = &iwe_buf;
 
911
        char *pos, *end, *custom, *buf;
 
912
 
 
913
        pos = data;
 
914
        end = data + len;
 
915
 
 
916
        while (pos + IW_EV_LCP_LEN <= end) {
 
917
                /* Event data may be unaligned, so make a local, aligned copy
 
918
                 * before processing. */
 
919
                memcpy(&iwe_buf, pos, IW_EV_LCP_LEN);
 
920
                wpa_printf(MSG_MSGDUMP, "Wireless event: cmd=0x%x len=%d",
 
921
                           iwe->cmd, iwe->len);
 
922
                if (iwe->len <= IW_EV_LCP_LEN)
 
923
                        return;
 
924
 
 
925
                custom = pos + IW_EV_POINT_LEN;
 
926
                if (drv->we_version > 18 &&
 
927
                    (iwe->cmd == IWEVMICHAELMICFAILURE ||
 
928
                     iwe->cmd == IWEVASSOCREQIE ||
 
929
                     iwe->cmd == IWEVCUSTOM)) {
 
930
                        /* WE-19 removed the pointer from struct iw_point */
 
931
                        char *dpos = (char *) &iwe_buf.u.data.length;
 
932
                        int dlen = dpos - (char *) &iwe_buf;
 
933
                        memcpy(dpos, pos + IW_EV_LCP_LEN,
 
934
                               sizeof(struct iw_event) - dlen);
 
935
                } else {
 
936
                        memcpy(&iwe_buf, pos, sizeof(struct iw_event));
 
937
                        custom += IW_EV_POINT_OFF;
 
938
                }
 
939
 
 
940
                switch (iwe->cmd) {
 
941
                case IWEVEXPIRED:
 
942
                        drv_event_disassoc(drv->hapd,
 
943
                                           (u8 *) iwe->u.addr.sa_data);
 
944
                        break;
 
945
                case IWEVREGISTERED:
 
946
                        madwifi_new_sta(drv, (u8 *) iwe->u.addr.sa_data);
 
947
                        break;
 
948
                case IWEVASSOCREQIE:
 
949
                        /* Driver hack.. Use IWEVASSOCREQIE to bypass
 
950
                         * IWEVCUSTOM size limitations. Need to handle this
 
951
                         * just like IWEVCUSTOM.
 
952
                         */
 
953
                case IWEVCUSTOM:
 
954
                        if (custom + iwe->u.data.length > end)
 
955
                                return;
 
956
                        buf = malloc(iwe->u.data.length + 1);
 
957
                        if (buf == NULL)
 
958
                                return;         /* XXX */
 
959
                        memcpy(buf, custom, iwe->u.data.length);
 
960
                        buf[iwe->u.data.length] = '\0';
 
961
                        madwifi_wireless_event_wireless_custom(
 
962
                                drv, buf, buf + iwe->u.data.length);
 
963
                        free(buf);
 
964
                        break;
 
965
                }
 
966
 
 
967
                pos += iwe->len;
 
968
        }
 
969
}
 
970
 
 
971
 
 
972
static void
 
973
madwifi_wireless_event_rtm_newlink(void *ctx,
 
974
                                   struct ifinfomsg *ifi, u8 *buf, size_t len)
 
975
{
 
976
        struct madwifi_driver_data *drv = ctx;
 
977
        int attrlen, rta_len;
 
978
        struct rtattr *attr;
 
979
 
 
980
        if (ifi->ifi_index != drv->ifindex)
 
981
                return;
 
982
 
 
983
        attrlen = len;
 
984
        attr = (struct rtattr *) buf;
 
985
 
 
986
        rta_len = RTA_ALIGN(sizeof(struct rtattr));
 
987
        while (RTA_OK(attr, attrlen)) {
 
988
                if (attr->rta_type == IFLA_WIRELESS) {
 
989
                        madwifi_wireless_event_wireless(
 
990
                                drv, ((char *) attr) + rta_len,
 
991
                                attr->rta_len - rta_len);
 
992
                }
 
993
                attr = RTA_NEXT(attr, attrlen);
 
994
        }
 
995
}
 
996
 
 
997
 
 
998
static int
 
999
madwifi_get_we_version(struct madwifi_driver_data *drv)
 
1000
{
 
1001
        struct iw_range *range;
 
1002
        struct iwreq iwr;
 
1003
        int minlen;
 
1004
        size_t buflen;
 
1005
 
 
1006
        drv->we_version = 0;
 
1007
 
 
1008
        /*
 
1009
         * Use larger buffer than struct iw_range in order to allow the
 
1010
         * structure to grow in the future.
 
1011
         */
 
1012
        buflen = sizeof(struct iw_range) + 500;
 
1013
        range = os_zalloc(buflen);
 
1014
        if (range == NULL)
 
1015
                return -1;
 
1016
 
 
1017
        memset(&iwr, 0, sizeof(iwr));
 
1018
        os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
 
1019
        iwr.u.data.pointer = (caddr_t) range;
 
1020
        iwr.u.data.length = buflen;
 
1021
 
 
1022
        minlen = ((char *) &range->enc_capa) - (char *) range +
 
1023
                sizeof(range->enc_capa);
 
1024
 
 
1025
        if (ioctl(drv->ioctl_sock, SIOCGIWRANGE, &iwr) < 0) {
 
1026
                perror("ioctl[SIOCGIWRANGE]");
 
1027
                free(range);
 
1028
                return -1;
 
1029
        } else if (iwr.u.data.length >= minlen &&
 
1030
                   range->we_version_compiled >= 18) {
 
1031
                wpa_printf(MSG_DEBUG, "SIOCGIWRANGE: WE(compiled)=%d "
 
1032
                           "WE(source)=%d enc_capa=0x%x",
 
1033
                           range->we_version_compiled,
 
1034
                           range->we_version_source,
 
1035
                           range->enc_capa);
 
1036
                drv->we_version = range->we_version_compiled;
 
1037
        }
 
1038
 
 
1039
        free(range);
 
1040
        return 0;
 
1041
}
 
1042
 
 
1043
 
 
1044
static int
 
1045
madwifi_wireless_event_init(struct madwifi_driver_data *drv)
 
1046
{
 
1047
        struct netlink_config *cfg;
 
1048
 
 
1049
        madwifi_get_we_version(drv);
 
1050
 
 
1051
        cfg = os_zalloc(sizeof(*cfg));
 
1052
        if (cfg == NULL)
 
1053
                return -1;
 
1054
        cfg->ctx = drv;
 
1055
        cfg->newlink_cb = madwifi_wireless_event_rtm_newlink;
 
1056
        drv->netlink = netlink_init(cfg);
 
1057
        if (drv->netlink == NULL) {
 
1058
                os_free(cfg);
 
1059
                return -1;
 
1060
        }
 
1061
 
 
1062
        return 0;
 
1063
}
 
1064
 
 
1065
 
 
1066
static int
 
1067
madwifi_send_eapol(void *priv, const u8 *addr, const u8 *data, size_t data_len,
 
1068
                   int encrypt, const u8 *own_addr)
 
1069
{
 
1070
        struct madwifi_driver_data *drv = priv;
 
1071
        unsigned char buf[3000];
 
1072
        unsigned char *bp = buf;
 
1073
        struct l2_ethhdr *eth;
 
1074
        size_t len;
 
1075
        int status;
 
1076
 
 
1077
        /*
 
1078
         * Prepend the Ethernet header.  If the caller left us
 
1079
         * space at the front we could just insert it but since
 
1080
         * we don't know we copy to a local buffer.  Given the frequency
 
1081
         * and size of frames this probably doesn't matter.
 
1082
         */
 
1083
        len = data_len + sizeof(struct l2_ethhdr);
 
1084
        if (len > sizeof(buf)) {
 
1085
                bp = malloc(len);
 
1086
                if (bp == NULL) {
 
1087
                        printf("EAPOL frame discarded, cannot malloc temp "
 
1088
                               "buffer of size %lu!\n", (unsigned long) len);
 
1089
                        return -1;
 
1090
                }
 
1091
        }
 
1092
        eth = (struct l2_ethhdr *) bp;
 
1093
        memcpy(eth->h_dest, addr, ETH_ALEN);
 
1094
        memcpy(eth->h_source, own_addr, ETH_ALEN);
 
1095
        eth->h_proto = host_to_be16(ETH_P_EAPOL);
 
1096
        memcpy(eth+1, data, data_len);
 
1097
 
 
1098
        wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", bp, len);
 
1099
 
 
1100
        status = l2_packet_send(drv->sock_xmit, addr, ETH_P_EAPOL, bp, len);
 
1101
 
 
1102
        if (bp != buf)
 
1103
                free(bp);
 
1104
        return status;
 
1105
}
 
1106
 
 
1107
static void
 
1108
handle_read(void *ctx, const u8 *src_addr, const u8 *buf, size_t len)
 
1109
{
 
1110
        struct madwifi_driver_data *drv = ctx;
 
1111
        drv_event_eapol_rx(drv->hapd, src_addr, buf + sizeof(struct l2_ethhdr),
 
1112
                           len - sizeof(struct l2_ethhdr));
 
1113
}
 
1114
 
 
1115
static void *
 
1116
madwifi_init(struct hostapd_data *hapd, struct wpa_init_params *params)
 
1117
{
 
1118
        struct madwifi_driver_data *drv;
 
1119
        struct ifreq ifr;
 
1120
        struct iwreq iwr;
 
1121
        char brname[IFNAMSIZ];
 
1122
 
 
1123
        drv = os_zalloc(sizeof(struct madwifi_driver_data));
 
1124
        if (drv == NULL) {
 
1125
                printf("Could not allocate memory for madwifi driver data\n");
 
1126
                return NULL;
 
1127
        }
 
1128
 
 
1129
        drv->hapd = hapd;
 
1130
        drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
 
1131
        if (drv->ioctl_sock < 0) {
 
1132
                perror("socket[PF_INET,SOCK_DGRAM]");
 
1133
                goto bad;
 
1134
        }
 
1135
        memcpy(drv->iface, params->ifname, sizeof(drv->iface));
 
1136
 
 
1137
        memset(&ifr, 0, sizeof(ifr));
 
1138
        os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name));
 
1139
        if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) {
 
1140
                perror("ioctl(SIOCGIFINDEX)");
 
1141
                goto bad;
 
1142
        }
 
1143
        drv->ifindex = ifr.ifr_ifindex;
 
1144
 
 
1145
        drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL,
 
1146
                                        handle_read, drv, 1);
 
1147
        if (drv->sock_xmit == NULL)
 
1148
                goto bad;
 
1149
        if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr))
 
1150
                goto bad;
 
1151
        if (params->bridge[0]) {
 
1152
                wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.",
 
1153
                           params->bridge[0]);
 
1154
                drv->sock_recv = l2_packet_init(params->bridge[0], NULL,
 
1155
                                                ETH_P_EAPOL, handle_read, drv,
 
1156
                                                1);
 
1157
                if (drv->sock_recv == NULL)
 
1158
                        goto bad;
 
1159
        } else if (linux_br_get(brname, drv->iface) == 0) {
 
1160
                wpa_printf(MSG_DEBUG, "Interface in bridge %s; configure for "
 
1161
                           "EAPOL receive", brname);
 
1162
                drv->sock_recv = l2_packet_init(brname, NULL, ETH_P_EAPOL,
 
1163
                                                handle_read, drv, 1);
 
1164
                if (drv->sock_recv == NULL)
 
1165
                        goto bad;
 
1166
        } else
 
1167
                drv->sock_recv = drv->sock_xmit;
 
1168
 
 
1169
        memset(&iwr, 0, sizeof(iwr));
 
1170
        os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
 
1171
 
 
1172
        iwr.u.mode = IW_MODE_MASTER;
 
1173
 
 
1174
        if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) {
 
1175
                perror("ioctl[SIOCSIWMODE]");
 
1176
                printf("Could not set interface to master mode!\n");
 
1177
                goto bad;
 
1178
        }
 
1179
 
 
1180
        /* mark down during setup */
 
1181
        linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0);
 
1182
        madwifi_set_privacy(drv, 0); /* default to no privacy */
 
1183
 
 
1184
        madwifi_receive_probe_req(drv);
 
1185
 
 
1186
        if (madwifi_wireless_event_init(drv))
 
1187
                goto bad;
 
1188
 
 
1189
        return drv;
 
1190
bad:
 
1191
        if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit)
 
1192
                l2_packet_deinit(drv->sock_recv);
 
1193
        if (drv->sock_xmit != NULL)
 
1194
                l2_packet_deinit(drv->sock_xmit);
 
1195
        if (drv->ioctl_sock >= 0)
 
1196
                close(drv->ioctl_sock);
 
1197
        if (drv != NULL)
 
1198
                free(drv);
 
1199
        return NULL;
 
1200
}
 
1201
 
 
1202
 
 
1203
static void
 
1204
madwifi_deinit(void *priv)
 
1205
{
 
1206
        struct madwifi_driver_data *drv = priv;
 
1207
 
 
1208
        netlink_deinit(drv->netlink);
 
1209
        (void) linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0);
 
1210
        if (drv->ioctl_sock >= 0)
 
1211
                close(drv->ioctl_sock);
 
1212
        if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit)
 
1213
                l2_packet_deinit(drv->sock_recv);
 
1214
        if (drv->sock_xmit != NULL)
 
1215
                l2_packet_deinit(drv->sock_xmit);
 
1216
        if (drv->sock_raw)
 
1217
                l2_packet_deinit(drv->sock_raw);
 
1218
        free(drv);
 
1219
}
 
1220
 
 
1221
static int
 
1222
madwifi_set_ssid(void *priv, const u8 *buf, int len)
 
1223
{
 
1224
        struct madwifi_driver_data *drv = priv;
 
1225
        struct iwreq iwr;
 
1226
 
 
1227
        memset(&iwr, 0, sizeof(iwr));
 
1228
        os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
 
1229
        iwr.u.essid.flags = 1; /* SSID active */
 
1230
        iwr.u.essid.pointer = (caddr_t) buf;
 
1231
        iwr.u.essid.length = len + 1;
 
1232
 
 
1233
        if (ioctl(drv->ioctl_sock, SIOCSIWESSID, &iwr) < 0) {
 
1234
                perror("ioctl[SIOCSIWESSID]");
 
1235
                printf("len=%d\n", len);
 
1236
                return -1;
 
1237
        }
 
1238
        return 0;
 
1239
}
 
1240
 
 
1241
static int
 
1242
madwifi_get_ssid(void *priv, u8 *buf, int len)
 
1243
{
 
1244
        struct madwifi_driver_data *drv = priv;
 
1245
        struct iwreq iwr;
 
1246
        int ret = 0;
 
1247
 
 
1248
        memset(&iwr, 0, sizeof(iwr));
 
1249
        os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ);
 
1250
        iwr.u.essid.pointer = (caddr_t) buf;
 
1251
        iwr.u.essid.length = len;
 
1252
 
 
1253
        if (ioctl(drv->ioctl_sock, SIOCGIWESSID, &iwr) < 0) {
 
1254
                perror("ioctl[SIOCGIWESSID]");
 
1255
                ret = -1;
 
1256
        } else
 
1257
                ret = iwr.u.essid.length;
 
1258
 
 
1259
        return ret;
 
1260
}
 
1261
 
 
1262
static int
 
1263
madwifi_set_countermeasures(void *priv, int enabled)
 
1264
{
 
1265
        struct madwifi_driver_data *drv = priv;
 
1266
        wpa_printf(MSG_DEBUG, "%s: enabled=%d", __FUNCTION__, enabled);
 
1267
        return set80211param(drv, IEEE80211_PARAM_COUNTERMEASURES, enabled);
 
1268
}
 
1269
 
 
1270
static int
 
1271
madwifi_commit(void *priv)
 
1272
{
 
1273
        struct madwifi_driver_data *drv = priv;
 
1274
        return linux_set_iface_flags(drv->ioctl_sock, drv->iface, 1);
 
1275
}
 
1276
 
 
1277
const struct wpa_driver_ops wpa_driver_atheros_ops = {
 
1278
        .name                   = "atheros",
 
1279
        .hapd_init              = madwifi_init,
 
1280
        .hapd_deinit            = madwifi_deinit,
 
1281
        .set_ieee8021x          = madwifi_set_ieee8021x,
 
1282
        .set_privacy            = madwifi_set_privacy,
 
1283
        .set_key                = madwifi_set_key,
 
1284
        .get_seqnum             = madwifi_get_seqnum,
 
1285
        .flush                  = madwifi_flush,
 
1286
        .set_generic_elem       = madwifi_set_opt_ie,
 
1287
        .sta_set_flags          = madwifi_sta_set_flags,
 
1288
        .read_sta_data          = madwifi_read_sta_driver_data,
 
1289
        .hapd_send_eapol        = madwifi_send_eapol,
 
1290
        .sta_disassoc           = madwifi_sta_disassoc,
 
1291
        .sta_deauth             = madwifi_sta_deauth,
 
1292
        .hapd_set_ssid          = madwifi_set_ssid,
 
1293
        .hapd_get_ssid          = madwifi_get_ssid,
 
1294
        .set_countermeasures    = madwifi_set_countermeasures,
 
1295
        .sta_clear_stats        = madwifi_sta_clear_stats,
 
1296
        .commit                 = madwifi_commit,
 
1297
        .set_ap_wps_ie          = madwifi_set_ap_wps_ie,
 
1298
};