2 * hostapd / Driver interaction with Atheros driver
3 * Copyright (c) 2004, Sam Leffler <sam@errno.com>
4 * Copyright (c) 2004, Video54 Technologies
5 * Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi>
6 * Copyright (c) 2009, Atheros Communications
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
12 * Alternatively, this software may be distributed under the terms of BSD
15 * See README and COPYING for more details.
20 #include <sys/ioctl.h>
24 #ifdef WORDS_BIGENDIAN
25 #define _BYTE_ORDER _BIG_ENDIAN
27 #define _BYTE_ORDER _LITTLE_ENDIAN
29 #endif /* _BYTE_ORDER */
31 #include <net80211/ieee80211.h>
32 #include <net80211/_ieee80211.h>
33 #include <net80211/ieee80211_crypto.h>
36 * Note, the ATH_WPS_IE setting must match with the driver build.. If the
37 * driver does not include this, the IEEE80211_IOCTL_GETWPAIE ioctl will fail.
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.
59 #include "wireless_copy.h"
63 #include "priv_netlink.h"
64 #include "l2_packet/l2_packet.h"
65 #include "common/ieee802_11_defs.h"
69 struct madwifi_driver_data
{
70 struct hostapd_data
*hapd
; /* back pointer */
72 char iface
[IFNAMSIZ
+ 1];
74 struct l2_packet_data
*sock_xmit
; /* raw packet xmit socket */
75 struct l2_packet_data
*sock_recv
; /* raw packet recv socket */
76 int ioctl_sock
; /* socket for ioctl() use */
77 struct netlink_data
*netlink
;
79 u8 acct_mac
[ETH_ALEN
];
80 struct hostap_sta_driver_data acct_data
;
82 struct l2_packet_data
*sock_raw
; /* raw 802.11 management frames */
85 static int madwifi_sta_deauth(void *priv
, const u8
*own_addr
, const u8
*addr
,
89 set80211priv(struct madwifi_driver_data
*drv
, int op
, void *data
, int len
)
92 int do_inline
= len
< IFNAMSIZ
;
94 /* Certain ioctls must use the non-inlined method */
95 if (op
== IEEE80211_IOCTL_SET_APPIEBUF
||
96 op
== IEEE80211_IOCTL_FILTERFRAME
)
99 memset(&iwr
, 0, sizeof(iwr
));
100 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
103 * Argument data fits inline; put it there.
105 memcpy(iwr
.u
.name
, data
, len
);
108 * Argument data too big for inline transfer; setup a
109 * parameter block instead; the kernel will transfer
110 * the data for the driver.
112 iwr
.u
.data
.pointer
= data
;
113 iwr
.u
.data
.length
= len
;
116 if (ioctl(drv
->ioctl_sock
, op
, &iwr
) < 0) {
117 int first
= IEEE80211_IOCTL_SETPARAM
;
118 static const char *opnames
[] = {
119 "ioctl[IEEE80211_IOCTL_SETPARAM]",
120 "ioctl[IEEE80211_IOCTL_GETPARAM]",
121 "ioctl[IEEE80211_IOCTL_SETKEY]",
122 "ioctl[IEEE80211_IOCTL_SETWMMPARAMS]",
123 "ioctl[IEEE80211_IOCTL_DELKEY]",
124 "ioctl[IEEE80211_IOCTL_GETWMMPARAMS]",
125 "ioctl[IEEE80211_IOCTL_SETMLME]",
126 "ioctl[IEEE80211_IOCTL_GETCHANINFO]",
127 "ioctl[IEEE80211_IOCTL_SETOPTIE]",
128 "ioctl[IEEE80211_IOCTL_GETOPTIE]",
129 "ioctl[IEEE80211_IOCTL_ADDMAC]",
130 "ioctl[IEEE80211_IOCTL_DELMAC]",
131 "ioctl[IEEE80211_IOCTL_GETCHANLIST]",
132 "ioctl[IEEE80211_IOCTL_SETCHANLIST]",
133 "ioctl[IEEE80211_IOCTL_KICKMAC]",
134 "ioctl[IEEE80211_IOCTL_CHANSWITCH]",
135 "ioctl[IEEE80211_IOCTL_GETMODE]",
136 "ioctl[IEEE80211_IOCTL_SETMODE]",
137 "ioctl[IEEE80211_IOCTL_GET_APPIEBUF]",
138 "ioctl[IEEE80211_IOCTL_SET_APPIEBUF]",
140 "ioctl[IEEE80211_IOCTL_FILTERFRAME]",
142 int idx
= op
- first
;
144 idx
< (int) (sizeof(opnames
) / sizeof(opnames
[0])) &&
146 perror(opnames
[idx
]);
148 perror("ioctl[unknown???]");
149 wpa_printf(MSG_DEBUG
, "Failed ioctl: 0x%x", op
);
157 set80211param(struct madwifi_driver_data
*drv
, int op
, int arg
)
161 memset(&iwr
, 0, sizeof(iwr
));
162 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
164 memcpy(iwr
.u
.name
+sizeof(__u32
), &arg
, sizeof(arg
));
166 if (ioctl(drv
->ioctl_sock
, IEEE80211_IOCTL_SETPARAM
, &iwr
) < 0) {
167 perror("ioctl[IEEE80211_IOCTL_SETPARAM]");
168 wpa_printf(MSG_DEBUG
, "%s: Failed to set parameter (op %d "
169 "arg %d)", __func__
, op
, arg
);
175 #ifndef CONFIG_NO_STDOUT_DEBUG
177 ether_sprintf(const u8
*addr
)
179 static char buf
[sizeof(MACSTR
)];
182 snprintf(buf
, sizeof(buf
), MACSTR
, MAC2STR(addr
));
184 snprintf(buf
, sizeof(buf
), MACSTR
, 0,0,0,0,0,0);
187 #endif /* CONFIG_NO_STDOUT_DEBUG */
190 * Configure WPA parameters.
193 madwifi_configure_wpa(struct madwifi_driver_data
*drv
,
194 struct wpa_bss_params
*params
)
198 switch (params
->wpa_group
) {
199 case WPA_CIPHER_CCMP
:
200 v
= IEEE80211_CIPHER_AES_CCM
;
202 case WPA_CIPHER_TKIP
:
203 v
= IEEE80211_CIPHER_TKIP
;
205 case WPA_CIPHER_WEP104
:
206 v
= IEEE80211_CIPHER_WEP
;
208 case WPA_CIPHER_WEP40
:
209 v
= IEEE80211_CIPHER_WEP
;
211 case WPA_CIPHER_NONE
:
212 v
= IEEE80211_CIPHER_NONE
;
215 wpa_printf(MSG_ERROR
, "Unknown group key cipher %u",
219 wpa_printf(MSG_DEBUG
, "%s: group key cipher=%d", __func__
, v
);
220 if (set80211param(drv
, IEEE80211_PARAM_MCASTCIPHER
, v
)) {
221 printf("Unable to set group key cipher to %u\n", v
);
224 if (v
== IEEE80211_CIPHER_WEP
) {
225 /* key length is done only for specific ciphers */
226 v
= (params
->wpa_group
== WPA_CIPHER_WEP104
? 13 : 5);
227 if (set80211param(drv
, IEEE80211_PARAM_MCASTKEYLEN
, v
)) {
228 printf("Unable to set group key length to %u\n", v
);
234 if (params
->wpa_pairwise
& WPA_CIPHER_CCMP
)
235 v
|= 1<<IEEE80211_CIPHER_AES_CCM
;
236 if (params
->wpa_pairwise
& WPA_CIPHER_TKIP
)
237 v
|= 1<<IEEE80211_CIPHER_TKIP
;
238 if (params
->wpa_pairwise
& WPA_CIPHER_NONE
)
239 v
|= 1<<IEEE80211_CIPHER_NONE
;
240 wpa_printf(MSG_DEBUG
, "%s: pairwise key ciphers=0x%x", __func__
, v
);
241 if (set80211param(drv
, IEEE80211_PARAM_UCASTCIPHERS
, v
)) {
242 printf("Unable to set pairwise key ciphers to 0x%x\n", v
);
246 wpa_printf(MSG_DEBUG
, "%s: key management algorithms=0x%x",
247 __func__
, params
->wpa_key_mgmt
);
248 if (set80211param(drv
, IEEE80211_PARAM_KEYMGTALGS
,
249 params
->wpa_key_mgmt
)) {
250 printf("Unable to set key management algorithms to 0x%x\n",
251 params
->wpa_key_mgmt
);
256 if (params
->rsn_preauth
)
258 wpa_printf(MSG_DEBUG
, "%s: rsn capabilities=0x%x",
259 __func__
, params
->rsn_preauth
);
260 if (set80211param(drv
, IEEE80211_PARAM_RSNCAPS
, v
)) {
261 printf("Unable to set RSN capabilities to 0x%x\n", v
);
265 wpa_printf(MSG_DEBUG
, "%s: enable WPA=0x%x", __func__
, params
->wpa
);
266 if (set80211param(drv
, IEEE80211_PARAM_WPA
, params
->wpa
)) {
267 printf("Unable to set WPA to %u\n", params
->wpa
);
275 madwifi_set_iface_flags(void *priv
, int dev_up
)
277 struct madwifi_driver_data
*drv
= priv
;
280 wpa_printf(MSG_DEBUG
, "%s: dev_up=%d", __func__
, dev_up
);
282 if (drv
->ioctl_sock
< 0)
285 memset(&ifr
, 0, sizeof(ifr
));
286 os_strlcpy(ifr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
288 if (ioctl(drv
->ioctl_sock
, SIOCGIFFLAGS
, &ifr
) != 0) {
289 perror("ioctl[SIOCGIFFLAGS]");
294 ifr
.ifr_flags
|= IFF_UP
;
296 ifr
.ifr_flags
&= ~IFF_UP
;
298 if (ioctl(drv
->ioctl_sock
, SIOCSIFFLAGS
, &ifr
) != 0) {
299 perror("ioctl[SIOCSIFFLAGS]");
307 madwifi_set_ieee8021x(void *priv
, struct wpa_bss_params
*params
)
309 struct madwifi_driver_data
*drv
= priv
;
311 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __func__
, params
->enabled
);
313 if (!params
->enabled
) {
314 /* XXX restore state */
315 return set80211param(priv
, IEEE80211_PARAM_AUTHMODE
,
316 IEEE80211_AUTH_AUTO
);
318 if (!params
->wpa
&& !params
->ieee802_1x
) {
319 hostapd_logger(drv
->hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
320 HOSTAPD_LEVEL_WARNING
, "No 802.1X or WPA enabled!");
323 if (params
->wpa
&& madwifi_configure_wpa(drv
, params
) != 0) {
324 hostapd_logger(drv
->hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
325 HOSTAPD_LEVEL_WARNING
, "Error configuring WPA state!");
328 if (set80211param(priv
, IEEE80211_PARAM_AUTHMODE
,
329 (params
->wpa
? IEEE80211_AUTH_WPA
: IEEE80211_AUTH_8021X
))) {
330 hostapd_logger(drv
->hapd
, NULL
, HOSTAPD_MODULE_DRIVER
,
331 HOSTAPD_LEVEL_WARNING
, "Error enabling WPA/802.1X!");
339 madwifi_set_privacy(const char *ifname
, void *priv
, int enabled
)
341 struct madwifi_driver_data
*drv
= priv
;
343 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __func__
, enabled
);
345 return set80211param(drv
, IEEE80211_PARAM_PRIVACY
, enabled
);
349 madwifi_set_sta_authorized(void *priv
, const u8
*addr
, int authorized
)
351 struct madwifi_driver_data
*drv
= priv
;
352 struct ieee80211req_mlme mlme
;
355 wpa_printf(MSG_DEBUG
, "%s: addr=%s authorized=%d",
356 __func__
, ether_sprintf(addr
), authorized
);
359 mlme
.im_op
= IEEE80211_MLME_AUTHORIZE
;
361 mlme
.im_op
= IEEE80211_MLME_UNAUTHORIZE
;
363 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
364 ret
= set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
, sizeof(mlme
));
366 wpa_printf(MSG_DEBUG
, "%s: Failed to %sauthorize STA " MACSTR
,
367 __func__
, authorized
? "" : "un", MAC2STR(addr
));
374 madwifi_sta_set_flags(void *priv
, const u8
*addr
, int total_flags
,
375 int flags_or
, int flags_and
)
377 /* For now, only support setting Authorized flag */
378 if (flags_or
& WPA_STA_AUTHORIZED
)
379 return madwifi_set_sta_authorized(priv
, addr
, 1);
380 if (!(flags_and
& WPA_STA_AUTHORIZED
))
381 return madwifi_set_sta_authorized(priv
, addr
, 0);
386 madwifi_del_key(void *priv
, const u8
*addr
, int key_idx
)
388 struct madwifi_driver_data
*drv
= priv
;
389 struct ieee80211req_del_key wk
;
392 wpa_printf(MSG_DEBUG
, "%s: addr=%s key_idx=%d",
393 __func__
, ether_sprintf(addr
), key_idx
);
395 memset(&wk
, 0, sizeof(wk
));
397 memcpy(wk
.idk_macaddr
, addr
, IEEE80211_ADDR_LEN
);
398 wk
.idk_keyix
= (u8
) IEEE80211_KEYIX_NONE
;
400 wk
.idk_keyix
= key_idx
;
403 ret
= set80211priv(drv
, IEEE80211_IOCTL_DELKEY
, &wk
, sizeof(wk
));
405 wpa_printf(MSG_DEBUG
, "%s: Failed to delete key (addr %s"
406 " key_idx %d)", __func__
, ether_sprintf(addr
),
414 madwifi_set_key(const char *ifname
, void *priv
, enum wpa_alg alg
,
415 const u8
*addr
, int key_idx
, int set_tx
, const u8
*seq
,
416 size_t seq_len
, const u8
*key
, size_t key_len
)
418 struct madwifi_driver_data
*drv
= priv
;
419 struct ieee80211req_key wk
;
423 if (alg
== WPA_ALG_NONE
)
424 return madwifi_del_key(drv
, addr
, key_idx
);
426 wpa_printf(MSG_DEBUG
, "%s: alg=%d addr=%s key_idx=%d",
427 __func__
, alg
, ether_sprintf(addr
), key_idx
);
431 cipher
= IEEE80211_CIPHER_WEP
;
434 cipher
= IEEE80211_CIPHER_TKIP
;
437 cipher
= IEEE80211_CIPHER_AES_CCM
;
440 printf("%s: unknown/unsupported algorithm %d\n",
445 if (key_len
> sizeof(wk
.ik_keydata
)) {
446 printf("%s: key length %lu too big\n", __func__
,
447 (unsigned long) key_len
);
451 memset(&wk
, 0, sizeof(wk
));
453 wk
.ik_flags
= IEEE80211_KEY_RECV
| IEEE80211_KEY_XMIT
;
455 memset(wk
.ik_macaddr
, 0xff, IEEE80211_ADDR_LEN
);
456 wk
.ik_keyix
= key_idx
;
457 wk
.ik_flags
|= IEEE80211_KEY_DEFAULT
;
459 memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
460 wk
.ik_keyix
= IEEE80211_KEYIX_NONE
;
462 wk
.ik_keylen
= key_len
;
463 memcpy(wk
.ik_keydata
, key
, key_len
);
465 ret
= set80211priv(drv
, IEEE80211_IOCTL_SETKEY
, &wk
, sizeof(wk
));
467 wpa_printf(MSG_DEBUG
, "%s: Failed to set key (addr %s"
468 " key_idx %d alg %d key_len %lu set_tx %d)",
469 __func__
, ether_sprintf(wk
.ik_macaddr
), key_idx
,
470 alg
, (unsigned long) key_len
, set_tx
);
478 madwifi_get_seqnum(const char *ifname
, void *priv
, const u8
*addr
, int idx
,
481 struct madwifi_driver_data
*drv
= priv
;
482 struct ieee80211req_key wk
;
484 wpa_printf(MSG_DEBUG
, "%s: addr=%s idx=%d",
485 __func__
, ether_sprintf(addr
), idx
);
487 memset(&wk
, 0, sizeof(wk
));
489 memset(wk
.ik_macaddr
, 0xff, IEEE80211_ADDR_LEN
);
491 memcpy(wk
.ik_macaddr
, addr
, IEEE80211_ADDR_LEN
);
494 if (set80211priv(drv
, IEEE80211_IOCTL_GETKEY
, &wk
, sizeof(wk
))) {
495 wpa_printf(MSG_DEBUG
, "%s: Failed to get encryption data "
496 "(addr " MACSTR
" key_idx %d)",
497 __func__
, MAC2STR(wk
.ik_macaddr
), idx
);
501 #ifdef WORDS_BIGENDIAN
504 * wk.ik_keytsc is in host byte order (big endian), need to
505 * swap it to match with the byte order used in WPA.
508 u8 tmp
[WPA_KEY_RSC_LEN
];
509 memcpy(tmp
, &wk
.ik_keytsc
, sizeof(wk
.ik_keytsc
));
510 for (i
= 0; i
< WPA_KEY_RSC_LEN
; i
++) {
511 seq
[i
] = tmp
[WPA_KEY_RSC_LEN
- i
- 1];
514 #else /* WORDS_BIGENDIAN */
515 memcpy(seq
, &wk
.ik_keytsc
, sizeof(wk
.ik_keytsc
));
516 #endif /* WORDS_BIGENDIAN */
522 madwifi_flush(void *priv
)
524 u8 allsta
[IEEE80211_ADDR_LEN
];
525 memset(allsta
, 0xff, IEEE80211_ADDR_LEN
);
526 return madwifi_sta_deauth(priv
, NULL
, allsta
,
527 IEEE80211_REASON_AUTH_LEAVE
);
532 madwifi_read_sta_driver_data(void *priv
, struct hostap_sta_driver_data
*data
,
535 struct madwifi_driver_data
*drv
= priv
;
536 struct ieee80211req_sta_stats stats
;
538 memset(data
, 0, sizeof(*data
));
541 * Fetch statistics for station from the system.
543 memset(&stats
, 0, sizeof(stats
));
544 memcpy(stats
.is_u
.macaddr
, addr
, IEEE80211_ADDR_LEN
);
545 if (set80211priv(drv
, IEEE80211_IOCTL_STA_STATS
,
546 &stats
, sizeof(stats
))) {
547 wpa_printf(MSG_DEBUG
, "%s: Failed to fetch STA stats (addr "
548 MACSTR
")", __func__
, MAC2STR(addr
));
549 if (memcmp(addr
, drv
->acct_mac
, ETH_ALEN
) == 0) {
550 memcpy(data
, &drv
->acct_data
, sizeof(*data
));
554 printf("Failed to get station stats information element.\n");
558 data
->rx_packets
= stats
.is_stats
.ns_rx_data
;
559 data
->rx_bytes
= stats
.is_stats
.ns_rx_bytes
;
560 data
->tx_packets
= stats
.is_stats
.ns_tx_data
;
561 data
->tx_bytes
= stats
.is_stats
.ns_tx_bytes
;
567 madwifi_sta_clear_stats(void *priv
, const u8
*addr
)
569 struct madwifi_driver_data
*drv
= priv
;
570 struct ieee80211req_mlme mlme
;
573 wpa_printf(MSG_DEBUG
, "%s: addr=%s", __func__
, ether_sprintf(addr
));
575 mlme
.im_op
= IEEE80211_MLME_CLEAR_STATS
;
576 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
577 ret
= set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
,
580 wpa_printf(MSG_DEBUG
, "%s: Failed to clear STA stats (addr "
581 MACSTR
")", __func__
, MAC2STR(addr
));
589 madwifi_set_opt_ie(const char *ifname
, void *priv
, const u8
*ie
, size_t ie_len
)
592 * Do nothing; we setup parameters at startup that define the
593 * contents of the beacon information element.
599 madwifi_sta_deauth(void *priv
, const u8
*own_addr
, const u8
*addr
,
602 struct madwifi_driver_data
*drv
= priv
;
603 struct ieee80211req_mlme mlme
;
606 wpa_printf(MSG_DEBUG
, "%s: addr=%s reason_code=%d",
607 __func__
, ether_sprintf(addr
), reason_code
);
609 mlme
.im_op
= IEEE80211_MLME_DEAUTH
;
610 mlme
.im_reason
= reason_code
;
611 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
612 ret
= set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
, sizeof(mlme
));
614 wpa_printf(MSG_DEBUG
, "%s: Failed to deauth STA (addr " MACSTR
616 __func__
, MAC2STR(addr
), reason_code
);
623 madwifi_sta_disassoc(void *priv
, const u8
*own_addr
, const u8
*addr
,
626 struct madwifi_driver_data
*drv
= priv
;
627 struct ieee80211req_mlme mlme
;
630 wpa_printf(MSG_DEBUG
, "%s: addr=%s reason_code=%d",
631 __func__
, ether_sprintf(addr
), reason_code
);
633 mlme
.im_op
= IEEE80211_MLME_DISASSOC
;
634 mlme
.im_reason
= reason_code
;
635 memcpy(mlme
.im_macaddr
, addr
, IEEE80211_ADDR_LEN
);
636 ret
= set80211priv(drv
, IEEE80211_IOCTL_SETMLME
, &mlme
, sizeof(mlme
));
638 wpa_printf(MSG_DEBUG
, "%s: Failed to disassoc STA (addr "
639 MACSTR
" reason %d)",
640 __func__
, MAC2STR(addr
), reason_code
);
647 static void madwifi_raw_receive(void *ctx
, const u8
*src_addr
, const u8
*buf
,
650 struct madwifi_driver_data
*drv
= ctx
;
651 const struct ieee80211_mgmt
*mgmt
;
656 /* Send Probe Request information to WPS processing */
658 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.probe_req
))
660 mgmt
= (const struct ieee80211_mgmt
*) buf
;
662 fc
= le_to_host16(mgmt
->frame_control
);
663 if (WLAN_FC_GET_TYPE(fc
) != WLAN_FC_TYPE_MGMT
||
664 WLAN_FC_GET_STYPE(fc
) != WLAN_FC_STYPE_PROBE_REQ
)
668 ie
= mgmt
->u
.probe_req
.variable
;
669 ie_len
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.probe_req
));
671 hostapd_probe_req_rx(drv
->hapd
, mgmt
->sa
, ie
, ie_len
);
673 #endif /* CONFIG_WPS */
675 static int madwifi_receive_probe_req(struct madwifi_driver_data
*drv
)
679 struct ieee80211req_set_filter filt
;
681 wpa_printf(MSG_DEBUG
, "%s Enter", __func__
);
682 filt
.app_filterype
= IEEE80211_FILTER_TYPE_PROBE_REQ
;
684 ret
= set80211priv(drv
, IEEE80211_IOCTL_FILTERFRAME
, &filt
,
685 sizeof(struct ieee80211req_set_filter
));
689 drv
->sock_raw
= l2_packet_init(drv
->iface
, NULL
, ETH_P_80211_RAW
,
690 madwifi_raw_receive
, drv
, 1);
691 if (drv
->sock_raw
== NULL
)
693 #endif /* CONFIG_WPS */
699 madwifi_set_wps_ie(void *priv
, const u8
*ie
, size_t len
, u32 frametype
)
701 struct madwifi_driver_data
*drv
= priv
;
703 struct ieee80211req_getset_appiebuf
*beac_ie
;
705 wpa_printf(MSG_DEBUG
, "%s buflen = %lu", __func__
,
706 (unsigned long) len
);
708 beac_ie
= (struct ieee80211req_getset_appiebuf
*) buf
;
709 beac_ie
->app_frmtype
= frametype
;
710 beac_ie
->app_buflen
= len
;
711 memcpy(&(beac_ie
->app_buf
[0]), ie
, len
);
713 return set80211priv(drv
, IEEE80211_IOCTL_SET_APPIEBUF
, beac_ie
,
714 sizeof(struct ieee80211req_getset_appiebuf
) + len
);
718 madwifi_set_ap_wps_ie(const char *ifname
, void *priv
,
719 const struct wpabuf
*beacon
,
720 const struct wpabuf
*proberesp
)
722 if (madwifi_set_wps_ie(priv
, beacon
? wpabuf_head(beacon
) : NULL
,
723 beacon
? wpabuf_len(beacon
) : 0,
724 IEEE80211_APPIE_FRAME_BEACON
))
726 return madwifi_set_wps_ie(priv
,
727 proberesp
? wpabuf_head(proberesp
) : NULL
,
728 proberesp
? wpabuf_len(proberesp
): 0,
729 IEEE80211_APPIE_FRAME_PROBE_RESP
);
731 #else /* CONFIG_WPS */
732 #define madwifi_set_ap_wps_ie NULL
733 #endif /* CONFIG_WPS */
736 madwifi_new_sta(struct madwifi_driver_data
*drv
, u8 addr
[IEEE80211_ADDR_LEN
])
738 struct hostapd_data
*hapd
= drv
->hapd
;
739 struct ieee80211req_wpaie ie
;
744 * Fetch negotiated WPA/RSN parameters from the system.
746 memset(&ie
, 0, sizeof(ie
));
747 memcpy(ie
.wpa_macaddr
, addr
, IEEE80211_ADDR_LEN
);
748 if (set80211priv(drv
, IEEE80211_IOCTL_GETWPAIE
, &ie
, sizeof(ie
))) {
750 * See ATH_WPS_IE comment in the beginning of the file for a
751 * possible cause for the failure..
753 wpa_printf(MSG_DEBUG
, "%s: Failed to get WPA/RSN IE: %s",
754 __func__
, strerror(errno
));
757 wpa_hexdump(MSG_MSGDUMP
, "madwifi req WPA IE",
758 ie
.wpa_ie
, IEEE80211_MAX_OPT_IE
);
759 wpa_hexdump(MSG_MSGDUMP
, "madwifi req RSN IE",
760 ie
.rsn_ie
, IEEE80211_MAX_OPT_IE
);
762 /* madwifi seems to return some random data if WPA/RSN IE is not set.
763 * Assume the IE was not included if the IE type is unknown. */
764 if (iebuf
[0] != WLAN_EID_VENDOR_SPECIFIC
)
766 if (iebuf
[1] == 0 && ie
.rsn_ie
[1] > 0) {
767 /* madwifi-ng svn #1453 added rsn_ie. Use it, if wpa_ie was not
768 * set. This is needed for WPA2. */
770 if (iebuf
[0] != WLAN_EID_RSN
)
781 res
= hostapd_notif_assoc(hapd
, addr
, iebuf
, ielen
);
783 if (memcmp(addr
, drv
->acct_mac
, ETH_ALEN
) == 0) {
784 /* Cached accounting data is not valid anymore. */
785 memset(drv
->acct_mac
, 0, ETH_ALEN
);
786 memset(&drv
->acct_data
, 0, sizeof(drv
->acct_data
));
793 madwifi_wireless_event_wireless_custom(struct madwifi_driver_data
*drv
,
794 char *custom
, char *end
)
796 wpa_printf(MSG_DEBUG
, "Custom wireless event: '%s'", custom
);
798 if (strncmp(custom
, "MLME-MICHAELMICFAILURE.indication", 33) == 0) {
801 pos
= strstr(custom
, "addr=");
803 wpa_printf(MSG_DEBUG
,
804 "MLME-MICHAELMICFAILURE.indication "
805 "without sender address ignored");
809 if (hwaddr_aton(pos
, addr
) == 0) {
810 union wpa_event_data data
;
811 os_memset(&data
, 0, sizeof(data
));
812 data
.michael_mic_failure
.unicast
= 1;
813 data
.michael_mic_failure
.src
= addr
;
814 wpa_supplicant_event(drv
->hapd
,
815 EVENT_MICHAEL_MIC_FAILURE
, &data
);
817 wpa_printf(MSG_DEBUG
,
818 "MLME-MICHAELMICFAILURE.indication "
819 "with invalid MAC address");
821 } else if (strncmp(custom
, "STA-TRAFFIC-STAT", 16) == 0) {
825 while ((key
= strchr(key
, '\n')) != NULL
) {
827 value
= strchr(key
, '=');
831 val
= strtoul(value
, NULL
, 10);
832 if (strcmp(key
, "mac") == 0)
833 hwaddr_aton(value
, drv
->acct_mac
);
834 else if (strcmp(key
, "rx_packets") == 0)
835 drv
->acct_data
.rx_packets
= val
;
836 else if (strcmp(key
, "tx_packets") == 0)
837 drv
->acct_data
.tx_packets
= val
;
838 else if (strcmp(key
, "rx_bytes") == 0)
839 drv
->acct_data
.rx_bytes
= val
;
840 else if (strcmp(key
, "tx_bytes") == 0)
841 drv
->acct_data
.tx_bytes
= val
;
845 } else if (strncmp(custom
, "PUSH-BUTTON.indication", 22) == 0) {
846 /* Some atheros kernels send push button as a wireless event */
847 /* PROBLEM! this event is received for ALL BSSs ...
848 * so all are enabled for WPS... ugh.
850 wpa_supplicant_event(drv
->hapd
, EVENT_WPS_BUTTON_PUSHED
, NULL
);
851 } else if (strncmp(custom
, "Manage.prob_req ", 16) == 0) {
853 * Atheros driver uses a hack to pass Probe Request frames as a
854 * binary data in the custom wireless event. The old way (using
855 * packet sniffing) didn't work when bridging.
856 * Format: "Manage.prob_req <frame len>" | zero padding | frame
858 #define WPS_FRAM_TAG_SIZE 30 /* hardcoded in driver */
859 int len
= atoi(custom
+ 16);
860 if (len
< 0 || custom
+ WPS_FRAM_TAG_SIZE
+ len
> end
) {
861 wpa_printf(MSG_DEBUG
, "Invalid Manage.prob_req event "
865 madwifi_raw_receive(drv
, NULL
,
866 (u8
*) custom
+ WPS_FRAM_TAG_SIZE
, len
);
867 #endif /* CONFIG_WPS */
872 madwifi_wireless_event_wireless(struct madwifi_driver_data
*drv
,
875 struct iw_event iwe_buf
, *iwe
= &iwe_buf
;
876 char *pos
, *end
, *custom
, *buf
;
881 while (pos
+ IW_EV_LCP_LEN
<= end
) {
882 /* Event data may be unaligned, so make a local, aligned copy
883 * before processing. */
884 memcpy(&iwe_buf
, pos
, IW_EV_LCP_LEN
);
885 wpa_printf(MSG_MSGDUMP
, "Wireless event: cmd=0x%x len=%d",
887 if (iwe
->len
<= IW_EV_LCP_LEN
)
890 custom
= pos
+ IW_EV_POINT_LEN
;
891 if (drv
->we_version
> 18 &&
892 (iwe
->cmd
== IWEVMICHAELMICFAILURE
||
893 iwe
->cmd
== IWEVASSOCREQIE
||
894 iwe
->cmd
== IWEVCUSTOM
)) {
895 /* WE-19 removed the pointer from struct iw_point */
896 char *dpos
= (char *) &iwe_buf
.u
.data
.length
;
897 int dlen
= dpos
- (char *) &iwe_buf
;
898 memcpy(dpos
, pos
+ IW_EV_LCP_LEN
,
899 sizeof(struct iw_event
) - dlen
);
901 memcpy(&iwe_buf
, pos
, sizeof(struct iw_event
));
902 custom
+= IW_EV_POINT_OFF
;
907 hostapd_notif_disassoc(drv
->hapd
,
908 (u8
*) iwe
->u
.addr
.sa_data
);
911 madwifi_new_sta(drv
, (u8
*) iwe
->u
.addr
.sa_data
);
914 /* Driver hack.. Use IWEVASSOCREQIE to bypass
915 * IWEVCUSTOM size limitations. Need to handle this
916 * just like IWEVCUSTOM.
919 if (custom
+ iwe
->u
.data
.length
> end
)
921 buf
= malloc(iwe
->u
.data
.length
+ 1);
924 memcpy(buf
, custom
, iwe
->u
.data
.length
);
925 buf
[iwe
->u
.data
.length
] = '\0';
926 madwifi_wireless_event_wireless_custom(
927 drv
, buf
, buf
+ iwe
->u
.data
.length
);
938 madwifi_wireless_event_rtm_newlink(void *ctx
,
939 struct ifinfomsg
*ifi
, u8
*buf
, size_t len
)
941 struct madwifi_driver_data
*drv
= ctx
;
942 int attrlen
, rta_len
;
945 if (ifi
->ifi_index
!= drv
->ifindex
)
949 attr
= (struct rtattr
*) buf
;
951 rta_len
= RTA_ALIGN(sizeof(struct rtattr
));
952 while (RTA_OK(attr
, attrlen
)) {
953 if (attr
->rta_type
== IFLA_WIRELESS
) {
954 madwifi_wireless_event_wireless(
955 drv
, ((char *) attr
) + rta_len
,
956 attr
->rta_len
- rta_len
);
958 attr
= RTA_NEXT(attr
, attrlen
);
964 madwifi_get_we_version(struct madwifi_driver_data
*drv
)
966 struct iw_range
*range
;
974 * Use larger buffer than struct iw_range in order to allow the
975 * structure to grow in the future.
977 buflen
= sizeof(struct iw_range
) + 500;
978 range
= os_zalloc(buflen
);
982 memset(&iwr
, 0, sizeof(iwr
));
983 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
984 iwr
.u
.data
.pointer
= (caddr_t
) range
;
985 iwr
.u
.data
.length
= buflen
;
987 minlen
= ((char *) &range
->enc_capa
) - (char *) range
+
988 sizeof(range
->enc_capa
);
990 if (ioctl(drv
->ioctl_sock
, SIOCGIWRANGE
, &iwr
) < 0) {
991 perror("ioctl[SIOCGIWRANGE]");
994 } else if (iwr
.u
.data
.length
>= minlen
&&
995 range
->we_version_compiled
>= 18) {
996 wpa_printf(MSG_DEBUG
, "SIOCGIWRANGE: WE(compiled)=%d "
997 "WE(source)=%d enc_capa=0x%x",
998 range
->we_version_compiled
,
999 range
->we_version_source
,
1001 drv
->we_version
= range
->we_version_compiled
;
1010 madwifi_wireless_event_init(struct madwifi_driver_data
*drv
)
1012 struct netlink_config
*cfg
;
1014 madwifi_get_we_version(drv
);
1016 cfg
= os_zalloc(sizeof(*cfg
));
1020 cfg
->newlink_cb
= madwifi_wireless_event_rtm_newlink
;
1021 drv
->netlink
= netlink_init(cfg
);
1022 if (drv
->netlink
== NULL
) {
1032 madwifi_send_eapol(void *priv
, const u8
*addr
, const u8
*data
, size_t data_len
,
1033 int encrypt
, const u8
*own_addr
)
1035 struct madwifi_driver_data
*drv
= priv
;
1036 unsigned char buf
[3000];
1037 unsigned char *bp
= buf
;
1038 struct l2_ethhdr
*eth
;
1043 * Prepend the Ethernet header. If the caller left us
1044 * space at the front we could just insert it but since
1045 * we don't know we copy to a local buffer. Given the frequency
1046 * and size of frames this probably doesn't matter.
1048 len
= data_len
+ sizeof(struct l2_ethhdr
);
1049 if (len
> sizeof(buf
)) {
1052 printf("EAPOL frame discarded, cannot malloc temp "
1053 "buffer of size %lu!\n", (unsigned long) len
);
1057 eth
= (struct l2_ethhdr
*) bp
;
1058 memcpy(eth
->h_dest
, addr
, ETH_ALEN
);
1059 memcpy(eth
->h_source
, own_addr
, ETH_ALEN
);
1060 eth
->h_proto
= host_to_be16(ETH_P_EAPOL
);
1061 memcpy(eth
+1, data
, data_len
);
1063 wpa_hexdump(MSG_MSGDUMP
, "TX EAPOL", bp
, len
);
1065 status
= l2_packet_send(drv
->sock_xmit
, addr
, ETH_P_EAPOL
, bp
, len
);
1073 handle_read(void *ctx
, const u8
*src_addr
, const u8
*buf
, size_t len
)
1075 struct madwifi_driver_data
*drv
= ctx
;
1076 hostapd_eapol_receive(drv
->hapd
, src_addr
,
1077 buf
+ sizeof(struct l2_ethhdr
),
1078 len
- sizeof(struct l2_ethhdr
));
1082 madwifi_init(struct hostapd_data
*hapd
, struct wpa_init_params
*params
)
1084 struct madwifi_driver_data
*drv
;
1088 drv
= os_zalloc(sizeof(struct madwifi_driver_data
));
1090 printf("Could not allocate memory for madwifi driver data\n");
1095 drv
->ioctl_sock
= socket(PF_INET
, SOCK_DGRAM
, 0);
1096 if (drv
->ioctl_sock
< 0) {
1097 perror("socket[PF_INET,SOCK_DGRAM]");
1100 memcpy(drv
->iface
, params
->ifname
, sizeof(drv
->iface
));
1102 memset(&ifr
, 0, sizeof(ifr
));
1103 os_strlcpy(ifr
.ifr_name
, drv
->iface
, sizeof(ifr
.ifr_name
));
1104 if (ioctl(drv
->ioctl_sock
, SIOCGIFINDEX
, &ifr
) != 0) {
1105 perror("ioctl(SIOCGIFINDEX)");
1108 drv
->ifindex
= ifr
.ifr_ifindex
;
1110 drv
->sock_xmit
= l2_packet_init(drv
->iface
, NULL
, ETH_P_EAPOL
,
1111 handle_read
, drv
, 1);
1112 if (drv
->sock_xmit
== NULL
)
1114 if (l2_packet_get_own_addr(drv
->sock_xmit
, params
->own_addr
))
1116 if (params
->bridge
[0]) {
1117 wpa_printf(MSG_DEBUG
, "Configure bridge %s for EAPOL traffic.",
1119 drv
->sock_recv
= l2_packet_init(params
->bridge
[0], NULL
,
1120 ETH_P_EAPOL
, handle_read
, drv
,
1122 if (drv
->sock_recv
== NULL
)
1125 drv
->sock_recv
= drv
->sock_xmit
;
1127 memset(&iwr
, 0, sizeof(iwr
));
1128 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
1130 iwr
.u
.mode
= IW_MODE_MASTER
;
1132 if (ioctl(drv
->ioctl_sock
, SIOCSIWMODE
, &iwr
) < 0) {
1133 perror("ioctl[SIOCSIWMODE]");
1134 printf("Could not set interface to master mode!\n");
1138 madwifi_set_iface_flags(drv
, 0); /* mark down during setup */
1139 madwifi_set_privacy(drv
->iface
, drv
, 0); /* default to no privacy */
1141 madwifi_receive_probe_req(drv
);
1143 if (madwifi_wireless_event_init(drv
))
1148 if (drv
->sock_xmit
!= NULL
)
1149 l2_packet_deinit(drv
->sock_xmit
);
1150 if (drv
->ioctl_sock
>= 0)
1151 close(drv
->ioctl_sock
);
1159 madwifi_deinit(void *priv
)
1161 struct madwifi_driver_data
*drv
= priv
;
1163 netlink_deinit(drv
->netlink
);
1164 (void) madwifi_set_iface_flags(drv
, 0);
1165 if (drv
->ioctl_sock
>= 0)
1166 close(drv
->ioctl_sock
);
1167 if (drv
->sock_recv
!= NULL
&& drv
->sock_recv
!= drv
->sock_xmit
)
1168 l2_packet_deinit(drv
->sock_recv
);
1169 if (drv
->sock_xmit
!= NULL
)
1170 l2_packet_deinit(drv
->sock_xmit
);
1172 l2_packet_deinit(drv
->sock_raw
);
1177 madwifi_set_ssid(const char *ifname
, void *priv
, const u8
*buf
, int len
)
1179 struct madwifi_driver_data
*drv
= priv
;
1182 memset(&iwr
, 0, sizeof(iwr
));
1183 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
1184 iwr
.u
.essid
.flags
= 1; /* SSID active */
1185 iwr
.u
.essid
.pointer
= (caddr_t
) buf
;
1186 iwr
.u
.essid
.length
= len
+ 1;
1188 if (ioctl(drv
->ioctl_sock
, SIOCSIWESSID
, &iwr
) < 0) {
1189 perror("ioctl[SIOCSIWESSID]");
1190 printf("len=%d\n", len
);
1197 madwifi_get_ssid(const char *ifname
, void *priv
, u8
*buf
, int len
)
1199 struct madwifi_driver_data
*drv
= priv
;
1203 memset(&iwr
, 0, sizeof(iwr
));
1204 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
1205 iwr
.u
.essid
.pointer
= (caddr_t
) buf
;
1206 iwr
.u
.essid
.length
= len
;
1208 if (ioctl(drv
->ioctl_sock
, SIOCGIWESSID
, &iwr
) < 0) {
1209 perror("ioctl[SIOCGIWESSID]");
1212 ret
= iwr
.u
.essid
.length
;
1218 madwifi_set_countermeasures(void *priv
, int enabled
)
1220 struct madwifi_driver_data
*drv
= priv
;
1221 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __FUNCTION__
, enabled
);
1222 return set80211param(drv
, IEEE80211_PARAM_COUNTERMEASURES
, enabled
);
1226 madwifi_commit(void *priv
)
1228 return madwifi_set_iface_flags(priv
, 1);
1231 const struct wpa_driver_ops wpa_driver_atheros_ops
= {
1233 .hapd_init
= madwifi_init
,
1234 .deinit
= madwifi_deinit
,
1235 .set_ieee8021x
= madwifi_set_ieee8021x
,
1236 .set_privacy
= madwifi_set_privacy
,
1237 .set_key
= madwifi_set_key
,
1238 .get_seqnum
= madwifi_get_seqnum
,
1239 .flush
= madwifi_flush
,
1240 .set_generic_elem
= madwifi_set_opt_ie
,
1241 .sta_set_flags
= madwifi_sta_set_flags
,
1242 .read_sta_data
= madwifi_read_sta_driver_data
,
1243 .hapd_send_eapol
= madwifi_send_eapol
,
1244 .sta_disassoc
= madwifi_sta_disassoc
,
1245 .sta_deauth
= madwifi_sta_deauth
,
1246 .hapd_set_ssid
= madwifi_set_ssid
,
1247 .hapd_get_ssid
= madwifi_get_ssid
,
1248 .set_countermeasures
= madwifi_set_countermeasures
,
1249 .sta_clear_stats
= madwifi_sta_clear_stats
,
1250 .commit
= madwifi_commit
,
1251 .set_ap_wps_ie
= madwifi_set_ap_wps_ie
,