2 * WPA Supplicant - driver interaction with MADWIFI 802.11 driver
3 * Copyright (c) 2004, Sam Leffler <sam@errno.com>
4 * Copyright (c) 2004, Video54 Technologies
5 * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * Alternatively, this software may be distributed under the terms of BSD
14 * See README and COPYING for more details.
16 * While this driver wrapper supports both AP (hostapd) and station
17 * (wpa_supplicant) operations, the station side is deprecated and
18 * driver_wext.c should be used instead. This driver wrapper should only be
19 * used with hostapd for AP mode functionality.
23 #include <sys/ioctl.h>
27 #include "driver_wext.h"
29 #include "common/ieee802_11_defs.h"
30 #include "wireless_copy.h"
33 * Avoid conflicts with wpa_supplicant definitions by undefining a definition.
37 #include <include/compat.h>
38 #include <net80211/ieee80211.h>
40 /* Assume this is built against BSD branch of madwifi driver. */
42 #include <net80211/_ieee80211.h>
43 #endif /* WME_NUM_AC */
44 #include <net80211/ieee80211_crypto.h>
45 #include <net80211/ieee80211_ioctl.h>
48 #ifdef IEEE80211_IOCTL_FILTERFRAME
49 #include <netpacket/packet.h>
51 #ifndef ETH_P_80211_RAW
52 #define ETH_P_80211_RAW 0x0019
54 #endif /* IEEE80211_IOCTL_FILTERFRAME */
55 #endif /* CONFIG_WPS */
58 * Avoid conflicts with hostapd definitions by undefining couple of defines
59 * from madwifi header files.
67 #ifdef IEEE80211_IOCTL_SETWMMPARAMS
68 /* Assume this is built against madwifi-ng */
70 #endif /* IEEE80211_IOCTL_SETWMMPARAMS */
75 #include "priv_netlink.h"
77 #include "linux_ioctl.h"
78 #include "l2_packet/l2_packet.h"
81 struct madwifi_driver_data
{
82 struct hostapd_data
*hapd
; /* back pointer */
84 char iface
[IFNAMSIZ
+ 1];
86 struct l2_packet_data
*sock_xmit
; /* raw packet xmit socket */
87 struct l2_packet_data
*sock_recv
; /* raw packet recv socket */
88 int ioctl_sock
; /* socket for ioctl() use */
89 struct netlink_data
*netlink
;
91 u8 acct_mac
[ETH_ALEN
];
92 struct hostap_sta_driver_data acct_data
;
94 struct l2_packet_data
*sock_raw
; /* raw 802.11 management frames */
97 static int madwifi_sta_deauth(void *priv
, const u8
*own_addr
, const u8
*addr
,
101 set80211priv(struct madwifi_driver_data
*drv
, int op
, void *data
, int len
)
104 int do_inline
= len
< IFNAMSIZ
;
106 memset(&iwr
, 0, sizeof(iwr
));
107 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
108 #ifdef IEEE80211_IOCTL_FILTERFRAME
109 /* FILTERFRAME must be NOT inline, regardless of size. */
110 if (op
== IEEE80211_IOCTL_FILTERFRAME
)
112 #endif /* IEEE80211_IOCTL_FILTERFRAME */
113 if (op
== IEEE80211_IOCTL_SET_APPIEBUF
)
117 * Argument data fits inline; put it there.
119 memcpy(iwr
.u
.name
, data
, len
);
122 * Argument data too big for inline transfer; setup a
123 * parameter block instead; the kernel will transfer
124 * the data for the driver.
126 iwr
.u
.data
.pointer
= data
;
127 iwr
.u
.data
.length
= len
;
130 if (ioctl(drv
->ioctl_sock
, op
, &iwr
) < 0) {
132 int first
= IEEE80211_IOCTL_SETPARAM
;
133 static const char *opnames
[] = {
134 "ioctl[IEEE80211_IOCTL_SETPARAM]",
135 "ioctl[IEEE80211_IOCTL_GETPARAM]",
136 "ioctl[IEEE80211_IOCTL_SETMODE]",
137 "ioctl[IEEE80211_IOCTL_GETMODE]",
138 "ioctl[IEEE80211_IOCTL_SETWMMPARAMS]",
139 "ioctl[IEEE80211_IOCTL_GETWMMPARAMS]",
140 "ioctl[IEEE80211_IOCTL_SETCHANLIST]",
141 "ioctl[IEEE80211_IOCTL_GETCHANLIST]",
142 "ioctl[IEEE80211_IOCTL_CHANSWITCH]",
143 "ioctl[IEEE80211_IOCTL_GET_APPIEBUF]",
144 "ioctl[IEEE80211_IOCTL_SET_APPIEBUF]",
145 "ioctl[IEEE80211_IOCTL_GETSCANRESULTS]",
146 "ioctl[IEEE80211_IOCTL_FILTERFRAME]",
147 "ioctl[IEEE80211_IOCTL_GETCHANINFO]",
148 "ioctl[IEEE80211_IOCTL_SETOPTIE]",
149 "ioctl[IEEE80211_IOCTL_GETOPTIE]",
150 "ioctl[IEEE80211_IOCTL_SETMLME]",
152 "ioctl[IEEE80211_IOCTL_SETKEY]",
154 "ioctl[IEEE80211_IOCTL_DELKEY]",
156 "ioctl[IEEE80211_IOCTL_ADDMAC]",
158 "ioctl[IEEE80211_IOCTL_DELMAC]",
160 "ioctl[IEEE80211_IOCTL_WDSMAC]",
162 "ioctl[IEEE80211_IOCTL_WDSDELMAC]",
164 "ioctl[IEEE80211_IOCTL_KICKMAC]",
166 #else /* MADWIFI_NG */
167 int first
= IEEE80211_IOCTL_SETPARAM
;
168 static const char *opnames
[] = {
169 "ioctl[IEEE80211_IOCTL_SETPARAM]",
170 "ioctl[IEEE80211_IOCTL_GETPARAM]",
171 "ioctl[IEEE80211_IOCTL_SETKEY]",
172 "ioctl[SIOCIWFIRSTPRIV+3]",
173 "ioctl[IEEE80211_IOCTL_DELKEY]",
174 "ioctl[SIOCIWFIRSTPRIV+5]",
175 "ioctl[IEEE80211_IOCTL_SETMLME]",
176 "ioctl[SIOCIWFIRSTPRIV+7]",
177 "ioctl[IEEE80211_IOCTL_SETOPTIE]",
178 "ioctl[IEEE80211_IOCTL_GETOPTIE]",
179 "ioctl[IEEE80211_IOCTL_ADDMAC]",
180 "ioctl[SIOCIWFIRSTPRIV+11]",
181 "ioctl[IEEE80211_IOCTL_DELMAC]",
182 "ioctl[SIOCIWFIRSTPRIV+13]",
183 "ioctl[IEEE80211_IOCTL_CHANLIST]",
184 "ioctl[SIOCIWFIRSTPRIV+15]",
185 "ioctl[IEEE80211_IOCTL_GETRSN]",
186 "ioctl[SIOCIWFIRSTPRIV+17]",
187 "ioctl[IEEE80211_IOCTL_GETKEY]",
189 #endif /* MADWIFI_NG */
190 int idx
= op
- first
;
192 idx
< (int) (sizeof(opnames
) / sizeof(opnames
[0])) &&
194 perror(opnames
[idx
]);
196 perror("ioctl[unknown???]");
203 set80211param(struct madwifi_driver_data
*drv
, int op
, int arg
)
207 memset(&iwr
, 0, sizeof(iwr
));
208 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
210 memcpy(iwr
.u
.name
+sizeof(__u32
), &arg
, sizeof(arg
));
212 if (ioctl(drv
->ioctl_sock
, IEEE80211_IOCTL_SETPARAM
, &iwr
) < 0) {
213 perror("ioctl[IEEE80211_IOCTL_SETPARAM]");
214 wpa_printf(MSG_DEBUG
, "%s: Failed to set parameter (op %d "
215 "arg %d)", __func__
, op
, arg
);
221 #ifndef CONFIG_NO_STDOUT_DEBUG
223 ether_sprintf(const u8
*addr
)
225 static char buf
[sizeof(MACSTR
)];
228 snprintf(buf
, sizeof(buf
), MACSTR
, MAC2STR(addr
));
230 snprintf(buf
, sizeof(buf
), MACSTR
, 0,0,0,0,0,0);
233 #endif /* CONFIG_NO_STDOUT_DEBUG */
236 * Configure WPA parameters.
239 madwifi_configure_wpa(struct madwifi_driver_data
*drv
,
240 struct wpa_bss_params
*params
)
244 switch (params
->wpa_group
) {
245 case WPA_CIPHER_CCMP
:
246 v
= IEEE80211_CIPHER_AES_CCM
;
248 case WPA_CIPHER_TKIP
:
249 v
= IEEE80211_CIPHER_TKIP
;
251 case WPA_CIPHER_WEP104
:
252 v
= IEEE80211_CIPHER_WEP
;
254 case WPA_CIPHER_WEP40
:
255 v
= IEEE80211_CIPHER_WEP
;
257 case WPA_CIPHER_NONE
:
258 v
= IEEE80211_CIPHER_NONE
;
261 wpa_printf(MSG_ERROR
, "Unknown group key cipher %u",
265 wpa_printf(MSG_DEBUG
, "%s: group key cipher=%d", __func__
, v
);
266 if (set80211param(drv
, IEEE80211_PARAM_MCASTCIPHER
, v
)) {
267 printf("Unable to set group key cipher to %u\n", v
);
270 if (v
== IEEE80211_CIPHER_WEP
) {
271 /* key length is done only for specific ciphers */
272 v
= (params
->wpa_group
== WPA_CIPHER_WEP104
? 13 : 5);
273 if (set80211param(drv
, IEEE80211_PARAM_MCASTKEYLEN
, v
)) {
274 printf("Unable to set group key length to %u\n", v
);
280 if (params
->wpa_pairwise
& WPA_CIPHER_CCMP
)
281 v
|= 1<<IEEE80211_CIPHER_AES_CCM
;
282 if (params
->wpa_pairwise
& WPA_CIPHER_TKIP
)
283 v
|= 1<<IEEE80211_CIPHER_TKIP
;
284 if (params
->wpa_pairwise
& WPA_CIPHER_NONE
)
285 v
|= 1<<IEEE80211_CIPHER_NONE
;
286 wpa_printf(MSG_DEBUG
, "%s: pairwise key ciphers=0x%x", __func__
, v
);
287 if (set80211param(drv
, IEEE80211_PARAM_UCASTCIPHERS
, v
)) {
288 printf("Unable to set pairwise key ciphers to 0x%x\n", v
);
292 wpa_printf(MSG_DEBUG
, "%s: key management algorithms=0x%x",
293 __func__
, params
->wpa_key_mgmt
);
294 if (set80211param(drv
, IEEE80211_PARAM_KEYMGTALGS
,
295 params
->wpa_key_mgmt
)) {
296 printf("Unable to set key management algorithms to 0x%x\n",
297 params
->wpa_key_mgmt
);
302 if (params
->rsn_preauth
)
304 wpa_printf(MSG_DEBUG
, "%s: rsn capabilities=0x%x",
305 __func__
, params
->rsn_preauth
);
306 if (set80211param(drv
, IEEE80211_PARAM_RSNCAPS
, v
)) {
307 printf("Unable to set RSN capabilities to 0x%x\n", v
);
311 wpa_printf(MSG_DEBUG
, "%s: enable WPA=0x%x", __func__
, params
->wpa
);
312 if (set80211param(drv
, IEEE80211_PARAM_WPA
, params
->wpa
)) {
313 printf("Unable to set WPA to %u\n", params
->wpa
);
320 madwifi_set_ieee8021x(void *priv
, struct wpa_bss_params
*params
)
322 struct madwifi_driver_data
*drv
= priv
;
324 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __func__
, params
->enabled
);
326 if (!params
->enabled
) {
327 /* XXX restore state */
328 return set80211param(priv
, IEEE80211_PARAM_AUTHMODE
,
329 IEEE80211_AUTH_AUTO
);
331 if (!params
->wpa
&& !params
->ieee802_1x
) {
332 hostapd_logger(drv
->hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
333 HOSTAPD_LEVEL_WARNING
, "No 802.1X or WPA enabled!");
336 if (params
->wpa
&& madwifi_configure_wpa(drv
, params
) != 0) {
337 hostapd_logger(drv
->hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
338 HOSTAPD_LEVEL_WARNING
, "Error configuring WPA state!");
341 if (set80211param(priv
, IEEE80211_PARAM_AUTHMODE
,
342 (params
->wpa
? IEEE80211_AUTH_WPA
: IEEE80211_AUTH_8021X
))) {
343 hostapd_logger(drv
->hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
344 HOSTAPD_LEVEL_WARNING
, "Error enabling WPA/802.1X!");
352 madwifi_set_privacy(void *priv
, int enabled
)
354 struct madwifi_driver_data
*drv
= priv
;
356 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __func__
, enabled
);
358 return set80211param(drv
, IEEE80211_PARAM_PRIVACY
, enabled
);
362 madwifi_set_sta_authorized(void *priv
, const u8
*addr
, int authorized
)
364 struct madwifi_driver_data
*drv
= priv
;
365 struct ieee80211req_mlme mlme
;
368 wpa_printf(MSG_DEBUG
, "%s: addr=%s authorized=%d",
369 __func__
, ether_sprintf(addr
), authorized
);
372 mlme
.im_op
= IEEE80211_MLME_AUTHORIZE
;
374 mlme
.im_op
= IEEE80211_MLME_UNAUTHORIZE
;
376 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
377 ret
= set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
, sizeof(mlme
));
379 wpa_printf(MSG_DEBUG
, "%s: Failed to %sauthorize STA " MACSTR
,
380 __func__
, authorized
? "" : "un", MAC2STR(addr
));
387 madwifi_sta_set_flags(void *priv
, const u8
*addr
,
388 int total_flags
, int flags_or
, int flags_and
)
390 /* For now, only support setting Authorized flag */
391 if (flags_or
& WPA_STA_AUTHORIZED
)
392 return madwifi_set_sta_authorized(priv
, addr
, 1);
393 if (!(flags_and
& WPA_STA_AUTHORIZED
))
394 return madwifi_set_sta_authorized(priv
, addr
, 0);
399 madwifi_del_key(void *priv
, const u8
*addr
, int key_idx
)
401 struct madwifi_driver_data
*drv
= priv
;
402 struct ieee80211req_del_key wk
;
405 wpa_printf(MSG_DEBUG
, "%s: addr=%s key_idx=%d",
406 __func__
, ether_sprintf(addr
), key_idx
);
408 memset(&wk
, 0, sizeof(wk
));
410 memcpy(wk
.idk_macaddr
, addr
, IEEE80211_ADDR_LEN
);
411 wk
.idk_keyix
= (u8
) IEEE80211_KEYIX_NONE
;
413 wk
.idk_keyix
= key_idx
;
416 ret
= set80211priv(drv
, IEEE80211_IOCTL_DELKEY
, &wk
, sizeof(wk
));
418 wpa_printf(MSG_DEBUG
, "%s: Failed to delete key (addr %s"
419 " key_idx %d)", __func__
, ether_sprintf(addr
),
427 wpa_driver_madwifi_set_key(const char *ifname
, void *priv
, enum wpa_alg alg
,
428 const u8
*addr
, int key_idx
, int set_tx
,
429 const u8
*seq
, size_t seq_len
,
430 const u8
*key
, size_t key_len
)
432 struct madwifi_driver_data
*drv
= priv
;
433 struct ieee80211req_key wk
;
437 if (alg
== WPA_ALG_NONE
)
438 return madwifi_del_key(drv
, addr
, key_idx
);
440 wpa_printf(MSG_DEBUG
, "%s: alg=%d addr=%s key_idx=%d",
441 __func__
, alg
, ether_sprintf(addr
), key_idx
);
443 if (alg
== WPA_ALG_WEP
)
444 cipher
= IEEE80211_CIPHER_WEP
;
445 else if (alg
== WPA_ALG_TKIP
)
446 cipher
= IEEE80211_CIPHER_TKIP
;
447 else if (alg
== WPA_ALG_CCMP
)
448 cipher
= IEEE80211_CIPHER_AES_CCM
;
450 printf("%s: unknown/unsupported algorithm %d\n",
455 if (key_len
> sizeof(wk
.ik_keydata
)) {
456 printf("%s: key length %lu too big\n", __func__
,
457 (unsigned long) key_len
);
461 memset(&wk
, 0, sizeof(wk
));
463 wk
.ik_flags
= IEEE80211_KEY_RECV
| IEEE80211_KEY_XMIT
;
465 memset(wk
.ik_macaddr
, 0xff, IEEE80211_ADDR_LEN
);
466 wk
.ik_keyix
= key_idx
;
467 wk
.ik_flags
|= IEEE80211_KEY_DEFAULT
;
469 memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
470 wk
.ik_keyix
= IEEE80211_KEYIX_NONE
;
472 wk
.ik_keylen
= key_len
;
473 memcpy(wk
.ik_keydata
, key
, key_len
);
475 ret
= set80211priv(drv
, IEEE80211_IOCTL_SETKEY
, &wk
, sizeof(wk
));
477 wpa_printf(MSG_DEBUG
, "%s: Failed to set key (addr %s"
478 " key_idx %d alg %d key_len %lu set_tx %d)",
479 __func__
, ether_sprintf(wk
.ik_macaddr
), key_idx
,
480 alg
, (unsigned long) key_len
, set_tx
);
488 madwifi_get_seqnum(const char *ifname
, void *priv
, const u8
*addr
, int idx
,
491 struct madwifi_driver_data
*drv
= priv
;
492 struct ieee80211req_key wk
;
494 wpa_printf(MSG_DEBUG
, "%s: addr=%s idx=%d",
495 __func__
, ether_sprintf(addr
), idx
);
497 memset(&wk
, 0, sizeof(wk
));
499 memset(wk
.ik_macaddr
, 0xff, IEEE80211_ADDR_LEN
);
501 memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
504 if (set80211priv(drv
, IEEE80211_IOCTL_GETKEY
, &wk
, sizeof(wk
))) {
505 wpa_printf(MSG_DEBUG
, "%s: Failed to get encryption data "
506 "(addr " MACSTR
" key_idx %d)",
507 __func__
, MAC2STR(wk
.ik_macaddr
), idx
);
511 #ifdef WORDS_BIGENDIAN
514 * wk.ik_keytsc is in host byte order (big endian), need to
515 * swap it to match with the byte order used in WPA.
518 u8 tmp
[WPA_KEY_RSC_LEN
];
519 memcpy(tmp
, &wk
.ik_keytsc
, sizeof(wk
.ik_keytsc
));
520 for (i
= 0; i
< WPA_KEY_RSC_LEN
; i
++) {
521 seq
[i
] = tmp
[WPA_KEY_RSC_LEN
- i
- 1];
524 #else /* WORDS_BIGENDIAN */
525 memcpy(seq
, &wk
.ik_keytsc
, sizeof(wk
.ik_keytsc
));
526 #endif /* WORDS_BIGENDIAN */
532 madwifi_flush(void *priv
)
535 u8 allsta
[IEEE80211_ADDR_LEN
];
536 memset(allsta
, 0xff, IEEE80211_ADDR_LEN
);
537 return madwifi_sta_deauth(priv
, NULL
, allsta
,
538 IEEE80211_REASON_AUTH_LEAVE
);
539 #else /* MADWIFI_BSD */
541 #endif /* MADWIFI_BSD */
546 madwifi_read_sta_driver_data(void *priv
, struct hostap_sta_driver_data
*data
,
549 struct madwifi_driver_data
*drv
= priv
;
552 struct ieee80211req_sta_stats stats
;
554 memset(data
, 0, sizeof(*data
));
557 * Fetch statistics for station from the system.
559 memset(&stats
, 0, sizeof(stats
));
560 memcpy(stats
.is_u
.macaddr
, addr
, IEEE80211_ADDR_LEN
);
561 if (set80211priv(drv
,
563 IEEE80211_IOCTL_STA_STATS
,
564 #else /* MADWIFI_NG */
565 IEEE80211_IOCTL_GETSTASTATS
,
566 #endif /* MADWIFI_NG */
567 &stats
, sizeof(stats
))) {
568 wpa_printf(MSG_DEBUG
, "%s: Failed to fetch STA stats (addr "
569 MACSTR
")", __func__
, MAC2STR(addr
));
570 if (memcmp(addr
, drv
->acct_mac
, ETH_ALEN
) == 0) {
571 memcpy(data
, &drv
->acct_data
, sizeof(*data
));
575 printf("Failed to get station stats information element.\n");
579 data
->rx_packets
= stats
.is_stats
.ns_rx_data
;
580 data
->rx_bytes
= stats
.is_stats
.ns_rx_bytes
;
581 data
->tx_packets
= stats
.is_stats
.ns_tx_data
;
582 data
->tx_bytes
= stats
.is_stats
.ns_tx_bytes
;
585 #else /* MADWIFI_BSD */
587 char buf
[1024], line
[128], *pos
;
591 memset(data
, 0, sizeof(*data
));
592 snprintf(buf
, sizeof(buf
), "/proc/net/madwifi/%s/" MACSTR
,
593 drv
->iface
, MAC2STR(addr
));
597 if (memcmp(addr
, drv
->acct_mac
, ETH_ALEN
) != 0)
599 memcpy(data
, &drv
->acct_data
, sizeof(*data
));
602 /* Need to read proc file with in one piece, so use large enough
604 setbuffer(f
, buf
, sizeof(buf
));
606 while (fgets(line
, sizeof(line
), f
)) {
607 pos
= strchr(line
, '=');
611 val
= strtoul(pos
, NULL
, 10);
612 if (strcmp(line
, "rx_packets") == 0)
613 data
->rx_packets
= val
;
614 else if (strcmp(line
, "tx_packets") == 0)
615 data
->tx_packets
= val
;
616 else if (strcmp(line
, "rx_bytes") == 0)
617 data
->rx_bytes
= val
;
618 else if (strcmp(line
, "tx_bytes") == 0)
619 data
->tx_bytes
= val
;
625 #endif /* MADWIFI_BSD */
630 madwifi_sta_clear_stats(void *priv
, const u8
*addr
)
632 #if defined(MADWIFI_BSD) && defined(IEEE80211_MLME_CLEAR_STATS)
633 struct madwifi_driver_data
*drv
= priv
;
634 struct ieee80211req_mlme mlme
;
637 wpa_printf(MSG_DEBUG
, "%s: addr=%s", __func__
, ether_sprintf(addr
));
639 mlme
.im_op
= IEEE80211_MLME_CLEAR_STATS
;
640 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
641 ret
= set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
,
644 wpa_printf(MSG_DEBUG
, "%s: Failed to clear STA stats (addr "
645 MACSTR
")", __func__
, MAC2STR(addr
));
649 #else /* MADWIFI_BSD && IEEE80211_MLME_CLEAR_STATS */
651 #endif /* MADWIFI_BSD && IEEE80211_MLME_CLEAR_STATS */
656 madwifi_set_opt_ie(void *priv
, const u8
*ie
, size_t ie_len
)
659 * Do nothing; we setup parameters at startup that define the
660 * contents of the beacon information element.
666 madwifi_sta_deauth(void *priv
, const u8
*own_addr
, const u8
*addr
,
669 struct madwifi_driver_data
*drv
= priv
;
670 struct ieee80211req_mlme mlme
;
673 wpa_printf(MSG_DEBUG
, "%s: addr=%s reason_code=%d",
674 __func__
, ether_sprintf(addr
), reason_code
);
676 mlme
.im_op
= IEEE80211_MLME_DEAUTH
;
677 mlme
.im_reason
= reason_code
;
678 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
679 ret
= set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
, sizeof(mlme
));
681 wpa_printf(MSG_DEBUG
, "%s: Failed to deauth STA (addr " MACSTR
683 __func__
, MAC2STR(addr
), reason_code
);
690 madwifi_sta_disassoc(void *priv
, const u8
*own_addr
, const u8
*addr
,
693 struct madwifi_driver_data
*drv
= priv
;
694 struct ieee80211req_mlme mlme
;
697 wpa_printf(MSG_DEBUG
, "%s: addr=%s reason_code=%d",
698 __func__
, ether_sprintf(addr
), reason_code
);
700 mlme
.im_op
= IEEE80211_MLME_DISASSOC
;
701 mlme
.im_reason
= reason_code
;
702 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
703 ret
= set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
, sizeof(mlme
));
705 wpa_printf(MSG_DEBUG
, "%s: Failed to disassoc STA (addr "
706 MACSTR
" reason %d)",
707 __func__
, MAC2STR(addr
), reason_code
);
714 #ifdef IEEE80211_IOCTL_FILTERFRAME
715 static void madwifi_raw_receive(void *ctx
, const u8
*src_addr
, const u8
*buf
,
718 struct madwifi_driver_data
*drv
= ctx
;
719 const struct ieee80211_mgmt
*mgmt
;
721 union wpa_event_data event
;
723 /* Send Probe Request information to WPS processing */
725 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.probe_req
))
727 mgmt
= (const struct ieee80211_mgmt
*) buf
;
729 fc
= le_to_host16(mgmt
->frame_control
);
730 if (WLAN_FC_GET_TYPE(fc
) != WLAN_FC_TYPE_MGMT
||
731 WLAN_FC_GET_STYPE(fc
) != WLAN_FC_STYPE_PROBE_REQ
)
734 os_memset(&event
, 0, sizeof(event
));
735 event
.rx_probe_req
.sa
= mgmt
->sa
;
736 event
.rx_probe_req
.ie
= mgmt
->u
.probe_req
.variable
;
737 event
.rx_probe_req
.ie_len
=
738 len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.probe_req
));
739 wpa_supplicant_event(drv
->hapd
, EVENT_RX_PROBE_REQ
, &event
);
741 #endif /* IEEE80211_IOCTL_FILTERFRAME */
742 #endif /* CONFIG_WPS */
744 static int madwifi_receive_probe_req(struct madwifi_driver_data
*drv
)
748 #ifdef IEEE80211_IOCTL_FILTERFRAME
749 struct ieee80211req_set_filter filt
;
751 wpa_printf(MSG_DEBUG
, "%s Enter", __func__
);
752 filt
.app_filterype
= IEEE80211_FILTER_TYPE_PROBE_REQ
;
754 ret
= set80211priv(drv
, IEEE80211_IOCTL_FILTERFRAME
, &filt
,
755 sizeof(struct ieee80211req_set_filter
));
759 drv
->sock_raw
= l2_packet_init(drv
->iface
, NULL
, ETH_P_80211_RAW
,
760 madwifi_raw_receive
, drv
, 1);
761 if (drv
->sock_raw
== NULL
)
763 #endif /* IEEE80211_IOCTL_FILTERFRAME */
764 #endif /* CONFIG_WPS */
770 madwifi_set_wps_ie(void *priv
, const u8
*ie
, size_t len
, u32 frametype
)
772 struct madwifi_driver_data
*drv
= priv
;
774 struct ieee80211req_getset_appiebuf
*beac_ie
;
776 wpa_printf(MSG_DEBUG
, "%s buflen = %lu", __func__
,
777 (unsigned long) len
);
779 beac_ie
= (struct ieee80211req_getset_appiebuf
*) buf
;
780 beac_ie
->app_frmtype
= frametype
;
781 beac_ie
->app_buflen
= len
;
782 memcpy(&(beac_ie
->app_buf
[0]), ie
, len
);
784 return set80211priv(drv
, IEEE80211_IOCTL_SET_APPIEBUF
, beac_ie
,
785 sizeof(struct ieee80211req_getset_appiebuf
) + len
);
789 madwifi_set_ap_wps_ie(void *priv
, const struct wpabuf
*beacon
,
790 const struct wpabuf
*proberesp
)
792 if (madwifi_set_wps_ie(priv
, beacon
? wpabuf_head(beacon
) : NULL
,
793 beacon
? wpabuf_len(beacon
) : 0,
794 IEEE80211_APPIE_FRAME_BEACON
) < 0)
796 return madwifi_set_wps_ie(priv
,
797 proberesp
? wpabuf_head(proberesp
) : NULL
,
798 proberesp
? wpabuf_len(proberesp
) : 0,
799 IEEE80211_APPIE_FRAME_PROBE_RESP
);
801 #else /* CONFIG_WPS */
802 #define madwifi_set_ap_wps_ie NULL
803 #endif /* CONFIG_WPS */
806 madwifi_new_sta(struct madwifi_driver_data
*drv
, u8 addr
[IEEE80211_ADDR_LEN
])
808 struct hostapd_data
*hapd
= drv
->hapd
;
809 struct ieee80211req_wpaie ie
;
814 * Fetch negotiated WPA/RSN parameters from the system.
816 memset(&ie
, 0, sizeof(ie
));
817 memcpy(ie
.wpa_macaddr
, addr
, IEEE80211_ADDR_LEN
);
818 if (set80211priv(drv
, IEEE80211_IOCTL_GETWPAIE
, &ie
, sizeof(ie
))) {
819 wpa_printf(MSG_DEBUG
, "%s: Failed to get WPA/RSN IE",
823 wpa_hexdump(MSG_MSGDUMP
, "madwifi req WPA IE",
824 ie
.wpa_ie
, IEEE80211_MAX_OPT_IE
);
826 /* madwifi seems to return some random data if WPA/RSN IE is not set.
827 * Assume the IE was not included if the IE type is unknown. */
828 if (iebuf
[0] != WLAN_EID_VENDOR_SPECIFIC
)
831 wpa_hexdump(MSG_MSGDUMP
, "madwifi req RSN IE",
832 ie
.rsn_ie
, IEEE80211_MAX_OPT_IE
);
833 if (iebuf
[1] == 0 && ie
.rsn_ie
[1] > 0) {
834 /* madwifi-ng svn #1453 added rsn_ie. Use it, if wpa_ie was not
835 * set. This is needed for WPA2. */
837 if (iebuf
[0] != WLAN_EID_RSN
)
840 #endif /* MADWIFI_NG */
849 drv_event_assoc(hapd
, addr
, iebuf
, ielen
);
851 if (memcmp(addr
, drv
->acct_mac
, ETH_ALEN
) == 0) {
852 /* Cached accounting data is not valid anymore. */
853 memset(drv
->acct_mac
, 0, ETH_ALEN
);
854 memset(&drv
->acct_data
, 0, sizeof(drv
->acct_data
));
859 madwifi_wireless_event_wireless_custom(struct madwifi_driver_data
*drv
,
862 wpa_printf(MSG_DEBUG
, "Custom wireless event: '%s'", custom
);
864 if (strncmp(custom
, "MLME-MICHAELMICFAILURE.indication", 33) == 0) {
867 pos
= strstr(custom
, "addr=");
869 wpa_printf(MSG_DEBUG
,
870 "MLME-MICHAELMICFAILURE.indication "
871 "without sender address ignored");
875 if (hwaddr_aton(pos
, addr
) == 0) {
876 union wpa_event_data data
;
877 os_memset(&data
, 0, sizeof(data
));
878 data
.michael_mic_failure
.unicast
= 1;
879 data
.michael_mic_failure
.src
= addr
;
880 wpa_supplicant_event(drv
->hapd
,
881 EVENT_MICHAEL_MIC_FAILURE
, &data
);
883 wpa_printf(MSG_DEBUG
,
884 "MLME-MICHAELMICFAILURE.indication "
885 "with invalid MAC address");
887 } else if (strncmp(custom
, "STA-TRAFFIC-STAT", 16) == 0) {
891 while ((key
= strchr(key
, '\n')) != NULL
) {
893 value
= strchr(key
, '=');
897 val
= strtoul(value
, NULL
, 10);
898 if (strcmp(key
, "mac") == 0)
899 hwaddr_aton(value
, drv
->acct_mac
);
900 else if (strcmp(key
, "rx_packets") == 0)
901 drv
->acct_data
.rx_packets
= val
;
902 else if (strcmp(key
, "tx_packets") == 0)
903 drv
->acct_data
.tx_packets
= val
;
904 else if (strcmp(key
, "rx_bytes") == 0)
905 drv
->acct_data
.rx_bytes
= val
;
906 else if (strcmp(key
, "tx_bytes") == 0)
907 drv
->acct_data
.tx_bytes
= val
;
914 madwifi_wireless_event_wireless(struct madwifi_driver_data
*drv
,
917 struct iw_event iwe_buf
, *iwe
= &iwe_buf
;
918 char *pos
, *end
, *custom
, *buf
;
923 while (pos
+ IW_EV_LCP_LEN
<= end
) {
924 /* Event data may be unaligned, so make a local, aligned copy
925 * before processing. */
926 memcpy(&iwe_buf
, pos
, IW_EV_LCP_LEN
);
927 wpa_printf(MSG_MSGDUMP
, "Wireless event: cmd=0x%x len=%d",
929 if (iwe
->len
<= IW_EV_LCP_LEN
)
932 custom
= pos
+ IW_EV_POINT_LEN
;
933 if (drv
->we_version
> 18 &&
934 (iwe
->cmd
== IWEVMICHAELMICFAILURE
||
935 iwe
->cmd
== IWEVCUSTOM
)) {
936 /* WE-19 removed the pointer from struct iw_point */
937 char *dpos
= (char *) &iwe_buf
.u
.data
.length
;
938 int dlen
= dpos
- (char *) &iwe_buf
;
939 memcpy(dpos
, pos
+ IW_EV_LCP_LEN
,
940 sizeof(struct iw_event
) - dlen
);
942 memcpy(&iwe_buf
, pos
, sizeof(struct iw_event
));
943 custom
+= IW_EV_POINT_OFF
;
948 drv_event_disassoc(drv
->hapd
,
949 (u8
*) iwe
->u
.addr
.sa_data
);
952 madwifi_new_sta(drv
, (u8
*) iwe
->u
.addr
.sa_data
);
955 if (custom
+ iwe
->u
.data
.length
> end
)
957 buf
= malloc(iwe
->u
.data
.length
+ 1);
960 memcpy(buf
, custom
, iwe
->u
.data
.length
);
961 buf
[iwe
->u
.data
.length
] = '\0';
962 madwifi_wireless_event_wireless_custom(drv
, buf
);
973 madwifi_wireless_event_rtm_newlink(void *ctx
, struct ifinfomsg
*ifi
,
976 struct madwifi_driver_data
*drv
= ctx
;
977 int attrlen
, rta_len
;
980 if (ifi
->ifi_index
!= drv
->ifindex
)
984 attr
= (struct rtattr
*) buf
;
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
);
993 attr
= RTA_NEXT(attr
, attrlen
);
999 madwifi_get_we_version(struct madwifi_driver_data
*drv
)
1001 struct iw_range
*range
;
1006 drv
->we_version
= 0;
1009 * Use larger buffer than struct iw_range in order to allow the
1010 * structure to grow in the future.
1012 buflen
= sizeof(struct iw_range
) + 500;
1013 range
= os_zalloc(buflen
);
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
;
1022 minlen
= ((char *) &range
->enc_capa
) - (char *) range
+
1023 sizeof(range
->enc_capa
);
1025 if (ioctl(drv
->ioctl_sock
, SIOCGIWRANGE
, &iwr
) < 0) {
1026 perror("ioctl[SIOCGIWRANGE]");
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
,
1036 drv
->we_version
= range
->we_version_compiled
;
1045 madwifi_wireless_event_init(struct madwifi_driver_data
*drv
)
1047 struct netlink_config
*cfg
;
1049 madwifi_get_we_version(drv
);
1051 cfg
= os_zalloc(sizeof(*cfg
));
1055 cfg
->newlink_cb
= madwifi_wireless_event_rtm_newlink
;
1056 drv
->netlink
= netlink_init(cfg
);
1057 if (drv
->netlink
== NULL
) {
1067 madwifi_send_eapol(void *priv
, const u8
*addr
, const u8
*data
, size_t data_len
,
1068 int encrypt
, const u8
*own_addr
)
1070 struct madwifi_driver_data
*drv
= priv
;
1071 unsigned char buf
[3000];
1072 unsigned char *bp
= buf
;
1073 struct l2_ethhdr
*eth
;
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.
1083 len
= data_len
+ sizeof(struct l2_ethhdr
);
1084 if (len
> sizeof(buf
)) {
1087 printf("EAPOL frame discarded, cannot malloc temp "
1088 "buffer of size %lu!\n", (unsigned long) len
);
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
);
1098 wpa_hexdump(MSG_MSGDUMP
, "TX EAPOL", bp
, len
);
1100 status
= l2_packet_send(drv
->sock_xmit
, addr
, ETH_P_EAPOL
, bp
, len
);
1108 handle_read(void *ctx
, const u8
*src_addr
, const u8
*buf
, size_t len
)
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
));
1116 madwifi_init(struct hostapd_data
*hapd
, struct wpa_init_params
*params
)
1118 struct madwifi_driver_data
*drv
;
1121 char brname
[IFNAMSIZ
];
1123 drv
= os_zalloc(sizeof(struct madwifi_driver_data
));
1125 printf("Could not allocate memory for madwifi driver data\n");
1130 drv
->ioctl_sock
= socket(PF_INET
, SOCK_DGRAM
, 0);
1131 if (drv
->ioctl_sock
< 0) {
1132 perror("socket[PF_INET,SOCK_DGRAM]");
1135 memcpy(drv
->iface
, params
->ifname
, sizeof(drv
->iface
));
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)");
1143 drv
->ifindex
= ifr
.ifr_ifindex
;
1145 drv
->sock_xmit
= l2_packet_init(drv
->iface
, NULL
, ETH_P_EAPOL
,
1146 handle_read
, drv
, 1);
1147 if (drv
->sock_xmit
== NULL
)
1149 if (l2_packet_get_own_addr(drv
->sock_xmit
, params
->own_addr
))
1151 if (params
->bridge
[0]) {
1152 wpa_printf(MSG_DEBUG
, "Configure bridge %s for EAPOL traffic.",
1154 drv
->sock_recv
= l2_packet_init(params
->bridge
[0], NULL
,
1155 ETH_P_EAPOL
, handle_read
, drv
,
1157 if (drv
->sock_recv
== NULL
)
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
)
1167 drv
->sock_recv
= drv
->sock_xmit
;
1169 memset(&iwr
, 0, sizeof(iwr
));
1170 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
1172 iwr
.u
.mode
= IW_MODE_MASTER
;
1174 if (ioctl(drv
->ioctl_sock
, SIOCSIWMODE
, &iwr
) < 0) {
1175 perror("ioctl[SIOCSIWMODE]");
1176 printf("Could not set interface to master mode!\n");
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 */
1184 madwifi_receive_probe_req(drv
);
1186 if (madwifi_wireless_event_init(drv
))
1191 if (drv
->sock_xmit
!= NULL
)
1192 l2_packet_deinit(drv
->sock_xmit
);
1193 if (drv
->ioctl_sock
>= 0)
1194 close(drv
->ioctl_sock
);
1202 madwifi_deinit(void *priv
)
1204 struct madwifi_driver_data
*drv
= priv
;
1206 netlink_deinit(drv
->netlink
);
1207 (void) linux_set_iface_flags(drv
->ioctl_sock
, drv
->iface
, 0);
1208 if (drv
->ioctl_sock
>= 0)
1209 close(drv
->ioctl_sock
);
1210 if (drv
->sock_recv
!= NULL
&& drv
->sock_recv
!= drv
->sock_xmit
)
1211 l2_packet_deinit(drv
->sock_recv
);
1212 if (drv
->sock_xmit
!= NULL
)
1213 l2_packet_deinit(drv
->sock_xmit
);
1215 l2_packet_deinit(drv
->sock_raw
);
1220 madwifi_set_ssid(void *priv
, const u8
*buf
, int len
)
1222 struct madwifi_driver_data
*drv
= priv
;
1225 memset(&iwr
, 0, sizeof(iwr
));
1226 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
1227 iwr
.u
.essid
.flags
= 1; /* SSID active */
1228 iwr
.u
.essid
.pointer
= (caddr_t
) buf
;
1229 iwr
.u
.essid
.length
= len
+ 1;
1231 if (ioctl(drv
->ioctl_sock
, SIOCSIWESSID
, &iwr
) < 0) {
1232 perror("ioctl[SIOCSIWESSID]");
1233 printf("len=%d\n", len
);
1240 madwifi_get_ssid(void *priv
, u8
*buf
, int len
)
1242 struct madwifi_driver_data
*drv
= priv
;
1246 memset(&iwr
, 0, sizeof(iwr
));
1247 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
1248 iwr
.u
.essid
.pointer
= (caddr_t
) buf
;
1249 iwr
.u
.essid
.length
= len
;
1251 if (ioctl(drv
->ioctl_sock
, SIOCGIWESSID
, &iwr
) < 0) {
1252 perror("ioctl[SIOCGIWESSID]");
1255 ret
= iwr
.u
.essid
.length
;
1261 madwifi_set_countermeasures(void *priv
, int enabled
)
1263 struct madwifi_driver_data
*drv
= priv
;
1264 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __FUNCTION__
, enabled
);
1265 return set80211param(drv
, IEEE80211_PARAM_COUNTERMEASURES
, enabled
);
1269 madwifi_commit(void *priv
)
1271 struct madwifi_driver_data
*drv
= priv
;
1272 return linux_set_iface_flags(drv
->ioctl_sock
, drv
->iface
, 1);
1277 struct wpa_driver_madwifi_data
{
1278 void *wext
; /* private data for driver_wext */
1280 char ifname
[IFNAMSIZ
+ 1];
1284 static int wpa_driver_madwifi_set_auth_alg(void *priv
, int auth_alg
);
1285 static int wpa_driver_madwifi_set_probe_req_ie(void *priv
, const u8
*ies
,
1290 set80211priv(struct wpa_driver_madwifi_data
*drv
, int op
, void *data
, int len
,
1295 os_memset(&iwr
, 0, sizeof(iwr
));
1296 os_strlcpy(iwr
.ifr_name
, drv
->ifname
, IFNAMSIZ
);
1297 if (len
< IFNAMSIZ
&&
1298 op
!= IEEE80211_IOCTL_SET_APPIEBUF
) {
1300 * Argument data fits inline; put it there.
1302 os_memcpy(iwr
.u
.name
, data
, len
);
1305 * Argument data too big for inline transfer; setup a
1306 * parameter block instead; the kernel will transfer
1307 * the data for the driver.
1309 iwr
.u
.data
.pointer
= data
;
1310 iwr
.u
.data
.length
= len
;
1313 if (ioctl(drv
->sock
, op
, &iwr
) < 0) {
1316 int first
= IEEE80211_IOCTL_SETPARAM
;
1317 int last
= IEEE80211_IOCTL_KICKMAC
;
1318 static const char *opnames
[] = {
1319 "ioctl[IEEE80211_IOCTL_SETPARAM]",
1320 "ioctl[IEEE80211_IOCTL_GETPARAM]",
1321 "ioctl[IEEE80211_IOCTL_SETMODE]",
1322 "ioctl[IEEE80211_IOCTL_GETMODE]",
1323 "ioctl[IEEE80211_IOCTL_SETWMMPARAMS]",
1324 "ioctl[IEEE80211_IOCTL_GETWMMPARAMS]",
1325 "ioctl[IEEE80211_IOCTL_SETCHANLIST]",
1326 "ioctl[IEEE80211_IOCTL_GETCHANLIST]",
1327 "ioctl[IEEE80211_IOCTL_CHANSWITCH]",
1329 "ioctl[IEEE80211_IOCTL_SET_APPIEBUF]",
1330 "ioctl[IEEE80211_IOCTL_GETSCANRESULTS]",
1332 "ioctl[IEEE80211_IOCTL_GETCHANINFO]",
1333 "ioctl[IEEE80211_IOCTL_SETOPTIE]",
1334 "ioctl[IEEE80211_IOCTL_GETOPTIE]",
1335 "ioctl[IEEE80211_IOCTL_SETMLME]",
1337 "ioctl[IEEE80211_IOCTL_SETKEY]",
1339 "ioctl[IEEE80211_IOCTL_DELKEY]",
1341 "ioctl[IEEE80211_IOCTL_ADDMAC]",
1343 "ioctl[IEEE80211_IOCTL_DELMAC]",
1345 "ioctl[IEEE80211_IOCTL_WDSMAC]",
1347 "ioctl[IEEE80211_IOCTL_WDSDELMAC]",
1349 "ioctl[IEEE80211_IOCTL_KICKMAC]",
1351 #else /* MADWIFI_NG */
1352 int first
= IEEE80211_IOCTL_SETPARAM
;
1353 int last
= IEEE80211_IOCTL_CHANLIST
;
1354 static const char *opnames
[] = {
1355 "ioctl[IEEE80211_IOCTL_SETPARAM]",
1356 "ioctl[IEEE80211_IOCTL_GETPARAM]",
1357 "ioctl[IEEE80211_IOCTL_SETKEY]",
1358 "ioctl[IEEE80211_IOCTL_GETKEY]",
1359 "ioctl[IEEE80211_IOCTL_DELKEY]",
1361 "ioctl[IEEE80211_IOCTL_SETMLME]",
1363 "ioctl[IEEE80211_IOCTL_SETOPTIE]",
1364 "ioctl[IEEE80211_IOCTL_GETOPTIE]",
1365 "ioctl[IEEE80211_IOCTL_ADDMAC]",
1367 "ioctl[IEEE80211_IOCTL_DELMAC]",
1369 "ioctl[IEEE80211_IOCTL_CHANLIST]",
1371 #endif /* MADWIFI_NG */
1372 int idx
= op
- first
;
1373 if (first
<= op
&& op
<= last
&&
1374 idx
< (int) (sizeof(opnames
) / sizeof(opnames
[0]))
1376 perror(opnames
[idx
]);
1378 perror("ioctl[unknown???]");
1386 set80211param(struct wpa_driver_madwifi_data
*drv
, int op
, int arg
,
1391 os_memset(&iwr
, 0, sizeof(iwr
));
1392 os_strlcpy(iwr
.ifr_name
, drv
->ifname
, IFNAMSIZ
);
1394 os_memcpy(iwr
.u
.name
+sizeof(u32
), &arg
, sizeof(arg
));
1396 if (ioctl(drv
->sock
, IEEE80211_IOCTL_SETPARAM
, &iwr
) < 0) {
1398 perror("ioctl[IEEE80211_IOCTL_SETPARAM]");
1405 wpa_driver_madwifi_set_wpa_ie(struct wpa_driver_madwifi_data
*drv
,
1406 const u8
*wpa_ie
, size_t wpa_ie_len
)
1410 os_memset(&iwr
, 0, sizeof(iwr
));
1411 os_strlcpy(iwr
.ifr_name
, drv
->ifname
, IFNAMSIZ
);
1412 /* NB: SETOPTIE is not fixed-size so must not be inlined */
1413 iwr
.u
.data
.pointer
= (void *) wpa_ie
;
1414 iwr
.u
.data
.length
= wpa_ie_len
;
1416 if (ioctl(drv
->sock
, IEEE80211_IOCTL_SETOPTIE
, &iwr
) < 0) {
1417 perror("ioctl[IEEE80211_IOCTL_SETOPTIE]");
1424 wpa_driver_madwifi_del_key(struct wpa_driver_madwifi_data
*drv
, int key_idx
,
1427 struct ieee80211req_del_key wk
;
1429 wpa_printf(MSG_DEBUG
, "%s: keyidx=%d", __FUNCTION__
, key_idx
);
1430 os_memset(&wk
, 0, sizeof(wk
));
1431 wk
.idk_keyix
= key_idx
;
1433 os_memcpy(wk
.idk_macaddr
, addr
, IEEE80211_ADDR_LEN
);
1435 return set80211priv(drv
, IEEE80211_IOCTL_DELKEY
, &wk
, sizeof(wk
), 1);
1439 wpa_driver_madwifi_set_key(const char *ifname
, void *priv
, enum wpa_alg alg
,
1440 const u8
*addr
, int key_idx
, int set_tx
,
1441 const u8
*seq
, size_t seq_len
,
1442 const u8
*key
, size_t key_len
)
1444 struct wpa_driver_madwifi_data
*drv
= priv
;
1445 struct ieee80211req_key wk
;
1449 if (alg
== WPA_ALG_NONE
)
1450 return wpa_driver_madwifi_del_key(drv
, key_idx
, addr
);
1454 if (addr
== NULL
|| os_memcmp(addr
, "\xff\xff\xff\xff\xff\xff",
1457 * madwifi did not seem to like static WEP key
1458 * configuration with IEEE80211_IOCTL_SETKEY, so use
1459 * Linux wireless extensions ioctl for this.
1461 return wpa_driver_wext_set_key(ifname
, drv
->wext
, alg
,
1462 addr
, key_idx
, set_tx
,
1467 cipher
= IEEE80211_CIPHER_WEP
;
1471 cipher
= IEEE80211_CIPHER_TKIP
;
1475 cipher
= IEEE80211_CIPHER_AES_CCM
;
1478 wpa_printf(MSG_DEBUG
, "%s: unknown/unsupported algorithm %d",
1483 wpa_printf(MSG_DEBUG
, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu "
1484 "key_len=%lu", __FUNCTION__
, alg_name
, key_idx
, set_tx
,
1485 (unsigned long) seq_len
, (unsigned long) key_len
);
1487 if (seq_len
> sizeof(u_int64_t
)) {
1488 wpa_printf(MSG_DEBUG
, "%s: seq_len %lu too big",
1489 __FUNCTION__
, (unsigned long) seq_len
);
1492 if (key_len
> sizeof(wk
.ik_keydata
)) {
1493 wpa_printf(MSG_DEBUG
, "%s: key length %lu too big",
1494 __FUNCTION__
, (unsigned long) key_len
);
1498 os_memset(&wk
, 0, sizeof(wk
));
1499 wk
.ik_type
= cipher
;
1500 wk
.ik_flags
= IEEE80211_KEY_RECV
;
1502 os_memcmp(addr
, "\xff\xff\xff\xff\xff\xff", ETH_ALEN
) == 0)
1503 wk
.ik_flags
|= IEEE80211_KEY_GROUP
;
1505 wk
.ik_flags
|= IEEE80211_KEY_XMIT
| IEEE80211_KEY_DEFAULT
;
1506 os_memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
1508 os_memset(wk
.ik_macaddr
, 0, IEEE80211_ADDR_LEN
);
1509 wk
.ik_keyix
= key_idx
;
1510 wk
.ik_keylen
= key_len
;
1511 #ifdef WORDS_BIGENDIAN
1512 #define WPA_KEY_RSC_LEN 8
1515 u8 tmp
[WPA_KEY_RSC_LEN
];
1516 os_memset(tmp
, 0, sizeof(tmp
));
1517 for (i
= 0; i
< seq_len
; i
++)
1518 tmp
[WPA_KEY_RSC_LEN
- i
- 1] = seq
[i
];
1519 os_memcpy(&wk
.ik_keyrsc
, tmp
, WPA_KEY_RSC_LEN
);
1521 #else /* WORDS_BIGENDIAN */
1522 os_memcpy(&wk
.ik_keyrsc
, seq
, seq_len
);
1523 #endif /* WORDS_BIGENDIAN */
1524 os_memcpy(wk
.ik_keydata
, key
, key_len
);
1526 return set80211priv(drv
, IEEE80211_IOCTL_SETKEY
, &wk
, sizeof(wk
), 1);
1530 wpa_driver_madwifi_set_countermeasures(void *priv
, int enabled
)
1532 struct wpa_driver_madwifi_data
*drv
= priv
;
1533 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __FUNCTION__
, enabled
);
1534 return set80211param(drv
, IEEE80211_PARAM_COUNTERMEASURES
, enabled
, 1);
1538 wpa_driver_madwifi_deauthenticate(void *priv
, const u8
*addr
, int reason_code
)
1540 struct wpa_driver_madwifi_data
*drv
= priv
;
1541 struct ieee80211req_mlme mlme
;
1543 wpa_printf(MSG_DEBUG
, "%s", __FUNCTION__
);
1544 mlme
.im_op
= IEEE80211_MLME_DEAUTH
;
1545 mlme
.im_reason
= reason_code
;
1546 os_memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
1547 return set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
, sizeof(mlme
), 1);
1551 wpa_driver_madwifi_disassociate(void *priv
, const u8
*addr
, int reason_code
)
1553 struct wpa_driver_madwifi_data
*drv
= priv
;
1554 struct ieee80211req_mlme mlme
;
1556 wpa_printf(MSG_DEBUG
, "%s", __FUNCTION__
);
1557 mlme
.im_op
= IEEE80211_MLME_DISASSOC
;
1558 mlme
.im_reason
= reason_code
;
1559 os_memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
1560 return set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
, sizeof(mlme
), 1);
1564 wpa_driver_madwifi_associate(void *priv
,
1565 struct wpa_driver_associate_params
*params
)
1567 struct wpa_driver_madwifi_data
*drv
= priv
;
1568 struct ieee80211req_mlme mlme
;
1569 int ret
= 0, privacy
= 1;
1571 wpa_printf(MSG_DEBUG
, "%s", __FUNCTION__
);
1573 if (set80211param(drv
, IEEE80211_PARAM_DROPUNENCRYPTED
,
1574 params
->drop_unencrypted
, 1) < 0)
1576 if (wpa_driver_madwifi_set_auth_alg(drv
, params
->auth_alg
) < 0)
1580 * NB: Don't need to set the freq or cipher-related state as
1581 * this is implied by the bssid which is used to locate
1582 * the scanned node state which holds it. The ssid is
1583 * needed to disambiguate an AP that broadcasts multiple
1584 * ssid's but uses the same bssid.
1586 /* XXX error handling is wrong but unclear what to do... */
1587 if (wpa_driver_madwifi_set_wpa_ie(drv
, params
->wpa_ie
,
1588 params
->wpa_ie_len
) < 0)
1591 if (params
->pairwise_suite
== CIPHER_NONE
&&
1592 params
->group_suite
== CIPHER_NONE
&&
1593 params
->key_mgmt_suite
== KEY_MGMT_NONE
&&
1594 params
->wpa_ie_len
== 0)
1597 if (set80211param(drv
, IEEE80211_PARAM_PRIVACY
, privacy
, 1) < 0)
1600 if (params
->wpa_ie_len
&&
1601 set80211param(drv
, IEEE80211_PARAM_WPA
,
1602 params
->wpa_ie
[0] == WLAN_EID_RSN
? 2 : 1, 1) < 0)
1605 if (params
->bssid
== NULL
) {
1606 /* ap_scan=2 mode - driver takes care of AP selection and
1608 /* FIX: this does not seem to work; would probably need to
1609 * change something in the driver */
1610 if (set80211param(drv
, IEEE80211_PARAM_ROAMING
, 0, 1) < 0)
1613 if (wpa_driver_wext_set_ssid(drv
->wext
, params
->ssid
,
1614 params
->ssid_len
) < 0)
1617 if (set80211param(drv
, IEEE80211_PARAM_ROAMING
, 2, 1) < 0)
1619 if (wpa_driver_wext_set_ssid(drv
->wext
, params
->ssid
,
1620 params
->ssid_len
) < 0)
1622 os_memset(&mlme
, 0, sizeof(mlme
));
1623 mlme
.im_op
= IEEE80211_MLME_ASSOC
;
1624 os_memcpy(mlme
.im_macaddr
, params
->bssid
, IEEE80211_ADDR_LEN
);
1625 if (set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
,
1626 sizeof(mlme
), 1) < 0) {
1627 wpa_printf(MSG_DEBUG
, "%s: SETMLME[ASSOC] failed",
1637 wpa_driver_madwifi_set_auth_alg(void *priv
, int auth_alg
)
1639 struct wpa_driver_madwifi_data
*drv
= priv
;
1642 if ((auth_alg
& WPA_AUTH_ALG_OPEN
) &&
1643 (auth_alg
& WPA_AUTH_ALG_SHARED
))
1644 authmode
= IEEE80211_AUTH_AUTO
;
1645 else if (auth_alg
& WPA_AUTH_ALG_SHARED
)
1646 authmode
= IEEE80211_AUTH_SHARED
;
1648 authmode
= IEEE80211_AUTH_OPEN
;
1650 return set80211param(drv
, IEEE80211_PARAM_AUTHMODE
, authmode
, 1);
1654 wpa_driver_madwifi_scan(void *priv
, struct wpa_driver_scan_params
*params
)
1656 struct wpa_driver_madwifi_data
*drv
= priv
;
1659 const u8
*ssid
= params
->ssids
[0].ssid
;
1660 size_t ssid_len
= params
->ssids
[0].ssid_len
;
1662 wpa_driver_madwifi_set_probe_req_ie(drv
, params
->extra_ies
,
1663 params
->extra_ies_len
);
1665 os_memset(&iwr
, 0, sizeof(iwr
));
1666 os_strlcpy(iwr
.ifr_name
, drv
->ifname
, IFNAMSIZ
);
1668 /* set desired ssid before scan */
1669 /* FIX: scan should not break the current association, so using
1670 * set_ssid may not be the best way of doing this.. */
1671 if (wpa_driver_wext_set_ssid(drv
->wext
, ssid
, ssid_len
) < 0)
1674 if (ioctl(drv
->sock
, SIOCSIWSCAN
, &iwr
) < 0) {
1675 perror("ioctl[SIOCSIWSCAN]");
1680 * madwifi delivers a scan complete event so no need to poll, but
1681 * register a backup timeout anyway to make sure that we recover even
1682 * if the driver does not send this event for any reason. This timeout
1683 * will only be used if the event is not delivered (event handler will
1684 * cancel the timeout).
1686 eloop_cancel_timeout(wpa_driver_wext_scan_timeout
, drv
->wext
,
1688 eloop_register_timeout(30, 0, wpa_driver_wext_scan_timeout
, drv
->wext
,
1694 static int wpa_driver_madwifi_get_bssid(void *priv
, u8
*bssid
)
1696 struct wpa_driver_madwifi_data
*drv
= priv
;
1697 return wpa_driver_wext_get_bssid(drv
->wext
, bssid
);
1701 static int wpa_driver_madwifi_get_ssid(void *priv
, u8
*ssid
)
1703 struct wpa_driver_madwifi_data
*drv
= priv
;
1704 return wpa_driver_wext_get_ssid(drv
->wext
, ssid
);
1708 static struct wpa_scan_results
*
1709 wpa_driver_madwifi_get_scan_results(void *priv
)
1711 struct wpa_driver_madwifi_data
*drv
= priv
;
1712 return wpa_driver_wext_get_scan_results(drv
->wext
);
1716 static int wpa_driver_madwifi_set_operstate(void *priv
, int state
)
1718 struct wpa_driver_madwifi_data
*drv
= priv
;
1719 return wpa_driver_wext_set_operstate(drv
->wext
, state
);
1723 static int wpa_driver_madwifi_set_probe_req_ie(void *priv
, const u8
*ies
,
1726 struct ieee80211req_getset_appiebuf
*probe_req_ie
;
1729 probe_req_ie
= os_malloc(sizeof(*probe_req_ie
) + ies_len
);
1730 if (probe_req_ie
== NULL
)
1733 probe_req_ie
->app_frmtype
= IEEE80211_APPIE_FRAME_PROBE_REQ
;
1734 probe_req_ie
->app_buflen
= ies_len
;
1735 os_memcpy(probe_req_ie
->app_buf
, ies
, ies_len
);
1737 ret
= set80211priv(priv
, IEEE80211_IOCTL_SET_APPIEBUF
, probe_req_ie
,
1738 sizeof(struct ieee80211req_getset_appiebuf
) +
1741 os_free(probe_req_ie
);
1747 static void * wpa_driver_madwifi_init(void *ctx
, const char *ifname
)
1749 struct wpa_driver_madwifi_data
*drv
;
1751 drv
= os_zalloc(sizeof(*drv
));
1754 drv
->wext
= wpa_driver_wext_init(ctx
, ifname
);
1755 if (drv
->wext
== NULL
)
1759 os_strlcpy(drv
->ifname
, ifname
, sizeof(drv
->ifname
));
1760 drv
->sock
= socket(PF_INET
, SOCK_DGRAM
, 0);
1764 if (set80211param(drv
, IEEE80211_PARAM_ROAMING
, 2, 1) < 0) {
1765 wpa_printf(MSG_DEBUG
, "%s: failed to set wpa_supplicant-based "
1766 "roaming", __FUNCTION__
);
1770 if (set80211param(drv
, IEEE80211_PARAM_WPA
, 3, 1) < 0) {
1771 wpa_printf(MSG_DEBUG
, "%s: failed to enable WPA support",
1781 wpa_driver_wext_deinit(drv
->wext
);
1788 static void wpa_driver_madwifi_deinit(void *priv
)
1790 struct wpa_driver_madwifi_data
*drv
= priv
;
1792 if (wpa_driver_madwifi_set_wpa_ie(drv
, NULL
, 0) < 0) {
1793 wpa_printf(MSG_DEBUG
, "%s: failed to clear WPA IE",
1796 if (set80211param(drv
, IEEE80211_PARAM_ROAMING
, 0, 1) < 0) {
1797 wpa_printf(MSG_DEBUG
, "%s: failed to enable driver-based "
1798 "roaming", __FUNCTION__
);
1800 if (set80211param(drv
, IEEE80211_PARAM_PRIVACY
, 0, 1) < 0) {
1801 wpa_printf(MSG_DEBUG
, "%s: failed to disable forced Privacy "
1802 "flag", __FUNCTION__
);
1804 if (set80211param(drv
, IEEE80211_PARAM_WPA
, 0, 1) < 0) {
1805 wpa_printf(MSG_DEBUG
, "%s: failed to disable WPA",
1809 wpa_driver_wext_deinit(drv
->wext
);
1815 #endif /* HOSTAPD */
1818 const struct wpa_driver_ops wpa_driver_madwifi_ops
= {
1820 .desc
= "MADWIFI 802.11 support (Atheros, etc.)",
1821 .set_key
= wpa_driver_madwifi_set_key
,
1823 .hapd_init
= madwifi_init
,
1824 .hapd_deinit
= madwifi_deinit
,
1825 .set_ieee8021x
= madwifi_set_ieee8021x
,
1826 .set_privacy
= madwifi_set_privacy
,
1827 .get_seqnum
= madwifi_get_seqnum
,
1828 .flush
= madwifi_flush
,
1829 .set_generic_elem
= madwifi_set_opt_ie
,
1830 .sta_set_flags
= madwifi_sta_set_flags
,
1831 .read_sta_data
= madwifi_read_sta_driver_data
,
1832 .hapd_send_eapol
= madwifi_send_eapol
,
1833 .sta_disassoc
= madwifi_sta_disassoc
,
1834 .sta_deauth
= madwifi_sta_deauth
,
1835 .hapd_set_ssid
= madwifi_set_ssid
,
1836 .hapd_get_ssid
= madwifi_get_ssid
,
1837 .hapd_set_countermeasures
= madwifi_set_countermeasures
,
1838 .sta_clear_stats
= madwifi_sta_clear_stats
,
1839 .commit
= madwifi_commit
,
1840 .set_ap_wps_ie
= madwifi_set_ap_wps_ie
,
1842 .get_bssid
= wpa_driver_madwifi_get_bssid
,
1843 .get_ssid
= wpa_driver_madwifi_get_ssid
,
1844 .init
= wpa_driver_madwifi_init
,
1845 .deinit
= wpa_driver_madwifi_deinit
,
1846 .set_countermeasures
= wpa_driver_madwifi_set_countermeasures
,
1847 .scan2
= wpa_driver_madwifi_scan
,
1848 .get_scan_results2
= wpa_driver_madwifi_get_scan_results
,
1849 .deauthenticate
= wpa_driver_madwifi_deauthenticate
,
1850 .disassociate
= wpa_driver_madwifi_disassociate
,
1851 .associate
= wpa_driver_madwifi_associate
,
1852 .set_operstate
= wpa_driver_madwifi_set_operstate
,
1853 #endif /* HOSTAPD */