2 * hostapd / IEEE 802.11 Management
3 * Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
11 #ifndef CONFIG_NATIVE_WINDOWS
13 #include "utils/common.h"
14 #include "utils/eloop.h"
15 #include "crypto/crypto.h"
16 #include "crypto/sha256.h"
17 #include "crypto/random.h"
18 #include "common/ieee802_11_defs.h"
19 #include "common/ieee802_11_common.h"
20 #include "common/wpa_ctrl.h"
21 #include "common/sae.h"
22 #include "radius/radius.h"
23 #include "radius/radius_client.h"
28 #include "ieee802_11_auth.h"
30 #include "ieee802_1x.h"
32 #include "pmksa_cache_auth.h"
35 #include "accounting.h"
36 #include "ap_config.h"
38 #include "p2p_hostapd.h"
39 #include "ap_drv_ops.h"
41 #include "ieee802_11.h"
45 u8
* hostapd_eid_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
50 if (hapd
->iface
->current_rates
== NULL
)
53 *pos
++ = WLAN_EID_SUPP_RATES
;
54 num
= hapd
->iface
->num_rates
;
55 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
)
57 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
)
60 /* rest of the rates are encoded in Extended supported
66 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
;
69 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
70 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
75 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&& count
< 8) {
77 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY
;
80 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&& count
< 8) {
82 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY
;
89 u8
* hostapd_eid_ext_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
94 if (hapd
->iface
->current_rates
== NULL
)
97 num
= hapd
->iface
->num_rates
;
98 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
)
100 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
)
106 *pos
++ = WLAN_EID_EXT_SUPP_RATES
;
108 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
+ 8;
112 continue; /* already in SuppRates IE */
113 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
114 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
119 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
) {
122 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY
;
125 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
) {
128 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY
;
135 u16
hostapd_own_capab_info(struct hostapd_data
*hapd
, struct sta_info
*sta
,
138 int capab
= WLAN_CAPABILITY_ESS
;
142 /* Check if any of configured channels require DFS */
143 dfs
= hostapd_is_dfs_required(hapd
->iface
);
145 wpa_printf(MSG_WARNING
, "Failed to check if DFS is required; ret=%d",
150 if (hapd
->iface
->num_sta_no_short_preamble
== 0 &&
151 hapd
->iconf
->preamble
== SHORT_PREAMBLE
)
152 capab
|= WLAN_CAPABILITY_SHORT_PREAMBLE
;
154 privacy
= hapd
->conf
->ssid
.wep
.keys_set
;
156 if (hapd
->conf
->ieee802_1x
&&
157 (hapd
->conf
->default_wep_key_len
||
158 hapd
->conf
->individual_wep_key_len
))
165 if (hapd
->conf
->osen
)
167 #endif /* CONFIG_HS20 */
170 int policy
, def_klen
;
171 if (probe
&& sta
->ssid_probe
) {
172 policy
= sta
->ssid_probe
->security_policy
;
173 def_klen
= sta
->ssid_probe
->wep
.default_len
;
175 policy
= sta
->ssid
->security_policy
;
176 def_klen
= sta
->ssid
->wep
.default_len
;
178 privacy
= policy
!= SECURITY_PLAINTEXT
;
179 if (policy
== SECURITY_IEEE_802_1X
&& def_klen
== 0)
184 capab
|= WLAN_CAPABILITY_PRIVACY
;
186 if (hapd
->iface
->current_mode
&&
187 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
&&
188 hapd
->iface
->num_sta_no_short_slot_time
== 0)
189 capab
|= WLAN_CAPABILITY_SHORT_SLOT_TIME
;
192 * Currently, Spectrum Management capability bit is set when directly
193 * requested in configuration by spectrum_mgmt_required or when AP is
194 * running on DFS channel.
195 * TODO: Also consider driver support for TPC to set Spectrum Mgmt bit
197 if (hapd
->iface
->current_mode
&&
198 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211A
&&
199 (hapd
->iconf
->spectrum_mgmt_required
|| dfs
))
200 capab
|= WLAN_CAPABILITY_SPECTRUM_MGMT
;
202 if (hapd
->conf
->radio_measurements
)
203 capab
|= IEEE80211_CAP_RRM
;
209 static u16
auth_shared_key(struct hostapd_data
*hapd
, struct sta_info
*sta
,
210 u16 auth_transaction
, const u8
*challenge
,
213 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
215 "authentication (shared key, transaction %d)",
218 if (auth_transaction
== 1) {
219 if (!sta
->challenge
) {
220 /* Generate a pseudo-random challenge */
224 sta
->challenge
= os_zalloc(WLAN_AUTH_CHALLENGE_LEN
);
225 if (sta
->challenge
== NULL
)
226 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
230 os_memcpy(key
, &now
.sec
, 4);
231 os_memcpy(key
+ 4, &r
, 4);
232 rc4_skip(key
, sizeof(key
), 0,
233 sta
->challenge
, WLAN_AUTH_CHALLENGE_LEN
);
238 if (auth_transaction
!= 3)
239 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
242 if (!iswep
|| !sta
->challenge
|| !challenge
||
243 os_memcmp_const(sta
->challenge
, challenge
,
244 WLAN_AUTH_CHALLENGE_LEN
)) {
245 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
247 "shared key authentication - invalid "
248 "challenge-response");
249 return WLAN_STATUS_CHALLENGE_FAIL
;
252 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
254 "authentication OK (shared key)");
255 sta
->flags
|= WLAN_STA_AUTH
;
256 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
257 os_free(sta
->challenge
);
258 sta
->challenge
= NULL
;
264 static void send_auth_reply(struct hostapd_data
*hapd
,
265 const u8
*dst
, const u8
*bssid
,
266 u16 auth_alg
, u16 auth_transaction
, u16 resp
,
267 const u8
*ies
, size_t ies_len
)
269 struct ieee80211_mgmt
*reply
;
273 rlen
= IEEE80211_HDRLEN
+ sizeof(reply
->u
.auth
) + ies_len
;
274 buf
= os_zalloc(rlen
);
278 reply
= (struct ieee80211_mgmt
*) buf
;
279 reply
->frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
281 os_memcpy(reply
->da
, dst
, ETH_ALEN
);
282 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
283 os_memcpy(reply
->bssid
, bssid
, ETH_ALEN
);
285 reply
->u
.auth
.auth_alg
= host_to_le16(auth_alg
);
286 reply
->u
.auth
.auth_transaction
= host_to_le16(auth_transaction
);
287 reply
->u
.auth
.status_code
= host_to_le16(resp
);
290 os_memcpy(reply
->u
.auth
.variable
, ies
, ies_len
);
292 wpa_printf(MSG_DEBUG
, "authentication reply: STA=" MACSTR
293 " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)",
294 MAC2STR(dst
), auth_alg
, auth_transaction
,
295 resp
, (unsigned long) ies_len
);
296 if (hostapd_drv_send_mlme(hapd
, reply
, rlen
, 0) < 0)
297 wpa_printf(MSG_INFO
, "send_auth_reply: send");
303 #ifdef CONFIG_IEEE80211R
304 static void handle_auth_ft_finish(void *ctx
, const u8
*dst
, const u8
*bssid
,
305 u16 auth_transaction
, u16 status
,
306 const u8
*ies
, size_t ies_len
)
308 struct hostapd_data
*hapd
= ctx
;
309 struct sta_info
*sta
;
311 send_auth_reply(hapd
, dst
, bssid
, WLAN_AUTH_FT
, auth_transaction
,
312 status
, ies
, ies_len
);
314 if (status
!= WLAN_STATUS_SUCCESS
)
317 sta
= ap_get_sta(hapd
, dst
);
321 hostapd_logger(hapd
, dst
, HOSTAPD_MODULE_IEEE80211
,
322 HOSTAPD_LEVEL_DEBUG
, "authentication OK (FT)");
323 sta
->flags
|= WLAN_STA_AUTH
;
324 mlme_authenticate_indication(hapd
, sta
);
326 #endif /* CONFIG_IEEE80211R */
331 static struct wpabuf
* auth_build_sae_commit(struct hostapd_data
*hapd
,
332 struct sta_info
*sta
, int update
)
336 if (hapd
->conf
->ssid
.wpa_passphrase
== NULL
) {
337 wpa_printf(MSG_DEBUG
, "SAE: No password available");
342 sae_prepare_commit(hapd
->own_addr
, sta
->addr
,
343 (u8
*) hapd
->conf
->ssid
.wpa_passphrase
,
344 os_strlen(hapd
->conf
->ssid
.wpa_passphrase
),
346 wpa_printf(MSG_DEBUG
, "SAE: Could not pick PWE");
350 buf
= wpabuf_alloc(SAE_COMMIT_MAX_LEN
);
353 sae_write_commit(sta
->sae
, buf
, sta
->sae
->tmp
?
354 sta
->sae
->tmp
->anti_clogging_token
: NULL
);
360 static struct wpabuf
* auth_build_sae_confirm(struct hostapd_data
*hapd
,
361 struct sta_info
*sta
)
365 buf
= wpabuf_alloc(SAE_CONFIRM_MAX_LEN
);
369 sae_write_confirm(sta
->sae
, buf
);
375 static int auth_sae_send_commit(struct hostapd_data
*hapd
,
376 struct sta_info
*sta
,
377 const u8
*bssid
, int update
)
381 data
= auth_build_sae_commit(hapd
, sta
, update
);
383 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
385 send_auth_reply(hapd
, sta
->addr
, bssid
,
386 WLAN_AUTH_SAE
, 1, WLAN_STATUS_SUCCESS
,
387 wpabuf_head(data
), wpabuf_len(data
));
391 return WLAN_STATUS_SUCCESS
;
395 static int auth_sae_send_confirm(struct hostapd_data
*hapd
,
396 struct sta_info
*sta
,
401 data
= auth_build_sae_confirm(hapd
, sta
);
403 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
405 send_auth_reply(hapd
, sta
->addr
, bssid
,
406 WLAN_AUTH_SAE
, 2, WLAN_STATUS_SUCCESS
,
407 wpabuf_head(data
), wpabuf_len(data
));
411 return WLAN_STATUS_SUCCESS
;
415 static int use_sae_anti_clogging(struct hostapd_data
*hapd
)
417 struct sta_info
*sta
;
418 unsigned int open
= 0;
420 if (hapd
->conf
->sae_anti_clogging_threshold
== 0)
423 for (sta
= hapd
->sta_list
; sta
; sta
= sta
->next
) {
426 if (sta
->sae
->state
!= SAE_COMMITTED
&&
427 sta
->sae
->state
!= SAE_CONFIRMED
)
430 if (open
>= hapd
->conf
->sae_anti_clogging_threshold
)
438 static int check_sae_token(struct hostapd_data
*hapd
, const u8
*addr
,
439 const u8
*token
, size_t token_len
)
441 u8 mac
[SHA256_MAC_LEN
];
443 if (token_len
!= SHA256_MAC_LEN
)
445 if (hmac_sha256(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
446 addr
, ETH_ALEN
, mac
) < 0 ||
447 os_memcmp_const(token
, mac
, SHA256_MAC_LEN
) != 0)
454 static struct wpabuf
* auth_build_token_req(struct hostapd_data
*hapd
,
455 int group
, const u8
*addr
)
459 struct os_reltime now
;
461 os_get_reltime(&now
);
462 if (!os_reltime_initialized(&hapd
->last_sae_token_key_update
) ||
463 os_reltime_expired(&now
, &hapd
->last_sae_token_key_update
, 60)) {
464 if (random_get_bytes(hapd
->sae_token_key
,
465 sizeof(hapd
->sae_token_key
)) < 0)
467 wpa_hexdump(MSG_DEBUG
, "SAE: Updated token key",
468 hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
));
469 hapd
->last_sae_token_key_update
= now
;
472 buf
= wpabuf_alloc(sizeof(le16
) + SHA256_MAC_LEN
);
476 wpabuf_put_le16(buf
, group
); /* Finite Cyclic Group */
478 token
= wpabuf_put(buf
, SHA256_MAC_LEN
);
479 hmac_sha256(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
480 addr
, ETH_ALEN
, token
);
486 static int sae_sm_step(struct hostapd_data
*hapd
, struct sta_info
*sta
,
487 const u8
*bssid
, u8 auth_transaction
)
491 if (auth_transaction
!= 1 && auth_transaction
!= 2)
492 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
494 switch (sta
->sae
->state
) {
496 if (auth_transaction
== 1) {
497 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1);
500 sta
->sae
->state
= SAE_COMMITTED
;
502 if (sae_process_commit(sta
->sae
) < 0)
503 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
506 * In mesh case, both Commit and Confirm can be sent
507 * immediately. In infrastructure BSS, only a single
508 * Authentication frame (Commit) is expected from the AP
509 * here and the second one (Confirm) will be sent once
510 * the STA has sent its second Authentication frame
513 if (hapd
->conf
->mesh
& MESH_ENABLED
) {
515 * Send both Commit and Confirm immediately
516 * based on SAE finite state machine
517 * Nothing -> Confirm transition.
519 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
522 sta
->sae
->state
= SAE_CONFIRMED
;
525 * For infrastructure BSS, send only the Commit
526 * message now to get alternating sequence of
527 * Authentication frames between the AP and STA.
528 * Confirm will be sent in
529 * Commited -> Confirmed/Accepted transition
530 * when receiving Confirm from STA.
534 hostapd_logger(hapd
, sta
->addr
,
535 HOSTAPD_MODULE_IEEE80211
,
537 "SAE confirm before commit");
541 if (auth_transaction
== 1) {
542 if (sae_process_commit(sta
->sae
) < 0)
543 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
545 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
548 sta
->sae
->state
= SAE_CONFIRMED
;
549 } else if (hapd
->conf
->mesh
& MESH_ENABLED
) {
551 * In mesh case, follow SAE finite state machine and
554 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1);
559 * For instructure BSS, send the postponed Confirm from
560 * Nothing -> Confirmed transition that was reduced to
561 * Nothing -> Committed above.
563 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
567 sta
->sae
->state
= SAE_CONFIRMED
;
570 * Since this was triggered on Confirm RX, run another
571 * step to get to Accepted without waiting for
574 return sae_sm_step(hapd
, sta
, bssid
, auth_transaction
);
578 if (auth_transaction
== 1) {
579 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1);
583 if (sae_process_commit(sta
->sae
) < 0)
584 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
586 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
590 sta
->flags
|= WLAN_STA_AUTH
;
591 sta
->auth_alg
= WLAN_AUTH_SAE
;
592 mlme_authenticate_indication(hapd
, sta
);
593 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
594 sta
->sae
->state
= SAE_ACCEPTED
;
595 wpa_auth_pmksa_add_sae(hapd
->wpa_auth
, sta
->addr
,
600 if (auth_transaction
== 1) {
601 wpa_printf(MSG_DEBUG
, "SAE: remove the STA (" MACSTR
602 ") doing reauthentication",
604 ap_free_sta(hapd
, sta
);
606 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
607 sae_clear_temp_data(sta
->sae
);
613 wpa_printf(MSG_ERROR
, "SAE: invalid state %d",
615 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
617 return WLAN_STATUS_SUCCESS
;
621 static void handle_auth_sae(struct hostapd_data
*hapd
, struct sta_info
*sta
,
622 const struct ieee80211_mgmt
*mgmt
, size_t len
,
623 u16 auth_transaction
, u16 status_code
)
625 u16 resp
= WLAN_STATUS_SUCCESS
;
626 struct wpabuf
*data
= NULL
;
629 if (auth_transaction
!= 1 || status_code
!= WLAN_STATUS_SUCCESS
)
631 sta
->sae
= os_zalloc(sizeof(*sta
->sae
));
632 if (sta
->sae
== NULL
)
634 sta
->sae
->state
= SAE_NOTHING
;
637 if (auth_transaction
== 1) {
638 const u8
*token
= NULL
, *pos
, *end
;
639 size_t token_len
= 0;
640 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
642 "start SAE authentication (RX commit, status=%u)",
645 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
646 status_code
== WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
&&
648 pos
= mgmt
->u
.auth
.variable
;
649 end
= ((const u8
*) mgmt
) + len
;
650 if (pos
+ sizeof(le16
) > end
) {
651 wpa_printf(MSG_ERROR
,
652 "SAE: Too short anti-clogging token request");
653 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
656 resp
= sae_group_allowed(sta
->sae
,
657 hapd
->conf
->sae_groups
,
659 if (resp
!= WLAN_STATUS_SUCCESS
) {
660 wpa_printf(MSG_ERROR
,
661 "SAE: Invalid group in anti-clogging token request");
666 wpabuf_free(sta
->sae
->tmp
->anti_clogging_token
);
667 sta
->sae
->tmp
->anti_clogging_token
=
668 wpabuf_alloc_copy(pos
, end
- pos
);
669 if (sta
->sae
->tmp
->anti_clogging_token
== NULL
) {
670 wpa_printf(MSG_ERROR
,
671 "SAE: Failed to alloc for anti-clogging token");
676 * IEEE Std 802.11-2012, 11.3.8.6.4: If the Status code
677 * is 76, a new Commit Message shall be constructed
678 * with the Anti-Clogging Token from the received
679 * Authentication frame, and the commit-scalar and
680 * COMMIT-ELEMENT previously sent.
682 if (auth_sae_send_commit(hapd
, sta
, mgmt
->bssid
, 0)) {
683 wpa_printf(MSG_ERROR
,
684 "SAE: Failed to send commit message");
687 sta
->sae
->state
= SAE_COMMITTED
;
691 if (status_code
!= WLAN_STATUS_SUCCESS
)
694 resp
= sae_parse_commit(sta
->sae
, mgmt
->u
.auth
.variable
,
695 ((const u8
*) mgmt
) + len
-
696 mgmt
->u
.auth
.variable
, &token
,
697 &token_len
, hapd
->conf
->sae_groups
);
698 if (token
&& check_sae_token(hapd
, sta
->addr
, token
, token_len
)
700 wpa_printf(MSG_DEBUG
, "SAE: Drop commit message with "
701 "incorrect token from " MACSTR
,
706 if (resp
!= WLAN_STATUS_SUCCESS
)
709 if (!token
&& use_sae_anti_clogging(hapd
)) {
710 wpa_printf(MSG_DEBUG
,
711 "SAE: Request anti-clogging token from "
712 MACSTR
, MAC2STR(sta
->addr
));
713 data
= auth_build_token_req(hapd
, sta
->sae
->group
,
715 resp
= WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
;
716 if (hapd
->conf
->mesh
& MESH_ENABLED
)
717 sta
->sae
->state
= SAE_NOTHING
;
721 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
);
722 } else if (auth_transaction
== 2) {
723 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
725 "SAE authentication (RX confirm, status=%u)",
727 if (status_code
!= WLAN_STATUS_SUCCESS
)
729 if (sta
->sae
->state
>= SAE_CONFIRMED
||
730 !(hapd
->conf
->mesh
& MESH_ENABLED
)) {
731 if (sae_check_confirm(sta
->sae
, mgmt
->u
.auth
.variable
,
732 ((u8
*) mgmt
) + len
-
733 mgmt
->u
.auth
.variable
) < 0) {
734 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
738 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
);
740 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
742 "unexpected SAE authentication transaction %u (status=%u)",
743 auth_transaction
, status_code
);
744 if (status_code
!= WLAN_STATUS_SUCCESS
)
746 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
750 if (resp
!= WLAN_STATUS_SUCCESS
) {
751 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
752 auth_transaction
, resp
,
753 data
? wpabuf_head(data
) : (u8
*) "",
754 data
? wpabuf_len(data
) : 0);
761 * auth_sae_init_committed - Send COMMIT and start SAE in committed state
762 * @hapd: BSS data for the device initiating the authentication
763 * @sta: the peer to which commit authentication frame is sent
765 * This function implements Init event handling (IEEE Std 802.11-2012,
766 * 11.3.8.6.3) in which initial COMMIT message is sent. Prior to calling, the
767 * sta->sae structure should be initialized appropriately via a call to
768 * sae_prepare_commit().
770 int auth_sae_init_committed(struct hostapd_data
*hapd
, struct sta_info
*sta
)
774 if (!sta
->sae
|| !sta
->sae
->tmp
)
777 if (sta
->sae
->state
!= SAE_NOTHING
)
780 ret
= auth_sae_send_commit(hapd
, sta
, hapd
->own_addr
, 0);
784 sta
->sae
->state
= SAE_COMMITTED
;
789 #endif /* CONFIG_SAE */
792 static void handle_auth(struct hostapd_data
*hapd
,
793 const struct ieee80211_mgmt
*mgmt
, size_t len
)
795 u16 auth_alg
, auth_transaction
, status_code
;
796 u16 resp
= WLAN_STATUS_SUCCESS
;
797 struct sta_info
*sta
= NULL
;
800 const u8
*challenge
= NULL
;
801 u32 session_timeout
, acct_interim_interval
;
803 struct hostapd_sta_wpa_psk_short
*psk
= NULL
;
804 u8 resp_ies
[2 + WLAN_AUTH_CHALLENGE_LEN
];
805 size_t resp_ies_len
= 0;
806 char *identity
= NULL
;
807 char *radius_cui
= NULL
;
810 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
811 wpa_printf(MSG_INFO
, "handle_auth - too short payload (len=%lu)",
812 (unsigned long) len
);
816 #ifdef CONFIG_TESTING_OPTIONS
817 if (hapd
->iconf
->ignore_auth_probability
> 0.0 &&
818 drand48() < hapd
->iconf
->ignore_auth_probability
) {
820 "TESTING: ignoring auth frame from " MACSTR
,
824 #endif /* CONFIG_TESTING_OPTIONS */
826 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
827 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
828 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
829 fc
= le_to_host16(mgmt
->frame_control
);
830 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
832 if (len
>= IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
) +
833 2 + WLAN_AUTH_CHALLENGE_LEN
&&
834 mgmt
->u
.auth
.variable
[0] == WLAN_EID_CHALLENGE
&&
835 mgmt
->u
.auth
.variable
[1] == WLAN_AUTH_CHALLENGE_LEN
)
836 challenge
= &mgmt
->u
.auth
.variable
[2];
838 wpa_printf(MSG_DEBUG
, "authentication: STA=" MACSTR
" auth_alg=%d "
839 "auth_transaction=%d status_code=%d wep=%d%s "
841 MAC2STR(mgmt
->sa
), auth_alg
, auth_transaction
,
842 status_code
, !!(fc
& WLAN_FC_ISWEP
),
843 challenge
? " challenge" : "",
844 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
846 if (hapd
->tkip_countermeasures
) {
847 resp
= WLAN_REASON_MICHAEL_MIC_FAILURE
;
851 if (!(((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_OPEN
) &&
852 auth_alg
== WLAN_AUTH_OPEN
) ||
853 #ifdef CONFIG_IEEE80211R
854 (hapd
->conf
->wpa
&& wpa_key_mgmt_ft(hapd
->conf
->wpa_key_mgmt
) &&
855 auth_alg
== WLAN_AUTH_FT
) ||
856 #endif /* CONFIG_IEEE80211R */
858 (hapd
->conf
->wpa
&& wpa_key_mgmt_sae(hapd
->conf
->wpa_key_mgmt
) &&
859 auth_alg
== WLAN_AUTH_SAE
) ||
860 #endif /* CONFIG_SAE */
861 ((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_SHARED
) &&
862 auth_alg
== WLAN_AUTH_SHARED_KEY
))) {
863 wpa_printf(MSG_INFO
, "Unsupported authentication algorithm (%d)",
865 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
869 if (!(auth_transaction
== 1 || auth_alg
== WLAN_AUTH_SAE
||
870 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 3))) {
871 wpa_printf(MSG_INFO
, "Unknown authentication transaction number (%d)",
873 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
877 if (os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
878 wpa_printf(MSG_INFO
, "Station " MACSTR
" not allowed to authenticate",
880 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
884 res
= hostapd_allowed_address(hapd
, mgmt
->sa
, (u8
*) mgmt
, len
,
886 &acct_interim_interval
, &vlan_id
,
887 &psk
, &identity
, &radius_cui
);
889 if (res
== HOSTAPD_ACL_REJECT
) {
890 wpa_printf(MSG_INFO
, "Station " MACSTR
" not allowed to authenticate",
892 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
895 if (res
== HOSTAPD_ACL_PENDING
) {
896 wpa_printf(MSG_DEBUG
, "Authentication frame from " MACSTR
897 " waiting for an external authentication",
899 /* Authentication code will re-send the authentication frame
900 * after it has received (and cached) information from the
901 * external source. */
905 sta
= ap_get_sta(hapd
, mgmt
->sa
);
907 if ((fc
& WLAN_FC_RETRY
) &&
908 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
909 sta
->last_seq_ctrl
== seq_ctrl
&&
910 sta
->last_subtype
== WLAN_FC_STYPE_AUTH
) {
911 hostapd_logger(hapd
, sta
->addr
,
912 HOSTAPD_MODULE_IEEE80211
,
914 "Drop repeated authentication frame seq_ctrl=0x%x",
920 if (hapd
->conf
->mesh
& MESH_ENABLED
) {
921 /* if the mesh peer is not available, we don't do auth.
923 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
924 " not yet known - drop Authentiation frame",
927 * Save a copy of the frame so that it can be processed
928 * if a new peer entry is added shortly after this.
930 wpabuf_free(hapd
->mesh_pending_auth
);
931 hapd
->mesh_pending_auth
= wpabuf_alloc_copy(mgmt
, len
);
932 os_get_reltime(&hapd
->mesh_pending_auth_time
);
935 #endif /* CONFIG_MESH */
937 sta
= ap_sta_add(hapd
, mgmt
->sa
);
939 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
943 sta
->last_seq_ctrl
= seq_ctrl
;
944 sta
->last_subtype
= WLAN_FC_STYPE_AUTH
;
947 if (!hostapd_vlan_id_valid(hapd
->conf
->vlan
, vlan_id
)) {
948 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
949 HOSTAPD_LEVEL_INFO
, "Invalid VLAN ID "
950 "%d received from RADIUS server",
952 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
955 sta
->vlan_id
= vlan_id
;
956 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
957 HOSTAPD_LEVEL_INFO
, "VLAN ID %d", sta
->vlan_id
);
960 hostapd_free_psk_list(sta
->psk
);
961 if (hapd
->conf
->wpa_psk_radius
!= PSK_RADIUS_IGNORED
) {
968 sta
->identity
= identity
;
970 sta
->radius_cui
= radius_cui
;
973 sta
->flags
&= ~WLAN_STA_PREAUTH
;
974 ieee802_1x_notify_pre_auth(sta
->eapol_sm
, 0);
976 if (hapd
->conf
->acct_interim_interval
== 0 && acct_interim_interval
)
977 sta
->acct_interim_interval
= acct_interim_interval
;
978 if (res
== HOSTAPD_ACL_ACCEPT_TIMEOUT
)
979 ap_sta_session_timeout(hapd
, sta
, session_timeout
);
981 ap_sta_no_session_timeout(hapd
, sta
);
985 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
987 "authentication OK (open system)");
988 sta
->flags
|= WLAN_STA_AUTH
;
989 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
990 sta
->auth_alg
= WLAN_AUTH_OPEN
;
991 mlme_authenticate_indication(hapd
, sta
);
993 case WLAN_AUTH_SHARED_KEY
:
994 resp
= auth_shared_key(hapd
, sta
, auth_transaction
, challenge
,
996 sta
->auth_alg
= WLAN_AUTH_SHARED_KEY
;
997 mlme_authenticate_indication(hapd
, sta
);
998 if (sta
->challenge
&& auth_transaction
== 1) {
999 resp_ies
[0] = WLAN_EID_CHALLENGE
;
1000 resp_ies
[1] = WLAN_AUTH_CHALLENGE_LEN
;
1001 os_memcpy(resp_ies
+ 2, sta
->challenge
,
1002 WLAN_AUTH_CHALLENGE_LEN
);
1003 resp_ies_len
= 2 + WLAN_AUTH_CHALLENGE_LEN
;
1006 #ifdef CONFIG_IEEE80211R
1008 sta
->auth_alg
= WLAN_AUTH_FT
;
1009 if (sta
->wpa_sm
== NULL
)
1010 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
1012 if (sta
->wpa_sm
== NULL
) {
1013 wpa_printf(MSG_DEBUG
, "FT: Failed to initialize WPA "
1015 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1018 wpa_ft_process_auth(sta
->wpa_sm
, mgmt
->bssid
,
1019 auth_transaction
, mgmt
->u
.auth
.variable
,
1020 len
- IEEE80211_HDRLEN
-
1021 sizeof(mgmt
->u
.auth
),
1022 handle_auth_ft_finish
, hapd
);
1023 /* handle_auth_ft_finish() callback will complete auth. */
1025 #endif /* CONFIG_IEEE80211R */
1029 if (status_code
== WLAN_STATUS_SUCCESS
&&
1030 hapd
->conf
->mesh
& MESH_ENABLED
) {
1031 if (sta
->wpa_sm
== NULL
)
1033 wpa_auth_sta_init(hapd
->wpa_auth
,
1035 if (sta
->wpa_sm
== NULL
) {
1036 wpa_printf(MSG_DEBUG
,
1037 "SAE: Failed to initialize WPA state machine");
1038 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1042 #endif /* CONFIG_MESH */
1043 handle_auth_sae(hapd
, sta
, mgmt
, len
, auth_transaction
,
1046 #endif /* CONFIG_SAE */
1051 os_free(radius_cui
);
1052 hostapd_free_psk_list(psk
);
1054 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, auth_alg
,
1055 auth_transaction
+ 1, resp
, resp_ies
, resp_ies_len
);
1059 static int hostapd_get_aid(struct hostapd_data
*hapd
, struct sta_info
*sta
)
1063 /* get a unique AID */
1065 wpa_printf(MSG_DEBUG
, " old AID %d", sta
->aid
);
1069 for (i
= 0; i
< AID_WORDS
; i
++) {
1070 if (hapd
->sta_aid
[i
] == (u32
) -1)
1072 for (j
= 0; j
< 32; j
++) {
1073 if (!(hapd
->sta_aid
[i
] & BIT(j
)))
1081 aid
= i
* 32 + j
+ 1;
1086 hapd
->sta_aid
[i
] |= BIT(j
);
1087 wpa_printf(MSG_DEBUG
, " new AID %d", sta
->aid
);
1092 static u16
check_ssid(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1093 const u8
*ssid_ie
, size_t ssid_ie_len
)
1095 if (ssid_ie
== NULL
)
1096 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1098 if (ssid_ie_len
!= hapd
->conf
->ssid
.ssid_len
||
1099 os_memcmp(ssid_ie
, hapd
->conf
->ssid
.ssid
, ssid_ie_len
) != 0) {
1100 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1102 "Station tried to associate with unknown SSID "
1103 "'%s'", wpa_ssid_txt(ssid_ie
, ssid_ie_len
));
1104 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1107 return WLAN_STATUS_SUCCESS
;
1111 static u16
check_wmm(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1112 const u8
*wmm_ie
, size_t wmm_ie_len
)
1114 sta
->flags
&= ~WLAN_STA_WMM
;
1116 if (wmm_ie
&& hapd
->conf
->wmm_enabled
) {
1117 struct wmm_information_element
*wmm
;
1119 if (!hostapd_eid_wmm_valid(hapd
, wmm_ie
, wmm_ie_len
)) {
1120 hostapd_logger(hapd
, sta
->addr
,
1122 HOSTAPD_LEVEL_DEBUG
,
1123 "invalid WMM element in association "
1125 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1128 sta
->flags
|= WLAN_STA_WMM
;
1129 wmm
= (struct wmm_information_element
*) wmm_ie
;
1130 sta
->qosinfo
= wmm
->qos_info
;
1132 return WLAN_STATUS_SUCCESS
;
1136 static u16
copy_supp_rates(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1137 struct ieee802_11_elems
*elems
)
1139 if (!elems
->supp_rates
) {
1140 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1141 HOSTAPD_LEVEL_DEBUG
,
1142 "No supported rates element in AssocReq");
1143 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1146 if (elems
->supp_rates_len
+ elems
->ext_supp_rates_len
>
1147 sizeof(sta
->supported_rates
)) {
1148 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1149 HOSTAPD_LEVEL_DEBUG
,
1150 "Invalid supported rates element length %d+%d",
1151 elems
->supp_rates_len
,
1152 elems
->ext_supp_rates_len
);
1153 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1156 sta
->supported_rates_len
= merge_byte_arrays(
1157 sta
->supported_rates
, sizeof(sta
->supported_rates
),
1158 elems
->supp_rates
, elems
->supp_rates_len
,
1159 elems
->ext_supp_rates
, elems
->ext_supp_rates_len
);
1161 return WLAN_STATUS_SUCCESS
;
1165 static u16
check_ext_capab(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1166 const u8
*ext_capab_ie
, size_t ext_capab_ie_len
)
1168 #ifdef CONFIG_INTERWORKING
1169 /* check for QoS Map support */
1170 if (ext_capab_ie_len
>= 5) {
1171 if (ext_capab_ie
[4] & 0x01)
1172 sta
->qos_map_enabled
= 1;
1174 #endif /* CONFIG_INTERWORKING */
1176 return WLAN_STATUS_SUCCESS
;
1180 static u16
check_assoc_ies(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1181 const u8
*ies
, size_t ies_len
, int reassoc
)
1183 struct ieee802_11_elems elems
;
1187 const u8
*p2p_dev_addr
= NULL
;
1189 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 1) == ParseFailed
) {
1190 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1191 HOSTAPD_LEVEL_INFO
, "Station sent an invalid "
1192 "association request");
1193 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1196 resp
= check_ssid(hapd
, sta
, elems
.ssid
, elems
.ssid_len
);
1197 if (resp
!= WLAN_STATUS_SUCCESS
)
1199 resp
= check_wmm(hapd
, sta
, elems
.wmm
, elems
.wmm_len
);
1200 if (resp
!= WLAN_STATUS_SUCCESS
)
1202 resp
= check_ext_capab(hapd
, sta
, elems
.ext_capab
, elems
.ext_capab_len
);
1203 if (resp
!= WLAN_STATUS_SUCCESS
)
1205 resp
= copy_supp_rates(hapd
, sta
, &elems
);
1206 if (resp
!= WLAN_STATUS_SUCCESS
)
1208 #ifdef CONFIG_IEEE80211N
1209 resp
= copy_sta_ht_capab(hapd
, sta
, elems
.ht_capabilities
,
1210 elems
.ht_capabilities_len
);
1211 if (resp
!= WLAN_STATUS_SUCCESS
)
1213 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&&
1214 !(sta
->flags
& WLAN_STA_HT
)) {
1215 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1216 HOSTAPD_LEVEL_INFO
, "Station does not support "
1217 "mandatory HT PHY - reject association");
1218 return WLAN_STATUS_ASSOC_DENIED_NO_HT
;
1220 #endif /* CONFIG_IEEE80211N */
1222 #ifdef CONFIG_IEEE80211AC
1223 resp
= copy_sta_vht_capab(hapd
, sta
, elems
.vht_capabilities
,
1224 elems
.vht_capabilities_len
);
1225 if (resp
!= WLAN_STATUS_SUCCESS
)
1228 resp
= set_sta_vht_opmode(hapd
, sta
, elems
.vht_opmode_notif
);
1229 if (resp
!= WLAN_STATUS_SUCCESS
)
1232 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&&
1233 !(sta
->flags
& WLAN_STA_VHT
)) {
1234 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1235 HOSTAPD_LEVEL_INFO
, "Station does not support "
1236 "mandatory VHT PHY - reject association");
1237 return WLAN_STATUS_ASSOC_DENIED_NO_VHT
;
1239 #endif /* CONFIG_IEEE80211AC */
1243 wpabuf_free(sta
->p2p_ie
);
1244 sta
->p2p_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
1245 P2P_IE_VENDOR_TYPE
);
1247 p2p_dev_addr
= p2p_get_go_dev_addr(sta
->p2p_ie
);
1249 wpabuf_free(sta
->p2p_ie
);
1252 #endif /* CONFIG_P2P */
1254 if ((hapd
->conf
->wpa
& WPA_PROTO_RSN
) && elems
.rsn_ie
) {
1255 wpa_ie
= elems
.rsn_ie
;
1256 wpa_ie_len
= elems
.rsn_ie_len
;
1257 } else if ((hapd
->conf
->wpa
& WPA_PROTO_WPA
) &&
1259 wpa_ie
= elems
.wpa_ie
;
1260 wpa_ie_len
= elems
.wpa_ie_len
;
1267 sta
->flags
&= ~(WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
| WLAN_STA_WPS2
);
1268 if (hapd
->conf
->wps_state
&& elems
.wps_ie
) {
1269 wpa_printf(MSG_DEBUG
, "STA included WPS IE in (Re)Association "
1270 "Request - assume WPS is used");
1271 sta
->flags
|= WLAN_STA_WPS
;
1272 wpabuf_free(sta
->wps_ie
);
1273 sta
->wps_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
1274 WPS_IE_VENDOR_TYPE
);
1275 if (sta
->wps_ie
&& wps_is_20(sta
->wps_ie
)) {
1276 wpa_printf(MSG_DEBUG
, "WPS: STA supports WPS 2.0");
1277 sta
->flags
|= WLAN_STA_WPS2
;
1281 if (sta
->wps_ie
&& wps_validate_assoc_req(sta
->wps_ie
) < 0) {
1282 wpa_printf(MSG_DEBUG
, "WPS: Invalid WPS IE in "
1283 "(Re)Association Request - reject");
1284 return WLAN_STATUS_INVALID_IE
;
1286 } else if (hapd
->conf
->wps_state
&& wpa_ie
== NULL
) {
1287 wpa_printf(MSG_DEBUG
, "STA did not include WPA/RSN IE in "
1288 "(Re)Association Request - possible WPS use");
1289 sta
->flags
|= WLAN_STA_MAYBE_WPS
;
1291 #endif /* CONFIG_WPS */
1292 if (hapd
->conf
->wpa
&& wpa_ie
== NULL
) {
1293 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1295 "No WPA/RSN IE in association request");
1296 return WLAN_STATUS_INVALID_IE
;
1299 if (hapd
->conf
->wpa
&& wpa_ie
) {
1303 if (sta
->wpa_sm
== NULL
)
1304 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
1307 if (sta
->wpa_sm
== NULL
) {
1308 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
1310 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1312 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
1314 elems
.mdie
, elems
.mdie_len
);
1315 if (res
== WPA_INVALID_GROUP
)
1316 resp
= WLAN_STATUS_GROUP_CIPHER_NOT_VALID
;
1317 else if (res
== WPA_INVALID_PAIRWISE
)
1318 resp
= WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID
;
1319 else if (res
== WPA_INVALID_AKMP
)
1320 resp
= WLAN_STATUS_AKMP_NOT_VALID
;
1321 else if (res
== WPA_ALLOC_FAIL
)
1322 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1323 #ifdef CONFIG_IEEE80211W
1324 else if (res
== WPA_MGMT_FRAME_PROTECTION_VIOLATION
)
1325 resp
= WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
1326 else if (res
== WPA_INVALID_MGMT_GROUP_CIPHER
)
1327 resp
= WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
1328 #endif /* CONFIG_IEEE80211W */
1329 else if (res
== WPA_INVALID_MDIE
)
1330 resp
= WLAN_STATUS_INVALID_MDIE
;
1331 else if (res
!= WPA_IE_OK
)
1332 resp
= WLAN_STATUS_INVALID_IE
;
1333 if (resp
!= WLAN_STATUS_SUCCESS
)
1335 #ifdef CONFIG_IEEE80211W
1336 if ((sta
->flags
& WLAN_STA_MFP
) && !sta
->sa_query_timed_out
&&
1337 sta
->sa_query_count
> 0)
1338 ap_check_sa_query_timeout(hapd
, sta
);
1339 if ((sta
->flags
& WLAN_STA_MFP
) && !sta
->sa_query_timed_out
&&
1340 (!reassoc
|| sta
->auth_alg
!= WLAN_AUTH_FT
)) {
1342 * STA has already been associated with MFP and SA
1343 * Query timeout has not been reached. Reject the
1344 * association attempt temporarily and start SA Query,
1345 * if one is not pending.
1348 if (sta
->sa_query_count
== 0)
1349 ap_sta_start_sa_query(hapd
, sta
);
1351 return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
;
1354 if (wpa_auth_uses_mfp(sta
->wpa_sm
))
1355 sta
->flags
|= WLAN_STA_MFP
;
1357 sta
->flags
&= ~WLAN_STA_MFP
;
1358 #endif /* CONFIG_IEEE80211W */
1360 #ifdef CONFIG_IEEE80211R
1361 if (sta
->auth_alg
== WLAN_AUTH_FT
) {
1363 wpa_printf(MSG_DEBUG
, "FT: " MACSTR
" tried "
1364 "to use association (not "
1365 "re-association) with FT auth_alg",
1366 MAC2STR(sta
->addr
));
1367 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1370 resp
= wpa_ft_validate_reassoc(sta
->wpa_sm
, ies
,
1372 if (resp
!= WLAN_STATUS_SUCCESS
)
1375 #endif /* CONFIG_IEEE80211R */
1378 if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
1379 sta
->auth_alg
== WLAN_AUTH_OPEN
) {
1380 struct rsn_pmksa_cache_entry
*sa
;
1381 sa
= wpa_auth_sta_get_pmksa(sta
->wpa_sm
);
1382 if (!sa
|| sa
->akmp
!= WPA_KEY_MGMT_SAE
) {
1383 wpa_printf(MSG_DEBUG
,
1384 "SAE: No PMKSA cache entry found for "
1385 MACSTR
, MAC2STR(sta
->addr
));
1386 return WLAN_STATUS_INVALID_PMKID
;
1388 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
1389 " using PMKSA caching", MAC2STR(sta
->addr
));
1390 } else if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
1391 sta
->auth_alg
!= WLAN_AUTH_SAE
&&
1392 !(sta
->auth_alg
== WLAN_AUTH_FT
&&
1393 wpa_auth_uses_ft_sae(sta
->wpa_sm
))) {
1394 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
" tried to use "
1395 "SAE AKM after non-SAE auth_alg %u",
1396 MAC2STR(sta
->addr
), sta
->auth_alg
);
1397 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
1399 #endif /* CONFIG_SAE */
1401 #ifdef CONFIG_IEEE80211N
1402 if ((sta
->flags
& (WLAN_STA_HT
| WLAN_STA_VHT
)) &&
1403 wpa_auth_get_pairwise(sta
->wpa_sm
) == WPA_CIPHER_TKIP
) {
1404 hostapd_logger(hapd
, sta
->addr
,
1405 HOSTAPD_MODULE_IEEE80211
,
1407 "Station tried to use TKIP with HT "
1409 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
1411 #endif /* CONFIG_IEEE80211N */
1413 } else if (hapd
->conf
->osen
) {
1414 if (elems
.osen
== NULL
) {
1416 hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1418 "No HS 2.0 OSEN element in association request");
1419 return WLAN_STATUS_INVALID_IE
;
1422 wpa_printf(MSG_DEBUG
, "HS 2.0: OSEN association");
1423 if (sta
->wpa_sm
== NULL
)
1424 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
1426 if (sta
->wpa_sm
== NULL
) {
1427 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
1429 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1431 if (wpa_validate_osen(hapd
->wpa_auth
, sta
->wpa_sm
,
1432 elems
.osen
- 2, elems
.osen_len
+ 2) < 0)
1433 return WLAN_STATUS_INVALID_IE
;
1434 #endif /* CONFIG_HS20 */
1436 wpa_auth_sta_no_wpa(sta
->wpa_sm
);
1439 p2p_group_notif_assoc(hapd
->p2p_group
, sta
->addr
, ies
, ies_len
);
1440 #endif /* CONFIG_P2P */
1443 wpabuf_free(sta
->hs20_ie
);
1444 if (elems
.hs20
&& elems
.hs20_len
> 4) {
1445 sta
->hs20_ie
= wpabuf_alloc_copy(elems
.hs20
+ 4,
1446 elems
.hs20_len
- 4);
1448 sta
->hs20_ie
= NULL
;
1449 #endif /* CONFIG_HS20 */
1451 return WLAN_STATUS_SUCCESS
;
1455 static void send_deauth(struct hostapd_data
*hapd
, const u8
*addr
,
1459 struct ieee80211_mgmt reply
;
1461 os_memset(&reply
, 0, sizeof(reply
));
1462 reply
.frame_control
=
1463 IEEE80211_FC(WLAN_FC_TYPE_MGMT
, WLAN_FC_STYPE_DEAUTH
);
1464 os_memcpy(reply
.da
, addr
, ETH_ALEN
);
1465 os_memcpy(reply
.sa
, hapd
->own_addr
, ETH_ALEN
);
1466 os_memcpy(reply
.bssid
, hapd
->own_addr
, ETH_ALEN
);
1468 send_len
= IEEE80211_HDRLEN
+ sizeof(reply
.u
.deauth
);
1469 reply
.u
.deauth
.reason_code
= host_to_le16(reason_code
);
1471 if (hostapd_drv_send_mlme(hapd
, &reply
, send_len
, 0) < 0)
1472 wpa_printf(MSG_INFO
, "Failed to send deauth: %s",
1477 static void send_assoc_resp(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1478 u16 status_code
, int reassoc
, const u8
*ies
,
1482 u8 buf
[sizeof(struct ieee80211_mgmt
) + 1024];
1483 struct ieee80211_mgmt
*reply
;
1486 os_memset(buf
, 0, sizeof(buf
));
1487 reply
= (struct ieee80211_mgmt
*) buf
;
1488 reply
->frame_control
=
1489 IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
1490 (reassoc
? WLAN_FC_STYPE_REASSOC_RESP
:
1491 WLAN_FC_STYPE_ASSOC_RESP
));
1492 os_memcpy(reply
->da
, sta
->addr
, ETH_ALEN
);
1493 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
1494 os_memcpy(reply
->bssid
, hapd
->own_addr
, ETH_ALEN
);
1496 send_len
= IEEE80211_HDRLEN
;
1497 send_len
+= sizeof(reply
->u
.assoc_resp
);
1498 reply
->u
.assoc_resp
.capab_info
=
1499 host_to_le16(hostapd_own_capab_info(hapd
, sta
, 0));
1500 reply
->u
.assoc_resp
.status_code
= host_to_le16(status_code
);
1501 reply
->u
.assoc_resp
.aid
= host_to_le16(sta
->aid
| BIT(14) | BIT(15));
1502 /* Supported rates */
1503 p
= hostapd_eid_supp_rates(hapd
, reply
->u
.assoc_resp
.variable
);
1504 /* Extended supported rates */
1505 p
= hostapd_eid_ext_supp_rates(hapd
, p
);
1507 #ifdef CONFIG_IEEE80211R
1508 if (status_code
== WLAN_STATUS_SUCCESS
) {
1509 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
1510 * Transition Information, RSN, [RIC Response] */
1511 p
= wpa_sm_write_assoc_resp_ies(sta
->wpa_sm
, p
,
1512 buf
+ sizeof(buf
) - p
,
1513 sta
->auth_alg
, ies
, ies_len
);
1515 #endif /* CONFIG_IEEE80211R */
1517 #ifdef CONFIG_IEEE80211W
1518 if (status_code
== WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
)
1519 p
= hostapd_eid_assoc_comeback_time(hapd
, sta
, p
);
1520 #endif /* CONFIG_IEEE80211W */
1522 #ifdef CONFIG_IEEE80211N
1523 p
= hostapd_eid_ht_capabilities(hapd
, p
);
1524 p
= hostapd_eid_ht_operation(hapd
, p
);
1525 #endif /* CONFIG_IEEE80211N */
1527 #ifdef CONFIG_IEEE80211AC
1528 p
= hostapd_eid_vht_capabilities(hapd
, p
);
1529 p
= hostapd_eid_vht_operation(hapd
, p
);
1530 #endif /* CONFIG_IEEE80211AC */
1532 p
= hostapd_eid_ext_capab(hapd
, p
);
1533 p
= hostapd_eid_bss_max_idle_period(hapd
, p
);
1534 if (sta
->qos_map_enabled
)
1535 p
= hostapd_eid_qos_map_set(hapd
, p
);
1537 if (sta
->flags
& WLAN_STA_WMM
)
1538 p
= hostapd_eid_wmm(hapd
, p
);
1541 if ((sta
->flags
& WLAN_STA_WPS
) ||
1542 ((sta
->flags
& WLAN_STA_MAYBE_WPS
) && hapd
->conf
->wpa
)) {
1543 struct wpabuf
*wps
= wps_build_assoc_resp_ie();
1545 os_memcpy(p
, wpabuf_head(wps
), wpabuf_len(wps
));
1546 p
+= wpabuf_len(wps
);
1550 #endif /* CONFIG_WPS */
1554 struct wpabuf
*p2p_resp_ie
;
1555 enum p2p_status_code status
;
1556 switch (status_code
) {
1557 case WLAN_STATUS_SUCCESS
:
1558 status
= P2P_SC_SUCCESS
;
1560 case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
:
1561 status
= P2P_SC_FAIL_LIMIT_REACHED
;
1564 status
= P2P_SC_FAIL_INVALID_PARAMS
;
1567 p2p_resp_ie
= p2p_group_assoc_resp_ie(hapd
->p2p_group
, status
);
1569 os_memcpy(p
, wpabuf_head(p2p_resp_ie
),
1570 wpabuf_len(p2p_resp_ie
));
1571 p
+= wpabuf_len(p2p_resp_ie
);
1572 wpabuf_free(p2p_resp_ie
);
1575 #endif /* CONFIG_P2P */
1577 #ifdef CONFIG_P2P_MANAGER
1578 if (hapd
->conf
->p2p
& P2P_MANAGE
)
1579 p
= hostapd_eid_p2p_manage(hapd
, p
);
1580 #endif /* CONFIG_P2P_MANAGER */
1582 send_len
+= p
- reply
->u
.assoc_resp
.variable
;
1584 if (hostapd_drv_send_mlme(hapd
, reply
, send_len
, 0) < 0)
1585 wpa_printf(MSG_INFO
, "Failed to send assoc resp: %s",
1590 static void handle_assoc(struct hostapd_data
*hapd
,
1591 const struct ieee80211_mgmt
*mgmt
, size_t len
,
1594 u16 capab_info
, listen_interval
, seq_ctrl
, fc
;
1595 u16 resp
= WLAN_STATUS_SUCCESS
;
1598 struct sta_info
*sta
;
1600 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_req
) :
1601 sizeof(mgmt
->u
.assoc_req
))) {
1602 wpa_printf(MSG_INFO
, "handle_assoc(reassoc=%d) - too short payload (len=%lu)",
1603 reassoc
, (unsigned long) len
);
1607 #ifdef CONFIG_TESTING_OPTIONS
1609 if (hapd
->iconf
->ignore_reassoc_probability
> 0.0 &&
1610 drand48() < hapd
->iconf
->ignore_reassoc_probability
) {
1611 wpa_printf(MSG_INFO
,
1612 "TESTING: ignoring reassoc request from "
1613 MACSTR
, MAC2STR(mgmt
->sa
));
1617 if (hapd
->iconf
->ignore_assoc_probability
> 0.0 &&
1618 drand48() < hapd
->iconf
->ignore_assoc_probability
) {
1619 wpa_printf(MSG_INFO
,
1620 "TESTING: ignoring assoc request from "
1621 MACSTR
, MAC2STR(mgmt
->sa
));
1625 #endif /* CONFIG_TESTING_OPTIONS */
1627 fc
= le_to_host16(mgmt
->frame_control
);
1628 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
1631 capab_info
= le_to_host16(mgmt
->u
.reassoc_req
.capab_info
);
1632 listen_interval
= le_to_host16(
1633 mgmt
->u
.reassoc_req
.listen_interval
);
1634 wpa_printf(MSG_DEBUG
, "reassociation request: STA=" MACSTR
1635 " capab_info=0x%02x listen_interval=%d current_ap="
1636 MACSTR
" seq_ctrl=0x%x%s",
1637 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
1638 MAC2STR(mgmt
->u
.reassoc_req
.current_ap
),
1639 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
1640 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.reassoc_req
));
1641 pos
= mgmt
->u
.reassoc_req
.variable
;
1643 capab_info
= le_to_host16(mgmt
->u
.assoc_req
.capab_info
);
1644 listen_interval
= le_to_host16(
1645 mgmt
->u
.assoc_req
.listen_interval
);
1646 wpa_printf(MSG_DEBUG
, "association request: STA=" MACSTR
1647 " capab_info=0x%02x listen_interval=%d "
1649 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
1650 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
1651 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.assoc_req
));
1652 pos
= mgmt
->u
.assoc_req
.variable
;
1655 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1656 #ifdef CONFIG_IEEE80211R
1657 if (sta
&& sta
->auth_alg
== WLAN_AUTH_FT
&&
1658 (sta
->flags
& WLAN_STA_AUTH
) == 0) {
1659 wpa_printf(MSG_DEBUG
, "FT: Allow STA " MACSTR
" to associate "
1660 "prior to authentication since it is using "
1661 "over-the-DS FT", MAC2STR(mgmt
->sa
));
1663 #endif /* CONFIG_IEEE80211R */
1664 if (sta
== NULL
|| (sta
->flags
& WLAN_STA_AUTH
) == 0) {
1665 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1666 HOSTAPD_LEVEL_INFO
, "Station tried to "
1667 "associate before authentication "
1668 "(aid=%d flags=0x%x)",
1669 sta
? sta
->aid
: -1,
1670 sta
? sta
->flags
: 0);
1671 send_deauth(hapd
, mgmt
->sa
,
1672 WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA
);
1676 if ((fc
& WLAN_FC_RETRY
) &&
1677 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
1678 sta
->last_seq_ctrl
== seq_ctrl
&&
1679 sta
->last_subtype
== reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
1680 WLAN_FC_STYPE_ASSOC_REQ
) {
1681 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1682 HOSTAPD_LEVEL_DEBUG
,
1683 "Drop repeated association frame seq_ctrl=0x%x",
1687 sta
->last_seq_ctrl
= seq_ctrl
;
1688 sta
->last_subtype
= reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
1689 WLAN_FC_STYPE_ASSOC_REQ
;
1691 if (hapd
->tkip_countermeasures
) {
1692 resp
= WLAN_REASON_MICHAEL_MIC_FAILURE
;
1696 if (listen_interval
> hapd
->conf
->max_listen_interval
) {
1697 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1698 HOSTAPD_LEVEL_DEBUG
,
1699 "Too large Listen Interval (%d)",
1701 resp
= WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE
;
1705 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
1707 resp
= check_assoc_ies(hapd
, sta
, pos
, left
, reassoc
);
1708 if (resp
!= WLAN_STATUS_SUCCESS
)
1711 if (hostapd_get_aid(hapd
, sta
) < 0) {
1712 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1713 HOSTAPD_LEVEL_INFO
, "No room for more AIDs");
1714 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
1718 sta
->capability
= capab_info
;
1719 sta
->listen_interval
= listen_interval
;
1721 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
1722 sta
->flags
|= WLAN_STA_NONERP
;
1723 for (i
= 0; i
< sta
->supported_rates_len
; i
++) {
1724 if ((sta
->supported_rates
[i
] & 0x7f) > 22) {
1725 sta
->flags
&= ~WLAN_STA_NONERP
;
1729 if (sta
->flags
& WLAN_STA_NONERP
&& !sta
->nonerp_set
) {
1730 sta
->nonerp_set
= 1;
1731 hapd
->iface
->num_sta_non_erp
++;
1732 if (hapd
->iface
->num_sta_non_erp
== 1)
1733 ieee802_11_set_beacons(hapd
->iface
);
1736 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
) &&
1737 !sta
->no_short_slot_time_set
) {
1738 sta
->no_short_slot_time_set
= 1;
1739 hapd
->iface
->num_sta_no_short_slot_time
++;
1740 if (hapd
->iface
->current_mode
->mode
==
1741 HOSTAPD_MODE_IEEE80211G
&&
1742 hapd
->iface
->num_sta_no_short_slot_time
== 1)
1743 ieee802_11_set_beacons(hapd
->iface
);
1746 if (sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
1747 sta
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
1749 sta
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
1751 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
) &&
1752 !sta
->no_short_preamble_set
) {
1753 sta
->no_short_preamble_set
= 1;
1754 hapd
->iface
->num_sta_no_short_preamble
++;
1755 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
1756 && hapd
->iface
->num_sta_no_short_preamble
== 1)
1757 ieee802_11_set_beacons(hapd
->iface
);
1760 #ifdef CONFIG_IEEE80211N
1761 update_ht_state(hapd
, sta
);
1762 #endif /* CONFIG_IEEE80211N */
1764 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1765 HOSTAPD_LEVEL_DEBUG
,
1766 "association OK (aid %d)", sta
->aid
);
1767 /* Station will be marked associated, after it acknowledges AssocResp
1769 sta
->flags
|= WLAN_STA_ASSOC_REQ_OK
;
1771 #ifdef CONFIG_IEEE80211W
1772 if ((sta
->flags
& WLAN_STA_MFP
) && sta
->sa_query_timed_out
) {
1773 wpa_printf(MSG_DEBUG
, "Allowing %sassociation after timed out "
1774 "SA Query procedure", reassoc
? "re" : "");
1775 /* TODO: Send a protected Disassociate frame to the STA using
1776 * the old key and Reason Code "Previous Authentication no
1777 * longer valid". Make sure this is only sent protected since
1778 * unprotected frame would be received by the STA that is now
1779 * trying to associate.
1782 #endif /* CONFIG_IEEE80211W */
1784 /* Make sure that the previously registered inactivity timer will not
1785 * remove the STA immediately. */
1786 sta
->timeout_next
= STA_NULLFUNC
;
1789 send_assoc_resp(hapd
, sta
, resp
, reassoc
, pos
, left
);
1793 static void handle_disassoc(struct hostapd_data
*hapd
,
1794 const struct ieee80211_mgmt
*mgmt
, size_t len
)
1796 struct sta_info
*sta
;
1798 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.disassoc
)) {
1799 wpa_printf(MSG_INFO
, "handle_disassoc - too short payload (len=%lu)",
1800 (unsigned long) len
);
1804 wpa_printf(MSG_DEBUG
, "disassocation: STA=" MACSTR
" reason_code=%d",
1806 le_to_host16(mgmt
->u
.disassoc
.reason_code
));
1808 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1810 wpa_printf(MSG_INFO
, "Station " MACSTR
" trying to disassociate, but it is not associated",
1815 ap_sta_set_authorized(hapd
, sta
, 0);
1816 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
1817 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
);
1818 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
1819 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1820 HOSTAPD_LEVEL_INFO
, "disassociated");
1821 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
1822 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
1823 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
1825 accounting_sta_stop(hapd
, sta
);
1826 ieee802_1x_free_station(sta
);
1828 hostapd_drv_br_delete_ip_neigh(hapd
, 4, (u8
*) &sta
->ipaddr
);
1829 ap_sta_ip6addr_del(hapd
, sta
);
1830 hostapd_drv_sta_remove(hapd
, sta
->addr
);
1832 if (sta
->timeout_next
== STA_NULLFUNC
||
1833 sta
->timeout_next
== STA_DISASSOC
) {
1834 sta
->timeout_next
= STA_DEAUTH
;
1835 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
1836 eloop_register_timeout(AP_DEAUTH_DELAY
, 0, ap_handle_timer
,
1840 mlme_disassociate_indication(
1841 hapd
, sta
, le_to_host16(mgmt
->u
.disassoc
.reason_code
));
1845 static void handle_deauth(struct hostapd_data
*hapd
,
1846 const struct ieee80211_mgmt
*mgmt
, size_t len
)
1848 struct sta_info
*sta
;
1850 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.deauth
)) {
1851 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "handle_deauth - too short "
1852 "payload (len=%lu)", (unsigned long) len
);
1856 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "deauthentication: STA=" MACSTR
1858 MAC2STR(mgmt
->sa
), le_to_host16(mgmt
->u
.deauth
.reason_code
));
1860 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1862 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "Station " MACSTR
" trying "
1863 "to deauthenticate, but it is not authenticated",
1868 ap_sta_set_authorized(hapd
, sta
, 0);
1869 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
1870 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
|
1871 WLAN_STA_ASSOC_REQ_OK
);
1872 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
1873 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1874 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
1875 mlme_deauthenticate_indication(
1876 hapd
, sta
, le_to_host16(mgmt
->u
.deauth
.reason_code
));
1877 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
1878 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
1879 ap_free_sta(hapd
, sta
);
1883 static void handle_beacon(struct hostapd_data
*hapd
,
1884 const struct ieee80211_mgmt
*mgmt
, size_t len
,
1885 struct hostapd_frame_info
*fi
)
1887 struct ieee802_11_elems elems
;
1889 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.beacon
)) {
1890 wpa_printf(MSG_INFO
, "handle_beacon - too short payload (len=%lu)",
1891 (unsigned long) len
);
1895 (void) ieee802_11_parse_elems(mgmt
->u
.beacon
.variable
,
1896 len
- (IEEE80211_HDRLEN
+
1897 sizeof(mgmt
->u
.beacon
)), &elems
,
1900 ap_list_process_beacon(hapd
->iface
, mgmt
, &elems
, fi
);
1904 #ifdef CONFIG_IEEE80211W
1906 static int hostapd_sa_query_action(struct hostapd_data
*hapd
,
1907 const struct ieee80211_mgmt
*mgmt
,
1912 end
= mgmt
->u
.action
.u
.sa_query_resp
.trans_id
+
1913 WLAN_SA_QUERY_TR_ID_LEN
;
1914 if (((u8
*) mgmt
) + len
< end
) {
1915 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Too short SA Query Action "
1916 "frame (len=%lu)", (unsigned long) len
);
1920 ieee802_11_sa_query_action(hapd
, mgmt
->sa
,
1921 mgmt
->u
.action
.u
.sa_query_resp
.action
,
1922 mgmt
->u
.action
.u
.sa_query_resp
.trans_id
);
1927 static int robust_action_frame(u8 category
)
1929 return category
!= WLAN_ACTION_PUBLIC
&&
1930 category
!= WLAN_ACTION_HT
;
1932 #endif /* CONFIG_IEEE80211W */
1935 static int handle_action(struct hostapd_data
*hapd
,
1936 const struct ieee80211_mgmt
*mgmt
, size_t len
)
1938 struct sta_info
*sta
;
1939 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1941 if (len
< IEEE80211_HDRLEN
+ 1) {
1942 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1943 HOSTAPD_LEVEL_DEBUG
,
1944 "handle_action - too short payload (len=%lu)",
1945 (unsigned long) len
);
1949 if (mgmt
->u
.action
.category
!= WLAN_ACTION_PUBLIC
&&
1950 (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))) {
1951 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Ignored Action "
1952 "frame (category=%u) from unassociated STA " MACSTR
,
1953 MAC2STR(mgmt
->sa
), mgmt
->u
.action
.category
);
1957 #ifdef CONFIG_IEEE80211W
1958 if (sta
&& (sta
->flags
& WLAN_STA_MFP
) &&
1959 !(mgmt
->frame_control
& host_to_le16(WLAN_FC_ISWEP
)) &&
1960 robust_action_frame(mgmt
->u
.action
.category
)) {
1961 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1962 HOSTAPD_LEVEL_DEBUG
,
1963 "Dropped unprotected Robust Action frame from "
1967 #endif /* CONFIG_IEEE80211W */
1970 u16 fc
= le_to_host16(mgmt
->frame_control
);
1971 u16 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
1973 if ((fc
& WLAN_FC_RETRY
) &&
1974 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
1975 sta
->last_seq_ctrl
== seq_ctrl
&&
1976 sta
->last_subtype
== WLAN_FC_STYPE_ACTION
) {
1977 hostapd_logger(hapd
, sta
->addr
,
1978 HOSTAPD_MODULE_IEEE80211
,
1979 HOSTAPD_LEVEL_DEBUG
,
1980 "Drop repeated action frame seq_ctrl=0x%x",
1985 sta
->last_seq_ctrl
= seq_ctrl
;
1986 sta
->last_subtype
= WLAN_FC_STYPE_ACTION
;
1989 switch (mgmt
->u
.action
.category
) {
1990 #ifdef CONFIG_IEEE80211R
1991 case WLAN_ACTION_FT
:
1993 wpa_ft_action_rx(sta
->wpa_sm
, (u8
*) &mgmt
->u
.action
,
1994 len
- IEEE80211_HDRLEN
))
1997 #endif /* CONFIG_IEEE80211R */
1998 case WLAN_ACTION_WMM
:
1999 hostapd_wmm_action(hapd
, mgmt
, len
);
2001 #ifdef CONFIG_IEEE80211W
2002 case WLAN_ACTION_SA_QUERY
:
2003 return hostapd_sa_query_action(hapd
, mgmt
, len
);
2004 #endif /* CONFIG_IEEE80211W */
2006 case WLAN_ACTION_WNM
:
2007 ieee802_11_rx_wnm_action_ap(hapd
, mgmt
, len
);
2009 #endif /* CONFIG_WNM */
2010 case WLAN_ACTION_PUBLIC
:
2011 case WLAN_ACTION_PROTECTED_DUAL
:
2012 #ifdef CONFIG_IEEE80211N
2013 if (mgmt
->u
.action
.u
.public_action
.action
==
2014 WLAN_PA_20_40_BSS_COEX
) {
2015 wpa_printf(MSG_DEBUG
,
2016 "HT20/40 coex mgmt frame received from STA "
2017 MACSTR
, MAC2STR(mgmt
->sa
));
2018 hostapd_2040_coex_action(hapd
, mgmt
, len
);
2020 #endif /* CONFIG_IEEE80211N */
2021 if (hapd
->public_action_cb
) {
2022 hapd
->public_action_cb(hapd
->public_action_cb_ctx
,
2026 if (hapd
->public_action_cb2
) {
2027 hapd
->public_action_cb2(hapd
->public_action_cb2_ctx
,
2031 if (hapd
->public_action_cb
|| hapd
->public_action_cb2
)
2034 case WLAN_ACTION_VENDOR_SPECIFIC
:
2035 if (hapd
->vendor_action_cb
) {
2036 if (hapd
->vendor_action_cb(hapd
->vendor_action_cb_ctx
,
2038 hapd
->iface
->freq
) == 0)
2044 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
2045 HOSTAPD_LEVEL_DEBUG
,
2046 "handle_action - unknown action category %d or invalid "
2048 mgmt
->u
.action
.category
);
2049 if (!(mgmt
->da
[0] & 0x01) && !(mgmt
->u
.action
.category
& 0x80) &&
2050 !(mgmt
->sa
[0] & 0x01)) {
2051 struct ieee80211_mgmt
*resp
;
2054 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
2055 * Return the Action frame to the source without change
2056 * except that MSB of the Category set to 1.
2058 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Return unknown Action "
2059 "frame back to sender");
2060 resp
= os_malloc(len
);
2063 os_memcpy(resp
, mgmt
, len
);
2064 os_memcpy(resp
->da
, resp
->sa
, ETH_ALEN
);
2065 os_memcpy(resp
->sa
, hapd
->own_addr
, ETH_ALEN
);
2066 os_memcpy(resp
->bssid
, hapd
->own_addr
, ETH_ALEN
);
2067 resp
->u
.action
.category
|= 0x80;
2069 if (hostapd_drv_send_mlme(hapd
, resp
, len
, 0) < 0) {
2070 wpa_printf(MSG_ERROR
, "IEEE 802.11: Failed to send "
2081 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
2082 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
2084 * @buf: management frame data (starting from IEEE 802.11 header)
2085 * @len: length of frame data in octets
2086 * @fi: meta data about received frame (signal level, etc.)
2088 * Process all incoming IEEE 802.11 management frames. This will be called for
2089 * each frame received from the kernel driver through wlan#ap interface. In
2090 * addition, it can be called to re-inserted pending frames (e.g., when using
2091 * external RADIUS server as an MAC ACL).
2093 int ieee802_11_mgmt(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
2094 struct hostapd_frame_info
*fi
)
2096 struct ieee80211_mgmt
*mgmt
;
2104 mgmt
= (struct ieee80211_mgmt
*) buf
;
2105 fc
= le_to_host16(mgmt
->frame_control
);
2106 stype
= WLAN_FC_GET_STYPE(fc
);
2108 if (stype
== WLAN_FC_STYPE_BEACON
) {
2109 handle_beacon(hapd
, mgmt
, len
, fi
);
2113 broadcast
= mgmt
->bssid
[0] == 0xff && mgmt
->bssid
[1] == 0xff &&
2114 mgmt
->bssid
[2] == 0xff && mgmt
->bssid
[3] == 0xff &&
2115 mgmt
->bssid
[4] == 0xff && mgmt
->bssid
[5] == 0xff;
2119 /* Invitation responses can be sent with the peer MAC as BSSID */
2120 !((hapd
->conf
->p2p
& P2P_GROUP_OWNER
) &&
2121 stype
== WLAN_FC_STYPE_ACTION
) &&
2122 #endif /* CONFIG_P2P */
2124 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
2125 #endif /* CONFIG_MESH */
2126 os_memcmp(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
) != 0) {
2127 wpa_printf(MSG_INFO
, "MGMT: BSSID=" MACSTR
" not our address",
2128 MAC2STR(mgmt
->bssid
));
2133 if (stype
== WLAN_FC_STYPE_PROBE_REQ
) {
2134 handle_probe_req(hapd
, mgmt
, len
, fi
->ssi_signal
);
2138 if (os_memcmp(mgmt
->da
, hapd
->own_addr
, ETH_ALEN
) != 0) {
2139 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
2140 HOSTAPD_LEVEL_DEBUG
,
2141 "MGMT: DA=" MACSTR
" not our address",
2147 case WLAN_FC_STYPE_AUTH
:
2148 wpa_printf(MSG_DEBUG
, "mgmt::auth");
2149 handle_auth(hapd
, mgmt
, len
);
2152 case WLAN_FC_STYPE_ASSOC_REQ
:
2153 wpa_printf(MSG_DEBUG
, "mgmt::assoc_req");
2154 handle_assoc(hapd
, mgmt
, len
, 0);
2157 case WLAN_FC_STYPE_REASSOC_REQ
:
2158 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_req");
2159 handle_assoc(hapd
, mgmt
, len
, 1);
2162 case WLAN_FC_STYPE_DISASSOC
:
2163 wpa_printf(MSG_DEBUG
, "mgmt::disassoc");
2164 handle_disassoc(hapd
, mgmt
, len
);
2167 case WLAN_FC_STYPE_DEAUTH
:
2168 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "mgmt::deauth");
2169 handle_deauth(hapd
, mgmt
, len
);
2172 case WLAN_FC_STYPE_ACTION
:
2173 wpa_printf(MSG_DEBUG
, "mgmt::action");
2174 ret
= handle_action(hapd
, mgmt
, len
);
2177 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
2178 HOSTAPD_LEVEL_DEBUG
,
2179 "unknown mgmt frame subtype %d", stype
);
2187 static void handle_auth_cb(struct hostapd_data
*hapd
,
2188 const struct ieee80211_mgmt
*mgmt
,
2191 u16 auth_alg
, auth_transaction
, status_code
;
2192 struct sta_info
*sta
;
2195 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
2196 HOSTAPD_LEVEL_NOTICE
,
2197 "did not acknowledge authentication response");
2201 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
2202 wpa_printf(MSG_INFO
, "handle_auth_cb - too short payload (len=%lu)",
2203 (unsigned long) len
);
2207 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
2208 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
2209 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
2211 sta
= ap_get_sta(hapd
, mgmt
->da
);
2213 wpa_printf(MSG_INFO
, "handle_auth_cb: STA " MACSTR
" not found",
2218 if (status_code
== WLAN_STATUS_SUCCESS
&&
2219 ((auth_alg
== WLAN_AUTH_OPEN
&& auth_transaction
== 2) ||
2220 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 4))) {
2221 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2222 HOSTAPD_LEVEL_INFO
, "authenticated");
2223 sta
->flags
|= WLAN_STA_AUTH
;
2228 static void hostapd_set_wds_encryption(struct hostapd_data
*hapd
,
2229 struct sta_info
*sta
,
2233 struct hostapd_ssid
*ssid
= sta
->ssid
;
2235 if (hapd
->conf
->ieee802_1x
|| hapd
->conf
->wpa
)
2238 for (i
= 0; i
< 4; i
++) {
2239 if (ssid
->wep
.key
[i
] &&
2240 hostapd_drv_set_key(ifname_wds
, hapd
, WPA_ALG_WEP
, NULL
, i
,
2241 i
== ssid
->wep
.idx
, NULL
, 0,
2242 ssid
->wep
.key
[i
], ssid
->wep
.len
[i
])) {
2243 wpa_printf(MSG_WARNING
,
2244 "Could not set WEP keys for WDS interface; %s",
2252 static void handle_assoc_cb(struct hostapd_data
*hapd
,
2253 const struct ieee80211_mgmt
*mgmt
,
2254 size_t len
, int reassoc
, int ok
)
2257 struct sta_info
*sta
;
2259 struct ieee80211_ht_capabilities ht_cap
;
2260 struct ieee80211_vht_capabilities vht_cap
;
2262 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_resp
) :
2263 sizeof(mgmt
->u
.assoc_resp
))) {
2264 wpa_printf(MSG_INFO
, "handle_assoc_cb(reassoc=%d) - too short payload (len=%lu)",
2265 reassoc
, (unsigned long) len
);
2269 sta
= ap_get_sta(hapd
, mgmt
->da
);
2271 wpa_printf(MSG_INFO
, "handle_assoc_cb: STA " MACSTR
" not found",
2277 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
2278 HOSTAPD_LEVEL_DEBUG
,
2279 "did not acknowledge association response");
2280 sta
->flags
&= ~WLAN_STA_ASSOC_REQ_OK
;
2285 status
= le_to_host16(mgmt
->u
.reassoc_resp
.status_code
);
2287 status
= le_to_host16(mgmt
->u
.assoc_resp
.status_code
);
2289 if (status
!= WLAN_STATUS_SUCCESS
)
2292 /* Stop previous accounting session, if one is started, and allocate
2293 * new session id for the new session. */
2294 accounting_sta_stop(hapd
, sta
);
2296 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2298 "associated (aid %d)",
2301 if (sta
->flags
& WLAN_STA_ASSOC
)
2303 sta
->flags
|= WLAN_STA_ASSOC
;
2304 sta
->flags
&= ~WLAN_STA_WNM_SLEEP_MODE
;
2305 if ((!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
&& !hapd
->conf
->osen
) ||
2306 sta
->auth_alg
== WLAN_AUTH_FT
) {
2308 * Open, static WEP, or FT protocol; no separate authorization
2311 ap_sta_set_authorized(hapd
, sta
, 1);
2315 mlme_reassociate_indication(hapd
, sta
);
2317 mlme_associate_indication(hapd
, sta
);
2319 #ifdef CONFIG_IEEE80211W
2320 sta
->sa_query_timed_out
= 0;
2321 #endif /* CONFIG_IEEE80211W */
2324 * Remove the STA entry in order to make sure the STA PS state gets
2325 * cleared and configuration gets updated in case of reassociation back
2328 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2330 #ifdef CONFIG_IEEE80211N
2331 if (sta
->flags
& WLAN_STA_HT
)
2332 hostapd_get_ht_capab(hapd
, sta
->ht_capabilities
, &ht_cap
);
2333 #endif /* CONFIG_IEEE80211N */
2334 #ifdef CONFIG_IEEE80211AC
2335 if (sta
->flags
& WLAN_STA_VHT
)
2336 hostapd_get_vht_capab(hapd
, sta
->vht_capabilities
, &vht_cap
);
2337 #endif /* CONFIG_IEEE80211AC */
2339 if (hostapd_sta_add(hapd
, sta
->addr
, sta
->aid
, sta
->capability
,
2340 sta
->supported_rates
, sta
->supported_rates_len
,
2341 sta
->listen_interval
,
2342 sta
->flags
& WLAN_STA_HT
? &ht_cap
: NULL
,
2343 sta
->flags
& WLAN_STA_VHT
? &vht_cap
: NULL
,
2344 sta
->flags
, sta
->qosinfo
, sta
->vht_opmode
)) {
2345 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2346 HOSTAPD_LEVEL_NOTICE
,
2347 "Could not add STA to kernel driver");
2349 ap_sta_disconnect(hapd
, sta
, sta
->addr
,
2350 WLAN_REASON_DISASSOC_AP_BUSY
);
2355 if (sta
->flags
& WLAN_STA_WDS
) {
2357 char ifname_wds
[IFNAMSIZ
+ 1];
2359 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
, sta
->addr
,
2362 hostapd_set_wds_encryption(hapd
, sta
, ifname_wds
);
2365 if (sta
->eapol_sm
== NULL
) {
2367 * This STA does not use RADIUS server for EAP authentication,
2368 * so bind it to the selected VLAN interface now, since the
2369 * interface selection is not going to change anymore.
2371 if (ap_sta_bind_vlan(hapd
, sta
, 0) < 0)
2373 } else if (sta
->vlan_id
) {
2374 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
2375 if (ap_sta_bind_vlan(hapd
, sta
, 0) < 0)
2379 hostapd_set_sta_flags(hapd
, sta
);
2381 if (sta
->auth_alg
== WLAN_AUTH_FT
)
2382 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC_FT
);
2384 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
2385 hapd
->new_assoc_sta_cb(hapd
, sta
, !new_assoc
);
2387 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
2391 static void handle_deauth_cb(struct hostapd_data
*hapd
,
2392 const struct ieee80211_mgmt
*mgmt
,
2395 struct sta_info
*sta
;
2396 if (mgmt
->da
[0] & 0x01)
2398 sta
= ap_get_sta(hapd
, mgmt
->da
);
2400 wpa_printf(MSG_DEBUG
, "handle_deauth_cb: STA " MACSTR
2401 " not found", MAC2STR(mgmt
->da
));
2405 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged deauth",
2406 MAC2STR(sta
->addr
));
2408 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
2409 "deauth", MAC2STR(sta
->addr
));
2411 ap_sta_deauth_cb(hapd
, sta
);
2415 static void handle_disassoc_cb(struct hostapd_data
*hapd
,
2416 const struct ieee80211_mgmt
*mgmt
,
2419 struct sta_info
*sta
;
2420 if (mgmt
->da
[0] & 0x01)
2422 sta
= ap_get_sta(hapd
, mgmt
->da
);
2424 wpa_printf(MSG_DEBUG
, "handle_disassoc_cb: STA " MACSTR
2425 " not found", MAC2STR(mgmt
->da
));
2429 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged disassoc",
2430 MAC2STR(sta
->addr
));
2432 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
2433 "disassoc", MAC2STR(sta
->addr
));
2435 ap_sta_disassoc_cb(hapd
, sta
);
2440 * ieee802_11_mgmt_cb - Process management frame TX status callback
2441 * @hapd: hostapd BSS data structure (the BSS from which the management frame
2443 * @buf: management frame data (starting from IEEE 802.11 header)
2444 * @len: length of frame data in octets
2445 * @stype: management frame subtype from frame control field
2446 * @ok: Whether the frame was ACK'ed
2448 void ieee802_11_mgmt_cb(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
2451 const struct ieee80211_mgmt
*mgmt
;
2452 mgmt
= (const struct ieee80211_mgmt
*) buf
;
2454 #ifdef CONFIG_TESTING_OPTIONS
2455 if (hapd
->ext_mgmt_frame_handling
) {
2456 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, "MGMT-TX-STATUS stype=%u ok=%d",
2460 #endif /* CONFIG_TESTING_OPTIONS */
2463 case WLAN_FC_STYPE_AUTH
:
2464 wpa_printf(MSG_DEBUG
, "mgmt::auth cb");
2465 handle_auth_cb(hapd
, mgmt
, len
, ok
);
2467 case WLAN_FC_STYPE_ASSOC_RESP
:
2468 wpa_printf(MSG_DEBUG
, "mgmt::assoc_resp cb");
2469 handle_assoc_cb(hapd
, mgmt
, len
, 0, ok
);
2471 case WLAN_FC_STYPE_REASSOC_RESP
:
2472 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_resp cb");
2473 handle_assoc_cb(hapd
, mgmt
, len
, 1, ok
);
2475 case WLAN_FC_STYPE_PROBE_RESP
:
2476 wpa_printf(MSG_EXCESSIVE
, "mgmt::proberesp cb");
2478 case WLAN_FC_STYPE_DEAUTH
:
2479 wpa_printf(MSG_DEBUG
, "mgmt::deauth cb");
2480 handle_deauth_cb(hapd
, mgmt
, len
, ok
);
2482 case WLAN_FC_STYPE_DISASSOC
:
2483 wpa_printf(MSG_DEBUG
, "mgmt::disassoc cb");
2484 handle_disassoc_cb(hapd
, mgmt
, len
, ok
);
2486 case WLAN_FC_STYPE_ACTION
:
2487 wpa_printf(MSG_DEBUG
, "mgmt::action cb");
2490 wpa_printf(MSG_INFO
, "unknown mgmt cb frame subtype %d", stype
);
2496 int ieee802_11_get_mib(struct hostapd_data
*hapd
, char *buf
, size_t buflen
)
2503 int ieee802_11_get_mib_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2504 char *buf
, size_t buflen
)
2511 void hostapd_tx_status(struct hostapd_data
*hapd
, const u8
*addr
,
2512 const u8
*buf
, size_t len
, int ack
)
2514 struct sta_info
*sta
;
2515 struct hostapd_iface
*iface
= hapd
->iface
;
2517 sta
= ap_get_sta(hapd
, addr
);
2518 if (sta
== NULL
&& iface
->num_bss
> 1) {
2520 for (j
= 0; j
< iface
->num_bss
; j
++) {
2521 hapd
= iface
->bss
[j
];
2522 sta
= ap_get_sta(hapd
, addr
);
2527 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))
2529 if (sta
->flags
& WLAN_STA_PENDING_POLL
) {
2530 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" %s pending "
2531 "activity poll", MAC2STR(sta
->addr
),
2532 ack
? "ACKed" : "did not ACK");
2534 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
2537 ieee802_1x_tx_status(hapd
, sta
, buf
, len
, ack
);
2541 void hostapd_eapol_tx_status(struct hostapd_data
*hapd
, const u8
*dst
,
2542 const u8
*data
, size_t len
, int ack
)
2544 struct sta_info
*sta
;
2545 struct hostapd_iface
*iface
= hapd
->iface
;
2547 sta
= ap_get_sta(hapd
, dst
);
2548 if (sta
== NULL
&& iface
->num_bss
> 1) {
2550 for (j
= 0; j
< iface
->num_bss
; j
++) {
2551 hapd
= iface
->bss
[j
];
2552 sta
= ap_get_sta(hapd
, dst
);
2557 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
2558 wpa_printf(MSG_DEBUG
, "Ignore TX status for Data frame to STA "
2559 MACSTR
" that is not currently associated",
2564 ieee802_1x_eapol_tx_status(hapd
, sta
, data
, len
, ack
);
2568 void hostapd_client_poll_ok(struct hostapd_data
*hapd
, const u8
*addr
)
2570 struct sta_info
*sta
;
2571 struct hostapd_iface
*iface
= hapd
->iface
;
2573 sta
= ap_get_sta(hapd
, addr
);
2574 if (sta
== NULL
&& iface
->num_bss
> 1) {
2576 for (j
= 0; j
< iface
->num_bss
; j
++) {
2577 hapd
= iface
->bss
[j
];
2578 sta
= ap_get_sta(hapd
, addr
);
2585 if (!(sta
->flags
& WLAN_STA_PENDING_POLL
))
2588 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" ACKed pending "
2589 "activity poll", MAC2STR(sta
->addr
));
2590 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
2594 void ieee802_11_rx_from_unknown(struct hostapd_data
*hapd
, const u8
*src
,
2597 struct sta_info
*sta
;
2599 sta
= ap_get_sta(hapd
, src
);
2600 if (sta
&& (sta
->flags
& WLAN_STA_ASSOC
)) {
2601 if (!hapd
->conf
->wds_sta
)
2604 if (wds
&& !(sta
->flags
& WLAN_STA_WDS
)) {
2606 char ifname_wds
[IFNAMSIZ
+ 1];
2608 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for "
2609 "STA " MACSTR
" (aid %u)",
2610 MAC2STR(sta
->addr
), sta
->aid
);
2611 sta
->flags
|= WLAN_STA_WDS
;
2612 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
,
2613 sta
->addr
, sta
->aid
, 1);
2615 hostapd_set_wds_encryption(hapd
, sta
,
2621 wpa_printf(MSG_DEBUG
, "Data/PS-poll frame from not associated STA "
2622 MACSTR
, MAC2STR(src
));
2623 if (src
[0] & 0x01) {
2624 /* Broadcast bit set in SA?! Ignore the frame silently. */
2628 if (sta
&& (sta
->flags
& WLAN_STA_ASSOC_REQ_OK
)) {
2629 wpa_printf(MSG_DEBUG
, "Association Response to the STA has "
2630 "already been sent, but no TX status yet known - "
2631 "ignore Class 3 frame issue with " MACSTR
,
2636 if (sta
&& (sta
->flags
& WLAN_STA_AUTH
))
2637 hostapd_drv_sta_disassoc(
2639 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
2641 hostapd_drv_sta_deauth(
2643 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
2647 #endif /* CONFIG_NATIVE_WINDOWS */