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.
18 #include <sys/ioctl.h>
22 #include "driver_wext.h"
24 #include "ieee802_11_defs.h"
25 #include "wireless_copy.h"
28 * Avoid conflicts with wpa_supplicant definitions by undefining a definition.
32 #include <include/compat.h>
33 #include <net80211/ieee80211.h>
35 /* Assume this is built against BSD branch of madwifi driver. */
37 #include <net80211/_ieee80211.h>
38 #endif /* WME_NUM_AC */
39 #include <net80211/ieee80211_crypto.h>
40 #include <net80211/ieee80211_ioctl.h>
43 #ifdef IEEE80211_IOCTL_FILTERFRAME
44 #include <netpacket/packet.h>
46 #ifndef ETH_P_80211_RAW
47 #define ETH_P_80211_RAW 0x0019
49 #endif /* IEEE80211_IOCTL_FILTERFRAME */
50 #endif /* CONFIG_WPS */
53 * Avoid conflicts with hostapd definitions by undefining couple of defines
54 * from madwifi header files.
62 #ifdef IEEE80211_IOCTL_SETWMMPARAMS
63 /* Assume this is built against madwifi-ng */
65 #endif /* IEEE80211_IOCTL_SETWMMPARAMS */
70 #include "priv_netlink.h"
71 #include "l2_packet/l2_packet.h"
72 #include "../../hostapd/hostapd.h"
73 #include "../../hostapd/config.h"
74 #include "../../hostapd/wps_hostapd.h"
75 #include "../../hostapd/sta_flags.h"
78 struct madwifi_driver_data
{
79 struct hostapd_data
*hapd
; /* back pointer */
81 char iface
[IFNAMSIZ
+ 1];
83 struct l2_packet_data
*sock_xmit
; /* raw packet xmit socket */
84 struct l2_packet_data
*sock_recv
; /* raw packet recv socket */
85 int ioctl_sock
; /* socket for ioctl() use */
86 int wext_sock
; /* socket for wireless events */
88 u8 acct_mac
[ETH_ALEN
];
89 struct hostap_sta_driver_data acct_data
;
91 struct l2_packet_data
*sock_raw
; /* raw 802.11 management frames */
94 static int madwifi_sta_deauth(void *priv
, const u8
*addr
, int reason_code
);
97 set80211priv(struct madwifi_driver_data
*drv
, int op
, void *data
, int len
)
100 int do_inline
= len
< IFNAMSIZ
;
102 memset(&iwr
, 0, sizeof(iwr
));
103 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
104 #ifdef IEEE80211_IOCTL_FILTERFRAME
105 /* FILTERFRAME must be NOT inline, regardless of size. */
106 if (op
== IEEE80211_IOCTL_FILTERFRAME
)
108 #endif /* IEEE80211_IOCTL_FILTERFRAME */
109 if (op
== IEEE80211_IOCTL_SET_APPIEBUF
)
113 * Argument data fits inline; put it there.
115 memcpy(iwr
.u
.name
, data
, len
);
118 * Argument data too big for inline transfer; setup a
119 * parameter block instead; the kernel will transfer
120 * the data for the driver.
122 iwr
.u
.data
.pointer
= data
;
123 iwr
.u
.data
.length
= len
;
126 if (ioctl(drv
->ioctl_sock
, op
, &iwr
) < 0) {
128 int first
= IEEE80211_IOCTL_SETPARAM
;
129 static const char *opnames
[] = {
130 "ioctl[IEEE80211_IOCTL_SETPARAM]",
131 "ioctl[IEEE80211_IOCTL_GETPARAM]",
132 "ioctl[IEEE80211_IOCTL_SETMODE]",
133 "ioctl[IEEE80211_IOCTL_GETMODE]",
134 "ioctl[IEEE80211_IOCTL_SETWMMPARAMS]",
135 "ioctl[IEEE80211_IOCTL_GETWMMPARAMS]",
136 "ioctl[IEEE80211_IOCTL_SETCHANLIST]",
137 "ioctl[IEEE80211_IOCTL_GETCHANLIST]",
138 "ioctl[IEEE80211_IOCTL_CHANSWITCH]",
139 "ioctl[IEEE80211_IOCTL_GET_APPIEBUF]",
140 "ioctl[IEEE80211_IOCTL_SET_APPIEBUF]",
141 "ioctl[IEEE80211_IOCTL_GETSCANRESULTS]",
142 "ioctl[IEEE80211_IOCTL_FILTERFRAME]",
143 "ioctl[IEEE80211_IOCTL_GETCHANINFO]",
144 "ioctl[IEEE80211_IOCTL_SETOPTIE]",
145 "ioctl[IEEE80211_IOCTL_GETOPTIE]",
146 "ioctl[IEEE80211_IOCTL_SETMLME]",
148 "ioctl[IEEE80211_IOCTL_SETKEY]",
150 "ioctl[IEEE80211_IOCTL_DELKEY]",
152 "ioctl[IEEE80211_IOCTL_ADDMAC]",
154 "ioctl[IEEE80211_IOCTL_DELMAC]",
156 "ioctl[IEEE80211_IOCTL_WDSMAC]",
158 "ioctl[IEEE80211_IOCTL_WDSDELMAC]",
160 "ioctl[IEEE80211_IOCTL_KICKMAC]",
162 #else /* MADWIFI_NG */
163 int first
= IEEE80211_IOCTL_SETPARAM
;
164 static const char *opnames
[] = {
165 "ioctl[IEEE80211_IOCTL_SETPARAM]",
166 "ioctl[IEEE80211_IOCTL_GETPARAM]",
167 "ioctl[IEEE80211_IOCTL_SETKEY]",
168 "ioctl[SIOCIWFIRSTPRIV+3]",
169 "ioctl[IEEE80211_IOCTL_DELKEY]",
170 "ioctl[SIOCIWFIRSTPRIV+5]",
171 "ioctl[IEEE80211_IOCTL_SETMLME]",
172 "ioctl[SIOCIWFIRSTPRIV+7]",
173 "ioctl[IEEE80211_IOCTL_SETOPTIE]",
174 "ioctl[IEEE80211_IOCTL_GETOPTIE]",
175 "ioctl[IEEE80211_IOCTL_ADDMAC]",
176 "ioctl[SIOCIWFIRSTPRIV+11]",
177 "ioctl[IEEE80211_IOCTL_DELMAC]",
178 "ioctl[SIOCIWFIRSTPRIV+13]",
179 "ioctl[IEEE80211_IOCTL_CHANLIST]",
180 "ioctl[SIOCIWFIRSTPRIV+15]",
181 "ioctl[IEEE80211_IOCTL_GETRSN]",
182 "ioctl[SIOCIWFIRSTPRIV+17]",
183 "ioctl[IEEE80211_IOCTL_GETKEY]",
185 #endif /* MADWIFI_NG */
186 int idx
= op
- first
;
188 idx
< (int) (sizeof(opnames
) / sizeof(opnames
[0])) &&
190 perror(opnames
[idx
]);
192 perror("ioctl[unknown???]");
199 set80211param(struct madwifi_driver_data
*drv
, int op
, int arg
)
203 memset(&iwr
, 0, sizeof(iwr
));
204 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
206 memcpy(iwr
.u
.name
+sizeof(__u32
), &arg
, sizeof(arg
));
208 if (ioctl(drv
->ioctl_sock
, IEEE80211_IOCTL_SETPARAM
, &iwr
) < 0) {
209 perror("ioctl[IEEE80211_IOCTL_SETPARAM]");
210 wpa_printf(MSG_DEBUG
, "%s: Failed to set parameter (op %d "
211 "arg %d)", __func__
, op
, arg
);
217 #ifndef CONFIG_NO_STDOUT_DEBUG
219 ether_sprintf(const u8
*addr
)
221 static char buf
[sizeof(MACSTR
)];
224 snprintf(buf
, sizeof(buf
), MACSTR
, MAC2STR(addr
));
226 snprintf(buf
, sizeof(buf
), MACSTR
, 0,0,0,0,0,0);
229 #endif /* CONFIG_NO_STDOUT_DEBUG */
232 * Configure WPA parameters.
235 madwifi_configure_wpa(struct madwifi_driver_data
*drv
)
237 struct hostapd_data
*hapd
= drv
->hapd
;
238 struct hostapd_bss_config
*conf
= hapd
->conf
;
241 switch (conf
->wpa_group
) {
242 case WPA_CIPHER_CCMP
:
243 v
= IEEE80211_CIPHER_AES_CCM
;
245 case WPA_CIPHER_TKIP
:
246 v
= IEEE80211_CIPHER_TKIP
;
248 case WPA_CIPHER_WEP104
:
249 v
= IEEE80211_CIPHER_WEP
;
251 case WPA_CIPHER_WEP40
:
252 v
= IEEE80211_CIPHER_WEP
;
254 case WPA_CIPHER_NONE
:
255 v
= IEEE80211_CIPHER_NONE
;
258 wpa_printf(MSG_ERROR
, "Unknown group key cipher %u",
262 wpa_printf(MSG_DEBUG
, "%s: group key cipher=%d", __func__
, v
);
263 if (set80211param(drv
, IEEE80211_PARAM_MCASTCIPHER
, v
)) {
264 printf("Unable to set group key cipher to %u\n", v
);
267 if (v
== IEEE80211_CIPHER_WEP
) {
268 /* key length is done only for specific ciphers */
269 v
= (conf
->wpa_group
== WPA_CIPHER_WEP104
? 13 : 5);
270 if (set80211param(drv
, IEEE80211_PARAM_MCASTKEYLEN
, v
)) {
271 printf("Unable to set group key length to %u\n", v
);
277 if (conf
->wpa_pairwise
& WPA_CIPHER_CCMP
)
278 v
|= 1<<IEEE80211_CIPHER_AES_CCM
;
279 if (conf
->wpa_pairwise
& WPA_CIPHER_TKIP
)
280 v
|= 1<<IEEE80211_CIPHER_TKIP
;
281 if (conf
->wpa_pairwise
& WPA_CIPHER_NONE
)
282 v
|= 1<<IEEE80211_CIPHER_NONE
;
283 wpa_printf(MSG_DEBUG
, "%s: pairwise key ciphers=0x%x", __func__
, v
);
284 if (set80211param(drv
, IEEE80211_PARAM_UCASTCIPHERS
, v
)) {
285 printf("Unable to set pairwise key ciphers to 0x%x\n", v
);
289 wpa_printf(MSG_DEBUG
, "%s: key management algorithms=0x%x",
290 __func__
, conf
->wpa_key_mgmt
);
291 if (set80211param(drv
, IEEE80211_PARAM_KEYMGTALGS
, conf
->wpa_key_mgmt
)) {
292 printf("Unable to set key management algorithms to 0x%x\n",
298 if (conf
->rsn_preauth
)
300 wpa_printf(MSG_DEBUG
, "%s: rsn capabilities=0x%x",
301 __func__
, conf
->rsn_preauth
);
302 if (set80211param(drv
, IEEE80211_PARAM_RSNCAPS
, v
)) {
303 printf("Unable to set RSN capabilities to 0x%x\n", v
);
307 wpa_printf(MSG_DEBUG
, "%s: enable WPA=0x%x", __func__
, conf
->wpa
);
308 if (set80211param(drv
, IEEE80211_PARAM_WPA
, conf
->wpa
)) {
309 printf("Unable to set WPA to %u\n", conf
->wpa
);
317 madwifi_set_iface_flags(void *priv
, int dev_up
)
319 struct madwifi_driver_data
*drv
= priv
;
322 wpa_printf(MSG_DEBUG
, "%s: dev_up=%d", __func__
, dev_up
);
324 if (drv
->ioctl_sock
< 0)
327 memset(&ifr
, 0, sizeof(ifr
));
328 os_strlcpy(ifr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
330 if (ioctl(drv
->ioctl_sock
, SIOCGIFFLAGS
, &ifr
) != 0) {
331 perror("ioctl[SIOCGIFFLAGS]");
336 ifr
.ifr_flags
|= IFF_UP
;
338 ifr
.ifr_flags
&= ~IFF_UP
;
340 if (ioctl(drv
->ioctl_sock
, SIOCSIFFLAGS
, &ifr
) != 0) {
341 perror("ioctl[SIOCSIFFLAGS]");
346 memset(&ifr
, 0, sizeof(ifr
));
347 os_strlcpy(ifr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
348 ifr
.ifr_mtu
= HOSTAPD_MTU
;
349 if (ioctl(drv
->ioctl_sock
, SIOCSIFMTU
, &ifr
) != 0) {
350 perror("ioctl[SIOCSIFMTU]");
351 printf("Setting MTU failed - trying to survive with "
360 madwifi_set_ieee8021x(const char *ifname
, void *priv
, int enabled
)
362 struct madwifi_driver_data
*drv
= priv
;
363 struct hostapd_data
*hapd
= drv
->hapd
;
364 struct hostapd_bss_config
*conf
= hapd
->conf
;
366 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __func__
, enabled
);
369 /* XXX restore state */
370 return set80211param(priv
, IEEE80211_PARAM_AUTHMODE
,
371 IEEE80211_AUTH_AUTO
);
373 if (!conf
->wpa
&& !conf
->ieee802_1x
) {
374 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
375 HOSTAPD_LEVEL_WARNING
, "No 802.1X or WPA enabled!");
378 if (conf
->wpa
&& madwifi_configure_wpa(drv
) != 0) {
379 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
380 HOSTAPD_LEVEL_WARNING
, "Error configuring WPA state!");
383 if (set80211param(priv
, IEEE80211_PARAM_AUTHMODE
,
384 (conf
->wpa
? IEEE80211_AUTH_WPA
: IEEE80211_AUTH_8021X
))) {
385 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
386 HOSTAPD_LEVEL_WARNING
, "Error enabling WPA/802.1X!");
394 madwifi_set_privacy(const char *ifname
, void *priv
, int enabled
)
396 struct madwifi_driver_data
*drv
= priv
;
398 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __func__
, enabled
);
400 return set80211param(drv
, IEEE80211_PARAM_PRIVACY
, enabled
);
404 madwifi_set_sta_authorized(void *priv
, const u8
*addr
, int authorized
)
406 struct madwifi_driver_data
*drv
= priv
;
407 struct ieee80211req_mlme mlme
;
410 wpa_printf(MSG_DEBUG
, "%s: addr=%s authorized=%d",
411 __func__
, ether_sprintf(addr
), authorized
);
414 mlme
.im_op
= IEEE80211_MLME_AUTHORIZE
;
416 mlme
.im_op
= IEEE80211_MLME_UNAUTHORIZE
;
418 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
419 ret
= set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
, sizeof(mlme
));
421 wpa_printf(MSG_DEBUG
, "%s: Failed to %sauthorize STA " MACSTR
,
422 __func__
, authorized
? "" : "un", MAC2STR(addr
));
429 madwifi_sta_set_flags(void *priv
, const u8
*addr
, int total_flags
,
430 int flags_or
, int flags_and
)
432 /* For now, only support setting Authorized flag */
433 if (flags_or
& WLAN_STA_AUTHORIZED
)
434 return madwifi_set_sta_authorized(priv
, addr
, 1);
435 if (!(flags_and
& WLAN_STA_AUTHORIZED
))
436 return madwifi_set_sta_authorized(priv
, addr
, 0);
441 madwifi_del_key(void *priv
, const u8
*addr
, int key_idx
)
443 struct madwifi_driver_data
*drv
= priv
;
444 struct ieee80211req_del_key wk
;
447 wpa_printf(MSG_DEBUG
, "%s: addr=%s key_idx=%d",
448 __func__
, ether_sprintf(addr
), key_idx
);
450 memset(&wk
, 0, sizeof(wk
));
452 memcpy(wk
.idk_macaddr
, addr
, IEEE80211_ADDR_LEN
);
453 wk
.idk_keyix
= (u8
) IEEE80211_KEYIX_NONE
;
455 wk
.idk_keyix
= key_idx
;
458 ret
= set80211priv(drv
, IEEE80211_IOCTL_DELKEY
, &wk
, sizeof(wk
));
460 wpa_printf(MSG_DEBUG
, "%s: Failed to delete key (addr %s"
461 " key_idx %d)", __func__
, ether_sprintf(addr
),
469 madwifi_set_key(const char *ifname
, void *priv
, wpa_alg alg
,
470 const u8
*addr
, int key_idx
, int set_tx
, const u8
*seq
,
471 size_t seq_len
, const u8
*key
, size_t key_len
)
473 struct madwifi_driver_data
*drv
= priv
;
474 struct ieee80211req_key wk
;
478 if (alg
== WPA_ALG_NONE
)
479 return madwifi_del_key(drv
, addr
, key_idx
);
481 wpa_printf(MSG_DEBUG
, "%s: alg=%d addr=%s key_idx=%d",
482 __func__
, alg
, ether_sprintf(addr
), key_idx
);
484 if (alg
== WPA_ALG_WEP
)
485 cipher
= IEEE80211_CIPHER_WEP
;
486 else if (alg
== WPA_ALG_TKIP
)
487 cipher
= IEEE80211_CIPHER_TKIP
;
488 else if (alg
== WPA_ALG_CCMP
)
489 cipher
= IEEE80211_CIPHER_AES_CCM
;
491 printf("%s: unknown/unsupported algorithm %d\n",
496 if (key_len
> sizeof(wk
.ik_keydata
)) {
497 printf("%s: key length %lu too big\n", __func__
,
498 (unsigned long) key_len
);
502 memset(&wk
, 0, sizeof(wk
));
504 wk
.ik_flags
= IEEE80211_KEY_RECV
| IEEE80211_KEY_XMIT
;
506 memset(wk
.ik_macaddr
, 0xff, IEEE80211_ADDR_LEN
);
507 wk
.ik_keyix
= key_idx
;
508 wk
.ik_flags
|= IEEE80211_KEY_DEFAULT
;
510 memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
511 wk
.ik_keyix
= IEEE80211_KEYIX_NONE
;
513 wk
.ik_keylen
= key_len
;
514 memcpy(wk
.ik_keydata
, key
, key_len
);
516 ret
= set80211priv(drv
, IEEE80211_IOCTL_SETKEY
, &wk
, sizeof(wk
));
518 wpa_printf(MSG_DEBUG
, "%s: Failed to set key (addr %s"
519 " key_idx %d alg %d key_len %lu set_tx %d)",
520 __func__
, ether_sprintf(wk
.ik_macaddr
), key_idx
,
521 alg
, (unsigned long) key_len
, set_tx
);
529 madwifi_get_seqnum(const char *ifname
, void *priv
, const u8
*addr
, int idx
,
532 struct madwifi_driver_data
*drv
= priv
;
533 struct ieee80211req_key wk
;
535 wpa_printf(MSG_DEBUG
, "%s: addr=%s idx=%d",
536 __func__
, ether_sprintf(addr
), idx
);
538 memset(&wk
, 0, sizeof(wk
));
540 memset(wk
.ik_macaddr
, 0xff, IEEE80211_ADDR_LEN
);
542 memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
545 if (set80211priv(drv
, IEEE80211_IOCTL_GETKEY
, &wk
, sizeof(wk
))) {
546 wpa_printf(MSG_DEBUG
, "%s: Failed to get encryption data "
547 "(addr " MACSTR
" key_idx %d)",
548 __func__
, MAC2STR(wk
.ik_macaddr
), idx
);
552 #ifdef WORDS_BIGENDIAN
555 * wk.ik_keytsc is in host byte order (big endian), need to
556 * swap it to match with the byte order used in WPA.
559 u8 tmp
[WPA_KEY_RSC_LEN
];
560 memcpy(tmp
, &wk
.ik_keytsc
, sizeof(wk
.ik_keytsc
));
561 for (i
= 0; i
< WPA_KEY_RSC_LEN
; i
++) {
562 seq
[i
] = tmp
[WPA_KEY_RSC_LEN
- i
- 1];
565 #else /* WORDS_BIGENDIAN */
566 memcpy(seq
, &wk
.ik_keytsc
, sizeof(wk
.ik_keytsc
));
567 #endif /* WORDS_BIGENDIAN */
573 madwifi_flush(void *priv
)
576 u8 allsta
[IEEE80211_ADDR_LEN
];
577 memset(allsta
, 0xff, IEEE80211_ADDR_LEN
);
578 return madwifi_sta_deauth(priv
, allsta
, IEEE80211_REASON_AUTH_LEAVE
);
579 #else /* MADWIFI_BSD */
581 #endif /* MADWIFI_BSD */
586 madwifi_read_sta_driver_data(void *priv
, struct hostap_sta_driver_data
*data
,
589 struct madwifi_driver_data
*drv
= priv
;
592 struct ieee80211req_sta_stats stats
;
594 memset(data
, 0, sizeof(*data
));
597 * Fetch statistics for station from the system.
599 memset(&stats
, 0, sizeof(stats
));
600 memcpy(stats
.is_u
.macaddr
, addr
, IEEE80211_ADDR_LEN
);
601 if (set80211priv(drv
,
603 IEEE80211_IOCTL_STA_STATS
,
604 #else /* MADWIFI_NG */
605 IEEE80211_IOCTL_GETSTASTATS
,
606 #endif /* MADWIFI_NG */
607 &stats
, sizeof(stats
))) {
608 wpa_printf(MSG_DEBUG
, "%s: Failed to fetch STA stats (addr "
609 MACSTR
")", __func__
, MAC2STR(addr
));
610 if (memcmp(addr
, drv
->acct_mac
, ETH_ALEN
) == 0) {
611 memcpy(data
, &drv
->acct_data
, sizeof(*data
));
615 printf("Failed to get station stats information element.\n");
619 data
->rx_packets
= stats
.is_stats
.ns_rx_data
;
620 data
->rx_bytes
= stats
.is_stats
.ns_rx_bytes
;
621 data
->tx_packets
= stats
.is_stats
.ns_tx_data
;
622 data
->tx_bytes
= stats
.is_stats
.ns_tx_bytes
;
625 #else /* MADWIFI_BSD */
627 char buf
[1024], line
[128], *pos
;
631 memset(data
, 0, sizeof(*data
));
632 snprintf(buf
, sizeof(buf
), "/proc/net/madwifi/%s/" MACSTR
,
633 drv
->iface
, MAC2STR(addr
));
637 if (memcmp(addr
, drv
->acct_mac
, ETH_ALEN
) != 0)
639 memcpy(data
, &drv
->acct_data
, sizeof(*data
));
642 /* Need to read proc file with in one piece, so use large enough
644 setbuffer(f
, buf
, sizeof(buf
));
646 while (fgets(line
, sizeof(line
), f
)) {
647 pos
= strchr(line
, '=');
651 val
= strtoul(pos
, NULL
, 10);
652 if (strcmp(line
, "rx_packets") == 0)
653 data
->rx_packets
= val
;
654 else if (strcmp(line
, "tx_packets") == 0)
655 data
->tx_packets
= val
;
656 else if (strcmp(line
, "rx_bytes") == 0)
657 data
->rx_bytes
= val
;
658 else if (strcmp(line
, "tx_bytes") == 0)
659 data
->tx_bytes
= val
;
665 #endif /* MADWIFI_BSD */
670 madwifi_sta_clear_stats(void *priv
, const u8
*addr
)
672 #if defined(MADWIFI_BSD) && defined(IEEE80211_MLME_CLEAR_STATS)
673 struct madwifi_driver_data
*drv
= priv
;
674 struct ieee80211req_mlme mlme
;
677 wpa_printf(MSG_DEBUG
, "%s: addr=%s", __func__
, ether_sprintf(addr
));
679 mlme
.im_op
= IEEE80211_MLME_CLEAR_STATS
;
680 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
681 ret
= set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
,
684 wpa_printf(MSG_DEBUG
, "%s: Failed to clear STA stats (addr "
685 MACSTR
")", __func__
, MAC2STR(addr
));
689 #else /* MADWIFI_BSD && IEEE80211_MLME_CLEAR_STATS */
691 #endif /* MADWIFI_BSD && IEEE80211_MLME_CLEAR_STATS */
696 madwifi_set_opt_ie(const char *ifname
, void *priv
, const u8
*ie
, size_t ie_len
)
699 * Do nothing; we setup parameters at startup that define the
700 * contents of the beacon information element.
706 madwifi_sta_deauth(void *priv
, const u8
*addr
, int reason_code
)
708 struct madwifi_driver_data
*drv
= priv
;
709 struct ieee80211req_mlme mlme
;
712 wpa_printf(MSG_DEBUG
, "%s: addr=%s reason_code=%d",
713 __func__
, ether_sprintf(addr
), reason_code
);
715 mlme
.im_op
= IEEE80211_MLME_DEAUTH
;
716 mlme
.im_reason
= reason_code
;
717 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
718 ret
= set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
, sizeof(mlme
));
720 wpa_printf(MSG_DEBUG
, "%s: Failed to deauth STA (addr " MACSTR
722 __func__
, MAC2STR(addr
), reason_code
);
729 madwifi_sta_disassoc(void *priv
, const u8
*addr
, int reason_code
)
731 struct madwifi_driver_data
*drv
= priv
;
732 struct ieee80211req_mlme mlme
;
735 wpa_printf(MSG_DEBUG
, "%s: addr=%s reason_code=%d",
736 __func__
, ether_sprintf(addr
), reason_code
);
738 mlme
.im_op
= IEEE80211_MLME_DISASSOC
;
739 mlme
.im_reason
= reason_code
;
740 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
741 ret
= set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
, sizeof(mlme
));
743 wpa_printf(MSG_DEBUG
, "%s: Failed to disassoc STA (addr "
744 MACSTR
" reason %d)",
745 __func__
, MAC2STR(addr
), reason_code
);
752 #ifdef IEEE80211_IOCTL_FILTERFRAME
753 static void madwifi_raw_receive(void *ctx
, const u8
*src_addr
, const u8
*buf
,
756 struct madwifi_driver_data
*drv
= ctx
;
757 const struct ieee80211_mgmt
*mgmt
;
762 /* Send Probe Request information to WPS processing */
764 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.probe_req
))
766 mgmt
= (const struct ieee80211_mgmt
*) buf
;
768 fc
= le_to_host16(mgmt
->frame_control
);
769 if (WLAN_FC_GET_TYPE(fc
) != WLAN_FC_TYPE_MGMT
||
770 WLAN_FC_GET_STYPE(fc
) != WLAN_FC_STYPE_PROBE_REQ
)
774 ie
= mgmt
->u
.probe_req
.variable
;
775 ie_len
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.probe_req
));
777 hostapd_wps_probe_req_rx(drv
->hapd
, mgmt
->sa
, ie
, ie_len
);
779 #endif /* IEEE80211_IOCTL_FILTERFRAME */
780 #endif /* CONFIG_WPS */
782 static int madwifi_receive_probe_req(struct madwifi_driver_data
*drv
)
786 #ifdef IEEE80211_IOCTL_FILTERFRAME
787 struct ieee80211req_set_filter filt
;
789 wpa_printf(MSG_DEBUG
, "%s Enter", __func__
);
790 filt
.app_filterype
= IEEE80211_FILTER_TYPE_PROBE_REQ
;
792 ret
= set80211priv(drv
, IEEE80211_IOCTL_FILTERFRAME
, &filt
,
793 sizeof(struct ieee80211req_set_filter
));
797 drv
->sock_raw
= l2_packet_init(drv
->iface
, NULL
, ETH_P_80211_RAW
,
798 madwifi_raw_receive
, drv
, 1);
799 if (drv
->sock_raw
== NULL
)
801 #endif /* IEEE80211_IOCTL_FILTERFRAME */
802 #endif /* CONFIG_WPS */
808 madwifi_set_wps_ie(void *priv
, const u8
*ie
, size_t len
, u32 frametype
)
810 struct madwifi_driver_data
*drv
= priv
;
812 struct ieee80211req_getset_appiebuf
*beac_ie
;
814 wpa_printf(MSG_DEBUG
, "%s buflen = %lu", __func__
,
815 (unsigned long) len
);
817 beac_ie
= (struct ieee80211req_getset_appiebuf
*) buf
;
818 beac_ie
->app_frmtype
= frametype
;
819 beac_ie
->app_buflen
= len
;
820 memcpy(&(beac_ie
->app_buf
[0]), ie
, len
);
822 return set80211priv(drv
, IEEE80211_IOCTL_SET_APPIEBUF
, beac_ie
,
823 sizeof(struct ieee80211req_getset_appiebuf
) + len
);
827 madwifi_set_wps_beacon_ie(const char *ifname
, void *priv
, const u8
*ie
,
830 return madwifi_set_wps_ie(priv
, ie
, len
, IEEE80211_APPIE_FRAME_BEACON
);
834 madwifi_set_wps_probe_resp_ie(const char *ifname
, void *priv
, const u8
*ie
,
837 return madwifi_set_wps_ie(priv
, ie
, len
,
838 IEEE80211_APPIE_FRAME_PROBE_RESP
);
840 #else /* CONFIG_WPS */
841 #define madwifi_set_wps_beacon_ie NULL
842 #define madwifi_set_wps_probe_resp_ie NULL
843 #endif /* CONFIG_WPS */
846 madwifi_new_sta(struct madwifi_driver_data
*drv
, u8 addr
[IEEE80211_ADDR_LEN
])
848 struct hostapd_data
*hapd
= drv
->hapd
;
849 struct ieee80211req_wpaie ie
;
854 * Fetch negotiated WPA/RSN parameters from the system.
856 memset(&ie
, 0, sizeof(ie
));
857 memcpy(ie
.wpa_macaddr
, addr
, IEEE80211_ADDR_LEN
);
858 if (set80211priv(drv
, IEEE80211_IOCTL_GETWPAIE
, &ie
, sizeof(ie
))) {
859 wpa_printf(MSG_DEBUG
, "%s: Failed to get WPA/RSN IE",
863 wpa_hexdump(MSG_MSGDUMP
, "madwifi req WPA IE",
864 ie
.wpa_ie
, IEEE80211_MAX_OPT_IE
);
866 /* madwifi seems to return some random data if WPA/RSN IE is not set.
867 * Assume the IE was not included if the IE type is unknown. */
868 if (iebuf
[0] != WLAN_EID_VENDOR_SPECIFIC
)
871 wpa_hexdump(MSG_MSGDUMP
, "madwifi req RSN IE",
872 ie
.rsn_ie
, IEEE80211_MAX_OPT_IE
);
873 if (iebuf
[1] == 0 && ie
.rsn_ie
[1] > 0) {
874 /* madwifi-ng svn #1453 added rsn_ie. Use it, if wpa_ie was not
875 * set. This is needed for WPA2. */
877 if (iebuf
[0] != WLAN_EID_RSN
)
880 #endif /* MADWIFI_NG */
889 res
= hostapd_notif_assoc(hapd
, addr
, iebuf
, ielen
);
891 if (memcmp(addr
, drv
->acct_mac
, ETH_ALEN
) == 0) {
892 /* Cached accounting data is not valid anymore. */
893 memset(drv
->acct_mac
, 0, ETH_ALEN
);
894 memset(&drv
->acct_data
, 0, sizeof(drv
->acct_data
));
901 madwifi_wireless_event_wireless_custom(struct madwifi_driver_data
*drv
,
904 wpa_printf(MSG_DEBUG
, "Custom wireless event: '%s'", custom
);
906 if (strncmp(custom
, "MLME-MICHAELMICFAILURE.indication", 33) == 0) {
909 pos
= strstr(custom
, "addr=");
911 wpa_printf(MSG_DEBUG
,
912 "MLME-MICHAELMICFAILURE.indication "
913 "without sender address ignored");
917 if (hwaddr_aton(pos
, addr
) == 0) {
918 hostapd_michael_mic_failure(drv
->hapd
, addr
);
920 wpa_printf(MSG_DEBUG
,
921 "MLME-MICHAELMICFAILURE.indication "
922 "with invalid MAC address");
924 } else if (strncmp(custom
, "STA-TRAFFIC-STAT", 16) == 0) {
928 while ((key
= strchr(key
, '\n')) != NULL
) {
930 value
= strchr(key
, '=');
934 val
= strtoul(value
, NULL
, 10);
935 if (strcmp(key
, "mac") == 0)
936 hwaddr_aton(value
, drv
->acct_mac
);
937 else if (strcmp(key
, "rx_packets") == 0)
938 drv
->acct_data
.rx_packets
= val
;
939 else if (strcmp(key
, "tx_packets") == 0)
940 drv
->acct_data
.tx_packets
= val
;
941 else if (strcmp(key
, "rx_bytes") == 0)
942 drv
->acct_data
.rx_bytes
= val
;
943 else if (strcmp(key
, "tx_bytes") == 0)
944 drv
->acct_data
.tx_bytes
= val
;
951 madwifi_wireless_event_wireless(struct madwifi_driver_data
*drv
,
954 struct iw_event iwe_buf
, *iwe
= &iwe_buf
;
955 char *pos
, *end
, *custom
, *buf
;
960 while (pos
+ IW_EV_LCP_LEN
<= end
) {
961 /* Event data may be unaligned, so make a local, aligned copy
962 * before processing. */
963 memcpy(&iwe_buf
, pos
, IW_EV_LCP_LEN
);
964 wpa_printf(MSG_MSGDUMP
, "Wireless event: cmd=0x%x len=%d",
966 if (iwe
->len
<= IW_EV_LCP_LEN
)
969 custom
= pos
+ IW_EV_POINT_LEN
;
970 if (drv
->we_version
> 18 &&
971 (iwe
->cmd
== IWEVMICHAELMICFAILURE
||
972 iwe
->cmd
== IWEVCUSTOM
)) {
973 /* WE-19 removed the pointer from struct iw_point */
974 char *dpos
= (char *) &iwe_buf
.u
.data
.length
;
975 int dlen
= dpos
- (char *) &iwe_buf
;
976 memcpy(dpos
, pos
+ IW_EV_LCP_LEN
,
977 sizeof(struct iw_event
) - dlen
);
979 memcpy(&iwe_buf
, pos
, sizeof(struct iw_event
));
980 custom
+= IW_EV_POINT_OFF
;
985 hostapd_notif_disassoc(drv
->hapd
,
986 (u8
*) iwe
->u
.addr
.sa_data
);
989 madwifi_new_sta(drv
, (u8
*) iwe
->u
.addr
.sa_data
);
992 if (custom
+ iwe
->u
.data
.length
> end
)
994 buf
= malloc(iwe
->u
.data
.length
+ 1);
997 memcpy(buf
, custom
, iwe
->u
.data
.length
);
998 buf
[iwe
->u
.data
.length
] = '\0';
999 madwifi_wireless_event_wireless_custom(drv
, buf
);
1010 madwifi_wireless_event_rtm_newlink(struct madwifi_driver_data
*drv
,
1011 struct nlmsghdr
*h
, int len
)
1013 struct ifinfomsg
*ifi
;
1014 int attrlen
, nlmsg_len
, rta_len
;
1015 struct rtattr
* attr
;
1017 if (len
< (int) sizeof(*ifi
))
1020 ifi
= NLMSG_DATA(h
);
1022 if (ifi
->ifi_index
!= drv
->ifindex
)
1025 nlmsg_len
= NLMSG_ALIGN(sizeof(struct ifinfomsg
));
1027 attrlen
= h
->nlmsg_len
- nlmsg_len
;
1031 attr
= (struct rtattr
*) (((char *) ifi
) + nlmsg_len
);
1033 rta_len
= RTA_ALIGN(sizeof(struct rtattr
));
1034 while (RTA_OK(attr
, attrlen
)) {
1035 if (attr
->rta_type
== IFLA_WIRELESS
) {
1036 madwifi_wireless_event_wireless(
1037 drv
, ((char *) attr
) + rta_len
,
1038 attr
->rta_len
- rta_len
);
1040 attr
= RTA_NEXT(attr
, attrlen
);
1046 madwifi_wireless_event_receive(int sock
, void *eloop_ctx
, void *sock_ctx
)
1050 struct sockaddr_nl from
;
1053 struct madwifi_driver_data
*drv
= eloop_ctx
;
1055 fromlen
= sizeof(from
);
1056 left
= recvfrom(sock
, buf
, sizeof(buf
), MSG_DONTWAIT
,
1057 (struct sockaddr
*) &from
, &fromlen
);
1059 if (errno
!= EINTR
&& errno
!= EAGAIN
)
1060 perror("recvfrom(netlink)");
1064 h
= (struct nlmsghdr
*) buf
;
1065 while (left
>= (int) sizeof(*h
)) {
1069 plen
= len
- sizeof(*h
);
1070 if (len
> left
|| plen
< 0) {
1071 printf("Malformed netlink message: "
1072 "len=%d left=%d plen=%d\n",
1077 switch (h
->nlmsg_type
) {
1079 madwifi_wireless_event_rtm_newlink(drv
, h
, plen
);
1083 len
= NLMSG_ALIGN(len
);
1085 h
= (struct nlmsghdr
*) ((char *) h
+ len
);
1089 printf("%d extra bytes in the end of netlink message\n", left
);
1095 madwifi_get_we_version(struct madwifi_driver_data
*drv
)
1097 struct iw_range
*range
;
1102 drv
->we_version
= 0;
1105 * Use larger buffer than struct iw_range in order to allow the
1106 * structure to grow in the future.
1108 buflen
= sizeof(struct iw_range
) + 500;
1109 range
= os_zalloc(buflen
);
1113 memset(&iwr
, 0, sizeof(iwr
));
1114 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
1115 iwr
.u
.data
.pointer
= (caddr_t
) range
;
1116 iwr
.u
.data
.length
= buflen
;
1118 minlen
= ((char *) &range
->enc_capa
) - (char *) range
+
1119 sizeof(range
->enc_capa
);
1121 if (ioctl(drv
->ioctl_sock
, SIOCGIWRANGE
, &iwr
) < 0) {
1122 perror("ioctl[SIOCGIWRANGE]");
1125 } else if (iwr
.u
.data
.length
>= minlen
&&
1126 range
->we_version_compiled
>= 18) {
1127 wpa_printf(MSG_DEBUG
, "SIOCGIWRANGE: WE(compiled)=%d "
1128 "WE(source)=%d enc_capa=0x%x",
1129 range
->we_version_compiled
,
1130 range
->we_version_source
,
1132 drv
->we_version
= range
->we_version_compiled
;
1141 madwifi_wireless_event_init(struct madwifi_driver_data
*drv
)
1144 struct sockaddr_nl local
;
1146 madwifi_get_we_version(drv
);
1148 drv
->wext_sock
= -1;
1150 s
= socket(PF_NETLINK
, SOCK_RAW
, NETLINK_ROUTE
);
1152 perror("socket(PF_NETLINK,SOCK_RAW,NETLINK_ROUTE)");
1156 memset(&local
, 0, sizeof(local
));
1157 local
.nl_family
= AF_NETLINK
;
1158 local
.nl_groups
= RTMGRP_LINK
;
1159 if (bind(s
, (struct sockaddr
*) &local
, sizeof(local
)) < 0) {
1160 perror("bind(netlink)");
1165 eloop_register_read_sock(s
, madwifi_wireless_event_receive
, drv
, NULL
);
1173 madwifi_wireless_event_deinit(struct madwifi_driver_data
*drv
)
1175 if (drv
->wext_sock
< 0)
1177 eloop_unregister_read_sock(drv
->wext_sock
);
1178 close(drv
->wext_sock
);
1183 madwifi_send_eapol(void *priv
, const u8
*addr
, const u8
*data
, size_t data_len
,
1184 int encrypt
, const u8
*own_addr
)
1186 struct madwifi_driver_data
*drv
= priv
;
1187 unsigned char buf
[3000];
1188 unsigned char *bp
= buf
;
1189 struct l2_ethhdr
*eth
;
1194 * Prepend the Ethernet header. If the caller left us
1195 * space at the front we could just insert it but since
1196 * we don't know we copy to a local buffer. Given the frequency
1197 * and size of frames this probably doesn't matter.
1199 len
= data_len
+ sizeof(struct l2_ethhdr
);
1200 if (len
> sizeof(buf
)) {
1203 printf("EAPOL frame discarded, cannot malloc temp "
1204 "buffer of size %lu!\n", (unsigned long) len
);
1208 eth
= (struct l2_ethhdr
*) bp
;
1209 memcpy(eth
->h_dest
, addr
, ETH_ALEN
);
1210 memcpy(eth
->h_source
, own_addr
, ETH_ALEN
);
1211 eth
->h_proto
= host_to_be16(ETH_P_EAPOL
);
1212 memcpy(eth
+1, data
, data_len
);
1214 wpa_hexdump(MSG_MSGDUMP
, "TX EAPOL", bp
, len
);
1216 status
= l2_packet_send(drv
->sock_xmit
, addr
, ETH_P_EAPOL
, bp
, len
);
1224 handle_read(void *ctx
, const u8
*src_addr
, const u8
*buf
, size_t len
)
1226 struct madwifi_driver_data
*drv
= ctx
;
1227 hostapd_eapol_receive(drv
->hapd
, src_addr
,
1228 buf
+ sizeof(struct l2_ethhdr
),
1229 len
- sizeof(struct l2_ethhdr
));
1233 madwifi_init(struct hostapd_data
*hapd
)
1235 struct madwifi_driver_data
*drv
;
1239 drv
= os_zalloc(sizeof(struct madwifi_driver_data
));
1241 printf("Could not allocate memory for madwifi driver data\n");
1246 drv
->ioctl_sock
= socket(PF_INET
, SOCK_DGRAM
, 0);
1247 if (drv
->ioctl_sock
< 0) {
1248 perror("socket[PF_INET,SOCK_DGRAM]");
1251 memcpy(drv
->iface
, hapd
->conf
->iface
, sizeof(drv
->iface
));
1253 memset(&ifr
, 0, sizeof(ifr
));
1254 os_strlcpy(ifr
.ifr_name
, drv
->iface
, sizeof(ifr
.ifr_name
));
1255 if (ioctl(drv
->ioctl_sock
, SIOCGIFINDEX
, &ifr
) != 0) {
1256 perror("ioctl(SIOCGIFINDEX)");
1259 drv
->ifindex
= ifr
.ifr_ifindex
;
1261 drv
->sock_xmit
= l2_packet_init(drv
->iface
, NULL
, ETH_P_EAPOL
,
1262 handle_read
, drv
, 1);
1263 if (drv
->sock_xmit
== NULL
)
1265 if (l2_packet_get_own_addr(drv
->sock_xmit
, hapd
->own_addr
))
1267 if (hapd
->conf
->bridge
[0] != '\0') {
1268 wpa_printf(MSG_DEBUG
, "Configure bridge %s for EAPOL traffic.",
1269 hapd
->conf
->bridge
);
1270 drv
->sock_recv
= l2_packet_init(hapd
->conf
->bridge
, NULL
,
1271 ETH_P_EAPOL
, handle_read
, drv
,
1273 if (drv
->sock_recv
== NULL
)
1276 drv
->sock_recv
= drv
->sock_xmit
;
1278 memset(&iwr
, 0, sizeof(iwr
));
1279 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
1281 iwr
.u
.mode
= IW_MODE_MASTER
;
1283 if (ioctl(drv
->ioctl_sock
, SIOCSIWMODE
, &iwr
) < 0) {
1284 perror("ioctl[SIOCSIWMODE]");
1285 printf("Could not set interface to master mode!\n");
1289 madwifi_set_iface_flags(drv
, 0); /* mark down during setup */
1290 madwifi_set_privacy(drv
->iface
, drv
, 0); /* default to no privacy */
1292 madwifi_receive_probe_req(drv
);
1294 if (madwifi_wireless_event_init(drv
))
1299 if (drv
->sock_xmit
!= NULL
)
1300 l2_packet_deinit(drv
->sock_xmit
);
1301 if (drv
->ioctl_sock
>= 0)
1302 close(drv
->ioctl_sock
);
1310 madwifi_deinit(void *priv
)
1312 struct madwifi_driver_data
*drv
= priv
;
1314 madwifi_wireless_event_deinit(drv
);
1315 (void) madwifi_set_iface_flags(drv
, 0);
1316 if (drv
->ioctl_sock
>= 0)
1317 close(drv
->ioctl_sock
);
1318 if (drv
->sock_recv
!= NULL
&& drv
->sock_recv
!= drv
->sock_xmit
)
1319 l2_packet_deinit(drv
->sock_recv
);
1320 if (drv
->sock_xmit
!= NULL
)
1321 l2_packet_deinit(drv
->sock_xmit
);
1323 l2_packet_deinit(drv
->sock_raw
);
1328 madwifi_set_ssid(const char *ifname
, void *priv
, const u8
*buf
, int len
)
1330 struct madwifi_driver_data
*drv
= priv
;
1333 memset(&iwr
, 0, sizeof(iwr
));
1334 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
1335 iwr
.u
.essid
.flags
= 1; /* SSID active */
1336 iwr
.u
.essid
.pointer
= (caddr_t
) buf
;
1337 iwr
.u
.essid
.length
= len
+ 1;
1339 if (ioctl(drv
->ioctl_sock
, SIOCSIWESSID
, &iwr
) < 0) {
1340 perror("ioctl[SIOCSIWESSID]");
1341 printf("len=%d\n", len
);
1348 madwifi_get_ssid(const char *ifname
, void *priv
, u8
*buf
, int len
)
1350 struct madwifi_driver_data
*drv
= priv
;
1354 memset(&iwr
, 0, sizeof(iwr
));
1355 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
1356 iwr
.u
.essid
.pointer
= (caddr_t
) buf
;
1357 iwr
.u
.essid
.length
= len
;
1359 if (ioctl(drv
->ioctl_sock
, SIOCGIWESSID
, &iwr
) < 0) {
1360 perror("ioctl[SIOCGIWESSID]");
1363 ret
= iwr
.u
.essid
.length
;
1369 madwifi_set_countermeasures(void *priv
, int enabled
)
1371 struct madwifi_driver_data
*drv
= priv
;
1372 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __FUNCTION__
, enabled
);
1373 return set80211param(drv
, IEEE80211_PARAM_COUNTERMEASURES
, enabled
);
1377 madwifi_commit(void *priv
)
1379 return madwifi_set_iface_flags(priv
, 1);
1384 struct wpa_driver_madwifi_data
{
1385 void *wext
; /* private data for driver_wext */
1387 char ifname
[IFNAMSIZ
+ 1];
1392 set80211priv(struct wpa_driver_madwifi_data
*drv
, int op
, void *data
, int len
,
1397 os_memset(&iwr
, 0, sizeof(iwr
));
1398 os_strlcpy(iwr
.ifr_name
, drv
->ifname
, IFNAMSIZ
);
1399 if (len
< IFNAMSIZ
&&
1400 op
!= IEEE80211_IOCTL_SET_APPIEBUF
) {
1402 * Argument data fits inline; put it there.
1404 os_memcpy(iwr
.u
.name
, data
, len
);
1407 * Argument data too big for inline transfer; setup a
1408 * parameter block instead; the kernel will transfer
1409 * the data for the driver.
1411 iwr
.u
.data
.pointer
= data
;
1412 iwr
.u
.data
.length
= len
;
1415 if (ioctl(drv
->sock
, op
, &iwr
) < 0) {
1418 int first
= IEEE80211_IOCTL_SETPARAM
;
1419 int last
= IEEE80211_IOCTL_KICKMAC
;
1420 static const char *opnames
[] = {
1421 "ioctl[IEEE80211_IOCTL_SETPARAM]",
1422 "ioctl[IEEE80211_IOCTL_GETPARAM]",
1423 "ioctl[IEEE80211_IOCTL_SETMODE]",
1424 "ioctl[IEEE80211_IOCTL_GETMODE]",
1425 "ioctl[IEEE80211_IOCTL_SETWMMPARAMS]",
1426 "ioctl[IEEE80211_IOCTL_GETWMMPARAMS]",
1427 "ioctl[IEEE80211_IOCTL_SETCHANLIST]",
1428 "ioctl[IEEE80211_IOCTL_GETCHANLIST]",
1429 "ioctl[IEEE80211_IOCTL_CHANSWITCH]",
1431 "ioctl[IEEE80211_IOCTL_SET_APPIEBUF]",
1432 "ioctl[IEEE80211_IOCTL_GETSCANRESULTS]",
1434 "ioctl[IEEE80211_IOCTL_GETCHANINFO]",
1435 "ioctl[IEEE80211_IOCTL_SETOPTIE]",
1436 "ioctl[IEEE80211_IOCTL_GETOPTIE]",
1437 "ioctl[IEEE80211_IOCTL_SETMLME]",
1439 "ioctl[IEEE80211_IOCTL_SETKEY]",
1441 "ioctl[IEEE80211_IOCTL_DELKEY]",
1443 "ioctl[IEEE80211_IOCTL_ADDMAC]",
1445 "ioctl[IEEE80211_IOCTL_DELMAC]",
1447 "ioctl[IEEE80211_IOCTL_WDSMAC]",
1449 "ioctl[IEEE80211_IOCTL_WDSDELMAC]",
1451 "ioctl[IEEE80211_IOCTL_KICKMAC]",
1453 #else /* MADWIFI_NG */
1454 int first
= IEEE80211_IOCTL_SETPARAM
;
1455 int last
= IEEE80211_IOCTL_CHANLIST
;
1456 static const char *opnames
[] = {
1457 "ioctl[IEEE80211_IOCTL_SETPARAM]",
1458 "ioctl[IEEE80211_IOCTL_GETPARAM]",
1459 "ioctl[IEEE80211_IOCTL_SETKEY]",
1460 "ioctl[IEEE80211_IOCTL_GETKEY]",
1461 "ioctl[IEEE80211_IOCTL_DELKEY]",
1463 "ioctl[IEEE80211_IOCTL_SETMLME]",
1465 "ioctl[IEEE80211_IOCTL_SETOPTIE]",
1466 "ioctl[IEEE80211_IOCTL_GETOPTIE]",
1467 "ioctl[IEEE80211_IOCTL_ADDMAC]",
1469 "ioctl[IEEE80211_IOCTL_DELMAC]",
1471 "ioctl[IEEE80211_IOCTL_CHANLIST]",
1473 #endif /* MADWIFI_NG */
1474 int idx
= op
- first
;
1475 if (first
<= op
&& op
<= last
&&
1476 idx
< (int) (sizeof(opnames
) / sizeof(opnames
[0]))
1478 perror(opnames
[idx
]);
1480 perror("ioctl[unknown???]");
1488 set80211param(struct wpa_driver_madwifi_data
*drv
, int op
, int arg
,
1493 os_memset(&iwr
, 0, sizeof(iwr
));
1494 os_strlcpy(iwr
.ifr_name
, drv
->ifname
, IFNAMSIZ
);
1496 os_memcpy(iwr
.u
.name
+sizeof(u32
), &arg
, sizeof(arg
));
1498 if (ioctl(drv
->sock
, IEEE80211_IOCTL_SETPARAM
, &iwr
) < 0) {
1500 perror("ioctl[IEEE80211_IOCTL_SETPARAM]");
1507 wpa_driver_madwifi_set_wpa_ie(struct wpa_driver_madwifi_data
*drv
,
1508 const u8
*wpa_ie
, size_t wpa_ie_len
)
1512 os_memset(&iwr
, 0, sizeof(iwr
));
1513 os_strlcpy(iwr
.ifr_name
, drv
->ifname
, IFNAMSIZ
);
1514 /* NB: SETOPTIE is not fixed-size so must not be inlined */
1515 iwr
.u
.data
.pointer
= (void *) wpa_ie
;
1516 iwr
.u
.data
.length
= wpa_ie_len
;
1518 if (ioctl(drv
->sock
, IEEE80211_IOCTL_SETOPTIE
, &iwr
) < 0) {
1519 perror("ioctl[IEEE80211_IOCTL_SETOPTIE]");
1526 wpa_driver_madwifi_del_key(struct wpa_driver_madwifi_data
*drv
, int key_idx
,
1529 struct ieee80211req_del_key wk
;
1531 wpa_printf(MSG_DEBUG
, "%s: keyidx=%d", __FUNCTION__
, key_idx
);
1532 os_memset(&wk
, 0, sizeof(wk
));
1533 wk
.idk_keyix
= key_idx
;
1535 os_memcpy(wk
.idk_macaddr
, addr
, IEEE80211_ADDR_LEN
);
1537 return set80211priv(drv
, IEEE80211_IOCTL_DELKEY
, &wk
, sizeof(wk
), 1);
1541 wpa_driver_madwifi_set_key(void *priv
, wpa_alg alg
,
1542 const u8
*addr
, int key_idx
, int set_tx
,
1543 const u8
*seq
, size_t seq_len
,
1544 const u8
*key
, size_t key_len
)
1546 struct wpa_driver_madwifi_data
*drv
= priv
;
1547 struct ieee80211req_key wk
;
1551 if (alg
== WPA_ALG_NONE
)
1552 return wpa_driver_madwifi_del_key(drv
, key_idx
, addr
);
1556 if (addr
== NULL
|| os_memcmp(addr
, "\xff\xff\xff\xff\xff\xff",
1559 * madwifi did not seem to like static WEP key
1560 * configuration with IEEE80211_IOCTL_SETKEY, so use
1561 * Linux wireless extensions ioctl for this.
1563 return wpa_driver_wext_set_key(drv
->wext
, alg
, addr
,
1569 cipher
= IEEE80211_CIPHER_WEP
;
1573 cipher
= IEEE80211_CIPHER_TKIP
;
1577 cipher
= IEEE80211_CIPHER_AES_CCM
;
1580 wpa_printf(MSG_DEBUG
, "%s: unknown/unsupported algorithm %d",
1585 wpa_printf(MSG_DEBUG
, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu "
1586 "key_len=%lu", __FUNCTION__
, alg_name
, key_idx
, set_tx
,
1587 (unsigned long) seq_len
, (unsigned long) key_len
);
1589 if (seq_len
> sizeof(u_int64_t
)) {
1590 wpa_printf(MSG_DEBUG
, "%s: seq_len %lu too big",
1591 __FUNCTION__
, (unsigned long) seq_len
);
1594 if (key_len
> sizeof(wk
.ik_keydata
)) {
1595 wpa_printf(MSG_DEBUG
, "%s: key length %lu too big",
1596 __FUNCTION__
, (unsigned long) key_len
);
1600 os_memset(&wk
, 0, sizeof(wk
));
1601 wk
.ik_type
= cipher
;
1602 wk
.ik_flags
= IEEE80211_KEY_RECV
;
1604 os_memcmp(addr
, "\xff\xff\xff\xff\xff\xff", ETH_ALEN
) == 0)
1605 wk
.ik_flags
|= IEEE80211_KEY_GROUP
;
1607 wk
.ik_flags
|= IEEE80211_KEY_XMIT
| IEEE80211_KEY_DEFAULT
;
1608 os_memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
1610 os_memset(wk
.ik_macaddr
, 0, IEEE80211_ADDR_LEN
);
1611 wk
.ik_keyix
= key_idx
;
1612 wk
.ik_keylen
= key_len
;
1613 #ifdef WORDS_BIGENDIAN
1614 #define WPA_KEY_RSC_LEN 8
1617 u8 tmp
[WPA_KEY_RSC_LEN
];
1618 os_memset(tmp
, 0, sizeof(tmp
));
1619 for (i
= 0; i
< seq_len
; i
++)
1620 tmp
[WPA_KEY_RSC_LEN
- i
- 1] = seq
[i
];
1621 os_memcpy(&wk
.ik_keyrsc
, tmp
, WPA_KEY_RSC_LEN
);
1623 #else /* WORDS_BIGENDIAN */
1624 os_memcpy(&wk
.ik_keyrsc
, seq
, seq_len
);
1625 #endif /* WORDS_BIGENDIAN */
1626 os_memcpy(wk
.ik_keydata
, key
, key_len
);
1628 return set80211priv(drv
, IEEE80211_IOCTL_SETKEY
, &wk
, sizeof(wk
), 1);
1632 wpa_driver_madwifi_set_countermeasures(void *priv
, int enabled
)
1634 struct wpa_driver_madwifi_data
*drv
= priv
;
1635 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __FUNCTION__
, enabled
);
1636 return set80211param(drv
, IEEE80211_PARAM_COUNTERMEASURES
, enabled
, 1);
1641 wpa_driver_madwifi_set_drop_unencrypted(void *priv
, int enabled
)
1643 struct wpa_driver_madwifi_data
*drv
= priv
;
1644 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __FUNCTION__
, enabled
);
1645 return set80211param(drv
, IEEE80211_PARAM_DROPUNENCRYPTED
, enabled
, 1);
1649 wpa_driver_madwifi_deauthenticate(void *priv
, const u8
*addr
, int reason_code
)
1651 struct wpa_driver_madwifi_data
*drv
= priv
;
1652 struct ieee80211req_mlme mlme
;
1654 wpa_printf(MSG_DEBUG
, "%s", __FUNCTION__
);
1655 mlme
.im_op
= IEEE80211_MLME_DEAUTH
;
1656 mlme
.im_reason
= reason_code
;
1657 os_memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
1658 return set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
, sizeof(mlme
), 1);
1662 wpa_driver_madwifi_disassociate(void *priv
, const u8
*addr
, int reason_code
)
1664 struct wpa_driver_madwifi_data
*drv
= priv
;
1665 struct ieee80211req_mlme mlme
;
1667 wpa_printf(MSG_DEBUG
, "%s", __FUNCTION__
);
1668 mlme
.im_op
= IEEE80211_MLME_DISASSOC
;
1669 mlme
.im_reason
= reason_code
;
1670 os_memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
1671 return set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
, sizeof(mlme
), 1);
1675 wpa_driver_madwifi_associate(void *priv
,
1676 struct wpa_driver_associate_params
*params
)
1678 struct wpa_driver_madwifi_data
*drv
= priv
;
1679 struct ieee80211req_mlme mlme
;
1680 int ret
= 0, privacy
= 1;
1682 wpa_printf(MSG_DEBUG
, "%s", __FUNCTION__
);
1685 * NB: Don't need to set the freq or cipher-related state as
1686 * this is implied by the bssid which is used to locate
1687 * the scanned node state which holds it. The ssid is
1688 * needed to disambiguate an AP that broadcasts multiple
1689 * ssid's but uses the same bssid.
1691 /* XXX error handling is wrong but unclear what to do... */
1692 if (wpa_driver_madwifi_set_wpa_ie(drv
, params
->wpa_ie
,
1693 params
->wpa_ie_len
) < 0)
1696 if (params
->pairwise_suite
== CIPHER_NONE
&&
1697 params
->group_suite
== CIPHER_NONE
&&
1698 params
->key_mgmt_suite
== KEY_MGMT_NONE
&&
1699 params
->wpa_ie_len
== 0)
1702 if (set80211param(drv
, IEEE80211_PARAM_PRIVACY
, privacy
, 1) < 0)
1705 if (params
->wpa_ie_len
&&
1706 set80211param(drv
, IEEE80211_PARAM_WPA
,
1707 params
->wpa_ie
[0] == WLAN_EID_RSN
? 2 : 1, 1) < 0)
1710 if (params
->bssid
== NULL
) {
1711 /* ap_scan=2 mode - driver takes care of AP selection and
1713 /* FIX: this does not seem to work; would probably need to
1714 * change something in the driver */
1715 if (set80211param(drv
, IEEE80211_PARAM_ROAMING
, 0, 1) < 0)
1718 if (wpa_driver_wext_set_ssid(drv
->wext
, params
->ssid
,
1719 params
->ssid_len
) < 0)
1722 if (set80211param(drv
, IEEE80211_PARAM_ROAMING
, 2, 1) < 0)
1724 if (wpa_driver_wext_set_ssid(drv
->wext
, params
->ssid
,
1725 params
->ssid_len
) < 0)
1727 os_memset(&mlme
, 0, sizeof(mlme
));
1728 mlme
.im_op
= IEEE80211_MLME_ASSOC
;
1729 os_memcpy(mlme
.im_macaddr
, params
->bssid
, IEEE80211_ADDR_LEN
);
1730 if (set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
,
1731 sizeof(mlme
), 1) < 0) {
1732 wpa_printf(MSG_DEBUG
, "%s: SETMLME[ASSOC] failed",
1742 wpa_driver_madwifi_set_auth_alg(void *priv
, int auth_alg
)
1744 struct wpa_driver_madwifi_data
*drv
= priv
;
1747 if ((auth_alg
& AUTH_ALG_OPEN_SYSTEM
) &&
1748 (auth_alg
& AUTH_ALG_SHARED_KEY
))
1749 authmode
= IEEE80211_AUTH_AUTO
;
1750 else if (auth_alg
& AUTH_ALG_SHARED_KEY
)
1751 authmode
= IEEE80211_AUTH_SHARED
;
1753 authmode
= IEEE80211_AUTH_OPEN
;
1755 return set80211param(drv
, IEEE80211_PARAM_AUTHMODE
, authmode
, 1);
1759 wpa_driver_madwifi_scan(void *priv
, const u8
*ssid
, size_t ssid_len
)
1761 struct wpa_driver_madwifi_data
*drv
= priv
;
1765 os_memset(&iwr
, 0, sizeof(iwr
));
1766 os_strlcpy(iwr
.ifr_name
, drv
->ifname
, IFNAMSIZ
);
1768 /* set desired ssid before scan */
1769 /* FIX: scan should not break the current association, so using
1770 * set_ssid may not be the best way of doing this.. */
1771 if (wpa_driver_wext_set_ssid(drv
->wext
, ssid
, ssid_len
) < 0)
1774 if (ioctl(drv
->sock
, SIOCSIWSCAN
, &iwr
) < 0) {
1775 perror("ioctl[SIOCSIWSCAN]");
1780 * madwifi delivers a scan complete event so no need to poll, but
1781 * register a backup timeout anyway to make sure that we recover even
1782 * if the driver does not send this event for any reason. This timeout
1783 * will only be used if the event is not delivered (event handler will
1784 * cancel the timeout).
1786 eloop_cancel_timeout(wpa_driver_wext_scan_timeout
, drv
->wext
,
1788 eloop_register_timeout(30, 0, wpa_driver_wext_scan_timeout
, drv
->wext
,
1794 static int wpa_driver_madwifi_get_bssid(void *priv
, u8
*bssid
)
1796 struct wpa_driver_madwifi_data
*drv
= priv
;
1797 return wpa_driver_wext_get_bssid(drv
->wext
, bssid
);
1801 static int wpa_driver_madwifi_get_ssid(void *priv
, u8
*ssid
)
1803 struct wpa_driver_madwifi_data
*drv
= priv
;
1804 return wpa_driver_wext_get_ssid(drv
->wext
, ssid
);
1808 static struct wpa_scan_results
*
1809 wpa_driver_madwifi_get_scan_results(void *priv
)
1811 struct wpa_driver_madwifi_data
*drv
= priv
;
1812 return wpa_driver_wext_get_scan_results(drv
->wext
);
1816 static int wpa_driver_madwifi_set_operstate(void *priv
, int state
)
1818 struct wpa_driver_madwifi_data
*drv
= priv
;
1819 return wpa_driver_wext_set_operstate(drv
->wext
, state
);
1823 static int wpa_driver_madwifi_set_probe_req_ie(void *priv
, const u8
*ies
,
1826 struct ieee80211req_getset_appiebuf
*probe_req_ie
;
1829 probe_req_ie
= os_malloc(sizeof(*probe_req_ie
) + ies_len
);
1830 if (probe_req_ie
== NULL
)
1833 probe_req_ie
->app_frmtype
= IEEE80211_APPIE_FRAME_PROBE_REQ
;
1834 probe_req_ie
->app_buflen
= ies_len
;
1835 os_memcpy(probe_req_ie
->app_buf
, ies
, ies_len
);
1837 ret
= set80211priv(priv
, IEEE80211_IOCTL_SET_APPIEBUF
, probe_req_ie
,
1838 sizeof(struct ieee80211req_getset_appiebuf
) +
1841 os_free(probe_req_ie
);
1847 static void * wpa_driver_madwifi_init(void *ctx
, const char *ifname
)
1849 struct wpa_driver_madwifi_data
*drv
;
1851 drv
= os_zalloc(sizeof(*drv
));
1854 drv
->wext
= wpa_driver_wext_init(ctx
, ifname
);
1855 if (drv
->wext
== NULL
)
1859 os_strlcpy(drv
->ifname
, ifname
, sizeof(drv
->ifname
));
1860 drv
->sock
= socket(PF_INET
, SOCK_DGRAM
, 0);
1864 if (set80211param(drv
, IEEE80211_PARAM_ROAMING
, 2, 1) < 0) {
1865 wpa_printf(MSG_DEBUG
, "%s: failed to set wpa_supplicant-based "
1866 "roaming", __FUNCTION__
);
1870 if (set80211param(drv
, IEEE80211_PARAM_WPA
, 3, 1) < 0) {
1871 wpa_printf(MSG_DEBUG
, "%s: failed to enable WPA support",
1881 wpa_driver_wext_deinit(drv
->wext
);
1888 static void wpa_driver_madwifi_deinit(void *priv
)
1890 struct wpa_driver_madwifi_data
*drv
= priv
;
1892 if (wpa_driver_madwifi_set_wpa_ie(drv
, NULL
, 0) < 0) {
1893 wpa_printf(MSG_DEBUG
, "%s: failed to clear WPA IE",
1896 if (set80211param(drv
, IEEE80211_PARAM_ROAMING
, 0, 1) < 0) {
1897 wpa_printf(MSG_DEBUG
, "%s: failed to enable driver-based "
1898 "roaming", __FUNCTION__
);
1900 if (set80211param(drv
, IEEE80211_PARAM_PRIVACY
, 0, 1) < 0) {
1901 wpa_printf(MSG_DEBUG
, "%s: failed to disable forced Privacy "
1902 "flag", __FUNCTION__
);
1904 if (set80211param(drv
, IEEE80211_PARAM_WPA
, 0, 1) < 0) {
1905 wpa_printf(MSG_DEBUG
, "%s: failed to disable WPA",
1909 wpa_driver_wext_deinit(drv
->wext
);
1915 #endif /* HOSTAPD */
1918 const struct wpa_driver_ops wpa_driver_madwifi_ops
= {
1920 .desc
= "MADWIFI 802.11 support (Atheros, etc.)",
1922 .hapd_init
= madwifi_init
,
1923 .hapd_deinit
= madwifi_deinit
,
1924 .set_ieee8021x
= madwifi_set_ieee8021x
,
1925 .set_privacy
= madwifi_set_privacy
,
1926 .hapd_set_key
= madwifi_set_key
,
1927 .get_seqnum
= madwifi_get_seqnum
,
1928 .flush
= madwifi_flush
,
1929 .set_generic_elem
= madwifi_set_opt_ie
,
1930 .sta_set_flags
= madwifi_sta_set_flags
,
1931 .read_sta_data
= madwifi_read_sta_driver_data
,
1932 .hapd_send_eapol
= madwifi_send_eapol
,
1933 .sta_disassoc
= madwifi_sta_disassoc
,
1934 .sta_deauth
= madwifi_sta_deauth
,
1935 .hapd_set_ssid
= madwifi_set_ssid
,
1936 .hapd_get_ssid
= madwifi_get_ssid
,
1937 .hapd_set_countermeasures
= madwifi_set_countermeasures
,
1938 .sta_clear_stats
= madwifi_sta_clear_stats
,
1939 .commit
= madwifi_commit
,
1940 .set_wps_beacon_ie
= madwifi_set_wps_beacon_ie
,
1941 .set_wps_probe_resp_ie
= madwifi_set_wps_probe_resp_ie
,
1943 .get_bssid
= wpa_driver_madwifi_get_bssid
,
1944 .get_ssid
= wpa_driver_madwifi_get_ssid
,
1945 .set_key
= wpa_driver_madwifi_set_key
,
1946 .init
= wpa_driver_madwifi_init
,
1947 .deinit
= wpa_driver_madwifi_deinit
,
1948 .set_countermeasures
= wpa_driver_madwifi_set_countermeasures
,
1949 .set_drop_unencrypted
= wpa_driver_madwifi_set_drop_unencrypted
,
1950 .scan
= wpa_driver_madwifi_scan
,
1951 .get_scan_results2
= wpa_driver_madwifi_get_scan_results
,
1952 .deauthenticate
= wpa_driver_madwifi_deauthenticate
,
1953 .disassociate
= wpa_driver_madwifi_disassociate
,
1954 .associate
= wpa_driver_madwifi_associate
,
1955 .set_auth_alg
= wpa_driver_madwifi_set_auth_alg
,
1956 .set_operstate
= wpa_driver_madwifi_set_operstate
,
1957 .set_probe_req_ie
= wpa_driver_madwifi_set_probe_req_ie
,
1958 #endif /* HOSTAPD */