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 */
72 #define WPA_KEY_RSC_LEN 8
76 #include "priv_netlink.h"
78 #include "linux_ioctl.h"
79 #include "l2_packet/l2_packet.h"
82 struct madwifi_driver_data
{
83 struct hostapd_data
*hapd
; /* back pointer */
85 char iface
[IFNAMSIZ
+ 1];
87 struct l2_packet_data
*sock_xmit
; /* raw packet xmit socket */
88 struct l2_packet_data
*sock_recv
; /* raw packet recv socket */
89 int ioctl_sock
; /* socket for ioctl() use */
90 struct netlink_data
*netlink
;
92 u8 acct_mac
[ETH_ALEN
];
93 struct hostap_sta_driver_data acct_data
;
95 struct l2_packet_data
*sock_raw
; /* raw 802.11 management frames */
98 static int madwifi_sta_deauth(void *priv
, const u8
*own_addr
, const u8
*addr
,
102 set80211priv(struct madwifi_driver_data
*drv
, int op
, void *data
, int len
)
105 int do_inline
= len
< IFNAMSIZ
;
107 memset(&iwr
, 0, sizeof(iwr
));
108 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
109 #ifdef IEEE80211_IOCTL_FILTERFRAME
110 /* FILTERFRAME must be NOT inline, regardless of size. */
111 if (op
== IEEE80211_IOCTL_FILTERFRAME
)
113 #endif /* IEEE80211_IOCTL_FILTERFRAME */
114 if (op
== IEEE80211_IOCTL_SET_APPIEBUF
)
118 * Argument data fits inline; put it there.
120 memcpy(iwr
.u
.name
, data
, len
);
123 * Argument data too big for inline transfer; setup a
124 * parameter block instead; the kernel will transfer
125 * the data for the driver.
127 iwr
.u
.data
.pointer
= data
;
128 iwr
.u
.data
.length
= len
;
131 if (ioctl(drv
->ioctl_sock
, op
, &iwr
) < 0) {
133 int first
= IEEE80211_IOCTL_SETPARAM
;
134 static const char *opnames
[] = {
135 "ioctl[IEEE80211_IOCTL_SETPARAM]",
136 "ioctl[IEEE80211_IOCTL_GETPARAM]",
137 "ioctl[IEEE80211_IOCTL_SETMODE]",
138 "ioctl[IEEE80211_IOCTL_GETMODE]",
139 "ioctl[IEEE80211_IOCTL_SETWMMPARAMS]",
140 "ioctl[IEEE80211_IOCTL_GETWMMPARAMS]",
141 "ioctl[IEEE80211_IOCTL_SETCHANLIST]",
142 "ioctl[IEEE80211_IOCTL_GETCHANLIST]",
143 "ioctl[IEEE80211_IOCTL_CHANSWITCH]",
144 "ioctl[IEEE80211_IOCTL_GET_APPIEBUF]",
145 "ioctl[IEEE80211_IOCTL_SET_APPIEBUF]",
146 "ioctl[IEEE80211_IOCTL_GETSCANRESULTS]",
147 "ioctl[IEEE80211_IOCTL_FILTERFRAME]",
148 "ioctl[IEEE80211_IOCTL_GETCHANINFO]",
149 "ioctl[IEEE80211_IOCTL_SETOPTIE]",
150 "ioctl[IEEE80211_IOCTL_GETOPTIE]",
151 "ioctl[IEEE80211_IOCTL_SETMLME]",
153 "ioctl[IEEE80211_IOCTL_SETKEY]",
155 "ioctl[IEEE80211_IOCTL_DELKEY]",
157 "ioctl[IEEE80211_IOCTL_ADDMAC]",
159 "ioctl[IEEE80211_IOCTL_DELMAC]",
161 "ioctl[IEEE80211_IOCTL_WDSMAC]",
163 "ioctl[IEEE80211_IOCTL_WDSDELMAC]",
165 "ioctl[IEEE80211_IOCTL_KICKMAC]",
167 #else /* MADWIFI_NG */
168 int first
= IEEE80211_IOCTL_SETPARAM
;
169 static const char *opnames
[] = {
170 "ioctl[IEEE80211_IOCTL_SETPARAM]",
171 "ioctl[IEEE80211_IOCTL_GETPARAM]",
172 "ioctl[IEEE80211_IOCTL_SETKEY]",
173 "ioctl[SIOCIWFIRSTPRIV+3]",
174 "ioctl[IEEE80211_IOCTL_DELKEY]",
175 "ioctl[SIOCIWFIRSTPRIV+5]",
176 "ioctl[IEEE80211_IOCTL_SETMLME]",
177 "ioctl[SIOCIWFIRSTPRIV+7]",
178 "ioctl[IEEE80211_IOCTL_SETOPTIE]",
179 "ioctl[IEEE80211_IOCTL_GETOPTIE]",
180 "ioctl[IEEE80211_IOCTL_ADDMAC]",
181 "ioctl[SIOCIWFIRSTPRIV+11]",
182 "ioctl[IEEE80211_IOCTL_DELMAC]",
183 "ioctl[SIOCIWFIRSTPRIV+13]",
184 "ioctl[IEEE80211_IOCTL_CHANLIST]",
185 "ioctl[SIOCIWFIRSTPRIV+15]",
186 "ioctl[IEEE80211_IOCTL_GETRSN]",
187 "ioctl[SIOCIWFIRSTPRIV+17]",
188 "ioctl[IEEE80211_IOCTL_GETKEY]",
190 #endif /* MADWIFI_NG */
191 int idx
= op
- first
;
193 idx
< (int) (sizeof(opnames
) / sizeof(opnames
[0])) &&
195 perror(opnames
[idx
]);
197 perror("ioctl[unknown???]");
204 set80211param(struct madwifi_driver_data
*drv
, int op
, int arg
)
208 memset(&iwr
, 0, sizeof(iwr
));
209 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
211 memcpy(iwr
.u
.name
+sizeof(__u32
), &arg
, sizeof(arg
));
213 if (ioctl(drv
->ioctl_sock
, IEEE80211_IOCTL_SETPARAM
, &iwr
) < 0) {
214 perror("ioctl[IEEE80211_IOCTL_SETPARAM]");
215 wpa_printf(MSG_DEBUG
, "%s: Failed to set parameter (op %d "
216 "arg %d)", __func__
, op
, arg
);
222 #ifndef CONFIG_NO_STDOUT_DEBUG
224 ether_sprintf(const u8
*addr
)
226 static char buf
[sizeof(MACSTR
)];
229 snprintf(buf
, sizeof(buf
), MACSTR
, MAC2STR(addr
));
231 snprintf(buf
, sizeof(buf
), MACSTR
, 0,0,0,0,0,0);
234 #endif /* CONFIG_NO_STDOUT_DEBUG */
237 * Configure WPA parameters.
240 madwifi_configure_wpa(struct madwifi_driver_data
*drv
,
241 struct wpa_bss_params
*params
)
245 switch (params
->wpa_group
) {
246 case WPA_CIPHER_CCMP
:
247 v
= IEEE80211_CIPHER_AES_CCM
;
249 case WPA_CIPHER_TKIP
:
250 v
= IEEE80211_CIPHER_TKIP
;
252 case WPA_CIPHER_WEP104
:
253 v
= IEEE80211_CIPHER_WEP
;
255 case WPA_CIPHER_WEP40
:
256 v
= IEEE80211_CIPHER_WEP
;
258 case WPA_CIPHER_NONE
:
259 v
= IEEE80211_CIPHER_NONE
;
262 wpa_printf(MSG_ERROR
, "Unknown group key cipher %u",
266 wpa_printf(MSG_DEBUG
, "%s: group key cipher=%d", __func__
, v
);
267 if (set80211param(drv
, IEEE80211_PARAM_MCASTCIPHER
, v
)) {
268 printf("Unable to set group key cipher to %u\n", v
);
271 if (v
== IEEE80211_CIPHER_WEP
) {
272 /* key length is done only for specific ciphers */
273 v
= (params
->wpa_group
== WPA_CIPHER_WEP104
? 13 : 5);
274 if (set80211param(drv
, IEEE80211_PARAM_MCASTKEYLEN
, v
)) {
275 printf("Unable to set group key length to %u\n", v
);
281 if (params
->wpa_pairwise
& WPA_CIPHER_CCMP
)
282 v
|= 1<<IEEE80211_CIPHER_AES_CCM
;
283 if (params
->wpa_pairwise
& WPA_CIPHER_TKIP
)
284 v
|= 1<<IEEE80211_CIPHER_TKIP
;
285 if (params
->wpa_pairwise
& WPA_CIPHER_NONE
)
286 v
|= 1<<IEEE80211_CIPHER_NONE
;
287 wpa_printf(MSG_DEBUG
, "%s: pairwise key ciphers=0x%x", __func__
, v
);
288 if (set80211param(drv
, IEEE80211_PARAM_UCASTCIPHERS
, v
)) {
289 printf("Unable to set pairwise key ciphers to 0x%x\n", v
);
293 wpa_printf(MSG_DEBUG
, "%s: key management algorithms=0x%x",
294 __func__
, params
->wpa_key_mgmt
);
295 if (set80211param(drv
, IEEE80211_PARAM_KEYMGTALGS
,
296 params
->wpa_key_mgmt
)) {
297 printf("Unable to set key management algorithms to 0x%x\n",
298 params
->wpa_key_mgmt
);
303 if (params
->rsn_preauth
)
305 wpa_printf(MSG_DEBUG
, "%s: rsn capabilities=0x%x",
306 __func__
, params
->rsn_preauth
);
307 if (set80211param(drv
, IEEE80211_PARAM_RSNCAPS
, v
)) {
308 printf("Unable to set RSN capabilities to 0x%x\n", v
);
312 wpa_printf(MSG_DEBUG
, "%s: enable WPA=0x%x", __func__
, params
->wpa
);
313 if (set80211param(drv
, IEEE80211_PARAM_WPA
, params
->wpa
)) {
314 printf("Unable to set WPA to %u\n", params
->wpa
);
321 madwifi_set_ieee8021x(void *priv
, struct wpa_bss_params
*params
)
323 struct madwifi_driver_data
*drv
= priv
;
325 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __func__
, params
->enabled
);
327 if (!params
->enabled
) {
328 /* XXX restore state */
329 return set80211param(priv
, IEEE80211_PARAM_AUTHMODE
,
330 IEEE80211_AUTH_AUTO
);
332 if (!params
->wpa
&& !params
->ieee802_1x
) {
333 hostapd_logger(drv
->hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
334 HOSTAPD_LEVEL_WARNING
, "No 802.1X or WPA enabled!");
337 if (params
->wpa
&& madwifi_configure_wpa(drv
, params
) != 0) {
338 hostapd_logger(drv
->hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
339 HOSTAPD_LEVEL_WARNING
, "Error configuring WPA state!");
342 if (set80211param(priv
, IEEE80211_PARAM_AUTHMODE
,
343 (params
->wpa
? IEEE80211_AUTH_WPA
: IEEE80211_AUTH_8021X
))) {
344 hostapd_logger(drv
->hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
345 HOSTAPD_LEVEL_WARNING
, "Error enabling WPA/802.1X!");
353 madwifi_set_privacy(void *priv
, int enabled
)
355 struct madwifi_driver_data
*drv
= priv
;
357 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __func__
, enabled
);
359 return set80211param(drv
, IEEE80211_PARAM_PRIVACY
, enabled
);
363 madwifi_set_sta_authorized(void *priv
, const u8
*addr
, int authorized
)
365 struct madwifi_driver_data
*drv
= priv
;
366 struct ieee80211req_mlme mlme
;
369 wpa_printf(MSG_DEBUG
, "%s: addr=%s authorized=%d",
370 __func__
, ether_sprintf(addr
), authorized
);
373 mlme
.im_op
= IEEE80211_MLME_AUTHORIZE
;
375 mlme
.im_op
= IEEE80211_MLME_UNAUTHORIZE
;
377 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
378 ret
= set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
, sizeof(mlme
));
380 wpa_printf(MSG_DEBUG
, "%s: Failed to %sauthorize STA " MACSTR
,
381 __func__
, authorized
? "" : "un", MAC2STR(addr
));
388 madwifi_sta_set_flags(void *priv
, const u8
*addr
,
389 int total_flags
, int flags_or
, int flags_and
)
391 /* For now, only support setting Authorized flag */
392 if (flags_or
& WPA_STA_AUTHORIZED
)
393 return madwifi_set_sta_authorized(priv
, addr
, 1);
394 if (!(flags_and
& WPA_STA_AUTHORIZED
))
395 return madwifi_set_sta_authorized(priv
, addr
, 0);
400 madwifi_del_key(void *priv
, const u8
*addr
, int key_idx
)
402 struct madwifi_driver_data
*drv
= priv
;
403 struct ieee80211req_del_key wk
;
406 wpa_printf(MSG_DEBUG
, "%s: addr=%s key_idx=%d",
407 __func__
, ether_sprintf(addr
), key_idx
);
409 memset(&wk
, 0, sizeof(wk
));
411 memcpy(wk
.idk_macaddr
, addr
, IEEE80211_ADDR_LEN
);
412 wk
.idk_keyix
= (u8
) IEEE80211_KEYIX_NONE
;
414 wk
.idk_keyix
= key_idx
;
417 ret
= set80211priv(drv
, IEEE80211_IOCTL_DELKEY
, &wk
, sizeof(wk
));
419 wpa_printf(MSG_DEBUG
, "%s: Failed to delete key (addr %s"
420 " key_idx %d)", __func__
, ether_sprintf(addr
),
428 wpa_driver_madwifi_set_key(const char *ifname
, void *priv
, enum wpa_alg alg
,
429 const u8
*addr
, int key_idx
, int set_tx
,
430 const u8
*seq
, size_t seq_len
,
431 const u8
*key
, size_t key_len
)
433 struct madwifi_driver_data
*drv
= priv
;
434 struct ieee80211req_key wk
;
438 if (alg
== WPA_ALG_NONE
)
439 return madwifi_del_key(drv
, addr
, key_idx
);
441 wpa_printf(MSG_DEBUG
, "%s: alg=%d addr=%s key_idx=%d",
442 __func__
, alg
, ether_sprintf(addr
), key_idx
);
444 if (alg
== WPA_ALG_WEP
)
445 cipher
= IEEE80211_CIPHER_WEP
;
446 else if (alg
== WPA_ALG_TKIP
)
447 cipher
= IEEE80211_CIPHER_TKIP
;
448 else if (alg
== WPA_ALG_CCMP
)
449 cipher
= IEEE80211_CIPHER_AES_CCM
;
451 printf("%s: unknown/unsupported algorithm %d\n",
456 if (key_len
> sizeof(wk
.ik_keydata
)) {
457 printf("%s: key length %lu too big\n", __func__
,
458 (unsigned long) key_len
);
462 memset(&wk
, 0, sizeof(wk
));
464 wk
.ik_flags
= IEEE80211_KEY_RECV
| IEEE80211_KEY_XMIT
;
465 if (addr
== NULL
|| is_broadcast_ether_addr(addr
)) {
466 memset(wk
.ik_macaddr
, 0xff, IEEE80211_ADDR_LEN
);
467 wk
.ik_keyix
= key_idx
;
468 wk
.ik_flags
|= IEEE80211_KEY_DEFAULT
;
470 memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
471 wk
.ik_keyix
= IEEE80211_KEYIX_NONE
;
473 wk
.ik_keylen
= key_len
;
474 memcpy(wk
.ik_keydata
, key
, key_len
);
476 ret
= set80211priv(drv
, IEEE80211_IOCTL_SETKEY
, &wk
, sizeof(wk
));
478 wpa_printf(MSG_DEBUG
, "%s: Failed to set key (addr %s"
479 " key_idx %d alg %d key_len %lu set_tx %d)",
480 __func__
, ether_sprintf(wk
.ik_macaddr
), key_idx
,
481 alg
, (unsigned long) key_len
, set_tx
);
489 madwifi_get_seqnum(const char *ifname
, void *priv
, const u8
*addr
, int idx
,
492 struct madwifi_driver_data
*drv
= priv
;
493 struct ieee80211req_key wk
;
495 wpa_printf(MSG_DEBUG
, "%s: addr=%s idx=%d",
496 __func__
, ether_sprintf(addr
), idx
);
498 memset(&wk
, 0, sizeof(wk
));
500 memset(wk
.ik_macaddr
, 0xff, IEEE80211_ADDR_LEN
);
502 memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
505 if (set80211priv(drv
, IEEE80211_IOCTL_GETKEY
, &wk
, sizeof(wk
))) {
506 wpa_printf(MSG_DEBUG
, "%s: Failed to get encryption data "
507 "(addr " MACSTR
" key_idx %d)",
508 __func__
, MAC2STR(wk
.ik_macaddr
), idx
);
512 #ifdef WORDS_BIGENDIAN
515 * wk.ik_keytsc is in host byte order (big endian), need to
516 * swap it to match with the byte order used in WPA.
519 u8 tmp
[WPA_KEY_RSC_LEN
];
520 memcpy(tmp
, &wk
.ik_keytsc
, sizeof(wk
.ik_keytsc
));
521 for (i
= 0; i
< WPA_KEY_RSC_LEN
; i
++) {
522 seq
[i
] = tmp
[WPA_KEY_RSC_LEN
- i
- 1];
525 #else /* WORDS_BIGENDIAN */
526 memcpy(seq
, &wk
.ik_keytsc
, sizeof(wk
.ik_keytsc
));
527 #endif /* WORDS_BIGENDIAN */
533 madwifi_flush(void *priv
)
536 u8 allsta
[IEEE80211_ADDR_LEN
];
537 memset(allsta
, 0xff, IEEE80211_ADDR_LEN
);
538 return madwifi_sta_deauth(priv
, NULL
, allsta
,
539 IEEE80211_REASON_AUTH_LEAVE
);
540 #else /* MADWIFI_BSD */
542 #endif /* MADWIFI_BSD */
547 madwifi_read_sta_driver_data(void *priv
, struct hostap_sta_driver_data
*data
,
550 struct madwifi_driver_data
*drv
= priv
;
553 struct ieee80211req_sta_stats stats
;
555 memset(data
, 0, sizeof(*data
));
558 * Fetch statistics for station from the system.
560 memset(&stats
, 0, sizeof(stats
));
561 memcpy(stats
.is_u
.macaddr
, addr
, IEEE80211_ADDR_LEN
);
562 if (set80211priv(drv
,
564 IEEE80211_IOCTL_STA_STATS
,
565 #else /* MADWIFI_NG */
566 IEEE80211_IOCTL_GETSTASTATS
,
567 #endif /* MADWIFI_NG */
568 &stats
, sizeof(stats
))) {
569 wpa_printf(MSG_DEBUG
, "%s: Failed to fetch STA stats (addr "
570 MACSTR
")", __func__
, MAC2STR(addr
));
571 if (memcmp(addr
, drv
->acct_mac
, ETH_ALEN
) == 0) {
572 memcpy(data
, &drv
->acct_data
, sizeof(*data
));
576 printf("Failed to get station stats information element.\n");
580 data
->rx_packets
= stats
.is_stats
.ns_rx_data
;
581 data
->rx_bytes
= stats
.is_stats
.ns_rx_bytes
;
582 data
->tx_packets
= stats
.is_stats
.ns_tx_data
;
583 data
->tx_bytes
= stats
.is_stats
.ns_tx_bytes
;
586 #else /* MADWIFI_BSD */
588 char buf
[1024], line
[128], *pos
;
592 memset(data
, 0, sizeof(*data
));
593 snprintf(buf
, sizeof(buf
), "/proc/net/madwifi/%s/" MACSTR
,
594 drv
->iface
, MAC2STR(addr
));
598 if (memcmp(addr
, drv
->acct_mac
, ETH_ALEN
) != 0)
600 memcpy(data
, &drv
->acct_data
, sizeof(*data
));
603 /* Need to read proc file with in one piece, so use large enough
605 setbuffer(f
, buf
, sizeof(buf
));
607 while (fgets(line
, sizeof(line
), f
)) {
608 pos
= strchr(line
, '=');
612 val
= strtoul(pos
, NULL
, 10);
613 if (strcmp(line
, "rx_packets") == 0)
614 data
->rx_packets
= val
;
615 else if (strcmp(line
, "tx_packets") == 0)
616 data
->tx_packets
= val
;
617 else if (strcmp(line
, "rx_bytes") == 0)
618 data
->rx_bytes
= val
;
619 else if (strcmp(line
, "tx_bytes") == 0)
620 data
->tx_bytes
= val
;
626 #endif /* MADWIFI_BSD */
631 madwifi_sta_clear_stats(void *priv
, const u8
*addr
)
633 #if defined(MADWIFI_BSD) && defined(IEEE80211_MLME_CLEAR_STATS)
634 struct madwifi_driver_data
*drv
= priv
;
635 struct ieee80211req_mlme mlme
;
638 wpa_printf(MSG_DEBUG
, "%s: addr=%s", __func__
, ether_sprintf(addr
));
640 mlme
.im_op
= IEEE80211_MLME_CLEAR_STATS
;
641 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
642 ret
= set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
,
645 wpa_printf(MSG_DEBUG
, "%s: Failed to clear STA stats (addr "
646 MACSTR
")", __func__
, MAC2STR(addr
));
650 #else /* MADWIFI_BSD && IEEE80211_MLME_CLEAR_STATS */
652 #endif /* MADWIFI_BSD && IEEE80211_MLME_CLEAR_STATS */
657 madwifi_set_opt_ie(void *priv
, const u8
*ie
, size_t ie_len
)
660 * Do nothing; we setup parameters at startup that define the
661 * contents of the beacon information element.
667 madwifi_sta_deauth(void *priv
, const u8
*own_addr
, const u8
*addr
,
670 struct madwifi_driver_data
*drv
= priv
;
671 struct ieee80211req_mlme mlme
;
674 wpa_printf(MSG_DEBUG
, "%s: addr=%s reason_code=%d",
675 __func__
, ether_sprintf(addr
), reason_code
);
677 mlme
.im_op
= IEEE80211_MLME_DEAUTH
;
678 mlme
.im_reason
= reason_code
;
679 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
680 ret
= set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
, sizeof(mlme
));
682 wpa_printf(MSG_DEBUG
, "%s: Failed to deauth STA (addr " MACSTR
684 __func__
, MAC2STR(addr
), reason_code
);
691 madwifi_sta_disassoc(void *priv
, const u8
*own_addr
, const u8
*addr
,
694 struct madwifi_driver_data
*drv
= priv
;
695 struct ieee80211req_mlme mlme
;
698 wpa_printf(MSG_DEBUG
, "%s: addr=%s reason_code=%d",
699 __func__
, ether_sprintf(addr
), reason_code
);
701 mlme
.im_op
= IEEE80211_MLME_DISASSOC
;
702 mlme
.im_reason
= reason_code
;
703 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
704 ret
= set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
, sizeof(mlme
));
706 wpa_printf(MSG_DEBUG
, "%s: Failed to disassoc STA (addr "
707 MACSTR
" reason %d)",
708 __func__
, MAC2STR(addr
), reason_code
);
715 #ifdef IEEE80211_IOCTL_FILTERFRAME
716 static void madwifi_raw_receive(void *ctx
, const u8
*src_addr
, const u8
*buf
,
719 struct madwifi_driver_data
*drv
= ctx
;
720 const struct ieee80211_mgmt
*mgmt
;
722 union wpa_event_data event
;
724 /* Send Probe Request information to WPS processing */
726 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.probe_req
))
728 mgmt
= (const struct ieee80211_mgmt
*) buf
;
730 fc
= le_to_host16(mgmt
->frame_control
);
731 if (WLAN_FC_GET_TYPE(fc
) != WLAN_FC_TYPE_MGMT
||
732 WLAN_FC_GET_STYPE(fc
) != WLAN_FC_STYPE_PROBE_REQ
)
735 os_memset(&event
, 0, sizeof(event
));
736 event
.rx_probe_req
.sa
= mgmt
->sa
;
737 event
.rx_probe_req
.da
= mgmt
->da
;
738 event
.rx_probe_req
.bssid
= mgmt
->bssid
;
739 event
.rx_probe_req
.ie
= mgmt
->u
.probe_req
.variable
;
740 event
.rx_probe_req
.ie_len
=
741 len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.probe_req
));
742 wpa_supplicant_event(drv
->hapd
, EVENT_RX_PROBE_REQ
, &event
);
744 #endif /* IEEE80211_IOCTL_FILTERFRAME */
745 #endif /* CONFIG_WPS */
747 static int madwifi_receive_probe_req(struct madwifi_driver_data
*drv
)
751 #ifdef IEEE80211_IOCTL_FILTERFRAME
752 struct ieee80211req_set_filter filt
;
754 wpa_printf(MSG_DEBUG
, "%s Enter", __func__
);
755 filt
.app_filterype
= IEEE80211_FILTER_TYPE_PROBE_REQ
;
757 ret
= set80211priv(drv
, IEEE80211_IOCTL_FILTERFRAME
, &filt
,
758 sizeof(struct ieee80211req_set_filter
));
762 drv
->sock_raw
= l2_packet_init(drv
->iface
, NULL
, ETH_P_80211_RAW
,
763 madwifi_raw_receive
, drv
, 1);
764 if (drv
->sock_raw
== NULL
)
766 #endif /* IEEE80211_IOCTL_FILTERFRAME */
767 #endif /* CONFIG_WPS */
773 madwifi_set_wps_ie(void *priv
, const u8
*ie
, size_t len
, u32 frametype
)
775 struct madwifi_driver_data
*drv
= priv
;
777 struct ieee80211req_getset_appiebuf
*beac_ie
;
779 wpa_printf(MSG_DEBUG
, "%s buflen = %lu", __func__
,
780 (unsigned long) len
);
782 beac_ie
= (struct ieee80211req_getset_appiebuf
*) buf
;
783 beac_ie
->app_frmtype
= frametype
;
784 beac_ie
->app_buflen
= len
;
785 memcpy(&(beac_ie
->app_buf
[0]), ie
, len
);
787 return set80211priv(drv
, IEEE80211_IOCTL_SET_APPIEBUF
, beac_ie
,
788 sizeof(struct ieee80211req_getset_appiebuf
) + len
);
792 madwifi_set_ap_wps_ie(void *priv
, const struct wpabuf
*beacon
,
793 const struct wpabuf
*proberesp
,
794 const struct wpabuf
*assocresp
)
796 if (madwifi_set_wps_ie(priv
, beacon
? wpabuf_head(beacon
) : NULL
,
797 beacon
? wpabuf_len(beacon
) : 0,
798 IEEE80211_APPIE_FRAME_BEACON
) < 0)
800 return madwifi_set_wps_ie(priv
,
801 proberesp
? wpabuf_head(proberesp
) : NULL
,
802 proberesp
? wpabuf_len(proberesp
) : 0,
803 IEEE80211_APPIE_FRAME_PROBE_RESP
);
805 #else /* CONFIG_WPS */
806 #define madwifi_set_ap_wps_ie NULL
807 #endif /* CONFIG_WPS */
809 static int madwifi_set_freq(void *priv
, struct hostapd_freq_params
*freq
)
811 struct madwifi_driver_data
*drv
= priv
;
814 os_memset(&iwr
, 0, sizeof(iwr
));
815 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
816 iwr
.u
.freq
.m
= freq
->channel
;
819 if (ioctl(drv
->ioctl_sock
, SIOCSIWFREQ
, &iwr
) < 0) {
820 perror("ioctl[SIOCSIWFREQ]");
828 madwifi_new_sta(struct madwifi_driver_data
*drv
, u8 addr
[IEEE80211_ADDR_LEN
])
830 struct hostapd_data
*hapd
= drv
->hapd
;
831 struct ieee80211req_wpaie ie
;
836 * Fetch negotiated WPA/RSN parameters from the system.
838 memset(&ie
, 0, sizeof(ie
));
839 memcpy(ie
.wpa_macaddr
, addr
, IEEE80211_ADDR_LEN
);
840 if (set80211priv(drv
, IEEE80211_IOCTL_GETWPAIE
, &ie
, sizeof(ie
))) {
841 wpa_printf(MSG_DEBUG
, "%s: Failed to get WPA/RSN IE",
845 wpa_hexdump(MSG_MSGDUMP
, "madwifi req WPA IE",
846 ie
.wpa_ie
, IEEE80211_MAX_OPT_IE
);
848 /* madwifi seems to return some random data if WPA/RSN IE is not set.
849 * Assume the IE was not included if the IE type is unknown. */
850 if (iebuf
[0] != WLAN_EID_VENDOR_SPECIFIC
)
853 wpa_hexdump(MSG_MSGDUMP
, "madwifi req RSN IE",
854 ie
.rsn_ie
, IEEE80211_MAX_OPT_IE
);
855 if (iebuf
[1] == 0 && ie
.rsn_ie
[1] > 0) {
856 /* madwifi-ng svn #1453 added rsn_ie. Use it, if wpa_ie was not
857 * set. This is needed for WPA2. */
859 if (iebuf
[0] != WLAN_EID_RSN
)
862 #endif /* MADWIFI_NG */
871 drv_event_assoc(hapd
, addr
, iebuf
, ielen
, 0);
873 if (memcmp(addr
, drv
->acct_mac
, ETH_ALEN
) == 0) {
874 /* Cached accounting data is not valid anymore. */
875 memset(drv
->acct_mac
, 0, ETH_ALEN
);
876 memset(&drv
->acct_data
, 0, sizeof(drv
->acct_data
));
881 madwifi_wireless_event_wireless_custom(struct madwifi_driver_data
*drv
,
884 wpa_printf(MSG_DEBUG
, "Custom wireless event: '%s'", custom
);
886 if (strncmp(custom
, "MLME-MICHAELMICFAILURE.indication", 33) == 0) {
889 pos
= strstr(custom
, "addr=");
891 wpa_printf(MSG_DEBUG
,
892 "MLME-MICHAELMICFAILURE.indication "
893 "without sender address ignored");
897 if (hwaddr_aton(pos
, addr
) == 0) {
898 union wpa_event_data data
;
899 os_memset(&data
, 0, sizeof(data
));
900 data
.michael_mic_failure
.unicast
= 1;
901 data
.michael_mic_failure
.src
= addr
;
902 wpa_supplicant_event(drv
->hapd
,
903 EVENT_MICHAEL_MIC_FAILURE
, &data
);
905 wpa_printf(MSG_DEBUG
,
906 "MLME-MICHAELMICFAILURE.indication "
907 "with invalid MAC address");
909 } else if (strncmp(custom
, "STA-TRAFFIC-STAT", 16) == 0) {
913 while ((key
= strchr(key
, '\n')) != NULL
) {
915 value
= strchr(key
, '=');
919 val
= strtoul(value
, NULL
, 10);
920 if (strcmp(key
, "mac") == 0)
921 hwaddr_aton(value
, drv
->acct_mac
);
922 else if (strcmp(key
, "rx_packets") == 0)
923 drv
->acct_data
.rx_packets
= val
;
924 else if (strcmp(key
, "tx_packets") == 0)
925 drv
->acct_data
.tx_packets
= val
;
926 else if (strcmp(key
, "rx_bytes") == 0)
927 drv
->acct_data
.rx_bytes
= val
;
928 else if (strcmp(key
, "tx_bytes") == 0)
929 drv
->acct_data
.tx_bytes
= val
;
936 madwifi_wireless_event_wireless(struct madwifi_driver_data
*drv
,
939 struct iw_event iwe_buf
, *iwe
= &iwe_buf
;
940 char *pos
, *end
, *custom
, *buf
;
945 while (pos
+ IW_EV_LCP_LEN
<= end
) {
946 /* Event data may be unaligned, so make a local, aligned copy
947 * before processing. */
948 memcpy(&iwe_buf
, pos
, IW_EV_LCP_LEN
);
949 wpa_printf(MSG_MSGDUMP
, "Wireless event: cmd=0x%x len=%d",
951 if (iwe
->len
<= IW_EV_LCP_LEN
)
954 custom
= pos
+ IW_EV_POINT_LEN
;
955 if (drv
->we_version
> 18 &&
956 (iwe
->cmd
== IWEVMICHAELMICFAILURE
||
957 iwe
->cmd
== IWEVCUSTOM
)) {
958 /* WE-19 removed the pointer from struct iw_point */
959 char *dpos
= (char *) &iwe_buf
.u
.data
.length
;
960 int dlen
= dpos
- (char *) &iwe_buf
;
961 memcpy(dpos
, pos
+ IW_EV_LCP_LEN
,
962 sizeof(struct iw_event
) - dlen
);
964 memcpy(&iwe_buf
, pos
, sizeof(struct iw_event
));
965 custom
+= IW_EV_POINT_OFF
;
970 drv_event_disassoc(drv
->hapd
,
971 (u8
*) iwe
->u
.addr
.sa_data
);
974 madwifi_new_sta(drv
, (u8
*) iwe
->u
.addr
.sa_data
);
977 if (custom
+ iwe
->u
.data
.length
> end
)
979 buf
= malloc(iwe
->u
.data
.length
+ 1);
982 memcpy(buf
, custom
, iwe
->u
.data
.length
);
983 buf
[iwe
->u
.data
.length
] = '\0';
984 madwifi_wireless_event_wireless_custom(drv
, buf
);
995 madwifi_wireless_event_rtm_newlink(void *ctx
, struct ifinfomsg
*ifi
,
998 struct madwifi_driver_data
*drv
= ctx
;
999 int attrlen
, rta_len
;
1000 struct rtattr
*attr
;
1002 if (ifi
->ifi_index
!= drv
->ifindex
)
1006 attr
= (struct rtattr
*) buf
;
1008 rta_len
= RTA_ALIGN(sizeof(struct rtattr
));
1009 while (RTA_OK(attr
, attrlen
)) {
1010 if (attr
->rta_type
== IFLA_WIRELESS
) {
1011 madwifi_wireless_event_wireless(
1012 drv
, ((char *) attr
) + rta_len
,
1013 attr
->rta_len
- rta_len
);
1015 attr
= RTA_NEXT(attr
, attrlen
);
1021 madwifi_get_we_version(struct madwifi_driver_data
*drv
)
1023 struct iw_range
*range
;
1028 drv
->we_version
= 0;
1031 * Use larger buffer than struct iw_range in order to allow the
1032 * structure to grow in the future.
1034 buflen
= sizeof(struct iw_range
) + 500;
1035 range
= os_zalloc(buflen
);
1039 memset(&iwr
, 0, sizeof(iwr
));
1040 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
1041 iwr
.u
.data
.pointer
= (caddr_t
) range
;
1042 iwr
.u
.data
.length
= buflen
;
1044 minlen
= ((char *) &range
->enc_capa
) - (char *) range
+
1045 sizeof(range
->enc_capa
);
1047 if (ioctl(drv
->ioctl_sock
, SIOCGIWRANGE
, &iwr
) < 0) {
1048 perror("ioctl[SIOCGIWRANGE]");
1051 } else if (iwr
.u
.data
.length
>= minlen
&&
1052 range
->we_version_compiled
>= 18) {
1053 wpa_printf(MSG_DEBUG
, "SIOCGIWRANGE: WE(compiled)=%d "
1054 "WE(source)=%d enc_capa=0x%x",
1055 range
->we_version_compiled
,
1056 range
->we_version_source
,
1058 drv
->we_version
= range
->we_version_compiled
;
1067 madwifi_wireless_event_init(struct madwifi_driver_data
*drv
)
1069 struct netlink_config
*cfg
;
1071 madwifi_get_we_version(drv
);
1073 cfg
= os_zalloc(sizeof(*cfg
));
1077 cfg
->newlink_cb
= madwifi_wireless_event_rtm_newlink
;
1078 drv
->netlink
= netlink_init(cfg
);
1079 if (drv
->netlink
== NULL
) {
1089 madwifi_send_eapol(void *priv
, const u8
*addr
, const u8
*data
, size_t data_len
,
1090 int encrypt
, const u8
*own_addr
, u32 flags
)
1092 struct madwifi_driver_data
*drv
= priv
;
1093 unsigned char buf
[3000];
1094 unsigned char *bp
= buf
;
1095 struct l2_ethhdr
*eth
;
1100 * Prepend the Ethernet header. If the caller left us
1101 * space at the front we could just insert it but since
1102 * we don't know we copy to a local buffer. Given the frequency
1103 * and size of frames this probably doesn't matter.
1105 len
= data_len
+ sizeof(struct l2_ethhdr
);
1106 if (len
> sizeof(buf
)) {
1109 printf("EAPOL frame discarded, cannot malloc temp "
1110 "buffer of size %lu!\n", (unsigned long) len
);
1114 eth
= (struct l2_ethhdr
*) bp
;
1115 memcpy(eth
->h_dest
, addr
, ETH_ALEN
);
1116 memcpy(eth
->h_source
, own_addr
, ETH_ALEN
);
1117 eth
->h_proto
= host_to_be16(ETH_P_EAPOL
);
1118 memcpy(eth
+1, data
, data_len
);
1120 wpa_hexdump(MSG_MSGDUMP
, "TX EAPOL", bp
, len
);
1122 status
= l2_packet_send(drv
->sock_xmit
, addr
, ETH_P_EAPOL
, bp
, len
);
1130 handle_read(void *ctx
, const u8
*src_addr
, const u8
*buf
, size_t len
)
1132 struct madwifi_driver_data
*drv
= ctx
;
1133 drv_event_eapol_rx(drv
->hapd
, src_addr
, buf
+ sizeof(struct l2_ethhdr
),
1134 len
- sizeof(struct l2_ethhdr
));
1138 madwifi_init(struct hostapd_data
*hapd
, struct wpa_init_params
*params
)
1140 struct madwifi_driver_data
*drv
;
1143 char brname
[IFNAMSIZ
];
1145 drv
= os_zalloc(sizeof(struct madwifi_driver_data
));
1147 printf("Could not allocate memory for madwifi driver data\n");
1152 drv
->ioctl_sock
= socket(PF_INET
, SOCK_DGRAM
, 0);
1153 if (drv
->ioctl_sock
< 0) {
1154 perror("socket[PF_INET,SOCK_DGRAM]");
1157 memcpy(drv
->iface
, params
->ifname
, sizeof(drv
->iface
));
1159 memset(&ifr
, 0, sizeof(ifr
));
1160 os_strlcpy(ifr
.ifr_name
, drv
->iface
, sizeof(ifr
.ifr_name
));
1161 if (ioctl(drv
->ioctl_sock
, SIOCGIFINDEX
, &ifr
) != 0) {
1162 perror("ioctl(SIOCGIFINDEX)");
1165 drv
->ifindex
= ifr
.ifr_ifindex
;
1167 drv
->sock_xmit
= l2_packet_init(drv
->iface
, NULL
, ETH_P_EAPOL
,
1168 handle_read
, drv
, 1);
1169 if (drv
->sock_xmit
== NULL
)
1171 if (l2_packet_get_own_addr(drv
->sock_xmit
, params
->own_addr
))
1173 if (params
->bridge
[0]) {
1174 wpa_printf(MSG_DEBUG
, "Configure bridge %s for EAPOL traffic.",
1176 drv
->sock_recv
= l2_packet_init(params
->bridge
[0], NULL
,
1177 ETH_P_EAPOL
, handle_read
, drv
,
1179 if (drv
->sock_recv
== NULL
)
1181 } else if (linux_br_get(brname
, drv
->iface
) == 0) {
1182 wpa_printf(MSG_DEBUG
, "Interface in bridge %s; configure for "
1183 "EAPOL receive", brname
);
1184 drv
->sock_recv
= l2_packet_init(brname
, NULL
, ETH_P_EAPOL
,
1185 handle_read
, drv
, 1);
1186 if (drv
->sock_recv
== NULL
)
1189 drv
->sock_recv
= drv
->sock_xmit
;
1191 memset(&iwr
, 0, sizeof(iwr
));
1192 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
1194 iwr
.u
.mode
= IW_MODE_MASTER
;
1196 if (ioctl(drv
->ioctl_sock
, SIOCSIWMODE
, &iwr
) < 0) {
1197 perror("ioctl[SIOCSIWMODE]");
1198 printf("Could not set interface to master mode!\n");
1202 /* mark down during setup */
1203 linux_set_iface_flags(drv
->ioctl_sock
, drv
->iface
, 0);
1204 madwifi_set_privacy(drv
, 0); /* default to no privacy */
1206 madwifi_receive_probe_req(drv
);
1208 if (madwifi_wireless_event_init(drv
))
1213 if (drv
->sock_xmit
!= NULL
)
1214 l2_packet_deinit(drv
->sock_xmit
);
1215 if (drv
->ioctl_sock
>= 0)
1216 close(drv
->ioctl_sock
);
1224 madwifi_deinit(void *priv
)
1226 struct madwifi_driver_data
*drv
= priv
;
1228 netlink_deinit(drv
->netlink
);
1229 (void) linux_set_iface_flags(drv
->ioctl_sock
, drv
->iface
, 0);
1230 if (drv
->ioctl_sock
>= 0)
1231 close(drv
->ioctl_sock
);
1232 if (drv
->sock_recv
!= NULL
&& drv
->sock_recv
!= drv
->sock_xmit
)
1233 l2_packet_deinit(drv
->sock_recv
);
1234 if (drv
->sock_xmit
!= NULL
)
1235 l2_packet_deinit(drv
->sock_xmit
);
1237 l2_packet_deinit(drv
->sock_raw
);
1242 madwifi_set_ssid(void *priv
, const u8
*buf
, int len
)
1244 struct madwifi_driver_data
*drv
= priv
;
1247 memset(&iwr
, 0, sizeof(iwr
));
1248 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
1249 iwr
.u
.essid
.flags
= 1; /* SSID active */
1250 iwr
.u
.essid
.pointer
= (caddr_t
) buf
;
1251 iwr
.u
.essid
.length
= len
+ 1;
1253 if (ioctl(drv
->ioctl_sock
, SIOCSIWESSID
, &iwr
) < 0) {
1254 perror("ioctl[SIOCSIWESSID]");
1255 printf("len=%d\n", len
);
1262 madwifi_get_ssid(void *priv
, u8
*buf
, int len
)
1264 struct madwifi_driver_data
*drv
= priv
;
1268 memset(&iwr
, 0, sizeof(iwr
));
1269 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
1270 iwr
.u
.essid
.pointer
= (caddr_t
) buf
;
1271 iwr
.u
.essid
.length
= len
;
1273 if (ioctl(drv
->ioctl_sock
, SIOCGIWESSID
, &iwr
) < 0) {
1274 perror("ioctl[SIOCGIWESSID]");
1277 ret
= iwr
.u
.essid
.length
;
1283 madwifi_set_countermeasures(void *priv
, int enabled
)
1285 struct madwifi_driver_data
*drv
= priv
;
1286 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __FUNCTION__
, enabled
);
1287 return set80211param(drv
, IEEE80211_PARAM_COUNTERMEASURES
, enabled
);
1291 madwifi_commit(void *priv
)
1293 struct madwifi_driver_data
*drv
= priv
;
1294 return linux_set_iface_flags(drv
->ioctl_sock
, drv
->iface
, 1);
1299 struct wpa_driver_madwifi_data
{
1300 void *wext
; /* private data for driver_wext */
1302 char ifname
[IFNAMSIZ
+ 1];
1306 static int wpa_driver_madwifi_set_auth_alg(void *priv
, int auth_alg
);
1307 static int wpa_driver_madwifi_set_probe_req_ie(void *priv
, const u8
*ies
,
1312 set80211priv(struct wpa_driver_madwifi_data
*drv
, int op
, void *data
, int len
,
1317 os_memset(&iwr
, 0, sizeof(iwr
));
1318 os_strlcpy(iwr
.ifr_name
, drv
->ifname
, IFNAMSIZ
);
1319 if (len
< IFNAMSIZ
&&
1320 op
!= IEEE80211_IOCTL_SET_APPIEBUF
) {
1322 * Argument data fits inline; put it there.
1324 os_memcpy(iwr
.u
.name
, data
, len
);
1327 * Argument data too big for inline transfer; setup a
1328 * parameter block instead; the kernel will transfer
1329 * the data for the driver.
1331 iwr
.u
.data
.pointer
= data
;
1332 iwr
.u
.data
.length
= len
;
1335 if (ioctl(drv
->sock
, op
, &iwr
) < 0) {
1338 int first
= IEEE80211_IOCTL_SETPARAM
;
1339 int last
= IEEE80211_IOCTL_KICKMAC
;
1340 static const char *opnames
[] = {
1341 "ioctl[IEEE80211_IOCTL_SETPARAM]",
1342 "ioctl[IEEE80211_IOCTL_GETPARAM]",
1343 "ioctl[IEEE80211_IOCTL_SETMODE]",
1344 "ioctl[IEEE80211_IOCTL_GETMODE]",
1345 "ioctl[IEEE80211_IOCTL_SETWMMPARAMS]",
1346 "ioctl[IEEE80211_IOCTL_GETWMMPARAMS]",
1347 "ioctl[IEEE80211_IOCTL_SETCHANLIST]",
1348 "ioctl[IEEE80211_IOCTL_GETCHANLIST]",
1349 "ioctl[IEEE80211_IOCTL_CHANSWITCH]",
1351 "ioctl[IEEE80211_IOCTL_SET_APPIEBUF]",
1352 "ioctl[IEEE80211_IOCTL_GETSCANRESULTS]",
1354 "ioctl[IEEE80211_IOCTL_GETCHANINFO]",
1355 "ioctl[IEEE80211_IOCTL_SETOPTIE]",
1356 "ioctl[IEEE80211_IOCTL_GETOPTIE]",
1357 "ioctl[IEEE80211_IOCTL_SETMLME]",
1359 "ioctl[IEEE80211_IOCTL_SETKEY]",
1361 "ioctl[IEEE80211_IOCTL_DELKEY]",
1363 "ioctl[IEEE80211_IOCTL_ADDMAC]",
1365 "ioctl[IEEE80211_IOCTL_DELMAC]",
1367 "ioctl[IEEE80211_IOCTL_WDSMAC]",
1369 "ioctl[IEEE80211_IOCTL_WDSDELMAC]",
1371 "ioctl[IEEE80211_IOCTL_KICKMAC]",
1373 #else /* MADWIFI_NG */
1374 int first
= IEEE80211_IOCTL_SETPARAM
;
1375 int last
= IEEE80211_IOCTL_CHANLIST
;
1376 static const char *opnames
[] = {
1377 "ioctl[IEEE80211_IOCTL_SETPARAM]",
1378 "ioctl[IEEE80211_IOCTL_GETPARAM]",
1379 "ioctl[IEEE80211_IOCTL_SETKEY]",
1380 "ioctl[IEEE80211_IOCTL_GETKEY]",
1381 "ioctl[IEEE80211_IOCTL_DELKEY]",
1383 "ioctl[IEEE80211_IOCTL_SETMLME]",
1385 "ioctl[IEEE80211_IOCTL_SETOPTIE]",
1386 "ioctl[IEEE80211_IOCTL_GETOPTIE]",
1387 "ioctl[IEEE80211_IOCTL_ADDMAC]",
1389 "ioctl[IEEE80211_IOCTL_DELMAC]",
1391 "ioctl[IEEE80211_IOCTL_CHANLIST]",
1393 #endif /* MADWIFI_NG */
1394 int idx
= op
- first
;
1395 if (first
<= op
&& op
<= last
&&
1396 idx
< (int) (sizeof(opnames
) / sizeof(opnames
[0]))
1398 perror(opnames
[idx
]);
1400 perror("ioctl[unknown???]");
1408 set80211param(struct wpa_driver_madwifi_data
*drv
, int op
, int arg
,
1413 os_memset(&iwr
, 0, sizeof(iwr
));
1414 os_strlcpy(iwr
.ifr_name
, drv
->ifname
, IFNAMSIZ
);
1416 os_memcpy(iwr
.u
.name
+sizeof(u32
), &arg
, sizeof(arg
));
1418 if (ioctl(drv
->sock
, IEEE80211_IOCTL_SETPARAM
, &iwr
) < 0) {
1420 perror("ioctl[IEEE80211_IOCTL_SETPARAM]");
1427 wpa_driver_madwifi_set_wpa_ie(struct wpa_driver_madwifi_data
*drv
,
1428 const u8
*wpa_ie
, size_t wpa_ie_len
)
1432 os_memset(&iwr
, 0, sizeof(iwr
));
1433 os_strlcpy(iwr
.ifr_name
, drv
->ifname
, IFNAMSIZ
);
1434 /* NB: SETOPTIE is not fixed-size so must not be inlined */
1435 iwr
.u
.data
.pointer
= (void *) wpa_ie
;
1436 iwr
.u
.data
.length
= wpa_ie_len
;
1438 if (ioctl(drv
->sock
, IEEE80211_IOCTL_SETOPTIE
, &iwr
) < 0) {
1439 perror("ioctl[IEEE80211_IOCTL_SETOPTIE]");
1446 wpa_driver_madwifi_del_key(struct wpa_driver_madwifi_data
*drv
, int key_idx
,
1449 struct ieee80211req_del_key wk
;
1451 wpa_printf(MSG_DEBUG
, "%s: keyidx=%d", __FUNCTION__
, key_idx
);
1452 os_memset(&wk
, 0, sizeof(wk
));
1453 wk
.idk_keyix
= key_idx
;
1455 os_memcpy(wk
.idk_macaddr
, addr
, IEEE80211_ADDR_LEN
);
1457 return set80211priv(drv
, IEEE80211_IOCTL_DELKEY
, &wk
, sizeof(wk
), 1);
1461 wpa_driver_madwifi_set_key(const char *ifname
, void *priv
, enum wpa_alg alg
,
1462 const u8
*addr
, int key_idx
, int set_tx
,
1463 const u8
*seq
, size_t seq_len
,
1464 const u8
*key
, size_t key_len
)
1466 struct wpa_driver_madwifi_data
*drv
= priv
;
1467 struct ieee80211req_key wk
;
1471 if (alg
== WPA_ALG_NONE
)
1472 return wpa_driver_madwifi_del_key(drv
, key_idx
, addr
);
1476 if (addr
== NULL
|| os_memcmp(addr
, "\xff\xff\xff\xff\xff\xff",
1479 * madwifi did not seem to like static WEP key
1480 * configuration with IEEE80211_IOCTL_SETKEY, so use
1481 * Linux wireless extensions ioctl for this.
1483 return wpa_driver_wext_set_key(ifname
, drv
->wext
, alg
,
1484 addr
, key_idx
, set_tx
,
1489 cipher
= IEEE80211_CIPHER_WEP
;
1493 cipher
= IEEE80211_CIPHER_TKIP
;
1497 cipher
= IEEE80211_CIPHER_AES_CCM
;
1500 wpa_printf(MSG_DEBUG
, "%s: unknown/unsupported algorithm %d",
1505 wpa_printf(MSG_DEBUG
, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu "
1506 "key_len=%lu", __FUNCTION__
, alg_name
, key_idx
, set_tx
,
1507 (unsigned long) seq_len
, (unsigned long) key_len
);
1509 if (seq_len
> sizeof(u_int64_t
)) {
1510 wpa_printf(MSG_DEBUG
, "%s: seq_len %lu too big",
1511 __FUNCTION__
, (unsigned long) seq_len
);
1514 if (key_len
> sizeof(wk
.ik_keydata
)) {
1515 wpa_printf(MSG_DEBUG
, "%s: key length %lu too big",
1516 __FUNCTION__
, (unsigned long) key_len
);
1520 os_memset(&wk
, 0, sizeof(wk
));
1521 wk
.ik_type
= cipher
;
1522 wk
.ik_flags
= IEEE80211_KEY_RECV
;
1524 os_memcmp(addr
, "\xff\xff\xff\xff\xff\xff", ETH_ALEN
) == 0)
1525 wk
.ik_flags
|= IEEE80211_KEY_GROUP
;
1527 wk
.ik_flags
|= IEEE80211_KEY_XMIT
| IEEE80211_KEY_DEFAULT
;
1528 os_memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
1530 os_memset(wk
.ik_macaddr
, 0, IEEE80211_ADDR_LEN
);
1531 wk
.ik_keyix
= key_idx
;
1532 wk
.ik_keylen
= key_len
;
1533 #ifdef WORDS_BIGENDIAN
1536 u8 tmp
[WPA_KEY_RSC_LEN
];
1537 os_memset(tmp
, 0, sizeof(tmp
));
1538 for (i
= 0; i
< seq_len
; i
++)
1539 tmp
[WPA_KEY_RSC_LEN
- i
- 1] = seq
[i
];
1540 os_memcpy(&wk
.ik_keyrsc
, tmp
, WPA_KEY_RSC_LEN
);
1542 #else /* WORDS_BIGENDIAN */
1544 os_memcpy(&wk
.ik_keyrsc
, seq
, seq_len
);
1545 #endif /* WORDS_BIGENDIAN */
1546 os_memcpy(wk
.ik_keydata
, key
, key_len
);
1548 return set80211priv(drv
, IEEE80211_IOCTL_SETKEY
, &wk
, sizeof(wk
), 1);
1552 wpa_driver_madwifi_set_countermeasures(void *priv
, int enabled
)
1554 struct wpa_driver_madwifi_data
*drv
= priv
;
1555 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __FUNCTION__
, enabled
);
1556 return set80211param(drv
, IEEE80211_PARAM_COUNTERMEASURES
, enabled
, 1);
1560 wpa_driver_madwifi_deauthenticate(void *priv
, const u8
*addr
, int reason_code
)
1562 struct wpa_driver_madwifi_data
*drv
= priv
;
1563 struct ieee80211req_mlme mlme
;
1565 wpa_printf(MSG_DEBUG
, "%s", __FUNCTION__
);
1566 mlme
.im_op
= IEEE80211_MLME_DEAUTH
;
1567 mlme
.im_reason
= reason_code
;
1568 os_memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
1569 return set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
, sizeof(mlme
), 1);
1573 wpa_driver_madwifi_disassociate(void *priv
, const u8
*addr
, int reason_code
)
1575 struct wpa_driver_madwifi_data
*drv
= priv
;
1576 struct ieee80211req_mlme mlme
;
1578 wpa_printf(MSG_DEBUG
, "%s", __FUNCTION__
);
1579 mlme
.im_op
= IEEE80211_MLME_DISASSOC
;
1580 mlme
.im_reason
= reason_code
;
1581 os_memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
1582 return set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
, sizeof(mlme
), 1);
1586 wpa_driver_madwifi_associate(void *priv
,
1587 struct wpa_driver_associate_params
*params
)
1589 struct wpa_driver_madwifi_data
*drv
= priv
;
1590 struct ieee80211req_mlme mlme
;
1591 int ret
= 0, privacy
= 1;
1593 wpa_printf(MSG_DEBUG
, "%s", __FUNCTION__
);
1595 if (set80211param(drv
, IEEE80211_PARAM_DROPUNENCRYPTED
,
1596 params
->drop_unencrypted
, 1) < 0)
1598 if (wpa_driver_madwifi_set_auth_alg(drv
, params
->auth_alg
) < 0)
1602 * NB: Don't need to set the freq or cipher-related state as
1603 * this is implied by the bssid which is used to locate
1604 * the scanned node state which holds it. The ssid is
1605 * needed to disambiguate an AP that broadcasts multiple
1606 * ssid's but uses the same bssid.
1608 /* XXX error handling is wrong but unclear what to do... */
1609 if (wpa_driver_madwifi_set_wpa_ie(drv
, params
->wpa_ie
,
1610 params
->wpa_ie_len
) < 0)
1613 if (params
->pairwise_suite
== CIPHER_NONE
&&
1614 params
->group_suite
== CIPHER_NONE
&&
1615 params
->key_mgmt_suite
== KEY_MGMT_NONE
&&
1616 params
->wpa_ie_len
== 0)
1619 if (set80211param(drv
, IEEE80211_PARAM_PRIVACY
, privacy
, 1) < 0)
1622 if (params
->wpa_ie_len
&&
1623 set80211param(drv
, IEEE80211_PARAM_WPA
,
1624 params
->wpa_ie
[0] == WLAN_EID_RSN
? 2 : 1, 1) < 0)
1627 if (params
->bssid
== NULL
) {
1628 /* ap_scan=2 mode - driver takes care of AP selection and
1630 /* FIX: this does not seem to work; would probably need to
1631 * change something in the driver */
1632 if (set80211param(drv
, IEEE80211_PARAM_ROAMING
, 0, 1) < 0)
1635 if (wpa_driver_wext_set_ssid(drv
->wext
, params
->ssid
,
1636 params
->ssid_len
) < 0)
1639 if (set80211param(drv
, IEEE80211_PARAM_ROAMING
, 2, 1) < 0)
1641 if (wpa_driver_wext_set_ssid(drv
->wext
, params
->ssid
,
1642 params
->ssid_len
) < 0)
1644 os_memset(&mlme
, 0, sizeof(mlme
));
1645 mlme
.im_op
= IEEE80211_MLME_ASSOC
;
1646 os_memcpy(mlme
.im_macaddr
, params
->bssid
, IEEE80211_ADDR_LEN
);
1647 if (set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
,
1648 sizeof(mlme
), 1) < 0) {
1649 wpa_printf(MSG_DEBUG
, "%s: SETMLME[ASSOC] failed",
1659 wpa_driver_madwifi_set_auth_alg(void *priv
, int auth_alg
)
1661 struct wpa_driver_madwifi_data
*drv
= priv
;
1664 if ((auth_alg
& WPA_AUTH_ALG_OPEN
) &&
1665 (auth_alg
& WPA_AUTH_ALG_SHARED
))
1666 authmode
= IEEE80211_AUTH_AUTO
;
1667 else if (auth_alg
& WPA_AUTH_ALG_SHARED
)
1668 authmode
= IEEE80211_AUTH_SHARED
;
1670 authmode
= IEEE80211_AUTH_OPEN
;
1672 return set80211param(drv
, IEEE80211_PARAM_AUTHMODE
, authmode
, 1);
1676 wpa_driver_madwifi_scan(void *priv
, struct wpa_driver_scan_params
*params
)
1678 struct wpa_driver_madwifi_data
*drv
= priv
;
1681 const u8
*ssid
= params
->ssids
[0].ssid
;
1682 size_t ssid_len
= params
->ssids
[0].ssid_len
;
1684 wpa_driver_madwifi_set_probe_req_ie(drv
, params
->extra_ies
,
1685 params
->extra_ies_len
);
1687 os_memset(&iwr
, 0, sizeof(iwr
));
1688 os_strlcpy(iwr
.ifr_name
, drv
->ifname
, IFNAMSIZ
);
1690 /* set desired ssid before scan */
1691 /* FIX: scan should not break the current association, so using
1692 * set_ssid may not be the best way of doing this.. */
1693 if (wpa_driver_wext_set_ssid(drv
->wext
, ssid
, ssid_len
) < 0)
1696 if (ioctl(drv
->sock
, SIOCSIWSCAN
, &iwr
) < 0) {
1697 perror("ioctl[SIOCSIWSCAN]");
1702 * madwifi delivers a scan complete event so no need to poll, but
1703 * register a backup timeout anyway to make sure that we recover even
1704 * if the driver does not send this event for any reason. This timeout
1705 * will only be used if the event is not delivered (event handler will
1706 * cancel the timeout).
1708 eloop_cancel_timeout(wpa_driver_wext_scan_timeout
, drv
->wext
,
1710 eloop_register_timeout(30, 0, wpa_driver_wext_scan_timeout
, drv
->wext
,
1716 static int wpa_driver_madwifi_get_bssid(void *priv
, u8
*bssid
)
1718 struct wpa_driver_madwifi_data
*drv
= priv
;
1719 return wpa_driver_wext_get_bssid(drv
->wext
, bssid
);
1723 static int wpa_driver_madwifi_get_ssid(void *priv
, u8
*ssid
)
1725 struct wpa_driver_madwifi_data
*drv
= priv
;
1726 return wpa_driver_wext_get_ssid(drv
->wext
, ssid
);
1730 static struct wpa_scan_results
*
1731 wpa_driver_madwifi_get_scan_results(void *priv
)
1733 struct wpa_driver_madwifi_data
*drv
= priv
;
1734 return wpa_driver_wext_get_scan_results(drv
->wext
);
1738 static int wpa_driver_madwifi_set_operstate(void *priv
, int state
)
1740 struct wpa_driver_madwifi_data
*drv
= priv
;
1741 return wpa_driver_wext_set_operstate(drv
->wext
, state
);
1745 static int wpa_driver_madwifi_set_probe_req_ie(void *priv
, const u8
*ies
,
1748 struct ieee80211req_getset_appiebuf
*probe_req_ie
;
1751 probe_req_ie
= os_malloc(sizeof(*probe_req_ie
) + ies_len
);
1752 if (probe_req_ie
== NULL
)
1755 probe_req_ie
->app_frmtype
= IEEE80211_APPIE_FRAME_PROBE_REQ
;
1756 probe_req_ie
->app_buflen
= ies_len
;
1757 os_memcpy(probe_req_ie
->app_buf
, ies
, ies_len
);
1759 ret
= set80211priv(priv
, IEEE80211_IOCTL_SET_APPIEBUF
, probe_req_ie
,
1760 sizeof(struct ieee80211req_getset_appiebuf
) +
1763 os_free(probe_req_ie
);
1769 static void * wpa_driver_madwifi_init(void *ctx
, const char *ifname
)
1771 struct wpa_driver_madwifi_data
*drv
;
1773 drv
= os_zalloc(sizeof(*drv
));
1776 drv
->wext
= wpa_driver_wext_init(ctx
, ifname
);
1777 if (drv
->wext
== NULL
)
1781 os_strlcpy(drv
->ifname
, ifname
, sizeof(drv
->ifname
));
1782 drv
->sock
= socket(PF_INET
, SOCK_DGRAM
, 0);
1786 if (set80211param(drv
, IEEE80211_PARAM_ROAMING
, 2, 1) < 0) {
1787 wpa_printf(MSG_DEBUG
, "%s: failed to set wpa_supplicant-based "
1788 "roaming", __FUNCTION__
);
1792 if (set80211param(drv
, IEEE80211_PARAM_WPA
, 3, 1) < 0) {
1793 wpa_printf(MSG_DEBUG
, "%s: failed to enable WPA support",
1803 wpa_driver_wext_deinit(drv
->wext
);
1810 static void wpa_driver_madwifi_deinit(void *priv
)
1812 struct wpa_driver_madwifi_data
*drv
= priv
;
1814 if (wpa_driver_madwifi_set_wpa_ie(drv
, NULL
, 0) < 0) {
1815 wpa_printf(MSG_DEBUG
, "%s: failed to clear WPA IE",
1818 if (set80211param(drv
, IEEE80211_PARAM_ROAMING
, 0, 1) < 0) {
1819 wpa_printf(MSG_DEBUG
, "%s: failed to enable driver-based "
1820 "roaming", __FUNCTION__
);
1822 if (set80211param(drv
, IEEE80211_PARAM_PRIVACY
, 0, 1) < 0) {
1823 wpa_printf(MSG_DEBUG
, "%s: failed to disable forced Privacy "
1824 "flag", __FUNCTION__
);
1826 if (set80211param(drv
, IEEE80211_PARAM_WPA
, 0, 1) < 0) {
1827 wpa_printf(MSG_DEBUG
, "%s: failed to disable WPA",
1831 wpa_driver_wext_deinit(drv
->wext
);
1837 #endif /* HOSTAPD */
1840 const struct wpa_driver_ops wpa_driver_madwifi_ops
= {
1842 .desc
= "MADWIFI 802.11 support (Atheros, etc.)",
1843 .set_key
= wpa_driver_madwifi_set_key
,
1845 .hapd_init
= madwifi_init
,
1846 .hapd_deinit
= madwifi_deinit
,
1847 .set_ieee8021x
= madwifi_set_ieee8021x
,
1848 .set_privacy
= madwifi_set_privacy
,
1849 .get_seqnum
= madwifi_get_seqnum
,
1850 .flush
= madwifi_flush
,
1851 .set_generic_elem
= madwifi_set_opt_ie
,
1852 .sta_set_flags
= madwifi_sta_set_flags
,
1853 .read_sta_data
= madwifi_read_sta_driver_data
,
1854 .hapd_send_eapol
= madwifi_send_eapol
,
1855 .sta_disassoc
= madwifi_sta_disassoc
,
1856 .sta_deauth
= madwifi_sta_deauth
,
1857 .hapd_set_ssid
= madwifi_set_ssid
,
1858 .hapd_get_ssid
= madwifi_get_ssid
,
1859 .hapd_set_countermeasures
= madwifi_set_countermeasures
,
1860 .sta_clear_stats
= madwifi_sta_clear_stats
,
1861 .commit
= madwifi_commit
,
1862 .set_ap_wps_ie
= madwifi_set_ap_wps_ie
,
1863 .set_freq
= madwifi_set_freq
,
1865 .get_bssid
= wpa_driver_madwifi_get_bssid
,
1866 .get_ssid
= wpa_driver_madwifi_get_ssid
,
1867 .init
= wpa_driver_madwifi_init
,
1868 .deinit
= wpa_driver_madwifi_deinit
,
1869 .set_countermeasures
= wpa_driver_madwifi_set_countermeasures
,
1870 .scan2
= wpa_driver_madwifi_scan
,
1871 .get_scan_results2
= wpa_driver_madwifi_get_scan_results
,
1872 .deauthenticate
= wpa_driver_madwifi_deauthenticate
,
1873 .disassociate
= wpa_driver_madwifi_disassociate
,
1874 .associate
= wpa_driver_madwifi_associate
,
1875 .set_operstate
= wpa_driver_madwifi_set_operstate
,
1876 #endif /* HOSTAPD */