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
, wpa_alg alg
, const u8
*addr
,
415 int key_idx
, int set_tx
, const u8
*seq
, size_t seq_len
,
416 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_wps_beacon_ie(const char *ifname
, void *priv
, const u8
*ie
,
721 return madwifi_set_wps_ie(priv
, ie
, len
, IEEE80211_APPIE_FRAME_BEACON
);
725 madwifi_set_wps_probe_resp_ie(const char *ifname
, void *priv
, const u8
*ie
,
728 return madwifi_set_wps_ie(priv
, ie
, len
,
729 IEEE80211_APPIE_FRAME_PROBE_RESP
);
731 #else /* CONFIG_WPS */
732 #define madwifi_set_wps_beacon_ie NULL
733 #define madwifi_set_wps_probe_resp_ie NULL
734 #endif /* CONFIG_WPS */
737 madwifi_new_sta(struct madwifi_driver_data
*drv
, u8 addr
[IEEE80211_ADDR_LEN
])
739 struct hostapd_data
*hapd
= drv
->hapd
;
740 struct ieee80211req_wpaie ie
;
745 * Fetch negotiated WPA/RSN parameters from the system.
747 memset(&ie
, 0, sizeof(ie
));
748 memcpy(ie
.wpa_macaddr
, addr
, IEEE80211_ADDR_LEN
);
749 if (set80211priv(drv
, IEEE80211_IOCTL_GETWPAIE
, &ie
, sizeof(ie
))) {
751 * See ATH_WPS_IE comment in the beginning of the file for a
752 * possible cause for the failure..
754 wpa_printf(MSG_DEBUG
, "%s: Failed to get WPA/RSN IE: %s",
755 __func__
, strerror(errno
));
758 wpa_hexdump(MSG_MSGDUMP
, "madwifi req WPA IE",
759 ie
.wpa_ie
, IEEE80211_MAX_OPT_IE
);
760 wpa_hexdump(MSG_MSGDUMP
, "madwifi req RSN IE",
761 ie
.rsn_ie
, IEEE80211_MAX_OPT_IE
);
763 /* madwifi seems to return some random data if WPA/RSN IE is not set.
764 * Assume the IE was not included if the IE type is unknown. */
765 if (iebuf
[0] != WLAN_EID_VENDOR_SPECIFIC
)
767 if (iebuf
[1] == 0 && ie
.rsn_ie
[1] > 0) {
768 /* madwifi-ng svn #1453 added rsn_ie. Use it, if wpa_ie was not
769 * set. This is needed for WPA2. */
771 if (iebuf
[0] != WLAN_EID_RSN
)
782 res
= hostapd_notif_assoc(hapd
, addr
, iebuf
, ielen
);
784 if (memcmp(addr
, drv
->acct_mac
, ETH_ALEN
) == 0) {
785 /* Cached accounting data is not valid anymore. */
786 memset(drv
->acct_mac
, 0, ETH_ALEN
);
787 memset(&drv
->acct_data
, 0, sizeof(drv
->acct_data
));
794 madwifi_wireless_event_wireless_custom(struct madwifi_driver_data
*drv
,
795 char *custom
, char *end
)
797 wpa_printf(MSG_DEBUG
, "Custom wireless event: '%s'", custom
);
799 if (strncmp(custom
, "MLME-MICHAELMICFAILURE.indication", 33) == 0) {
802 pos
= strstr(custom
, "addr=");
804 wpa_printf(MSG_DEBUG
,
805 "MLME-MICHAELMICFAILURE.indication "
806 "without sender address ignored");
810 if (hwaddr_aton(pos
, addr
) == 0) {
811 union wpa_event_data data
;
812 os_memset(&data
, 0, sizeof(data
));
813 data
.michael_mic_failure
.unicast
= 1;
814 data
.michael_mic_failure
.src
= addr
;
815 wpa_supplicant_event(drv
->hapd
,
816 EVENT_MICHAEL_MIC_FAILURE
, &data
);
818 wpa_printf(MSG_DEBUG
,
819 "MLME-MICHAELMICFAILURE.indication "
820 "with invalid MAC address");
822 } else if (strncmp(custom
, "STA-TRAFFIC-STAT", 16) == 0) {
826 while ((key
= strchr(key
, '\n')) != NULL
) {
828 value
= strchr(key
, '=');
832 val
= strtoul(value
, NULL
, 10);
833 if (strcmp(key
, "mac") == 0)
834 hwaddr_aton(value
, drv
->acct_mac
);
835 else if (strcmp(key
, "rx_packets") == 0)
836 drv
->acct_data
.rx_packets
= val
;
837 else if (strcmp(key
, "tx_packets") == 0)
838 drv
->acct_data
.tx_packets
= val
;
839 else if (strcmp(key
, "rx_bytes") == 0)
840 drv
->acct_data
.rx_bytes
= val
;
841 else if (strcmp(key
, "tx_bytes") == 0)
842 drv
->acct_data
.tx_bytes
= val
;
846 } else if (strncmp(custom
, "PUSH-BUTTON.indication", 22) == 0) {
847 /* Some atheros kernels send push button as a wireless event */
848 /* PROBLEM! this event is received for ALL BSSs ...
849 * so all are enabled for WPS... ugh.
851 wpa_supplicant_event(drv
->hapd
, EVENT_WPS_BUTTON_PUSHED
, NULL
);
852 } else if (strncmp(custom
, "Manage.prob_req ", 16) == 0) {
854 * Atheros driver uses a hack to pass Probe Request frames as a
855 * binary data in the custom wireless event. The old way (using
856 * packet sniffing) didn't work when bridging.
857 * Format: "Manage.prob_req <frame len>" | zero padding | frame
859 #define WPS_FRAM_TAG_SIZE 30 /* hardcoded in driver */
860 int len
= atoi(custom
+ 16);
861 if (len
< 0 || custom
+ WPS_FRAM_TAG_SIZE
+ len
> end
) {
862 wpa_printf(MSG_DEBUG
, "Invalid Manage.prob_req event "
866 madwifi_raw_receive(drv
, NULL
,
867 (u8
*) custom
+ WPS_FRAM_TAG_SIZE
, len
);
868 #endif /* CONFIG_WPS */
873 madwifi_wireless_event_wireless(struct madwifi_driver_data
*drv
,
876 struct iw_event iwe_buf
, *iwe
= &iwe_buf
;
877 char *pos
, *end
, *custom
, *buf
;
882 while (pos
+ IW_EV_LCP_LEN
<= end
) {
883 /* Event data may be unaligned, so make a local, aligned copy
884 * before processing. */
885 memcpy(&iwe_buf
, pos
, IW_EV_LCP_LEN
);
886 wpa_printf(MSG_MSGDUMP
, "Wireless event: cmd=0x%x len=%d",
888 if (iwe
->len
<= IW_EV_LCP_LEN
)
891 custom
= pos
+ IW_EV_POINT_LEN
;
892 if (drv
->we_version
> 18 &&
893 (iwe
->cmd
== IWEVMICHAELMICFAILURE
||
894 iwe
->cmd
== IWEVASSOCREQIE
||
895 iwe
->cmd
== IWEVCUSTOM
)) {
896 /* WE-19 removed the pointer from struct iw_point */
897 char *dpos
= (char *) &iwe_buf
.u
.data
.length
;
898 int dlen
= dpos
- (char *) &iwe_buf
;
899 memcpy(dpos
, pos
+ IW_EV_LCP_LEN
,
900 sizeof(struct iw_event
) - dlen
);
902 memcpy(&iwe_buf
, pos
, sizeof(struct iw_event
));
903 custom
+= IW_EV_POINT_OFF
;
908 hostapd_notif_disassoc(drv
->hapd
,
909 (u8
*) iwe
->u
.addr
.sa_data
);
912 madwifi_new_sta(drv
, (u8
*) iwe
->u
.addr
.sa_data
);
915 /* Driver hack.. Use IWEVASSOCREQIE to bypass
916 * IWEVCUSTOM size limitations. Need to handle this
917 * just like IWEVCUSTOM.
920 if (custom
+ iwe
->u
.data
.length
> end
)
922 buf
= malloc(iwe
->u
.data
.length
+ 1);
925 memcpy(buf
, custom
, iwe
->u
.data
.length
);
926 buf
[iwe
->u
.data
.length
] = '\0';
927 madwifi_wireless_event_wireless_custom(
928 drv
, buf
, buf
+ iwe
->u
.data
.length
);
939 madwifi_wireless_event_rtm_newlink(void *ctx
,
940 struct ifinfomsg
*ifi
, u8
*buf
, size_t len
)
942 struct madwifi_driver_data
*drv
= ctx
;
943 int attrlen
, rta_len
;
946 if (ifi
->ifi_index
!= drv
->ifindex
)
950 attr
= (struct rtattr
*) buf
;
952 rta_len
= RTA_ALIGN(sizeof(struct rtattr
));
953 while (RTA_OK(attr
, attrlen
)) {
954 if (attr
->rta_type
== IFLA_WIRELESS
) {
955 madwifi_wireless_event_wireless(
956 drv
, ((char *) attr
) + rta_len
,
957 attr
->rta_len
- rta_len
);
959 attr
= RTA_NEXT(attr
, attrlen
);
965 madwifi_get_we_version(struct madwifi_driver_data
*drv
)
967 struct iw_range
*range
;
975 * Use larger buffer than struct iw_range in order to allow the
976 * structure to grow in the future.
978 buflen
= sizeof(struct iw_range
) + 500;
979 range
= os_zalloc(buflen
);
983 memset(&iwr
, 0, sizeof(iwr
));
984 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
985 iwr
.u
.data
.pointer
= (caddr_t
) range
;
986 iwr
.u
.data
.length
= buflen
;
988 minlen
= ((char *) &range
->enc_capa
) - (char *) range
+
989 sizeof(range
->enc_capa
);
991 if (ioctl(drv
->ioctl_sock
, SIOCGIWRANGE
, &iwr
) < 0) {
992 perror("ioctl[SIOCGIWRANGE]");
995 } else if (iwr
.u
.data
.length
>= minlen
&&
996 range
->we_version_compiled
>= 18) {
997 wpa_printf(MSG_DEBUG
, "SIOCGIWRANGE: WE(compiled)=%d "
998 "WE(source)=%d enc_capa=0x%x",
999 range
->we_version_compiled
,
1000 range
->we_version_source
,
1002 drv
->we_version
= range
->we_version_compiled
;
1011 madwifi_wireless_event_init(struct madwifi_driver_data
*drv
)
1013 struct netlink_config
*cfg
;
1015 madwifi_get_we_version(drv
);
1017 cfg
= os_zalloc(sizeof(*cfg
));
1021 cfg
->newlink_cb
= madwifi_wireless_event_rtm_newlink
;
1022 drv
->netlink
= netlink_init(cfg
);
1023 if (drv
->netlink
== NULL
) {
1033 madwifi_send_eapol(void *priv
, const u8
*addr
, const u8
*data
, size_t data_len
,
1034 int encrypt
, const u8
*own_addr
)
1036 struct madwifi_driver_data
*drv
= priv
;
1037 unsigned char buf
[3000];
1038 unsigned char *bp
= buf
;
1039 struct l2_ethhdr
*eth
;
1044 * Prepend the Ethernet header. If the caller left us
1045 * space at the front we could just insert it but since
1046 * we don't know we copy to a local buffer. Given the frequency
1047 * and size of frames this probably doesn't matter.
1049 len
= data_len
+ sizeof(struct l2_ethhdr
);
1050 if (len
> sizeof(buf
)) {
1053 printf("EAPOL frame discarded, cannot malloc temp "
1054 "buffer of size %lu!\n", (unsigned long) len
);
1058 eth
= (struct l2_ethhdr
*) bp
;
1059 memcpy(eth
->h_dest
, addr
, ETH_ALEN
);
1060 memcpy(eth
->h_source
, own_addr
, ETH_ALEN
);
1061 eth
->h_proto
= host_to_be16(ETH_P_EAPOL
);
1062 memcpy(eth
+1, data
, data_len
);
1064 wpa_hexdump(MSG_MSGDUMP
, "TX EAPOL", bp
, len
);
1066 status
= l2_packet_send(drv
->sock_xmit
, addr
, ETH_P_EAPOL
, bp
, len
);
1074 handle_read(void *ctx
, const u8
*src_addr
, const u8
*buf
, size_t len
)
1076 struct madwifi_driver_data
*drv
= ctx
;
1077 hostapd_eapol_receive(drv
->hapd
, src_addr
,
1078 buf
+ sizeof(struct l2_ethhdr
),
1079 len
- sizeof(struct l2_ethhdr
));
1083 madwifi_init(struct hostapd_data
*hapd
, struct wpa_init_params
*params
)
1085 struct madwifi_driver_data
*drv
;
1089 drv
= os_zalloc(sizeof(struct madwifi_driver_data
));
1091 printf("Could not allocate memory for madwifi driver data\n");
1096 drv
->ioctl_sock
= socket(PF_INET
, SOCK_DGRAM
, 0);
1097 if (drv
->ioctl_sock
< 0) {
1098 perror("socket[PF_INET,SOCK_DGRAM]");
1101 memcpy(drv
->iface
, params
->ifname
, sizeof(drv
->iface
));
1103 memset(&ifr
, 0, sizeof(ifr
));
1104 os_strlcpy(ifr
.ifr_name
, drv
->iface
, sizeof(ifr
.ifr_name
));
1105 if (ioctl(drv
->ioctl_sock
, SIOCGIFINDEX
, &ifr
) != 0) {
1106 perror("ioctl(SIOCGIFINDEX)");
1109 drv
->ifindex
= ifr
.ifr_ifindex
;
1111 drv
->sock_xmit
= l2_packet_init(drv
->iface
, NULL
, ETH_P_EAPOL
,
1112 handle_read
, drv
, 1);
1113 if (drv
->sock_xmit
== NULL
)
1115 if (l2_packet_get_own_addr(drv
->sock_xmit
, params
->own_addr
))
1117 if (params
->bridge
[0]) {
1118 wpa_printf(MSG_DEBUG
, "Configure bridge %s for EAPOL traffic.",
1120 drv
->sock_recv
= l2_packet_init(params
->bridge
[0], NULL
,
1121 ETH_P_EAPOL
, handle_read
, drv
,
1123 if (drv
->sock_recv
== NULL
)
1126 drv
->sock_recv
= drv
->sock_xmit
;
1128 memset(&iwr
, 0, sizeof(iwr
));
1129 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
1131 iwr
.u
.mode
= IW_MODE_MASTER
;
1133 if (ioctl(drv
->ioctl_sock
, SIOCSIWMODE
, &iwr
) < 0) {
1134 perror("ioctl[SIOCSIWMODE]");
1135 printf("Could not set interface to master mode!\n");
1139 madwifi_set_iface_flags(drv
, 0); /* mark down during setup */
1140 madwifi_set_privacy(drv
->iface
, drv
, 0); /* default to no privacy */
1142 madwifi_receive_probe_req(drv
);
1144 if (madwifi_wireless_event_init(drv
))
1149 if (drv
->sock_xmit
!= NULL
)
1150 l2_packet_deinit(drv
->sock_xmit
);
1151 if (drv
->ioctl_sock
>= 0)
1152 close(drv
->ioctl_sock
);
1160 madwifi_deinit(void *priv
)
1162 struct madwifi_driver_data
*drv
= priv
;
1164 netlink_deinit(drv
->netlink
);
1165 (void) madwifi_set_iface_flags(drv
, 0);
1166 if (drv
->ioctl_sock
>= 0)
1167 close(drv
->ioctl_sock
);
1168 if (drv
->sock_recv
!= NULL
&& drv
->sock_recv
!= drv
->sock_xmit
)
1169 l2_packet_deinit(drv
->sock_recv
);
1170 if (drv
->sock_xmit
!= NULL
)
1171 l2_packet_deinit(drv
->sock_xmit
);
1173 l2_packet_deinit(drv
->sock_raw
);
1178 madwifi_set_ssid(const char *ifname
, void *priv
, const u8
*buf
, int len
)
1180 struct madwifi_driver_data
*drv
= priv
;
1183 memset(&iwr
, 0, sizeof(iwr
));
1184 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
1185 iwr
.u
.essid
.flags
= 1; /* SSID active */
1186 iwr
.u
.essid
.pointer
= (caddr_t
) buf
;
1187 iwr
.u
.essid
.length
= len
+ 1;
1189 if (ioctl(drv
->ioctl_sock
, SIOCSIWESSID
, &iwr
) < 0) {
1190 perror("ioctl[SIOCSIWESSID]");
1191 printf("len=%d\n", len
);
1198 madwifi_get_ssid(const char *ifname
, void *priv
, u8
*buf
, int len
)
1200 struct madwifi_driver_data
*drv
= priv
;
1204 memset(&iwr
, 0, sizeof(iwr
));
1205 os_strlcpy(iwr
.ifr_name
, drv
->iface
, IFNAMSIZ
);
1206 iwr
.u
.essid
.pointer
= (caddr_t
) buf
;
1207 iwr
.u
.essid
.length
= len
;
1209 if (ioctl(drv
->ioctl_sock
, SIOCGIWESSID
, &iwr
) < 0) {
1210 perror("ioctl[SIOCGIWESSID]");
1213 ret
= iwr
.u
.essid
.length
;
1219 madwifi_set_countermeasures(void *priv
, int enabled
)
1221 struct madwifi_driver_data
*drv
= priv
;
1222 wpa_printf(MSG_DEBUG
, "%s: enabled=%d", __FUNCTION__
, enabled
);
1223 return set80211param(drv
, IEEE80211_PARAM_COUNTERMEASURES
, enabled
);
1227 madwifi_commit(void *priv
)
1229 return madwifi_set_iface_flags(priv
, 1);
1232 const struct wpa_driver_ops wpa_driver_atheros_ops
= {
1234 .hapd_init
= madwifi_init
,
1235 .deinit
= madwifi_deinit
,
1236 .set_ieee8021x
= madwifi_set_ieee8021x
,
1237 .set_privacy
= madwifi_set_privacy
,
1238 .set_key
= madwifi_set_key
,
1239 .get_seqnum
= madwifi_get_seqnum
,
1240 .flush
= madwifi_flush
,
1241 .set_generic_elem
= madwifi_set_opt_ie
,
1242 .sta_set_flags
= madwifi_sta_set_flags
,
1243 .read_sta_data
= madwifi_read_sta_driver_data
,
1244 .hapd_send_eapol
= madwifi_send_eapol
,
1245 .sta_disassoc
= madwifi_sta_disassoc
,
1246 .sta_deauth
= madwifi_sta_deauth
,
1247 .hapd_set_ssid
= madwifi_set_ssid
,
1248 .hapd_get_ssid
= madwifi_get_ssid
,
1249 .set_countermeasures
= madwifi_set_countermeasures
,
1250 .sta_clear_stats
= madwifi_sta_clear_stats
,
1251 .commit
= madwifi_commit
,
1252 .set_wps_beacon_ie
= madwifi_set_wps_beacon_ie
,
1253 .set_wps_probe_resp_ie
= madwifi_set_wps_probe_resp_ie
,