2 * hostapd / IEEE 802.11 Management
3 * Copyright (c) 2002-2008, Jouni Malinen <j@w1.fi>
4 * Copyright (c) 2007-2008, Intel Corporation
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
10 * Alternatively, this software may be distributed under the terms of BSD
13 * See README and COPYING for more details.
18 #ifndef CONFIG_NATIVE_WINDOWS
24 #include "ieee802_11.h"
26 #include "hw_features.h"
27 #include "radius/radius.h"
28 #include "radius/radius_client.h"
29 #include "ieee802_11_auth.h"
32 #include "ieee802_1x.h"
36 #include "accounting.h"
41 u8
* hostapd_eid_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
46 if (hapd
->iface
->current_rates
== NULL
)
49 *pos
++ = WLAN_EID_SUPP_RATES
;
50 num
= hapd
->iface
->num_rates
;
52 /* rest of the rates are encoded in Extended supported
59 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
;
62 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
63 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
72 u8
* hostapd_eid_ext_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
77 if (hapd
->iface
->current_rates
== NULL
)
80 num
= hapd
->iface
->num_rates
;
85 *pos
++ = WLAN_EID_EXT_SUPP_RATES
;
88 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
+ 8;
92 continue; /* already in SuppRates IE */
93 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
94 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
103 u8
* hostapd_eid_ht_capabilities_info(struct hostapd_data
*hapd
, u8
*eid
)
105 #ifdef CONFIG_IEEE80211N
106 struct ieee80211_ht_capability
*cap
;
109 if (!hapd
->iconf
->ieee80211n
)
112 *pos
++ = WLAN_EID_HT_CAP
;
113 *pos
++ = sizeof(*cap
);
115 cap
= (struct ieee80211_ht_capability
*) pos
;
116 os_memset(cap
, 0, sizeof(*cap
));
117 SET_2BIT_U8(&cap
->mac_ht_params_info
,
118 MAC_HT_PARAM_INFO_MAX_RX_AMPDU_FACTOR_OFFSET
,
119 MAX_RX_AMPDU_FACTOR_64KB
);
121 cap
->capabilities_info
= host_to_le16(hapd
->iconf
->ht_capab
);
123 cap
->supported_mcs_set
[0] = 0xff;
124 cap
->supported_mcs_set
[1] = 0xff;
129 #else /* CONFIG_IEEE80211N */
131 #endif /* CONFIG_IEEE80211N */
135 u8
* hostapd_eid_ht_operation(struct hostapd_data
*hapd
, u8
*eid
)
137 #ifdef CONFIG_IEEE80211N
138 struct ieee80211_ht_operation
*oper
;
141 if (!hapd
->iconf
->ieee80211n
)
144 *pos
++ = WLAN_EID_HT_OPERATION
;
145 *pos
++ = sizeof(*oper
);
147 oper
= (struct ieee80211_ht_operation
*) pos
;
148 os_memset(oper
, 0, sizeof(*oper
));
150 oper
->control_chan
= hapd
->iconf
->channel
;
151 oper
->operation_mode
= host_to_le16(hapd
->iface
->ht_op_mode
);
152 if (hapd
->iconf
->secondary_channel
== 1)
153 oper
->ht_param
|= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE
|
154 HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH
;
155 if (hapd
->iconf
->secondary_channel
== -1)
156 oper
->ht_param
|= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW
|
157 HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH
;
159 pos
+= sizeof(*oper
);
162 #else /* CONFIG_IEEE80211N */
164 #endif /* CONFIG_IEEE80211N */
168 #ifdef CONFIG_IEEE80211N
172 Set to 0 (HT pure) under the followign conditions
173 - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
174 - all STAs in the BSS are 20 MHz HT in 20 MHz BSS
175 Set to 1 (HT non-member protection) if there may be non-HT STAs
176 in both the primary and the secondary channel
177 Set to 2 if only HT STAs are associated in BSS,
178 however and at least one 20 MHz HT STA is associated
179 Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
180 (currently non-GF HT station is considered as non-HT STA also)
182 int hostapd_ht_operation_update(struct hostapd_iface
*iface
)
184 u16 cur_op_mode
, new_op_mode
;
185 int op_mode_changes
= 0;
187 if (!iface
->conf
->ieee80211n
|| iface
->conf
->ht_op_mode_fixed
)
190 wpa_printf(MSG_DEBUG
, "%s current operation mode=0x%X",
191 __func__
, iface
->ht_op_mode
);
193 if (!(iface
->ht_op_mode
& HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT
)
194 && iface
->num_sta_ht_no_gf
) {
196 HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT
;
198 } else if ((iface
->ht_op_mode
&
199 HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT
) &&
200 iface
->num_sta_ht_no_gf
== 0) {
202 ~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT
;
206 if (!(iface
->ht_op_mode
& HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT
) &&
207 (iface
->num_sta_no_ht
|| iface
->olbc_ht
)) {
208 iface
->ht_op_mode
|= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT
;
210 } else if ((iface
->ht_op_mode
&
211 HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT
) &&
212 (iface
->num_sta_no_ht
== 0 && !iface
->olbc_ht
)) {
214 ~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT
;
218 /* Note: currently we switch to the MIXED op mode if HT non-greenfield
219 * station is associated. Probably it's a theoretical case, since
220 * it looks like all known HT STAs support greenfield.
223 if (iface
->num_sta_no_ht
||
224 (iface
->ht_op_mode
& HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT
))
225 new_op_mode
= OP_MODE_MIXED
;
226 else if ((iface
->conf
->ht_capab
& HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
)
227 && iface
->num_sta_ht_20mhz
)
228 new_op_mode
= OP_MODE_20MHZ_HT_STA_ASSOCED
;
229 else if (iface
->olbc_ht
)
230 new_op_mode
= OP_MODE_MAY_BE_LEGACY_STAS
;
232 new_op_mode
= OP_MODE_PURE
;
234 cur_op_mode
= iface
->ht_op_mode
& HT_INFO_OPERATION_MODE_OP_MODE_MASK
;
235 if (cur_op_mode
!= new_op_mode
) {
236 iface
->ht_op_mode
&= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK
;
237 iface
->ht_op_mode
|= new_op_mode
;
241 wpa_printf(MSG_DEBUG
, "%s new operation mode=0x%X changes=%d",
242 __func__
, iface
->ht_op_mode
, op_mode_changes
);
244 return op_mode_changes
;
247 #endif /* CONFIG_IEEE80211N */
250 u16
hostapd_own_capab_info(struct hostapd_data
*hapd
, struct sta_info
*sta
,
253 int capab
= WLAN_CAPABILITY_ESS
;
256 if (hapd
->iface
->num_sta_no_short_preamble
== 0 &&
257 hapd
->iconf
->preamble
== SHORT_PREAMBLE
)
258 capab
|= WLAN_CAPABILITY_SHORT_PREAMBLE
;
260 privacy
= hapd
->conf
->ssid
.wep
.keys_set
;
262 if (hapd
->conf
->ieee802_1x
&&
263 (hapd
->conf
->default_wep_key_len
||
264 hapd
->conf
->individual_wep_key_len
))
271 int policy
, def_klen
;
272 if (probe
&& sta
->ssid_probe
) {
273 policy
= sta
->ssid_probe
->security_policy
;
274 def_klen
= sta
->ssid_probe
->wep
.default_len
;
276 policy
= sta
->ssid
->security_policy
;
277 def_klen
= sta
->ssid
->wep
.default_len
;
279 privacy
= policy
!= SECURITY_PLAINTEXT
;
280 if (policy
== SECURITY_IEEE_802_1X
&& def_klen
== 0)
285 capab
|= WLAN_CAPABILITY_PRIVACY
;
287 if (hapd
->iface
->current_mode
&&
288 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
&&
289 hapd
->iface
->num_sta_no_short_slot_time
== 0)
290 capab
|= WLAN_CAPABILITY_SHORT_SLOT_TIME
;
296 #ifdef CONFIG_IEEE80211W
297 static u8
* hostapd_eid_assoc_comeback_time(struct hostapd_data
*hapd
,
298 struct sta_info
*sta
, u8
*eid
)
302 struct os_time now
, passed
;
304 *pos
++ = WLAN_EID_TIMEOUT_INTERVAL
;
306 *pos
++ = WLAN_TIMEOUT_ASSOC_COMEBACK
;
308 os_time_sub(&now
, &sta
->sa_query_start
, &passed
);
309 tu
= (passed
.sec
* 1000000 + passed
.usec
) / 1024;
310 if (hapd
->conf
->assoc_sa_query_max_timeout
> tu
)
311 timeout
= hapd
->conf
->assoc_sa_query_max_timeout
- tu
;
314 if (timeout
< hapd
->conf
->assoc_sa_query_max_timeout
)
315 timeout
++; /* add some extra time for local timers */
316 WPA_PUT_LE32(pos
, timeout
);
321 #endif /* CONFIG_IEEE80211W */
324 void ieee802_11_print_ssid(char *buf
, const u8
*ssid
, u8 len
)
327 if (len
> HOSTAPD_MAX_SSID_LEN
)
328 len
= HOSTAPD_MAX_SSID_LEN
;
329 for (i
= 0; i
< len
; i
++) {
330 if (ssid
[i
] >= 32 && ssid
[i
] < 127)
340 * ieee802_11_send_deauth - Send Deauthentication frame
341 * @hapd: hostapd BSS data
342 * @addr: Address of the destination STA
343 * @reason: Reason code for Deauthentication
345 void ieee802_11_send_deauth(struct hostapd_data
*hapd
, u8
*addr
, u16 reason
)
347 struct ieee80211_mgmt mgmt
;
349 hostapd_logger(hapd
, addr
, HOSTAPD_MODULE_IEEE80211
,
351 "deauthenticate - reason %d", reason
);
352 os_memset(&mgmt
, 0, sizeof(mgmt
));
353 mgmt
.frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
354 WLAN_FC_STYPE_DEAUTH
);
355 os_memcpy(mgmt
.da
, addr
, ETH_ALEN
);
356 os_memcpy(mgmt
.sa
, hapd
->own_addr
, ETH_ALEN
);
357 os_memcpy(mgmt
.bssid
, hapd
->own_addr
, ETH_ALEN
);
358 mgmt
.u
.deauth
.reason_code
= host_to_le16(reason
);
359 if (hostapd_send_mgmt_frame(hapd
, &mgmt
, IEEE80211_HDRLEN
+
360 sizeof(mgmt
.u
.deauth
), 0) < 0)
361 perror("ieee802_11_send_deauth: send");
365 static u16
auth_shared_key(struct hostapd_data
*hapd
, struct sta_info
*sta
,
366 u16 auth_transaction
, u8
*challenge
, int iswep
)
368 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
370 "authentication (shared key, transaction %d)",
373 if (auth_transaction
== 1) {
374 if (!sta
->challenge
) {
375 /* Generate a pseudo-random challenge */
379 sta
->challenge
= os_zalloc(WLAN_AUTH_CHALLENGE_LEN
);
380 if (sta
->challenge
== NULL
)
381 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
385 os_memcpy(key
, &now
, 4);
386 os_memcpy(key
+ 4, &r
, 4);
387 rc4_skip(key
, sizeof(key
), 0,
388 sta
->challenge
, WLAN_AUTH_CHALLENGE_LEN
);
393 if (auth_transaction
!= 3)
394 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
397 if (!iswep
|| !sta
->challenge
|| !challenge
||
398 os_memcmp(sta
->challenge
, challenge
, WLAN_AUTH_CHALLENGE_LEN
)) {
399 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
401 "shared key authentication - invalid "
402 "challenge-response");
403 return WLAN_STATUS_CHALLENGE_FAIL
;
406 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
408 "authentication OK (shared key)");
409 #ifdef IEEE80211_REQUIRE_AUTH_ACK
410 /* Station will be marked authenticated if it ACKs the
411 * authentication reply. */
413 sta
->flags
|= WLAN_STA_AUTH
;
414 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
416 os_free(sta
->challenge
);
417 sta
->challenge
= NULL
;
423 static void send_auth_reply(struct hostapd_data
*hapd
,
424 const u8
*dst
, const u8
*bssid
,
425 u16 auth_alg
, u16 auth_transaction
, u16 resp
,
426 const u8
*ies
, size_t ies_len
)
428 struct ieee80211_mgmt
*reply
;
432 rlen
= IEEE80211_HDRLEN
+ sizeof(reply
->u
.auth
) + ies_len
;
433 buf
= os_zalloc(rlen
);
437 reply
= (struct ieee80211_mgmt
*) buf
;
438 reply
->frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
440 os_memcpy(reply
->da
, dst
, ETH_ALEN
);
441 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
442 os_memcpy(reply
->bssid
, bssid
, ETH_ALEN
);
444 reply
->u
.auth
.auth_alg
= host_to_le16(auth_alg
);
445 reply
->u
.auth
.auth_transaction
= host_to_le16(auth_transaction
);
446 reply
->u
.auth
.status_code
= host_to_le16(resp
);
449 os_memcpy(reply
->u
.auth
.variable
, ies
, ies_len
);
451 wpa_printf(MSG_DEBUG
, "authentication reply: STA=" MACSTR
452 " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)",
453 MAC2STR(dst
), auth_alg
, auth_transaction
,
454 resp
, (unsigned long) ies_len
);
455 if (hostapd_send_mgmt_frame(hapd
, reply
, rlen
, 0) < 0)
456 perror("send_auth_reply: send");
462 #ifdef CONFIG_IEEE80211R
463 static void handle_auth_ft_finish(void *ctx
, const u8
*dst
, const u8
*bssid
,
464 u16 auth_transaction
, u16 status
,
465 const u8
*ies
, size_t ies_len
)
467 struct hostapd_data
*hapd
= ctx
;
468 struct sta_info
*sta
;
470 send_auth_reply(hapd
, dst
, bssid
, WLAN_AUTH_FT
, auth_transaction
,
471 status
, ies
, ies_len
);
473 if (status
!= WLAN_STATUS_SUCCESS
)
476 sta
= ap_get_sta(hapd
, dst
);
480 hostapd_logger(hapd
, dst
, HOSTAPD_MODULE_IEEE80211
,
481 HOSTAPD_LEVEL_DEBUG
, "authentication OK (FT)");
482 sta
->flags
|= WLAN_STA_AUTH
;
483 mlme_authenticate_indication(hapd
, sta
);
485 #endif /* CONFIG_IEEE80211R */
488 static void handle_auth(struct hostapd_data
*hapd
, struct ieee80211_mgmt
*mgmt
,
491 u16 auth_alg
, auth_transaction
, status_code
;
492 u16 resp
= WLAN_STATUS_SUCCESS
;
493 struct sta_info
*sta
= NULL
;
496 u8
*challenge
= NULL
;
497 u32 session_timeout
, acct_interim_interval
;
499 u8 resp_ies
[2 + WLAN_AUTH_CHALLENGE_LEN
];
500 size_t resp_ies_len
= 0;
502 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
503 printf("handle_auth - too short payload (len=%lu)\n",
504 (unsigned long) len
);
508 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
509 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
510 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
511 fc
= le_to_host16(mgmt
->frame_control
);
513 if (len
>= IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
) +
514 2 + WLAN_AUTH_CHALLENGE_LEN
&&
515 mgmt
->u
.auth
.variable
[0] == WLAN_EID_CHALLENGE
&&
516 mgmt
->u
.auth
.variable
[1] == WLAN_AUTH_CHALLENGE_LEN
)
517 challenge
= &mgmt
->u
.auth
.variable
[2];
519 wpa_printf(MSG_DEBUG
, "authentication: STA=" MACSTR
" auth_alg=%d "
520 "auth_transaction=%d status_code=%d wep=%d%s",
521 MAC2STR(mgmt
->sa
), auth_alg
, auth_transaction
,
522 status_code
, !!(fc
& WLAN_FC_ISWEP
),
523 challenge
? " challenge" : "");
525 if (hapd
->tkip_countermeasures
) {
526 resp
= WLAN_REASON_MICHAEL_MIC_FAILURE
;
530 if (!(((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_OPEN
) &&
531 auth_alg
== WLAN_AUTH_OPEN
) ||
532 #ifdef CONFIG_IEEE80211R
534 (hapd
->conf
->wpa_key_mgmt
&
535 (WPA_KEY_MGMT_FT_IEEE8021X
| WPA_KEY_MGMT_FT_PSK
)) &&
536 auth_alg
== WLAN_AUTH_FT
) ||
537 #endif /* CONFIG_IEEE80211R */
538 ((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_SHARED
) &&
539 auth_alg
== WLAN_AUTH_SHARED_KEY
))) {
540 printf("Unsupported authentication algorithm (%d)\n",
542 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
546 if (!(auth_transaction
== 1 ||
547 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 3))) {
548 printf("Unknown authentication transaction number (%d)\n",
550 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
554 if (os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
555 printf("Station " MACSTR
" not allowed to authenticate.\n",
557 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
561 res
= hostapd_allowed_address(hapd
, mgmt
->sa
, (u8
*) mgmt
, len
,
563 &acct_interim_interval
, &vlan_id
);
564 if (res
== HOSTAPD_ACL_REJECT
) {
565 printf("Station " MACSTR
" not allowed to authenticate.\n",
567 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
570 if (res
== HOSTAPD_ACL_PENDING
) {
571 wpa_printf(MSG_DEBUG
, "Authentication frame from " MACSTR
572 " waiting for an external authentication",
574 /* Authentication code will re-send the authentication frame
575 * after it has received (and cached) information from the
576 * external source. */
580 sta
= ap_sta_add(hapd
, mgmt
->sa
);
582 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
587 if (hostapd_get_vlan_id_ifname(hapd
->conf
->vlan
,
589 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
590 HOSTAPD_LEVEL_INFO
, "Invalid VLAN ID "
591 "%d received from RADIUS server",
593 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
596 sta
->vlan_id
= vlan_id
;
597 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
598 HOSTAPD_LEVEL_INFO
, "VLAN ID %d", sta
->vlan_id
);
601 sta
->flags
&= ~WLAN_STA_PREAUTH
;
602 ieee802_1x_notify_pre_auth(sta
->eapol_sm
, 0);
604 if (hapd
->conf
->radius
->acct_interim_interval
== 0 &&
605 acct_interim_interval
)
606 sta
->acct_interim_interval
= acct_interim_interval
;
607 if (res
== HOSTAPD_ACL_ACCEPT_TIMEOUT
)
608 ap_sta_session_timeout(hapd
, sta
, session_timeout
);
610 ap_sta_no_session_timeout(hapd
, sta
);
614 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
616 "authentication OK (open system)");
617 #ifdef IEEE80211_REQUIRE_AUTH_ACK
618 /* Station will be marked authenticated if it ACKs the
619 * authentication reply. */
621 sta
->flags
|= WLAN_STA_AUTH
;
622 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
623 sta
->auth_alg
= WLAN_AUTH_OPEN
;
624 mlme_authenticate_indication(hapd
, sta
);
627 case WLAN_AUTH_SHARED_KEY
:
628 resp
= auth_shared_key(hapd
, sta
, auth_transaction
, challenge
,
630 sta
->auth_alg
= WLAN_AUTH_SHARED_KEY
;
631 mlme_authenticate_indication(hapd
, sta
);
632 if (sta
->challenge
&& auth_transaction
== 1) {
633 resp_ies
[0] = WLAN_EID_CHALLENGE
;
634 resp_ies
[1] = WLAN_AUTH_CHALLENGE_LEN
;
635 os_memcpy(resp_ies
+ 2, sta
->challenge
,
636 WLAN_AUTH_CHALLENGE_LEN
);
637 resp_ies_len
= 2 + WLAN_AUTH_CHALLENGE_LEN
;
640 #ifdef CONFIG_IEEE80211R
642 sta
->auth_alg
= WLAN_AUTH_FT
;
643 if (sta
->wpa_sm
== NULL
)
644 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
646 if (sta
->wpa_sm
== NULL
) {
647 wpa_printf(MSG_DEBUG
, "FT: Failed to initialize WPA "
649 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
652 wpa_ft_process_auth(sta
->wpa_sm
, mgmt
->bssid
,
653 auth_transaction
, mgmt
->u
.auth
.variable
,
654 len
- IEEE80211_HDRLEN
-
655 sizeof(mgmt
->u
.auth
),
656 handle_auth_ft_finish
, hapd
);
657 /* handle_auth_ft_finish() callback will complete auth. */
659 #endif /* CONFIG_IEEE80211R */
663 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, auth_alg
,
664 auth_transaction
+ 1, resp
, resp_ies
, resp_ies_len
);
668 static void handle_assoc(struct hostapd_data
*hapd
,
669 struct ieee80211_mgmt
*mgmt
, size_t len
, int reassoc
)
671 u16 capab_info
, listen_interval
;
672 u16 resp
= WLAN_STATUS_SUCCESS
;
675 int send_deauth
= 0, send_len
, left
, i
;
676 struct sta_info
*sta
;
677 struct ieee802_11_elems elems
;
678 u8 buf
[sizeof(struct ieee80211_mgmt
) + 512];
679 struct ieee80211_mgmt
*reply
;
681 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_req
) :
682 sizeof(mgmt
->u
.assoc_req
))) {
683 printf("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
684 "\n", reassoc
, (unsigned long) len
);
689 capab_info
= le_to_host16(mgmt
->u
.reassoc_req
.capab_info
);
690 listen_interval
= le_to_host16(
691 mgmt
->u
.reassoc_req
.listen_interval
);
692 wpa_printf(MSG_DEBUG
, "reassociation request: STA=" MACSTR
693 " capab_info=0x%02x listen_interval=%d current_ap="
695 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
696 MAC2STR(mgmt
->u
.reassoc_req
.current_ap
));
697 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.reassoc_req
));
698 pos
= mgmt
->u
.reassoc_req
.variable
;
700 capab_info
= le_to_host16(mgmt
->u
.assoc_req
.capab_info
);
701 listen_interval
= le_to_host16(
702 mgmt
->u
.assoc_req
.listen_interval
);
703 wpa_printf(MSG_DEBUG
, "association request: STA=" MACSTR
704 " capab_info=0x%02x listen_interval=%d",
705 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
);
706 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.assoc_req
));
707 pos
= mgmt
->u
.assoc_req
.variable
;
710 sta
= ap_get_sta(hapd
, mgmt
->sa
);
711 #ifdef CONFIG_IEEE80211R
712 if (sta
&& sta
->auth_alg
== WLAN_AUTH_FT
&&
713 (sta
->flags
& WLAN_STA_AUTH
) == 0) {
714 wpa_printf(MSG_DEBUG
, "FT: Allow STA " MACSTR
" to associate "
715 "prior to authentication since it is using "
716 "over-the-DS FT", MAC2STR(mgmt
->sa
));
718 #endif /* CONFIG_IEEE80211R */
719 if (sta
== NULL
|| (sta
->flags
& WLAN_STA_AUTH
) == 0) {
720 printf("STA " MACSTR
" trying to associate before "
721 "authentication\n", MAC2STR(mgmt
->sa
));
723 printf(" sta: addr=" MACSTR
" aid=%d flags=0x%04x\n",
724 MAC2STR(sta
->addr
), sta
->aid
, sta
->flags
);
727 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
731 if (hapd
->tkip_countermeasures
) {
732 resp
= WLAN_REASON_MICHAEL_MIC_FAILURE
;
736 if (listen_interval
> hapd
->conf
->max_listen_interval
) {
737 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
739 "Too large Listen Interval (%d)",
741 resp
= WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE
;
745 sta
->capability
= capab_info
;
746 sta
->listen_interval
= listen_interval
;
748 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
750 if (ieee802_11_parse_elems(pos
, left
, &elems
, 1) == ParseFailed
||
752 printf("STA " MACSTR
" sent invalid association request\n",
754 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
758 if (elems
.ssid_len
!= hapd
->conf
->ssid
.ssid_len
||
759 os_memcmp(elems
.ssid
, hapd
->conf
->ssid
.ssid
, elems
.ssid_len
) != 0)
762 ieee802_11_print_ssid(ssid_txt
, elems
.ssid
, elems
.ssid_len
);
763 printf("Station " MACSTR
" tried to associate with "
764 "unknown SSID '%s'\n", MAC2STR(sta
->addr
), ssid_txt
);
765 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
769 sta
->flags
&= ~WLAN_STA_WMM
;
770 if (elems
.wmm
&& hapd
->conf
->wmm_enabled
) {
771 if (hostapd_eid_wmm_valid(hapd
, elems
.wmm
, elems
.wmm_len
))
772 hostapd_logger(hapd
, sta
->addr
,
775 "invalid WMM element in association "
778 sta
->flags
|= WLAN_STA_WMM
;
781 if (!elems
.supp_rates
) {
782 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
784 "No supported rates element in AssocReq");
785 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
789 if (elems
.supp_rates_len
> sizeof(sta
->supported_rates
)) {
790 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
792 "Invalid supported rates element length %d",
793 elems
.supp_rates_len
);
794 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
798 os_memset(sta
->supported_rates
, 0, sizeof(sta
->supported_rates
));
799 os_memcpy(sta
->supported_rates
, elems
.supp_rates
,
800 elems
.supp_rates_len
);
801 sta
->supported_rates_len
= elems
.supp_rates_len
;
803 if (elems
.ext_supp_rates
) {
804 if (elems
.supp_rates_len
+ elems
.ext_supp_rates_len
>
805 sizeof(sta
->supported_rates
)) {
806 hostapd_logger(hapd
, mgmt
->sa
,
807 HOSTAPD_MODULE_IEEE80211
,
809 "Invalid supported rates element length"
810 " %d+%d", elems
.supp_rates_len
,
811 elems
.ext_supp_rates_len
);
812 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
816 os_memcpy(sta
->supported_rates
+ elems
.supp_rates_len
,
817 elems
.ext_supp_rates
, elems
.ext_supp_rates_len
);
818 sta
->supported_rates_len
+= elems
.ext_supp_rates_len
;
821 #ifdef CONFIG_IEEE80211N
822 /* save HT capabilities in the sta object */
823 os_memset(&sta
->ht_capabilities
, 0, sizeof(sta
->ht_capabilities
));
824 if (elems
.ht_capabilities
&&
825 elems
.ht_capabilities_len
>=
826 sizeof(struct ieee80211_ht_capability
)) {
827 sta
->flags
|= WLAN_STA_HT
;
828 sta
->ht_capabilities
.id
= WLAN_EID_HT_CAP
;
829 sta
->ht_capabilities
.length
=
830 sizeof(struct ieee80211_ht_capability
);
831 os_memcpy(&sta
->ht_capabilities
.data
,
832 elems
.ht_capabilities
,
833 sizeof(struct ieee80211_ht_capability
));
835 sta
->flags
&= ~WLAN_STA_HT
;
836 #endif /* CONFIG_IEEE80211N */
838 if ((hapd
->conf
->wpa
& WPA_PROTO_RSN
) && elems
.rsn_ie
) {
839 wpa_ie
= elems
.rsn_ie
;
840 wpa_ie_len
= elems
.rsn_ie_len
;
841 } else if ((hapd
->conf
->wpa
& WPA_PROTO_WPA
) &&
843 wpa_ie
= elems
.wpa_ie
;
844 wpa_ie_len
= elems
.wpa_ie_len
;
850 sta
->flags
&= ~(WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
);
851 if (hapd
->conf
->wps_state
&& wpa_ie
== NULL
) {
853 wpa_printf(MSG_DEBUG
, "STA included WPS IE in "
854 "(Re)Association Request - assume WPS is "
856 sta
->flags
|= WLAN_STA_WPS
;
857 wpabuf_free(sta
->wps_ie
);
858 sta
->wps_ie
= wpabuf_alloc_copy(elems
.wps_ie
+ 4,
859 elems
.wps_ie_len
- 4);
861 wpa_printf(MSG_DEBUG
, "STA did not include WPA/RSN IE "
862 "in (Re)Association Request - possible WPS "
864 sta
->flags
|= WLAN_STA_MAYBE_WPS
;
867 #endif /* CONFIG_WPS */
868 if (hapd
->conf
->wpa
&& wpa_ie
== NULL
) {
869 printf("STA " MACSTR
": No WPA/RSN IE in association "
870 "request\n", MAC2STR(sta
->addr
));
871 resp
= WLAN_STATUS_INVALID_IE
;
875 if (hapd
->conf
->wpa
&& wpa_ie
) {
879 if (sta
->wpa_sm
== NULL
)
880 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
882 if (sta
->wpa_sm
== NULL
) {
883 printf("Failed to initialize WPA state machine\n");
884 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
887 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
889 elems
.mdie
, elems
.mdie_len
);
890 if (res
== WPA_INVALID_GROUP
)
891 resp
= WLAN_STATUS_GROUP_CIPHER_NOT_VALID
;
892 else if (res
== WPA_INVALID_PAIRWISE
)
893 resp
= WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID
;
894 else if (res
== WPA_INVALID_AKMP
)
895 resp
= WLAN_STATUS_AKMP_NOT_VALID
;
896 else if (res
== WPA_ALLOC_FAIL
)
897 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
898 #ifdef CONFIG_IEEE80211W
899 else if (res
== WPA_MGMT_FRAME_PROTECTION_VIOLATION
)
900 resp
= WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
901 else if (res
== WPA_INVALID_MGMT_GROUP_CIPHER
)
902 resp
= WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
903 #endif /* CONFIG_IEEE80211W */
904 else if (res
== WPA_INVALID_MDIE
)
905 resp
= WLAN_STATUS_INVALID_MDIE
;
906 else if (res
!= WPA_IE_OK
)
907 resp
= WLAN_STATUS_INVALID_IE
;
908 if (resp
!= WLAN_STATUS_SUCCESS
)
910 #ifdef CONFIG_IEEE80211W
911 if ((sta
->flags
& WLAN_STA_MFP
) && !sta
->sa_query_timed_out
&&
912 sta
->sa_query_count
> 0)
913 ap_check_sa_query_timeout(hapd
, sta
);
914 if ((sta
->flags
& WLAN_STA_MFP
) && !sta
->sa_query_timed_out
&&
915 (!reassoc
|| sta
->auth_alg
!= WLAN_AUTH_FT
)) {
917 * STA has already been associated with MFP and SA
918 * Query timeout has not been reached. Reject the
919 * association attempt temporarily and start SA Query,
920 * if one is not pending.
923 if (sta
->sa_query_count
== 0)
924 ap_sta_start_sa_query(hapd
, sta
);
926 resp
= WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
;
930 if (wpa_auth_uses_mfp(sta
->wpa_sm
))
931 sta
->flags
|= WLAN_STA_MFP
;
933 sta
->flags
&= ~WLAN_STA_MFP
;
934 #endif /* CONFIG_IEEE80211W */
936 #ifdef CONFIG_IEEE80211R
937 if (sta
->auth_alg
== WLAN_AUTH_FT
) {
939 wpa_printf(MSG_DEBUG
, "FT: " MACSTR
" tried "
940 "to use association (not "
941 "re-association) with FT auth_alg",
943 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
947 resp
= wpa_ft_validate_reassoc(sta
->wpa_sm
, pos
, left
);
948 if (resp
!= WLAN_STATUS_SUCCESS
)
951 #endif /* CONFIG_IEEE80211R */
952 #ifdef CONFIG_IEEE80211N
953 if ((sta
->flags
& WLAN_STA_HT
) &&
954 wpa_auth_get_pairwise(sta
->wpa_sm
) == WPA_CIPHER_TKIP
) {
955 wpa_printf(MSG_DEBUG
, "HT: " MACSTR
" tried to "
956 "use TKIP with HT association",
958 resp
= WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
961 #endif /* CONFIG_IEEE80211N */
963 wpa_auth_sta_no_wpa(sta
->wpa_sm
);
965 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
966 sta
->flags
|= WLAN_STA_NONERP
;
967 for (i
= 0; i
< sta
->supported_rates_len
; i
++) {
968 if ((sta
->supported_rates
[i
] & 0x7f) > 22) {
969 sta
->flags
&= ~WLAN_STA_NONERP
;
973 if (sta
->flags
& WLAN_STA_NONERP
&& !sta
->nonerp_set
) {
975 hapd
->iface
->num_sta_non_erp
++;
976 if (hapd
->iface
->num_sta_non_erp
== 1)
977 ieee802_11_set_beacons(hapd
->iface
);
980 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
) &&
981 !sta
->no_short_slot_time_set
) {
982 sta
->no_short_slot_time_set
= 1;
983 hapd
->iface
->num_sta_no_short_slot_time
++;
984 if (hapd
->iface
->current_mode
->mode
==
985 HOSTAPD_MODE_IEEE80211G
&&
986 hapd
->iface
->num_sta_no_short_slot_time
== 1)
987 ieee802_11_set_beacons(hapd
->iface
);
990 if (sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
991 sta
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
993 sta
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
995 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
) &&
996 !sta
->no_short_preamble_set
) {
997 sta
->no_short_preamble_set
= 1;
998 hapd
->iface
->num_sta_no_short_preamble
++;
999 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
1000 && hapd
->iface
->num_sta_no_short_preamble
== 1)
1001 ieee802_11_set_beacons(hapd
->iface
);
1004 #ifdef CONFIG_IEEE80211N
1005 if (sta
->flags
& WLAN_STA_HT
) {
1006 u16 ht_capab
= le_to_host16(
1007 sta
->ht_capabilities
.data
.capabilities_info
);
1008 wpa_printf(MSG_DEBUG
, "HT: STA " MACSTR
" HT Capabilities "
1009 "Info: 0x%04x", MAC2STR(sta
->addr
), ht_capab
);
1010 if ((ht_capab
& HT_CAP_INFO_GREEN_FIELD
) == 0) {
1011 if (!sta
->no_ht_gf_set
) {
1012 sta
->no_ht_gf_set
= 1;
1013 hapd
->iface
->num_sta_ht_no_gf
++;
1015 wpa_printf(MSG_DEBUG
, "%s STA " MACSTR
" - no "
1016 "greenfield, num of non-gf stations %d",
1017 __func__
, MAC2STR(sta
->addr
),
1018 hapd
->iface
->num_sta_ht_no_gf
);
1020 if ((ht_capab
& HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
) == 0) {
1021 if (!sta
->ht_20mhz_set
) {
1022 sta
->ht_20mhz_set
= 1;
1023 hapd
->iface
->num_sta_ht_20mhz
++;
1025 wpa_printf(MSG_DEBUG
, "%s STA " MACSTR
" - 20 MHz HT, "
1026 "num of 20MHz HT STAs %d",
1027 __func__
, MAC2STR(sta
->addr
),
1028 hapd
->iface
->num_sta_ht_20mhz
);
1031 if (!sta
->no_ht_set
) {
1033 hapd
->iface
->num_sta_no_ht
++;
1035 if (hapd
->iconf
->ieee80211n
) {
1036 wpa_printf(MSG_DEBUG
, "%s STA " MACSTR
1037 " - no HT, num of non-HT stations %d",
1038 __func__
, MAC2STR(sta
->addr
),
1039 hapd
->iface
->num_sta_no_ht
);
1043 if (hostapd_ht_operation_update(hapd
->iface
) > 0)
1044 ieee802_11_set_beacons(hapd
->iface
);
1045 #endif /* CONFIG_IEEE80211N */
1047 /* get a unique AID */
1049 wpa_printf(MSG_DEBUG
, " old AID %d", sta
->aid
);
1051 for (sta
->aid
= 1; sta
->aid
<= MAX_AID_TABLE_SIZE
; sta
->aid
++)
1052 if (hapd
->sta_aid
[sta
->aid
- 1] == NULL
)
1054 if (sta
->aid
> MAX_AID_TABLE_SIZE
) {
1056 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
1057 wpa_printf(MSG_ERROR
, " no room for more AIDs");
1060 hapd
->sta_aid
[sta
->aid
- 1] = sta
;
1061 wpa_printf(MSG_DEBUG
, " new AID %d", sta
->aid
);
1065 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1066 HOSTAPD_LEVEL_DEBUG
,
1067 "association OK (aid %d)", sta
->aid
);
1068 /* Station will be marked associated, after it acknowledges AssocResp
1071 #ifdef CONFIG_IEEE80211W
1072 if ((sta
->flags
& WLAN_STA_MFP
) && sta
->sa_query_timed_out
) {
1073 wpa_printf(MSG_DEBUG
, "Allowing %sassociation after timed out "
1074 "SA Query procedure", reassoc
? "re" : "");
1075 /* TODO: Send a protected Disassociate frame to the STA using
1076 * the old key and Reason Code "Previous Authentication no
1077 * longer valid". Make sure this is only sent protected since
1078 * unprotected frame would be received by the STA that is now
1079 * trying to associate.
1082 #endif /* CONFIG_IEEE80211W */
1085 os_memcpy(sta
->previous_ap
, mgmt
->u
.reassoc_req
.current_ap
,
1089 if (sta
->last_assoc_req
)
1090 os_free(sta
->last_assoc_req
);
1091 sta
->last_assoc_req
= os_malloc(len
);
1092 if (sta
->last_assoc_req
)
1093 os_memcpy(sta
->last_assoc_req
, mgmt
, len
);
1095 /* Make sure that the previously registered inactivity timer will not
1096 * remove the STA immediately. */
1097 sta
->timeout_next
= STA_NULLFUNC
;
1100 os_memset(buf
, 0, sizeof(buf
));
1101 reply
= (struct ieee80211_mgmt
*) buf
;
1102 reply
->frame_control
=
1103 IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
1104 (send_deauth
? WLAN_FC_STYPE_DEAUTH
:
1105 (reassoc
? WLAN_FC_STYPE_REASSOC_RESP
:
1106 WLAN_FC_STYPE_ASSOC_RESP
)));
1107 os_memcpy(reply
->da
, mgmt
->sa
, ETH_ALEN
);
1108 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
1109 os_memcpy(reply
->bssid
, mgmt
->bssid
, ETH_ALEN
);
1111 send_len
= IEEE80211_HDRLEN
;
1113 send_len
+= sizeof(reply
->u
.deauth
);
1114 reply
->u
.deauth
.reason_code
= host_to_le16(resp
);
1117 send_len
+= sizeof(reply
->u
.assoc_resp
);
1118 reply
->u
.assoc_resp
.capab_info
=
1119 host_to_le16(hostapd_own_capab_info(hapd
, sta
, 0));
1120 reply
->u
.assoc_resp
.status_code
= host_to_le16(resp
);
1121 reply
->u
.assoc_resp
.aid
= host_to_le16((sta
? sta
->aid
: 0)
1122 | BIT(14) | BIT(15));
1123 /* Supported rates */
1124 p
= hostapd_eid_supp_rates(hapd
, reply
->u
.assoc_resp
.variable
);
1125 /* Extended supported rates */
1126 p
= hostapd_eid_ext_supp_rates(hapd
, p
);
1127 if (sta
->flags
& WLAN_STA_WMM
)
1128 p
= hostapd_eid_wmm(hapd
, p
);
1130 p
= hostapd_eid_ht_capabilities_info(hapd
, p
);
1131 p
= hostapd_eid_ht_operation(hapd
, p
);
1133 #ifdef CONFIG_IEEE80211R
1134 if (resp
== WLAN_STATUS_SUCCESS
) {
1135 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
1136 * Transition Information, RSN */
1137 p
= wpa_sm_write_assoc_resp_ies(sta
->wpa_sm
, p
,
1138 buf
+ sizeof(buf
) - p
,
1141 #endif /* CONFIG_IEEE80211R */
1143 #ifdef CONFIG_IEEE80211W
1144 if (resp
== WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
)
1145 p
= hostapd_eid_assoc_comeback_time(hapd
, sta
, p
);
1146 #endif /* CONFIG_IEEE80211W */
1148 send_len
+= p
- reply
->u
.assoc_resp
.variable
;
1151 if (hostapd_send_mgmt_frame(hapd
, reply
, send_len
, 0) < 0)
1152 perror("handle_assoc: send");
1156 static void handle_disassoc(struct hostapd_data
*hapd
,
1157 struct ieee80211_mgmt
*mgmt
, size_t len
)
1159 struct sta_info
*sta
;
1161 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.disassoc
)) {
1162 printf("handle_disassoc - too short payload (len=%lu)\n",
1163 (unsigned long) len
);
1167 wpa_printf(MSG_DEBUG
, "disassocation: STA=" MACSTR
" reason_code=%d",
1169 le_to_host16(mgmt
->u
.disassoc
.reason_code
));
1171 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1173 printf("Station " MACSTR
" trying to disassociate, but it "
1174 "is not associated.\n", MAC2STR(mgmt
->sa
));
1178 sta
->flags
&= ~WLAN_STA_ASSOC
;
1179 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
1180 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1181 HOSTAPD_LEVEL_INFO
, "disassociated");
1182 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
1183 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
1184 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
1186 accounting_sta_stop(hapd
, sta
);
1187 ieee802_1x_free_station(sta
);
1188 hostapd_sta_remove(hapd
, sta
->addr
);
1190 if (sta
->timeout_next
== STA_NULLFUNC
||
1191 sta
->timeout_next
== STA_DISASSOC
) {
1192 sta
->timeout_next
= STA_DEAUTH
;
1193 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
1194 eloop_register_timeout(AP_DEAUTH_DELAY
, 0, ap_handle_timer
,
1198 mlme_disassociate_indication(
1199 hapd
, sta
, le_to_host16(mgmt
->u
.disassoc
.reason_code
));
1203 static void handle_deauth(struct hostapd_data
*hapd
,
1204 struct ieee80211_mgmt
*mgmt
, size_t len
)
1206 struct sta_info
*sta
;
1208 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.deauth
)) {
1209 printf("handle_deauth - too short payload (len=%lu)\n",
1210 (unsigned long) len
);
1214 wpa_printf(MSG_DEBUG
, "deauthentication: STA=" MACSTR
1217 le_to_host16(mgmt
->u
.deauth
.reason_code
));
1219 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1221 printf("Station " MACSTR
" trying to deauthenticate, but it "
1222 "is not authenticated.\n", MAC2STR(mgmt
->sa
));
1226 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
);
1227 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
1228 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1229 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
1230 mlme_deauthenticate_indication(
1231 hapd
, sta
, le_to_host16(mgmt
->u
.deauth
.reason_code
));
1232 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
1233 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
1234 ap_free_sta(hapd
, sta
);
1238 static void handle_beacon(struct hostapd_data
*hapd
,
1239 struct ieee80211_mgmt
*mgmt
, size_t len
,
1240 struct hostapd_frame_info
*fi
)
1242 struct ieee802_11_elems elems
;
1244 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.beacon
)) {
1245 printf("handle_beacon - too short payload (len=%lu)\n",
1246 (unsigned long) len
);
1250 (void) ieee802_11_parse_elems(mgmt
->u
.beacon
.variable
,
1251 len
- (IEEE80211_HDRLEN
+
1252 sizeof(mgmt
->u
.beacon
)), &elems
,
1255 ap_list_process_beacon(hapd
->iface
, mgmt
, &elems
, fi
);
1259 #ifdef CONFIG_IEEE80211W
1261 /* MLME-SAQuery.request */
1262 void ieee802_11_send_sa_query_req(struct hostapd_data
*hapd
,
1263 const u8
*addr
, const u8
*trans_id
)
1265 struct ieee80211_mgmt mgmt
;
1268 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Sending SA Query Request to "
1269 MACSTR
, MAC2STR(addr
));
1270 wpa_hexdump(MSG_DEBUG
, "IEEE 802.11: SA Query Transaction ID",
1271 trans_id
, WLAN_SA_QUERY_TR_ID_LEN
);
1273 os_memset(&mgmt
, 0, sizeof(mgmt
));
1274 mgmt
.frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
1275 WLAN_FC_STYPE_ACTION
);
1276 os_memcpy(mgmt
.da
, addr
, ETH_ALEN
);
1277 os_memcpy(mgmt
.sa
, hapd
->own_addr
, ETH_ALEN
);
1278 os_memcpy(mgmt
.bssid
, hapd
->own_addr
, ETH_ALEN
);
1279 mgmt
.u
.action
.category
= WLAN_ACTION_SA_QUERY
;
1280 mgmt
.u
.action
.u
.sa_query_req
.action
= WLAN_SA_QUERY_REQUEST
;
1281 os_memcpy(mgmt
.u
.action
.u
.sa_query_req
.trans_id
, trans_id
,
1282 WLAN_SA_QUERY_TR_ID_LEN
);
1283 end
= mgmt
.u
.action
.u
.sa_query_req
.trans_id
+ WLAN_SA_QUERY_TR_ID_LEN
;
1284 if (hostapd_send_mgmt_frame(hapd
, &mgmt
, end
- (u8
*) &mgmt
, 0) < 0)
1285 perror("ieee802_11_send_sa_query_req: send");
1289 static void hostapd_sa_query_action(struct hostapd_data
*hapd
,
1290 struct ieee80211_mgmt
*mgmt
, size_t len
)
1292 struct sta_info
*sta
;
1296 end
= mgmt
->u
.action
.u
.sa_query_resp
.trans_id
+
1297 WLAN_SA_QUERY_TR_ID_LEN
;
1298 if (((u8
*) mgmt
) + len
< end
) {
1299 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Too short SA Query Action "
1300 "frame (len=%lu)", (unsigned long) len
);
1304 if (mgmt
->u
.action
.u
.sa_query_resp
.action
!= WLAN_SA_QUERY_RESPONSE
) {
1305 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Unexpected SA Query "
1306 "Action %d", mgmt
->u
.action
.u
.sa_query_resp
.action
);
1310 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Received SA Query Response from "
1311 MACSTR
, MAC2STR(mgmt
->sa
));
1312 wpa_hexdump(MSG_DEBUG
, "IEEE 802.11: SA Query Transaction ID",
1313 mgmt
->u
.action
.u
.sa_query_resp
.trans_id
,
1314 WLAN_SA_QUERY_TR_ID_LEN
);
1316 /* MLME-SAQuery.confirm */
1318 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1319 if (sta
== NULL
|| sta
->sa_query_trans_id
== NULL
) {
1320 wpa_printf(MSG_DEBUG
, "IEEE 802.11: No matching STA with "
1321 "pending SA Query request found");
1325 for (i
= 0; i
< sta
->sa_query_count
; i
++) {
1326 if (os_memcmp(sta
->sa_query_trans_id
+
1327 i
* WLAN_SA_QUERY_TR_ID_LEN
,
1328 mgmt
->u
.action
.u
.sa_query_resp
.trans_id
,
1329 WLAN_SA_QUERY_TR_ID_LEN
) == 0)
1333 if (i
>= sta
->sa_query_count
) {
1334 wpa_printf(MSG_DEBUG
, "IEEE 802.11: No matching SA Query "
1335 "transaction identifier found");
1339 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1340 HOSTAPD_LEVEL_DEBUG
,
1341 "Reply to pending SA Query received");
1342 ap_sta_stop_sa_query(hapd
, sta
);
1346 static int robust_action_frame(u8 category
)
1348 return category
!= WLAN_ACTION_PUBLIC
&&
1349 category
!= WLAN_ACTION_HT
;
1351 #endif /* CONFIG_IEEE80211W */
1354 static void handle_action(struct hostapd_data
*hapd
,
1355 struct ieee80211_mgmt
*mgmt
, size_t len
)
1357 struct sta_info
*sta
;
1359 if (len
< IEEE80211_HDRLEN
+ 1) {
1360 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1361 HOSTAPD_LEVEL_DEBUG
,
1362 "handle_action - too short payload (len=%lu)",
1363 (unsigned long) len
);
1367 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1368 #ifdef CONFIG_IEEE80211W
1369 if (sta
&& (sta
->flags
& WLAN_STA_MFP
) &&
1370 !(mgmt
->frame_control
& host_to_le16(WLAN_FC_ISWEP
) &&
1371 robust_action_frame(mgmt
->u
.action
.category
))) {
1372 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1373 HOSTAPD_LEVEL_DEBUG
,
1374 "Dropped unprotected Robust Action frame from "
1378 #endif /* CONFIG_IEEE80211W */
1380 switch (mgmt
->u
.action
.category
) {
1381 #ifdef CONFIG_IEEE80211R
1382 case WLAN_ACTION_FT
:
1384 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
1385 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Ignored FT Action "
1386 "frame from unassociated STA " MACSTR
,
1391 if (wpa_ft_action_rx(sta
->wpa_sm
, (u8
*) &mgmt
->u
.action
,
1392 len
- IEEE80211_HDRLEN
))
1397 #endif /* CONFIG_IEEE80211R */
1398 case WLAN_ACTION_WMM
:
1399 hostapd_wmm_action(hapd
, mgmt
, len
);
1401 #ifdef CONFIG_IEEE80211W
1402 case WLAN_ACTION_SA_QUERY
:
1403 hostapd_sa_query_action(hapd
, mgmt
, len
);
1405 #endif /* CONFIG_IEEE80211W */
1408 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1409 HOSTAPD_LEVEL_DEBUG
,
1410 "handle_action - unknown action category %d or invalid "
1412 mgmt
->u
.action
.category
);
1413 if (!(mgmt
->da
[0] & 0x01) && !(mgmt
->u
.action
.category
& 0x80) &&
1414 !(mgmt
->sa
[0] & 0x01)) {
1416 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
1417 * Return the Action frame to the source without change
1418 * except that MSB of the Category set to 1.
1420 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Return unknown Action "
1421 "frame back to sender");
1422 os_memcpy(mgmt
->da
, mgmt
->sa
, ETH_ALEN
);
1423 os_memcpy(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
);
1424 os_memcpy(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
);
1425 mgmt
->u
.action
.category
|= 0x80;
1427 hostapd_send_mgmt_frame(hapd
, mgmt
, len
, 0);
1433 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
1434 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
1436 * @buf: management frame data (starting from IEEE 802.11 header)
1437 * @len: length of frame data in octets
1438 * @stype: management frame subtype from frame control field
1439 * @fi: meta data about received frame (signal level, etc.)
1441 * Process all incoming IEEE 802.11 management frames. This will be called for
1442 * each frame received from the kernel driver through wlan#ap interface. In
1443 * addition, it can be called to re-inserted pending frames (e.g., when using
1444 * external RADIUS server as an MAC ACL).
1446 void ieee802_11_mgmt(struct hostapd_data
*hapd
, u8
*buf
, size_t len
, u16 stype
,
1447 struct hostapd_frame_info
*fi
)
1449 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) buf
;
1452 if (stype
== WLAN_FC_STYPE_BEACON
) {
1453 handle_beacon(hapd
, mgmt
, len
, fi
);
1457 if (fi
&& fi
->passive_scan
)
1460 broadcast
= mgmt
->bssid
[0] == 0xff && mgmt
->bssid
[1] == 0xff &&
1461 mgmt
->bssid
[2] == 0xff && mgmt
->bssid
[3] == 0xff &&
1462 mgmt
->bssid
[4] == 0xff && mgmt
->bssid
[5] == 0xff;
1465 os_memcmp(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
) != 0) {
1466 printf("MGMT: BSSID=" MACSTR
" not our address\n",
1467 MAC2STR(mgmt
->bssid
));
1472 if (stype
== WLAN_FC_STYPE_PROBE_REQ
) {
1473 handle_probe_req(hapd
, mgmt
, len
);
1477 if (os_memcmp(mgmt
->da
, hapd
->own_addr
, ETH_ALEN
) != 0) {
1478 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1479 HOSTAPD_LEVEL_DEBUG
,
1480 "MGMT: DA=" MACSTR
" not our address",
1486 case WLAN_FC_STYPE_AUTH
:
1487 wpa_printf(MSG_DEBUG
, "mgmt::auth");
1488 handle_auth(hapd
, mgmt
, len
);
1490 case WLAN_FC_STYPE_ASSOC_REQ
:
1491 wpa_printf(MSG_DEBUG
, "mgmt::assoc_req");
1492 handle_assoc(hapd
, mgmt
, len
, 0);
1494 case WLAN_FC_STYPE_REASSOC_REQ
:
1495 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_req");
1496 handle_assoc(hapd
, mgmt
, len
, 1);
1498 case WLAN_FC_STYPE_DISASSOC
:
1499 wpa_printf(MSG_DEBUG
, "mgmt::disassoc");
1500 handle_disassoc(hapd
, mgmt
, len
);
1502 case WLAN_FC_STYPE_DEAUTH
:
1503 wpa_printf(MSG_DEBUG
, "mgmt::deauth");
1504 handle_deauth(hapd
, mgmt
, len
);
1506 case WLAN_FC_STYPE_ACTION
:
1507 wpa_printf(MSG_DEBUG
, "mgmt::action");
1508 handle_action(hapd
, mgmt
, len
);
1511 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1512 HOSTAPD_LEVEL_DEBUG
,
1513 "unknown mgmt frame subtype %d", stype
);
1519 static void handle_auth_cb(struct hostapd_data
*hapd
,
1520 struct ieee80211_mgmt
*mgmt
,
1523 u16 auth_alg
, auth_transaction
, status_code
;
1524 struct sta_info
*sta
;
1527 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
1528 HOSTAPD_LEVEL_NOTICE
,
1529 "did not acknowledge authentication response");
1533 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
1534 printf("handle_auth_cb - too short payload (len=%lu)\n",
1535 (unsigned long) len
);
1539 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
1540 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
1541 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
1543 sta
= ap_get_sta(hapd
, mgmt
->da
);
1545 printf("handle_auth_cb: STA " MACSTR
" not found\n",
1550 if (status_code
== WLAN_STATUS_SUCCESS
&&
1551 ((auth_alg
== WLAN_AUTH_OPEN
&& auth_transaction
== 2) ||
1552 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 4))) {
1553 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1554 HOSTAPD_LEVEL_INFO
, "authenticated");
1555 sta
->flags
|= WLAN_STA_AUTH
;
1560 #ifdef CONFIG_IEEE80211N
1562 hostapd_get_ht_capab(struct hostapd_data
*hapd
,
1563 struct ht_cap_ie
*ht_cap_ie
,
1564 struct ht_cap_ie
*neg_ht_cap_ie
)
1568 os_memcpy(neg_ht_cap_ie
, ht_cap_ie
, sizeof(struct ht_cap_ie
));
1569 cap
= le_to_host16(neg_ht_cap_ie
->data
.capabilities_info
);
1570 cap
&= hapd
->iconf
->ht_capab
;
1571 cap
|= (hapd
->iconf
->ht_capab
& HT_CAP_INFO_SMPS_DISABLED
);
1573 /* FIXME: Rx STBC needs to be handled specially */
1574 cap
|= (hapd
->iconf
->ht_capab
& HT_CAP_INFO_RX_STBC_MASK
);
1575 neg_ht_cap_ie
->data
.capabilities_info
= host_to_le16(cap
);
1577 #endif /* CONFIG_IEEE80211N */
1580 static void handle_assoc_cb(struct hostapd_data
*hapd
,
1581 struct ieee80211_mgmt
*mgmt
,
1582 size_t len
, int reassoc
, int ok
)
1585 struct sta_info
*sta
;
1587 #ifdef CONFIG_IEEE80211N
1588 struct ht_cap_ie ht_cap
;
1589 #endif /* CONFIG_IEEE80211N */
1590 struct ht_cap_ie
*ht_cap_ptr
= NULL
;
1591 int set_flags
, flags_and
, flags_or
;
1594 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
1595 HOSTAPD_LEVEL_DEBUG
,
1596 "did not acknowledge association response");
1600 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_resp
) :
1601 sizeof(mgmt
->u
.assoc_resp
))) {
1602 printf("handle_assoc_cb(reassoc=%d) - too short payload "
1603 "(len=%lu)\n", reassoc
, (unsigned long) len
);
1608 status
= le_to_host16(mgmt
->u
.reassoc_resp
.status_code
);
1610 status
= le_to_host16(mgmt
->u
.assoc_resp
.status_code
);
1612 sta
= ap_get_sta(hapd
, mgmt
->da
);
1614 printf("handle_assoc_cb: STA " MACSTR
" not found\n",
1619 if (status
!= WLAN_STATUS_SUCCESS
)
1622 /* Stop previous accounting session, if one is started, and allocate
1623 * new session id for the new session. */
1624 accounting_sta_stop(hapd
, sta
);
1626 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1628 "associated (aid %d)",
1631 if (sta
->flags
& WLAN_STA_ASSOC
)
1633 sta
->flags
|= WLAN_STA_ASSOC
;
1636 mlme_reassociate_indication(hapd
, sta
);
1638 mlme_associate_indication(hapd
, sta
);
1640 #ifdef CONFIG_IEEE80211N
1641 if (sta
->flags
& WLAN_STA_HT
) {
1642 ht_cap_ptr
= &ht_cap
;
1643 hostapd_get_ht_capab(hapd
, &sta
->ht_capabilities
, ht_cap_ptr
);
1645 #endif /* CONFIG_IEEE80211N */
1647 #ifdef CONFIG_IEEE80211W
1648 sta
->sa_query_timed_out
= 0;
1649 #endif /* CONFIG_IEEE80211W */
1652 * Remove the STA entry in order to make sure the STA PS state gets
1653 * cleared and configuration gets updated in case of reassociation back
1656 hostapd_sta_remove(hapd
, sta
->addr
);
1658 if (hostapd_sta_add(hapd
->conf
->iface
, hapd
, sta
->addr
, sta
->aid
,
1659 sta
->capability
, sta
->supported_rates
,
1660 sta
->supported_rates_len
, 0, sta
->listen_interval
,
1663 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1664 HOSTAPD_LEVEL_NOTICE
,
1665 "Could not add STA to kernel driver");
1668 if (sta
->eapol_sm
== NULL
) {
1670 * This STA does not use RADIUS server for EAP authentication,
1671 * so bind it to the selected VLAN interface now, since the
1672 * interface selection is not going to change anymore.
1674 ap_sta_bind_vlan(hapd
, sta
, 0);
1675 } else if (sta
->vlan_id
) {
1676 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
1677 ap_sta_bind_vlan(hapd
, sta
, 0);
1680 set_flags
= WLAN_STA_SHORT_PREAMBLE
| WLAN_STA_WMM
| WLAN_STA_MFP
;
1681 if (!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
&&
1682 sta
->flags
& WLAN_STA_AUTHORIZED
)
1683 set_flags
|= WLAN_STA_AUTHORIZED
;
1684 flags_or
= sta
->flags
& set_flags
;
1685 flags_and
= sta
->flags
| ~set_flags
;
1686 hostapd_sta_set_flags(hapd
, sta
->addr
, sta
->flags
,
1687 flags_or
, flags_and
);
1689 if (sta
->auth_alg
== WLAN_AUTH_FT
)
1690 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC_FT
);
1692 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
1693 hostapd_new_assoc_sta(hapd
, sta
, !new_assoc
);
1695 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
1698 /* Copy of the association request is not needed anymore */
1699 if (sta
->last_assoc_req
) {
1700 os_free(sta
->last_assoc_req
);
1701 sta
->last_assoc_req
= NULL
;
1707 * ieee802_11_mgmt_cb - Process management frame TX status callback
1708 * @hapd: hostapd BSS data structure (the BSS from which the management frame
1710 * @buf: management frame data (starting from IEEE 802.11 header)
1711 * @len: length of frame data in octets
1712 * @stype: management frame subtype from frame control field
1713 * @ok: Whether the frame was ACK'ed
1715 void ieee802_11_mgmt_cb(struct hostapd_data
*hapd
, u8
*buf
, size_t len
,
1718 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) buf
;
1721 case WLAN_FC_STYPE_AUTH
:
1722 wpa_printf(MSG_DEBUG
, "mgmt::auth cb");
1723 handle_auth_cb(hapd
, mgmt
, len
, ok
);
1725 case WLAN_FC_STYPE_ASSOC_RESP
:
1726 wpa_printf(MSG_DEBUG
, "mgmt::assoc_resp cb");
1727 handle_assoc_cb(hapd
, mgmt
, len
, 0, ok
);
1729 case WLAN_FC_STYPE_REASSOC_RESP
:
1730 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_resp cb");
1731 handle_assoc_cb(hapd
, mgmt
, len
, 1, ok
);
1733 case WLAN_FC_STYPE_PROBE_RESP
:
1734 wpa_printf(MSG_DEBUG
, "mgmt::proberesp cb");
1736 case WLAN_FC_STYPE_DEAUTH
:
1739 case WLAN_FC_STYPE_ACTION
:
1740 wpa_printf(MSG_DEBUG
, "mgmt::action cb");
1743 printf("unknown mgmt cb frame subtype %d\n", stype
);
1749 static void ieee80211_tkip_countermeasures_stop(void *eloop_ctx
,
1752 struct hostapd_data
*hapd
= eloop_ctx
;
1753 hapd
->tkip_countermeasures
= 0;
1754 hostapd_set_countermeasures(hapd
, 0);
1755 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_IEEE80211
,
1756 HOSTAPD_LEVEL_INFO
, "TKIP countermeasures ended");
1760 static void ieee80211_tkip_countermeasures_start(struct hostapd_data
*hapd
)
1762 struct sta_info
*sta
;
1764 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_IEEE80211
,
1765 HOSTAPD_LEVEL_INFO
, "TKIP countermeasures initiated");
1767 wpa_auth_countermeasures_start(hapd
->wpa_auth
);
1768 hapd
->tkip_countermeasures
= 1;
1769 hostapd_set_countermeasures(hapd
, 1);
1770 wpa_gtk_rekey(hapd
->wpa_auth
);
1771 eloop_cancel_timeout(ieee80211_tkip_countermeasures_stop
, hapd
, NULL
);
1772 eloop_register_timeout(60, 0, ieee80211_tkip_countermeasures_stop
,
1774 for (sta
= hapd
->sta_list
; sta
!= NULL
; sta
= sta
->next
) {
1775 hostapd_sta_deauth(hapd
, sta
->addr
,
1776 WLAN_REASON_MICHAEL_MIC_FAILURE
);
1777 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
|
1778 WLAN_STA_AUTHORIZED
);
1779 hostapd_sta_remove(hapd
, sta
->addr
);
1784 void ieee80211_michael_mic_failure(struct hostapd_data
*hapd
, const u8
*addr
,
1789 if (addr
&& local
) {
1790 struct sta_info
*sta
= ap_get_sta(hapd
, addr
);
1792 wpa_auth_sta_local_mic_failure_report(sta
->wpa_sm
);
1793 hostapd_logger(hapd
, addr
, HOSTAPD_MODULE_IEEE80211
,
1795 "Michael MIC failure detected in "
1797 mlme_michaelmicfailure_indication(hapd
, addr
);
1799 wpa_printf(MSG_DEBUG
,
1800 "MLME-MICHAELMICFAILURE.indication "
1801 "for not associated STA (" MACSTR
1802 ") ignored", MAC2STR(addr
));
1808 if (now
> hapd
->michael_mic_failure
+ 60) {
1809 hapd
->michael_mic_failures
= 1;
1811 hapd
->michael_mic_failures
++;
1812 if (hapd
->michael_mic_failures
> 1)
1813 ieee80211_tkip_countermeasures_start(hapd
);
1815 hapd
->michael_mic_failure
= now
;
1819 int ieee802_11_get_mib(struct hostapd_data
*hapd
, char *buf
, size_t buflen
)
1826 int ieee802_11_get_mib_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1827 char *buf
, size_t buflen
)
1833 #endif /* CONFIG_NATIVE_WINDOWS */