2 * hostapd / IEEE 802.11 Management
3 * Copyright (c) 2002-2012, 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 "drivers/driver.h"
19 #include "common/ieee802_11_defs.h"
20 #include "common/ieee802_11_common.h"
21 #include "common/wpa_ctrl.h"
22 #include "common/sae.h"
23 #include "radius/radius.h"
24 #include "radius/radius_client.h"
29 #include "ieee802_11_auth.h"
31 #include "ieee802_1x.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"
44 u8
* hostapd_eid_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
49 if (hapd
->iface
->current_rates
== NULL
)
52 *pos
++ = WLAN_EID_SUPP_RATES
;
53 num
= hapd
->iface
->num_rates
;
54 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
)
56 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
)
59 /* 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
;
109 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
+ 8;
113 continue; /* already in SuppRates IE */
114 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
115 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
120 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
) {
123 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY
;
126 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
) {
129 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY
;
136 u16
hostapd_own_capab_info(struct hostapd_data
*hapd
, struct sta_info
*sta
,
139 int capab
= WLAN_CAPABILITY_ESS
;
142 if (hapd
->iface
->num_sta_no_short_preamble
== 0 &&
143 hapd
->iconf
->preamble
== SHORT_PREAMBLE
)
144 capab
|= WLAN_CAPABILITY_SHORT_PREAMBLE
;
146 privacy
= hapd
->conf
->ssid
.wep
.keys_set
;
148 if (hapd
->conf
->ieee802_1x
&&
149 (hapd
->conf
->default_wep_key_len
||
150 hapd
->conf
->individual_wep_key_len
))
157 int policy
, def_klen
;
158 if (probe
&& sta
->ssid_probe
) {
159 policy
= sta
->ssid_probe
->security_policy
;
160 def_klen
= sta
->ssid_probe
->wep
.default_len
;
162 policy
= sta
->ssid
->security_policy
;
163 def_klen
= sta
->ssid
->wep
.default_len
;
165 privacy
= policy
!= SECURITY_PLAINTEXT
;
166 if (policy
== SECURITY_IEEE_802_1X
&& def_klen
== 0)
171 capab
|= WLAN_CAPABILITY_PRIVACY
;
173 if (hapd
->iface
->current_mode
&&
174 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
&&
175 hapd
->iface
->num_sta_no_short_slot_time
== 0)
176 capab
|= WLAN_CAPABILITY_SHORT_SLOT_TIME
;
182 void ieee802_11_print_ssid(char *buf
, const u8
*ssid
, u8 len
)
185 if (len
> HOSTAPD_MAX_SSID_LEN
)
186 len
= HOSTAPD_MAX_SSID_LEN
;
187 for (i
= 0; i
< len
; i
++) {
188 if (ssid
[i
] >= 32 && ssid
[i
] < 127)
197 static u16
auth_shared_key(struct hostapd_data
*hapd
, struct sta_info
*sta
,
198 u16 auth_transaction
, const u8
*challenge
,
201 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
203 "authentication (shared key, transaction %d)",
206 if (auth_transaction
== 1) {
207 if (!sta
->challenge
) {
208 /* Generate a pseudo-random challenge */
212 sta
->challenge
= os_zalloc(WLAN_AUTH_CHALLENGE_LEN
);
213 if (sta
->challenge
== NULL
)
214 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
218 os_memcpy(key
, &now
.sec
, 4);
219 os_memcpy(key
+ 4, &r
, 4);
220 rc4_skip(key
, sizeof(key
), 0,
221 sta
->challenge
, WLAN_AUTH_CHALLENGE_LEN
);
226 if (auth_transaction
!= 3)
227 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
230 if (!iswep
|| !sta
->challenge
|| !challenge
||
231 os_memcmp(sta
->challenge
, challenge
, WLAN_AUTH_CHALLENGE_LEN
)) {
232 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
234 "shared key authentication - invalid "
235 "challenge-response");
236 return WLAN_STATUS_CHALLENGE_FAIL
;
239 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
241 "authentication OK (shared key)");
242 #ifdef IEEE80211_REQUIRE_AUTH_ACK
243 /* Station will be marked authenticated if it ACKs the
244 * authentication reply. */
246 sta
->flags
|= WLAN_STA_AUTH
;
247 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
249 os_free(sta
->challenge
);
250 sta
->challenge
= NULL
;
256 static void send_auth_reply(struct hostapd_data
*hapd
,
257 const u8
*dst
, const u8
*bssid
,
258 u16 auth_alg
, u16 auth_transaction
, u16 resp
,
259 const u8
*ies
, size_t ies_len
)
261 struct ieee80211_mgmt
*reply
;
265 rlen
= IEEE80211_HDRLEN
+ sizeof(reply
->u
.auth
) + ies_len
;
266 buf
= os_zalloc(rlen
);
270 reply
= (struct ieee80211_mgmt
*) buf
;
271 reply
->frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
273 os_memcpy(reply
->da
, dst
, ETH_ALEN
);
274 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
275 os_memcpy(reply
->bssid
, bssid
, ETH_ALEN
);
277 reply
->u
.auth
.auth_alg
= host_to_le16(auth_alg
);
278 reply
->u
.auth
.auth_transaction
= host_to_le16(auth_transaction
);
279 reply
->u
.auth
.status_code
= host_to_le16(resp
);
282 os_memcpy(reply
->u
.auth
.variable
, ies
, ies_len
);
284 wpa_printf(MSG_DEBUG
, "authentication reply: STA=" MACSTR
285 " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)",
286 MAC2STR(dst
), auth_alg
, auth_transaction
,
287 resp
, (unsigned long) ies_len
);
288 if (hostapd_drv_send_mlme(hapd
, reply
, rlen
, 0) < 0)
289 perror("send_auth_reply: send");
295 #ifdef CONFIG_IEEE80211R
296 static void handle_auth_ft_finish(void *ctx
, const u8
*dst
, const u8
*bssid
,
297 u16 auth_transaction
, u16 status
,
298 const u8
*ies
, size_t ies_len
)
300 struct hostapd_data
*hapd
= ctx
;
301 struct sta_info
*sta
;
303 send_auth_reply(hapd
, dst
, bssid
, WLAN_AUTH_FT
, auth_transaction
,
304 status
, ies
, ies_len
);
306 if (status
!= WLAN_STATUS_SUCCESS
)
309 sta
= ap_get_sta(hapd
, dst
);
313 hostapd_logger(hapd
, dst
, HOSTAPD_MODULE_IEEE80211
,
314 HOSTAPD_LEVEL_DEBUG
, "authentication OK (FT)");
315 sta
->flags
|= WLAN_STA_AUTH
;
316 mlme_authenticate_indication(hapd
, sta
);
318 #endif /* CONFIG_IEEE80211R */
323 static struct wpabuf
* auth_process_sae_commit(struct hostapd_data
*hapd
,
324 struct sta_info
*sta
)
328 if (hapd
->conf
->ssid
.wpa_passphrase
== NULL
) {
329 wpa_printf(MSG_DEBUG
, "SAE: No password available");
333 if (sae_prepare_commit(hapd
->own_addr
, sta
->addr
,
334 (u8
*) hapd
->conf
->ssid
.wpa_passphrase
,
335 os_strlen(hapd
->conf
->ssid
.wpa_passphrase
),
337 wpa_printf(MSG_DEBUG
, "SAE: Could not pick PWE");
341 if (sae_process_commit(sta
->sae
) < 0) {
342 wpa_printf(MSG_DEBUG
, "SAE: Failed to process peer commit");
346 buf
= wpabuf_alloc(SAE_COMMIT_MAX_LEN
);
349 sae_write_commit(sta
->sae
, buf
, NULL
);
355 static struct wpabuf
* auth_build_sae_confirm(struct hostapd_data
*hapd
,
356 struct sta_info
*sta
)
360 buf
= wpabuf_alloc(SAE_CONFIRM_MAX_LEN
);
364 sae_write_confirm(sta
->sae
, buf
);
370 static int use_sae_anti_clogging(struct hostapd_data
*hapd
)
372 struct sta_info
*sta
;
373 unsigned int open
= 0;
375 if (hapd
->conf
->sae_anti_clogging_threshold
== 0)
378 for (sta
= hapd
->sta_list
; sta
; sta
= sta
->next
) {
381 if (sta
->sae
->state
!= SAE_COMMITTED
&&
382 sta
->sae
->state
!= SAE_CONFIRMED
)
385 if (open
>= hapd
->conf
->sae_anti_clogging_threshold
)
393 static int check_sae_token(struct hostapd_data
*hapd
, const u8
*addr
,
394 const u8
*token
, size_t token_len
)
396 u8 mac
[SHA256_MAC_LEN
];
398 if (token_len
!= SHA256_MAC_LEN
)
400 if (hmac_sha256(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
401 addr
, ETH_ALEN
, mac
) < 0 ||
402 os_memcmp(token
, mac
, SHA256_MAC_LEN
) != 0)
409 static struct wpabuf
* auth_build_token_req(struct hostapd_data
*hapd
,
417 if (hapd
->last_sae_token_key_update
== 0 ||
418 t
.sec
> hapd
->last_sae_token_key_update
+ 60) {
419 if (random_get_bytes(hapd
->sae_token_key
,
420 sizeof(hapd
->sae_token_key
)) < 0)
422 wpa_hexdump(MSG_DEBUG
, "SAE: Updated token key",
423 hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
));
424 hapd
->last_sae_token_key_update
= t
.sec
;
427 buf
= wpabuf_alloc(SHA256_MAC_LEN
);
431 token
= wpabuf_put(buf
, SHA256_MAC_LEN
);
432 hmac_sha256(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
433 addr
, ETH_ALEN
, token
);
439 static void handle_auth_sae(struct hostapd_data
*hapd
, struct sta_info
*sta
,
440 const struct ieee80211_mgmt
*mgmt
, size_t len
,
443 u16 resp
= WLAN_STATUS_SUCCESS
;
444 struct wpabuf
*data
= NULL
;
447 if (auth_transaction
!= 1)
449 sta
->sae
= os_zalloc(sizeof(*sta
->sae
));
450 if (sta
->sae
== NULL
)
452 sta
->sae
->state
= SAE_NOTHING
;
455 if (auth_transaction
== 1) {
456 const u8
*token
= NULL
;
457 size_t token_len
= 0;
458 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
460 "start SAE authentication (RX commit)");
461 resp
= sae_parse_commit(sta
->sae
, mgmt
->u
.auth
.variable
,
462 ((const u8
*) mgmt
) + len
-
463 mgmt
->u
.auth
.variable
, &token
,
464 &token_len
, hapd
->conf
->sae_groups
);
465 if (token
&& check_sae_token(hapd
, sta
->addr
, token
, token_len
)
467 wpa_printf(MSG_DEBUG
, "SAE: Drop commit message with "
468 "incorrect token from " MACSTR
,
473 if (resp
== WLAN_STATUS_SUCCESS
) {
474 if (!token
&& use_sae_anti_clogging(hapd
)) {
475 wpa_printf(MSG_DEBUG
, "SAE: Request anti-"
476 "clogging token from " MACSTR
,
478 data
= auth_build_token_req(hapd
, sta
->addr
);
479 resp
= WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
;
481 data
= auth_process_sae_commit(hapd
, sta
);
483 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
485 sta
->sae
->state
= SAE_COMMITTED
;
488 } else if (auth_transaction
== 2) {
489 if (sta
->sae
->state
!= SAE_COMMITTED
) {
490 hostapd_logger(hapd
, sta
->addr
,
491 HOSTAPD_MODULE_IEEE80211
,
493 "SAE confirm before commit");
494 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
496 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
498 "SAE authentication (RX confirm)");
499 if (sae_check_confirm(sta
->sae
, mgmt
->u
.auth
.variable
,
500 ((u8
*) mgmt
) + len
-
501 mgmt
->u
.auth
.variable
) < 0) {
502 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
504 resp
= WLAN_STATUS_SUCCESS
;
505 sta
->flags
|= WLAN_STA_AUTH
;
506 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
507 sta
->auth_alg
= WLAN_AUTH_SAE
;
508 mlme_authenticate_indication(hapd
, sta
);
510 data
= auth_build_sae_confirm(hapd
, sta
);
512 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
514 sta
->sae
->state
= SAE_ACCEPTED
;
515 sae_clear_temp_data(sta
->sae
);
519 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
521 "unexpected SAE authentication transaction %u",
523 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
526 sta
->auth_alg
= WLAN_AUTH_SAE
;
528 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
529 auth_transaction
, resp
,
530 data
? wpabuf_head(data
) : (u8
*) "",
531 data
? wpabuf_len(data
) : 0);
534 #endif /* CONFIG_SAE */
537 static void handle_auth(struct hostapd_data
*hapd
,
538 const struct ieee80211_mgmt
*mgmt
, size_t len
)
540 u16 auth_alg
, auth_transaction
, status_code
;
541 u16 resp
= WLAN_STATUS_SUCCESS
;
542 struct sta_info
*sta
= NULL
;
545 const u8
*challenge
= NULL
;
546 u32 session_timeout
, acct_interim_interval
;
548 struct hostapd_sta_wpa_psk_short
*psk
= NULL
;
549 u8 resp_ies
[2 + WLAN_AUTH_CHALLENGE_LEN
];
550 size_t resp_ies_len
= 0;
551 char *identity
= NULL
;
552 char *radius_cui
= NULL
;
554 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
555 printf("handle_auth - too short payload (len=%lu)\n",
556 (unsigned long) len
);
560 #ifdef CONFIG_TESTING_OPTIONS
561 if (hapd
->iconf
->ignore_auth_probability
> 0.0d
&&
562 drand48() < hapd
->iconf
->ignore_auth_probability
) {
564 "TESTING: ignoring auth frame from " MACSTR
,
568 #endif /* CONFIG_TESTING_OPTIONS */
570 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
571 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
572 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
573 fc
= le_to_host16(mgmt
->frame_control
);
575 if (len
>= IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
) +
576 2 + WLAN_AUTH_CHALLENGE_LEN
&&
577 mgmt
->u
.auth
.variable
[0] == WLAN_EID_CHALLENGE
&&
578 mgmt
->u
.auth
.variable
[1] == WLAN_AUTH_CHALLENGE_LEN
)
579 challenge
= &mgmt
->u
.auth
.variable
[2];
581 wpa_printf(MSG_DEBUG
, "authentication: STA=" MACSTR
" auth_alg=%d "
582 "auth_transaction=%d status_code=%d wep=%d%s",
583 MAC2STR(mgmt
->sa
), auth_alg
, auth_transaction
,
584 status_code
, !!(fc
& WLAN_FC_ISWEP
),
585 challenge
? " challenge" : "");
587 if (hapd
->tkip_countermeasures
) {
588 resp
= WLAN_REASON_MICHAEL_MIC_FAILURE
;
592 if (!(((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_OPEN
) &&
593 auth_alg
== WLAN_AUTH_OPEN
) ||
594 #ifdef CONFIG_IEEE80211R
595 (hapd
->conf
->wpa
&& wpa_key_mgmt_ft(hapd
->conf
->wpa_key_mgmt
) &&
596 auth_alg
== WLAN_AUTH_FT
) ||
597 #endif /* CONFIG_IEEE80211R */
599 (hapd
->conf
->wpa
&& wpa_key_mgmt_sae(hapd
->conf
->wpa_key_mgmt
) &&
600 auth_alg
== WLAN_AUTH_SAE
) ||
601 #endif /* CONFIG_SAE */
602 ((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_SHARED
) &&
603 auth_alg
== WLAN_AUTH_SHARED_KEY
))) {
604 printf("Unsupported authentication algorithm (%d)\n",
606 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
610 if (!(auth_transaction
== 1 || auth_alg
== WLAN_AUTH_SAE
||
611 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 3))) {
612 printf("Unknown authentication transaction number (%d)\n",
614 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
618 if (os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
619 printf("Station " MACSTR
" not allowed to authenticate.\n",
621 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
625 res
= hostapd_allowed_address(hapd
, mgmt
->sa
, (u8
*) mgmt
, len
,
627 &acct_interim_interval
, &vlan_id
,
628 &psk
, &identity
, &radius_cui
);
630 if (res
== HOSTAPD_ACL_REJECT
) {
631 printf("Station " MACSTR
" not allowed to authenticate.\n",
633 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
636 if (res
== HOSTAPD_ACL_PENDING
) {
637 wpa_printf(MSG_DEBUG
, "Authentication frame from " MACSTR
638 " waiting for an external authentication",
640 /* Authentication code will re-send the authentication frame
641 * after it has received (and cached) information from the
642 * external source. */
646 sta
= ap_sta_add(hapd
, mgmt
->sa
);
648 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
653 if (!hostapd_vlan_id_valid(hapd
->conf
->vlan
, vlan_id
)) {
654 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
655 HOSTAPD_LEVEL_INFO
, "Invalid VLAN ID "
656 "%d received from RADIUS server",
658 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
661 sta
->vlan_id
= vlan_id
;
662 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
663 HOSTAPD_LEVEL_INFO
, "VLAN ID %d", sta
->vlan_id
);
666 hostapd_free_psk_list(sta
->psk
);
667 if (hapd
->conf
->wpa_psk_radius
!= PSK_RADIUS_IGNORED
) {
674 sta
->identity
= identity
;
676 sta
->radius_cui
= radius_cui
;
679 sta
->flags
&= ~WLAN_STA_PREAUTH
;
680 ieee802_1x_notify_pre_auth(sta
->eapol_sm
, 0);
682 if (hapd
->conf
->acct_interim_interval
== 0 && acct_interim_interval
)
683 sta
->acct_interim_interval
= acct_interim_interval
;
684 if (res
== HOSTAPD_ACL_ACCEPT_TIMEOUT
)
685 ap_sta_session_timeout(hapd
, sta
, session_timeout
);
687 ap_sta_no_session_timeout(hapd
, sta
);
691 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
693 "authentication OK (open system)");
694 #ifdef IEEE80211_REQUIRE_AUTH_ACK
695 /* Station will be marked authenticated if it ACKs the
696 * authentication reply. */
698 sta
->flags
|= WLAN_STA_AUTH
;
699 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
700 sta
->auth_alg
= WLAN_AUTH_OPEN
;
701 mlme_authenticate_indication(hapd
, sta
);
704 case WLAN_AUTH_SHARED_KEY
:
705 resp
= auth_shared_key(hapd
, sta
, auth_transaction
, challenge
,
707 sta
->auth_alg
= WLAN_AUTH_SHARED_KEY
;
708 mlme_authenticate_indication(hapd
, sta
);
709 if (sta
->challenge
&& auth_transaction
== 1) {
710 resp_ies
[0] = WLAN_EID_CHALLENGE
;
711 resp_ies
[1] = WLAN_AUTH_CHALLENGE_LEN
;
712 os_memcpy(resp_ies
+ 2, sta
->challenge
,
713 WLAN_AUTH_CHALLENGE_LEN
);
714 resp_ies_len
= 2 + WLAN_AUTH_CHALLENGE_LEN
;
717 #ifdef CONFIG_IEEE80211R
719 sta
->auth_alg
= WLAN_AUTH_FT
;
720 if (sta
->wpa_sm
== NULL
)
721 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
723 if (sta
->wpa_sm
== NULL
) {
724 wpa_printf(MSG_DEBUG
, "FT: Failed to initialize WPA "
726 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
729 wpa_ft_process_auth(sta
->wpa_sm
, mgmt
->bssid
,
730 auth_transaction
, mgmt
->u
.auth
.variable
,
731 len
- IEEE80211_HDRLEN
-
732 sizeof(mgmt
->u
.auth
),
733 handle_auth_ft_finish
, hapd
);
734 /* handle_auth_ft_finish() callback will complete auth. */
736 #endif /* CONFIG_IEEE80211R */
739 handle_auth_sae(hapd
, sta
, mgmt
, len
, auth_transaction
);
741 #endif /* CONFIG_SAE */
747 hostapd_free_psk_list(psk
);
749 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, auth_alg
,
750 auth_transaction
+ 1, resp
, resp_ies
, resp_ies_len
);
754 static int hostapd_get_aid(struct hostapd_data
*hapd
, struct sta_info
*sta
)
758 /* get a unique AID */
760 wpa_printf(MSG_DEBUG
, " old AID %d", sta
->aid
);
764 for (i
= 0; i
< AID_WORDS
; i
++) {
765 if (hapd
->sta_aid
[i
] == (u32
) -1)
767 for (j
= 0; j
< 32; j
++) {
768 if (!(hapd
->sta_aid
[i
] & BIT(j
)))
776 aid
= i
* 32 + j
+ 1;
781 hapd
->sta_aid
[i
] |= BIT(j
);
782 wpa_printf(MSG_DEBUG
, " new AID %d", sta
->aid
);
787 static u16
check_ssid(struct hostapd_data
*hapd
, struct sta_info
*sta
,
788 const u8
*ssid_ie
, size_t ssid_ie_len
)
791 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
793 if (ssid_ie_len
!= hapd
->conf
->ssid
.ssid_len
||
794 os_memcmp(ssid_ie
, hapd
->conf
->ssid
.ssid
, ssid_ie_len
) != 0) {
796 ieee802_11_print_ssid(ssid_txt
, ssid_ie
, ssid_ie_len
);
797 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
799 "Station tried to associate with unknown SSID "
801 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
804 return WLAN_STATUS_SUCCESS
;
808 static u16
check_wmm(struct hostapd_data
*hapd
, struct sta_info
*sta
,
809 const u8
*wmm_ie
, size_t wmm_ie_len
)
811 sta
->flags
&= ~WLAN_STA_WMM
;
813 if (wmm_ie
&& hapd
->conf
->wmm_enabled
) {
814 struct wmm_information_element
*wmm
;
816 if (!hostapd_eid_wmm_valid(hapd
, wmm_ie
, wmm_ie_len
)) {
817 hostapd_logger(hapd
, sta
->addr
,
820 "invalid WMM element in association "
822 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
825 sta
->flags
|= WLAN_STA_WMM
;
826 wmm
= (struct wmm_information_element
*) wmm_ie
;
827 sta
->qosinfo
= wmm
->qos_info
;
829 return WLAN_STATUS_SUCCESS
;
833 static u16
copy_supp_rates(struct hostapd_data
*hapd
, struct sta_info
*sta
,
834 struct ieee802_11_elems
*elems
)
836 if (!elems
->supp_rates
) {
837 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
839 "No supported rates element in AssocReq");
840 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
843 if (elems
->supp_rates_len
+ elems
->ext_supp_rates_len
>
844 sizeof(sta
->supported_rates
)) {
845 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
847 "Invalid supported rates element length %d+%d",
848 elems
->supp_rates_len
,
849 elems
->ext_supp_rates_len
);
850 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
853 sta
->supported_rates_len
= merge_byte_arrays(
854 sta
->supported_rates
, sizeof(sta
->supported_rates
),
855 elems
->supp_rates
, elems
->supp_rates_len
,
856 elems
->ext_supp_rates
, elems
->ext_supp_rates_len
);
858 return WLAN_STATUS_SUCCESS
;
862 static u16
check_assoc_ies(struct hostapd_data
*hapd
, struct sta_info
*sta
,
863 const u8
*ies
, size_t ies_len
, int reassoc
)
865 struct ieee802_11_elems elems
;
870 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 1) == ParseFailed
) {
871 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
872 HOSTAPD_LEVEL_INFO
, "Station sent an invalid "
873 "association request");
874 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
877 resp
= check_ssid(hapd
, sta
, elems
.ssid
, elems
.ssid_len
);
878 if (resp
!= WLAN_STATUS_SUCCESS
)
880 resp
= check_wmm(hapd
, sta
, elems
.wmm
, elems
.wmm_len
);
881 if (resp
!= WLAN_STATUS_SUCCESS
)
883 resp
= copy_supp_rates(hapd
, sta
, &elems
);
884 if (resp
!= WLAN_STATUS_SUCCESS
)
886 #ifdef CONFIG_IEEE80211N
887 resp
= copy_sta_ht_capab(hapd
, sta
, elems
.ht_capabilities
,
888 elems
.ht_capabilities_len
);
889 if (resp
!= WLAN_STATUS_SUCCESS
)
891 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&&
892 !(sta
->flags
& WLAN_STA_HT
)) {
893 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
894 HOSTAPD_LEVEL_INFO
, "Station does not support "
895 "mandatory HT PHY - reject association");
896 return WLAN_STATUS_ASSOC_DENIED_NO_HT
;
898 #endif /* CONFIG_IEEE80211N */
900 #ifdef CONFIG_IEEE80211AC
901 resp
= copy_sta_vht_capab(hapd
, sta
, elems
.vht_capabilities
,
902 elems
.vht_capabilities_len
);
903 if (resp
!= WLAN_STATUS_SUCCESS
)
905 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&&
906 !(sta
->flags
& WLAN_STA_VHT
)) {
907 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
908 HOSTAPD_LEVEL_INFO
, "Station does not support "
909 "mandatory VHT PHY - reject association");
910 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
912 #endif /* CONFIG_IEEE80211AC */
914 if ((hapd
->conf
->wpa
& WPA_PROTO_RSN
) && elems
.rsn_ie
) {
915 wpa_ie
= elems
.rsn_ie
;
916 wpa_ie_len
= elems
.rsn_ie_len
;
917 } else if ((hapd
->conf
->wpa
& WPA_PROTO_WPA
) &&
919 wpa_ie
= elems
.wpa_ie
;
920 wpa_ie_len
= elems
.wpa_ie_len
;
927 sta
->flags
&= ~(WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
| WLAN_STA_WPS2
);
928 if (hapd
->conf
->wps_state
&& elems
.wps_ie
) {
929 wpa_printf(MSG_DEBUG
, "STA included WPS IE in (Re)Association "
930 "Request - assume WPS is used");
931 sta
->flags
|= WLAN_STA_WPS
;
932 wpabuf_free(sta
->wps_ie
);
933 sta
->wps_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
935 if (sta
->wps_ie
&& wps_is_20(sta
->wps_ie
)) {
936 wpa_printf(MSG_DEBUG
, "WPS: STA supports WPS 2.0");
937 sta
->flags
|= WLAN_STA_WPS2
;
941 if (sta
->wps_ie
&& wps_validate_assoc_req(sta
->wps_ie
) < 0) {
942 wpa_printf(MSG_DEBUG
, "WPS: Invalid WPS IE in "
943 "(Re)Association Request - reject");
944 return WLAN_STATUS_INVALID_IE
;
946 } else if (hapd
->conf
->wps_state
&& wpa_ie
== NULL
) {
947 wpa_printf(MSG_DEBUG
, "STA did not include WPA/RSN IE in "
948 "(Re)Association Request - possible WPS use");
949 sta
->flags
|= WLAN_STA_MAYBE_WPS
;
951 #endif /* CONFIG_WPS */
952 if (hapd
->conf
->wpa
&& wpa_ie
== NULL
) {
953 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
955 "No WPA/RSN IE in association request");
956 return WLAN_STATUS_INVALID_IE
;
959 if (hapd
->conf
->wpa
&& wpa_ie
) {
963 if (sta
->wpa_sm
== NULL
)
964 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
966 if (sta
->wpa_sm
== NULL
) {
967 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
969 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
971 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
973 elems
.mdie
, elems
.mdie_len
);
974 if (res
== WPA_INVALID_GROUP
)
975 resp
= WLAN_STATUS_GROUP_CIPHER_NOT_VALID
;
976 else if (res
== WPA_INVALID_PAIRWISE
)
977 resp
= WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID
;
978 else if (res
== WPA_INVALID_AKMP
)
979 resp
= WLAN_STATUS_AKMP_NOT_VALID
;
980 else if (res
== WPA_ALLOC_FAIL
)
981 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
982 #ifdef CONFIG_IEEE80211W
983 else if (res
== WPA_MGMT_FRAME_PROTECTION_VIOLATION
)
984 resp
= WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
985 else if (res
== WPA_INVALID_MGMT_GROUP_CIPHER
)
986 resp
= WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
987 #endif /* CONFIG_IEEE80211W */
988 else if (res
== WPA_INVALID_MDIE
)
989 resp
= WLAN_STATUS_INVALID_MDIE
;
990 else if (res
!= WPA_IE_OK
)
991 resp
= WLAN_STATUS_INVALID_IE
;
992 if (resp
!= WLAN_STATUS_SUCCESS
)
994 #ifdef CONFIG_IEEE80211W
995 if ((sta
->flags
& WLAN_STA_MFP
) && !sta
->sa_query_timed_out
&&
996 sta
->sa_query_count
> 0)
997 ap_check_sa_query_timeout(hapd
, sta
);
998 if ((sta
->flags
& WLAN_STA_MFP
) && !sta
->sa_query_timed_out
&&
999 (!reassoc
|| sta
->auth_alg
!= WLAN_AUTH_FT
)) {
1001 * STA has already been associated with MFP and SA
1002 * Query timeout has not been reached. Reject the
1003 * association attempt temporarily and start SA Query,
1004 * if one is not pending.
1007 if (sta
->sa_query_count
== 0)
1008 ap_sta_start_sa_query(hapd
, sta
);
1010 return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
;
1013 if (wpa_auth_uses_mfp(sta
->wpa_sm
))
1014 sta
->flags
|= WLAN_STA_MFP
;
1016 sta
->flags
&= ~WLAN_STA_MFP
;
1017 #endif /* CONFIG_IEEE80211W */
1019 #ifdef CONFIG_IEEE80211R
1020 if (sta
->auth_alg
== WLAN_AUTH_FT
) {
1022 wpa_printf(MSG_DEBUG
, "FT: " MACSTR
" tried "
1023 "to use association (not "
1024 "re-association) with FT auth_alg",
1025 MAC2STR(sta
->addr
));
1026 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1029 resp
= wpa_ft_validate_reassoc(sta
->wpa_sm
, ies
,
1031 if (resp
!= WLAN_STATUS_SUCCESS
)
1034 #endif /* CONFIG_IEEE80211R */
1037 if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
1038 sta
->auth_alg
!= WLAN_AUTH_SAE
) {
1039 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
" tried to use "
1040 "SAE AKM after non-SAE auth_alg %u",
1041 MAC2STR(sta
->addr
), sta
->auth_alg
);
1042 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
1044 #endif /* CONFIG_SAE */
1046 #ifdef CONFIG_IEEE80211N
1047 if ((sta
->flags
& (WLAN_STA_HT
| WLAN_STA_VHT
)) &&
1048 wpa_auth_get_pairwise(sta
->wpa_sm
) == WPA_CIPHER_TKIP
) {
1049 hostapd_logger(hapd
, sta
->addr
,
1050 HOSTAPD_MODULE_IEEE80211
,
1052 "Station tried to use TKIP with HT "
1054 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
1056 #endif /* CONFIG_IEEE80211N */
1058 wpa_auth_sta_no_wpa(sta
->wpa_sm
);
1062 wpabuf_free(sta
->p2p_ie
);
1063 sta
->p2p_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
1064 P2P_IE_VENDOR_TYPE
);
1067 wpabuf_free(sta
->p2p_ie
);
1071 p2p_group_notif_assoc(hapd
->p2p_group
, sta
->addr
, ies
, ies_len
);
1072 #endif /* CONFIG_P2P */
1075 wpabuf_free(sta
->hs20_ie
);
1076 if (elems
.hs20
&& elems
.hs20_len
> 4) {
1077 sta
->hs20_ie
= wpabuf_alloc_copy(elems
.hs20
+ 4,
1078 elems
.hs20_len
- 4);
1080 sta
->hs20_ie
= NULL
;
1081 #endif /* CONFIG_HS20 */
1083 return WLAN_STATUS_SUCCESS
;
1087 static void send_deauth(struct hostapd_data
*hapd
, const u8
*addr
,
1091 struct ieee80211_mgmt reply
;
1093 os_memset(&reply
, 0, sizeof(reply
));
1094 reply
.frame_control
=
1095 IEEE80211_FC(WLAN_FC_TYPE_MGMT
, WLAN_FC_STYPE_DEAUTH
);
1096 os_memcpy(reply
.da
, addr
, ETH_ALEN
);
1097 os_memcpy(reply
.sa
, hapd
->own_addr
, ETH_ALEN
);
1098 os_memcpy(reply
.bssid
, hapd
->own_addr
, ETH_ALEN
);
1100 send_len
= IEEE80211_HDRLEN
+ sizeof(reply
.u
.deauth
);
1101 reply
.u
.deauth
.reason_code
= host_to_le16(reason_code
);
1103 if (hostapd_drv_send_mlme(hapd
, &reply
, send_len
, 0) < 0)
1104 wpa_printf(MSG_INFO
, "Failed to send deauth: %s",
1109 static void send_assoc_resp(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1110 u16 status_code
, int reassoc
, const u8
*ies
,
1114 u8 buf
[sizeof(struct ieee80211_mgmt
) + 1024];
1115 struct ieee80211_mgmt
*reply
;
1118 os_memset(buf
, 0, sizeof(buf
));
1119 reply
= (struct ieee80211_mgmt
*) buf
;
1120 reply
->frame_control
=
1121 IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
1122 (reassoc
? WLAN_FC_STYPE_REASSOC_RESP
:
1123 WLAN_FC_STYPE_ASSOC_RESP
));
1124 os_memcpy(reply
->da
, sta
->addr
, ETH_ALEN
);
1125 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
1126 os_memcpy(reply
->bssid
, hapd
->own_addr
, ETH_ALEN
);
1128 send_len
= IEEE80211_HDRLEN
;
1129 send_len
+= sizeof(reply
->u
.assoc_resp
);
1130 reply
->u
.assoc_resp
.capab_info
=
1131 host_to_le16(hostapd_own_capab_info(hapd
, sta
, 0));
1132 reply
->u
.assoc_resp
.status_code
= host_to_le16(status_code
);
1133 reply
->u
.assoc_resp
.aid
= host_to_le16((sta
? sta
->aid
: 0)
1134 | BIT(14) | BIT(15));
1135 /* Supported rates */
1136 p
= hostapd_eid_supp_rates(hapd
, reply
->u
.assoc_resp
.variable
);
1137 /* Extended supported rates */
1138 p
= hostapd_eid_ext_supp_rates(hapd
, p
);
1140 #ifdef CONFIG_IEEE80211R
1141 if (status_code
== WLAN_STATUS_SUCCESS
) {
1142 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
1143 * Transition Information, RSN, [RIC Response] */
1144 p
= wpa_sm_write_assoc_resp_ies(sta
->wpa_sm
, p
,
1145 buf
+ sizeof(buf
) - p
,
1146 sta
->auth_alg
, ies
, ies_len
);
1148 #endif /* CONFIG_IEEE80211R */
1150 #ifdef CONFIG_IEEE80211W
1151 if (status_code
== WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
)
1152 p
= hostapd_eid_assoc_comeback_time(hapd
, sta
, p
);
1153 #endif /* CONFIG_IEEE80211W */
1155 #ifdef CONFIG_IEEE80211N
1156 p
= hostapd_eid_ht_capabilities(hapd
, p
);
1157 p
= hostapd_eid_ht_operation(hapd
, p
);
1158 #endif /* CONFIG_IEEE80211N */
1160 #ifdef CONFIG_IEEE80211AC
1161 p
= hostapd_eid_vht_capabilities(hapd
, p
);
1162 p
= hostapd_eid_vht_operation(hapd
, p
);
1163 #endif /* CONFIG_IEEE80211AC */
1165 p
= hostapd_eid_ext_capab(hapd
, p
);
1166 p
= hostapd_eid_bss_max_idle_period(hapd
, p
);
1168 if (sta
->flags
& WLAN_STA_WMM
)
1169 p
= hostapd_eid_wmm(hapd
, p
);
1172 if ((sta
->flags
& WLAN_STA_WPS
) ||
1173 ((sta
->flags
& WLAN_STA_MAYBE_WPS
) && hapd
->conf
->wpa
)) {
1174 struct wpabuf
*wps
= wps_build_assoc_resp_ie();
1176 os_memcpy(p
, wpabuf_head(wps
), wpabuf_len(wps
));
1177 p
+= wpabuf_len(wps
);
1181 #endif /* CONFIG_WPS */
1185 struct wpabuf
*p2p_resp_ie
;
1186 enum p2p_status_code status
;
1187 switch (status_code
) {
1188 case WLAN_STATUS_SUCCESS
:
1189 status
= P2P_SC_SUCCESS
;
1191 case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
:
1192 status
= P2P_SC_FAIL_LIMIT_REACHED
;
1195 status
= P2P_SC_FAIL_INVALID_PARAMS
;
1198 p2p_resp_ie
= p2p_group_assoc_resp_ie(hapd
->p2p_group
, status
);
1200 os_memcpy(p
, wpabuf_head(p2p_resp_ie
),
1201 wpabuf_len(p2p_resp_ie
));
1202 p
+= wpabuf_len(p2p_resp_ie
);
1203 wpabuf_free(p2p_resp_ie
);
1206 #endif /* CONFIG_P2P */
1208 #ifdef CONFIG_P2P_MANAGER
1209 if (hapd
->conf
->p2p
& P2P_MANAGE
)
1210 p
= hostapd_eid_p2p_manage(hapd
, p
);
1211 #endif /* CONFIG_P2P_MANAGER */
1213 send_len
+= p
- reply
->u
.assoc_resp
.variable
;
1215 if (hostapd_drv_send_mlme(hapd
, reply
, send_len
, 0) < 0)
1216 wpa_printf(MSG_INFO
, "Failed to send assoc resp: %s",
1221 static void handle_assoc(struct hostapd_data
*hapd
,
1222 const struct ieee80211_mgmt
*mgmt
, size_t len
,
1225 u16 capab_info
, listen_interval
;
1226 u16 resp
= WLAN_STATUS_SUCCESS
;
1229 struct sta_info
*sta
;
1231 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_req
) :
1232 sizeof(mgmt
->u
.assoc_req
))) {
1233 printf("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
1234 "\n", reassoc
, (unsigned long) len
);
1238 #ifdef CONFIG_TESTING_OPTIONS
1240 if (hapd
->iconf
->ignore_reassoc_probability
> 0.0d
&&
1241 drand48() < hapd
->iconf
->ignore_reassoc_probability
) {
1242 wpa_printf(MSG_INFO
,
1243 "TESTING: ignoring reassoc request from "
1244 MACSTR
, MAC2STR(mgmt
->sa
));
1248 if (hapd
->iconf
->ignore_assoc_probability
> 0.0d
&&
1249 drand48() < hapd
->iconf
->ignore_assoc_probability
) {
1250 wpa_printf(MSG_INFO
,
1251 "TESTING: ignoring assoc request from "
1252 MACSTR
, MAC2STR(mgmt
->sa
));
1256 #endif /* CONFIG_TESTING_OPTIONS */
1259 capab_info
= le_to_host16(mgmt
->u
.reassoc_req
.capab_info
);
1260 listen_interval
= le_to_host16(
1261 mgmt
->u
.reassoc_req
.listen_interval
);
1262 wpa_printf(MSG_DEBUG
, "reassociation request: STA=" MACSTR
1263 " capab_info=0x%02x listen_interval=%d current_ap="
1265 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
1266 MAC2STR(mgmt
->u
.reassoc_req
.current_ap
));
1267 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.reassoc_req
));
1268 pos
= mgmt
->u
.reassoc_req
.variable
;
1270 capab_info
= le_to_host16(mgmt
->u
.assoc_req
.capab_info
);
1271 listen_interval
= le_to_host16(
1272 mgmt
->u
.assoc_req
.listen_interval
);
1273 wpa_printf(MSG_DEBUG
, "association request: STA=" MACSTR
1274 " capab_info=0x%02x listen_interval=%d",
1275 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
);
1276 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.assoc_req
));
1277 pos
= mgmt
->u
.assoc_req
.variable
;
1280 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1281 #ifdef CONFIG_IEEE80211R
1282 if (sta
&& sta
->auth_alg
== WLAN_AUTH_FT
&&
1283 (sta
->flags
& WLAN_STA_AUTH
) == 0) {
1284 wpa_printf(MSG_DEBUG
, "FT: Allow STA " MACSTR
" to associate "
1285 "prior to authentication since it is using "
1286 "over-the-DS FT", MAC2STR(mgmt
->sa
));
1288 #endif /* CONFIG_IEEE80211R */
1289 if (sta
== NULL
|| (sta
->flags
& WLAN_STA_AUTH
) == 0) {
1290 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1291 HOSTAPD_LEVEL_INFO
, "Station tried to "
1292 "associate before authentication "
1293 "(aid=%d flags=0x%x)",
1294 sta
? sta
->aid
: -1,
1295 sta
? sta
->flags
: 0);
1296 send_deauth(hapd
, mgmt
->sa
,
1297 WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA
);
1301 if (hapd
->tkip_countermeasures
) {
1302 resp
= WLAN_REASON_MICHAEL_MIC_FAILURE
;
1306 if (listen_interval
> hapd
->conf
->max_listen_interval
) {
1307 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1308 HOSTAPD_LEVEL_DEBUG
,
1309 "Too large Listen Interval (%d)",
1311 resp
= WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE
;
1315 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
1317 resp
= check_assoc_ies(hapd
, sta
, pos
, left
, reassoc
);
1318 if (resp
!= WLAN_STATUS_SUCCESS
)
1321 if (hostapd_get_aid(hapd
, sta
) < 0) {
1322 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1323 HOSTAPD_LEVEL_INFO
, "No room for more AIDs");
1324 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
1328 sta
->capability
= capab_info
;
1329 sta
->listen_interval
= listen_interval
;
1331 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
1332 sta
->flags
|= WLAN_STA_NONERP
;
1333 for (i
= 0; i
< sta
->supported_rates_len
; i
++) {
1334 if ((sta
->supported_rates
[i
] & 0x7f) > 22) {
1335 sta
->flags
&= ~WLAN_STA_NONERP
;
1339 if (sta
->flags
& WLAN_STA_NONERP
&& !sta
->nonerp_set
) {
1340 sta
->nonerp_set
= 1;
1341 hapd
->iface
->num_sta_non_erp
++;
1342 if (hapd
->iface
->num_sta_non_erp
== 1)
1343 ieee802_11_set_beacons(hapd
->iface
);
1346 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
) &&
1347 !sta
->no_short_slot_time_set
) {
1348 sta
->no_short_slot_time_set
= 1;
1349 hapd
->iface
->num_sta_no_short_slot_time
++;
1350 if (hapd
->iface
->current_mode
->mode
==
1351 HOSTAPD_MODE_IEEE80211G
&&
1352 hapd
->iface
->num_sta_no_short_slot_time
== 1)
1353 ieee802_11_set_beacons(hapd
->iface
);
1356 if (sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
1357 sta
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
1359 sta
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
1361 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
) &&
1362 !sta
->no_short_preamble_set
) {
1363 sta
->no_short_preamble_set
= 1;
1364 hapd
->iface
->num_sta_no_short_preamble
++;
1365 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
1366 && hapd
->iface
->num_sta_no_short_preamble
== 1)
1367 ieee802_11_set_beacons(hapd
->iface
);
1370 #ifdef CONFIG_IEEE80211N
1371 update_ht_state(hapd
, sta
);
1372 #endif /* CONFIG_IEEE80211N */
1374 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1375 HOSTAPD_LEVEL_DEBUG
,
1376 "association OK (aid %d)", sta
->aid
);
1377 /* Station will be marked associated, after it acknowledges AssocResp
1379 sta
->flags
|= WLAN_STA_ASSOC_REQ_OK
;
1381 #ifdef CONFIG_IEEE80211W
1382 if ((sta
->flags
& WLAN_STA_MFP
) && sta
->sa_query_timed_out
) {
1383 wpa_printf(MSG_DEBUG
, "Allowing %sassociation after timed out "
1384 "SA Query procedure", reassoc
? "re" : "");
1385 /* TODO: Send a protected Disassociate frame to the STA using
1386 * the old key and Reason Code "Previous Authentication no
1387 * longer valid". Make sure this is only sent protected since
1388 * unprotected frame would be received by the STA that is now
1389 * trying to associate.
1392 #endif /* CONFIG_IEEE80211W */
1395 os_memcpy(sta
->previous_ap
, mgmt
->u
.reassoc_req
.current_ap
,
1399 if (sta
->last_assoc_req
)
1400 os_free(sta
->last_assoc_req
);
1401 sta
->last_assoc_req
= os_malloc(len
);
1402 if (sta
->last_assoc_req
)
1403 os_memcpy(sta
->last_assoc_req
, mgmt
, len
);
1405 /* Make sure that the previously registered inactivity timer will not
1406 * remove the STA immediately. */
1407 sta
->timeout_next
= STA_NULLFUNC
;
1410 send_assoc_resp(hapd
, sta
, resp
, reassoc
, pos
, left
);
1414 static void handle_disassoc(struct hostapd_data
*hapd
,
1415 const struct ieee80211_mgmt
*mgmt
, size_t len
)
1417 struct sta_info
*sta
;
1419 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.disassoc
)) {
1420 printf("handle_disassoc - too short payload (len=%lu)\n",
1421 (unsigned long) len
);
1425 wpa_printf(MSG_DEBUG
, "disassocation: STA=" MACSTR
" reason_code=%d",
1427 le_to_host16(mgmt
->u
.disassoc
.reason_code
));
1429 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1431 printf("Station " MACSTR
" trying to disassociate, but it "
1432 "is not associated.\n", MAC2STR(mgmt
->sa
));
1436 ap_sta_set_authorized(hapd
, sta
, 0);
1437 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
);
1438 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
1439 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1440 HOSTAPD_LEVEL_INFO
, "disassociated");
1441 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
1442 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
1443 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
1445 accounting_sta_stop(hapd
, sta
);
1446 ieee802_1x_free_station(sta
);
1447 hostapd_drv_sta_remove(hapd
, sta
->addr
);
1449 if (sta
->timeout_next
== STA_NULLFUNC
||
1450 sta
->timeout_next
== STA_DISASSOC
) {
1451 sta
->timeout_next
= STA_DEAUTH
;
1452 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
1453 eloop_register_timeout(AP_DEAUTH_DELAY
, 0, ap_handle_timer
,
1457 mlme_disassociate_indication(
1458 hapd
, sta
, le_to_host16(mgmt
->u
.disassoc
.reason_code
));
1462 static void handle_deauth(struct hostapd_data
*hapd
,
1463 const struct ieee80211_mgmt
*mgmt
, size_t len
)
1465 struct sta_info
*sta
;
1467 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.deauth
)) {
1468 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "handle_deauth - too short "
1469 "payload (len=%lu)", (unsigned long) len
);
1473 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "deauthentication: STA=" MACSTR
1475 MAC2STR(mgmt
->sa
), le_to_host16(mgmt
->u
.deauth
.reason_code
));
1477 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1479 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "Station " MACSTR
" trying "
1480 "to deauthenticate, but it is not authenticated",
1485 ap_sta_set_authorized(hapd
, sta
, 0);
1486 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
|
1487 WLAN_STA_ASSOC_REQ_OK
);
1488 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
1489 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1490 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
1491 mlme_deauthenticate_indication(
1492 hapd
, sta
, le_to_host16(mgmt
->u
.deauth
.reason_code
));
1493 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
1494 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
1495 ap_free_sta(hapd
, sta
);
1499 static void handle_beacon(struct hostapd_data
*hapd
,
1500 const struct ieee80211_mgmt
*mgmt
, size_t len
,
1501 struct hostapd_frame_info
*fi
)
1503 struct ieee802_11_elems elems
;
1505 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.beacon
)) {
1506 printf("handle_beacon - too short payload (len=%lu)\n",
1507 (unsigned long) len
);
1511 (void) ieee802_11_parse_elems(mgmt
->u
.beacon
.variable
,
1512 len
- (IEEE80211_HDRLEN
+
1513 sizeof(mgmt
->u
.beacon
)), &elems
,
1516 ap_list_process_beacon(hapd
->iface
, mgmt
, &elems
, fi
);
1520 #ifdef CONFIG_IEEE80211W
1522 static void hostapd_sa_query_action(struct hostapd_data
*hapd
,
1523 const struct ieee80211_mgmt
*mgmt
,
1528 end
= mgmt
->u
.action
.u
.sa_query_resp
.trans_id
+
1529 WLAN_SA_QUERY_TR_ID_LEN
;
1530 if (((u8
*) mgmt
) + len
< end
) {
1531 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Too short SA Query Action "
1532 "frame (len=%lu)", (unsigned long) len
);
1536 ieee802_11_sa_query_action(hapd
, mgmt
->sa
,
1537 mgmt
->u
.action
.u
.sa_query_resp
.action
,
1538 mgmt
->u
.action
.u
.sa_query_resp
.trans_id
);
1542 static int robust_action_frame(u8 category
)
1544 return category
!= WLAN_ACTION_PUBLIC
&&
1545 category
!= WLAN_ACTION_HT
;
1547 #endif /* CONFIG_IEEE80211W */
1551 static void hostapd_wnm_action(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1552 const struct ieee80211_mgmt
*mgmt
,
1555 struct rx_action action
;
1556 if (len
< IEEE80211_HDRLEN
+ 2)
1558 os_memset(&action
, 0, sizeof(action
));
1559 action
.da
= mgmt
->da
;
1560 action
.sa
= mgmt
->sa
;
1561 action
.bssid
= mgmt
->bssid
;
1562 action
.category
= mgmt
->u
.action
.category
;
1563 action
.data
= (const u8
*) &mgmt
->u
.action
.u
.wnm_sleep_req
.action
;
1564 action
.len
= len
- IEEE80211_HDRLEN
- 1;
1565 action
.freq
= hapd
->iface
->freq
;
1566 ieee802_11_rx_wnm_action_ap(hapd
, &action
);
1568 #endif /* CONFIG_WNM */
1571 static void handle_action(struct hostapd_data
*hapd
,
1572 const struct ieee80211_mgmt
*mgmt
, size_t len
)
1574 struct sta_info
*sta
;
1575 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1577 if (len
< IEEE80211_HDRLEN
+ 1) {
1578 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1579 HOSTAPD_LEVEL_DEBUG
,
1580 "handle_action - too short payload (len=%lu)",
1581 (unsigned long) len
);
1585 if (mgmt
->u
.action
.category
!= WLAN_ACTION_PUBLIC
&&
1586 (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))) {
1587 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Ignored Action "
1588 "frame (category=%u) from unassociated STA " MACSTR
,
1589 MAC2STR(mgmt
->sa
), mgmt
->u
.action
.category
);
1593 #ifdef CONFIG_IEEE80211W
1594 if (sta
&& (sta
->flags
& WLAN_STA_MFP
) &&
1595 !(mgmt
->frame_control
& host_to_le16(WLAN_FC_ISWEP
) &&
1596 robust_action_frame(mgmt
->u
.action
.category
))) {
1597 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1598 HOSTAPD_LEVEL_DEBUG
,
1599 "Dropped unprotected Robust Action frame from "
1603 #endif /* CONFIG_IEEE80211W */
1605 switch (mgmt
->u
.action
.category
) {
1606 #ifdef CONFIG_IEEE80211R
1607 case WLAN_ACTION_FT
:
1608 if (wpa_ft_action_rx(sta
->wpa_sm
, (u8
*) &mgmt
->u
.action
,
1609 len
- IEEE80211_HDRLEN
))
1612 #endif /* CONFIG_IEEE80211R */
1613 case WLAN_ACTION_WMM
:
1614 hostapd_wmm_action(hapd
, mgmt
, len
);
1616 #ifdef CONFIG_IEEE80211W
1617 case WLAN_ACTION_SA_QUERY
:
1618 hostapd_sa_query_action(hapd
, mgmt
, len
);
1620 #endif /* CONFIG_IEEE80211W */
1622 case WLAN_ACTION_WNM
:
1623 hostapd_wnm_action(hapd
, sta
, mgmt
, len
);
1625 #endif /* CONFIG_WNM */
1626 case WLAN_ACTION_PUBLIC
:
1627 if (hapd
->public_action_cb
) {
1628 hapd
->public_action_cb(hapd
->public_action_cb_ctx
,
1632 if (hapd
->public_action_cb2
) {
1633 hapd
->public_action_cb2(hapd
->public_action_cb2_ctx
,
1637 if (hapd
->public_action_cb
|| hapd
->public_action_cb2
)
1640 case WLAN_ACTION_VENDOR_SPECIFIC
:
1641 if (hapd
->vendor_action_cb
) {
1642 if (hapd
->vendor_action_cb(hapd
->vendor_action_cb_ctx
,
1644 hapd
->iface
->freq
) == 0)
1650 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1651 HOSTAPD_LEVEL_DEBUG
,
1652 "handle_action - unknown action category %d or invalid "
1654 mgmt
->u
.action
.category
);
1655 if (!(mgmt
->da
[0] & 0x01) && !(mgmt
->u
.action
.category
& 0x80) &&
1656 !(mgmt
->sa
[0] & 0x01)) {
1657 struct ieee80211_mgmt
*resp
;
1660 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
1661 * Return the Action frame to the source without change
1662 * except that MSB of the Category set to 1.
1664 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Return unknown Action "
1665 "frame back to sender");
1666 resp
= os_malloc(len
);
1669 os_memcpy(resp
, mgmt
, len
);
1670 os_memcpy(resp
->da
, resp
->sa
, ETH_ALEN
);
1671 os_memcpy(resp
->sa
, hapd
->own_addr
, ETH_ALEN
);
1672 os_memcpy(resp
->bssid
, hapd
->own_addr
, ETH_ALEN
);
1673 resp
->u
.action
.category
|= 0x80;
1675 if (hostapd_drv_send_mlme(hapd
, resp
, len
, 0) < 0) {
1676 wpa_printf(MSG_ERROR
, "IEEE 802.11: Failed to send "
1685 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
1686 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
1688 * @buf: management frame data (starting from IEEE 802.11 header)
1689 * @len: length of frame data in octets
1690 * @fi: meta data about received frame (signal level, etc.)
1692 * Process all incoming IEEE 802.11 management frames. This will be called for
1693 * each frame received from the kernel driver through wlan#ap interface. In
1694 * addition, it can be called to re-inserted pending frames (e.g., when using
1695 * external RADIUS server as an MAC ACL).
1697 void ieee802_11_mgmt(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
1698 struct hostapd_frame_info
*fi
)
1700 struct ieee80211_mgmt
*mgmt
;
1707 mgmt
= (struct ieee80211_mgmt
*) buf
;
1708 fc
= le_to_host16(mgmt
->frame_control
);
1709 stype
= WLAN_FC_GET_STYPE(fc
);
1711 if (stype
== WLAN_FC_STYPE_BEACON
) {
1712 handle_beacon(hapd
, mgmt
, len
, fi
);
1716 broadcast
= mgmt
->bssid
[0] == 0xff && mgmt
->bssid
[1] == 0xff &&
1717 mgmt
->bssid
[2] == 0xff && mgmt
->bssid
[3] == 0xff &&
1718 mgmt
->bssid
[4] == 0xff && mgmt
->bssid
[5] == 0xff;
1722 /* Invitation responses can be sent with the peer MAC as BSSID */
1723 !((hapd
->conf
->p2p
& P2P_GROUP_OWNER
) &&
1724 stype
== WLAN_FC_STYPE_ACTION
) &&
1725 #endif /* CONFIG_P2P */
1726 os_memcmp(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
) != 0) {
1727 printf("MGMT: BSSID=" MACSTR
" not our address\n",
1728 MAC2STR(mgmt
->bssid
));
1733 if (stype
== WLAN_FC_STYPE_PROBE_REQ
) {
1734 handle_probe_req(hapd
, mgmt
, len
, fi
->ssi_signal
);
1738 if (os_memcmp(mgmt
->da
, hapd
->own_addr
, ETH_ALEN
) != 0) {
1739 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1740 HOSTAPD_LEVEL_DEBUG
,
1741 "MGMT: DA=" MACSTR
" not our address",
1747 case WLAN_FC_STYPE_AUTH
:
1748 wpa_printf(MSG_DEBUG
, "mgmt::auth");
1749 handle_auth(hapd
, mgmt
, len
);
1751 case WLAN_FC_STYPE_ASSOC_REQ
:
1752 wpa_printf(MSG_DEBUG
, "mgmt::assoc_req");
1753 handle_assoc(hapd
, mgmt
, len
, 0);
1755 case WLAN_FC_STYPE_REASSOC_REQ
:
1756 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_req");
1757 handle_assoc(hapd
, mgmt
, len
, 1);
1759 case WLAN_FC_STYPE_DISASSOC
:
1760 wpa_printf(MSG_DEBUG
, "mgmt::disassoc");
1761 handle_disassoc(hapd
, mgmt
, len
);
1763 case WLAN_FC_STYPE_DEAUTH
:
1764 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "mgmt::deauth");
1765 handle_deauth(hapd
, mgmt
, len
);
1767 case WLAN_FC_STYPE_ACTION
:
1768 wpa_printf(MSG_DEBUG
, "mgmt::action");
1769 handle_action(hapd
, mgmt
, len
);
1772 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1773 HOSTAPD_LEVEL_DEBUG
,
1774 "unknown mgmt frame subtype %d", stype
);
1780 static void handle_auth_cb(struct hostapd_data
*hapd
,
1781 const struct ieee80211_mgmt
*mgmt
,
1784 u16 auth_alg
, auth_transaction
, status_code
;
1785 struct sta_info
*sta
;
1788 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
1789 HOSTAPD_LEVEL_NOTICE
,
1790 "did not acknowledge authentication response");
1794 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
1795 printf("handle_auth_cb - too short payload (len=%lu)\n",
1796 (unsigned long) len
);
1800 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
1801 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
1802 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
1804 sta
= ap_get_sta(hapd
, mgmt
->da
);
1806 printf("handle_auth_cb: STA " MACSTR
" not found\n",
1811 if (status_code
== WLAN_STATUS_SUCCESS
&&
1812 ((auth_alg
== WLAN_AUTH_OPEN
&& auth_transaction
== 2) ||
1813 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 4))) {
1814 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1815 HOSTAPD_LEVEL_INFO
, "authenticated");
1816 sta
->flags
|= WLAN_STA_AUTH
;
1821 static void handle_assoc_cb(struct hostapd_data
*hapd
,
1822 const struct ieee80211_mgmt
*mgmt
,
1823 size_t len
, int reassoc
, int ok
)
1826 struct sta_info
*sta
;
1828 struct ieee80211_ht_capabilities ht_cap
;
1829 struct ieee80211_vht_capabilities vht_cap
;
1831 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_resp
) :
1832 sizeof(mgmt
->u
.assoc_resp
))) {
1833 printf("handle_assoc_cb(reassoc=%d) - too short payload "
1834 "(len=%lu)\n", reassoc
, (unsigned long) len
);
1838 sta
= ap_get_sta(hapd
, mgmt
->da
);
1840 printf("handle_assoc_cb: STA " MACSTR
" not found\n",
1846 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
1847 HOSTAPD_LEVEL_DEBUG
,
1848 "did not acknowledge association response");
1849 sta
->flags
&= ~WLAN_STA_ASSOC_REQ_OK
;
1854 status
= le_to_host16(mgmt
->u
.reassoc_resp
.status_code
);
1856 status
= le_to_host16(mgmt
->u
.assoc_resp
.status_code
);
1858 if (status
!= WLAN_STATUS_SUCCESS
)
1861 /* Stop previous accounting session, if one is started, and allocate
1862 * new session id for the new session. */
1863 accounting_sta_stop(hapd
, sta
);
1865 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1867 "associated (aid %d)",
1870 if (sta
->flags
& WLAN_STA_ASSOC
)
1872 sta
->flags
|= WLAN_STA_ASSOC
;
1873 if ((!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
) ||
1874 sta
->auth_alg
== WLAN_AUTH_FT
) {
1876 * Open, static WEP, or FT protocol; no separate authorization
1879 ap_sta_set_authorized(hapd
, sta
, 1);
1883 mlme_reassociate_indication(hapd
, sta
);
1885 mlme_associate_indication(hapd
, sta
);
1887 #ifdef CONFIG_IEEE80211W
1888 sta
->sa_query_timed_out
= 0;
1889 #endif /* CONFIG_IEEE80211W */
1892 * Remove the STA entry in order to make sure the STA PS state gets
1893 * cleared and configuration gets updated in case of reassociation back
1896 hostapd_drv_sta_remove(hapd
, sta
->addr
);
1898 #ifdef CONFIG_IEEE80211N
1899 if (sta
->flags
& WLAN_STA_HT
)
1900 hostapd_get_ht_capab(hapd
, sta
->ht_capabilities
, &ht_cap
);
1901 #endif /* CONFIG_IEEE80211N */
1902 #ifdef CONFIG_IEEE80211AC
1903 if (sta
->flags
& WLAN_STA_VHT
)
1904 hostapd_get_vht_capab(hapd
, sta
->vht_capabilities
, &vht_cap
);
1905 #endif /* CONFIG_IEEE80211AC */
1907 if (hostapd_sta_add(hapd
, sta
->addr
, sta
->aid
, sta
->capability
,
1908 sta
->supported_rates
, sta
->supported_rates_len
,
1909 sta
->listen_interval
,
1910 sta
->flags
& WLAN_STA_HT
? &ht_cap
: NULL
,
1911 sta
->flags
& WLAN_STA_VHT
? &vht_cap
: NULL
,
1912 sta
->flags
, sta
->qosinfo
)) {
1913 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1914 HOSTAPD_LEVEL_NOTICE
,
1915 "Could not add STA to kernel driver");
1917 ap_sta_disconnect(hapd
, sta
, sta
->addr
,
1918 WLAN_REASON_DISASSOC_AP_BUSY
);
1923 if (sta
->flags
& WLAN_STA_WDS
)
1924 hostapd_set_wds_sta(hapd
, sta
->addr
, sta
->aid
, 1);
1926 if (sta
->eapol_sm
== NULL
) {
1928 * This STA does not use RADIUS server for EAP authentication,
1929 * so bind it to the selected VLAN interface now, since the
1930 * interface selection is not going to change anymore.
1932 if (ap_sta_bind_vlan(hapd
, sta
, 0) < 0)
1934 } else if (sta
->vlan_id
) {
1935 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
1936 if (ap_sta_bind_vlan(hapd
, sta
, 0) < 0)
1940 hostapd_set_sta_flags(hapd
, sta
);
1942 if (sta
->auth_alg
== WLAN_AUTH_FT
)
1943 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC_FT
);
1945 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
1946 hapd
->new_assoc_sta_cb(hapd
, sta
, !new_assoc
);
1948 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
1951 /* Copy of the association request is not needed anymore */
1952 if (sta
->last_assoc_req
) {
1953 os_free(sta
->last_assoc_req
);
1954 sta
->last_assoc_req
= NULL
;
1959 static void handle_deauth_cb(struct hostapd_data
*hapd
,
1960 const struct ieee80211_mgmt
*mgmt
,
1963 struct sta_info
*sta
;
1964 if (mgmt
->da
[0] & 0x01)
1966 sta
= ap_get_sta(hapd
, mgmt
->da
);
1968 wpa_printf(MSG_DEBUG
, "handle_deauth_cb: STA " MACSTR
1969 " not found", MAC2STR(mgmt
->da
));
1973 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged deauth",
1974 MAC2STR(sta
->addr
));
1976 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
1977 "deauth", MAC2STR(sta
->addr
));
1979 ap_sta_deauth_cb(hapd
, sta
);
1983 static void handle_disassoc_cb(struct hostapd_data
*hapd
,
1984 const struct ieee80211_mgmt
*mgmt
,
1987 struct sta_info
*sta
;
1988 if (mgmt
->da
[0] & 0x01)
1990 sta
= ap_get_sta(hapd
, mgmt
->da
);
1992 wpa_printf(MSG_DEBUG
, "handle_disassoc_cb: STA " MACSTR
1993 " not found", MAC2STR(mgmt
->da
));
1997 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged disassoc",
1998 MAC2STR(sta
->addr
));
2000 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
2001 "disassoc", MAC2STR(sta
->addr
));
2003 ap_sta_disassoc_cb(hapd
, sta
);
2008 * ieee802_11_mgmt_cb - Process management frame TX status callback
2009 * @hapd: hostapd BSS data structure (the BSS from which the management frame
2011 * @buf: management frame data (starting from IEEE 802.11 header)
2012 * @len: length of frame data in octets
2013 * @stype: management frame subtype from frame control field
2014 * @ok: Whether the frame was ACK'ed
2016 void ieee802_11_mgmt_cb(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
2019 const struct ieee80211_mgmt
*mgmt
;
2020 mgmt
= (const struct ieee80211_mgmt
*) buf
;
2023 case WLAN_FC_STYPE_AUTH
:
2024 wpa_printf(MSG_DEBUG
, "mgmt::auth cb");
2025 handle_auth_cb(hapd
, mgmt
, len
, ok
);
2027 case WLAN_FC_STYPE_ASSOC_RESP
:
2028 wpa_printf(MSG_DEBUG
, "mgmt::assoc_resp cb");
2029 handle_assoc_cb(hapd
, mgmt
, len
, 0, ok
);
2031 case WLAN_FC_STYPE_REASSOC_RESP
:
2032 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_resp cb");
2033 handle_assoc_cb(hapd
, mgmt
, len
, 1, ok
);
2035 case WLAN_FC_STYPE_PROBE_RESP
:
2036 wpa_printf(MSG_EXCESSIVE
, "mgmt::proberesp cb");
2038 case WLAN_FC_STYPE_DEAUTH
:
2039 wpa_printf(MSG_DEBUG
, "mgmt::deauth cb");
2040 handle_deauth_cb(hapd
, mgmt
, len
, ok
);
2042 case WLAN_FC_STYPE_DISASSOC
:
2043 wpa_printf(MSG_DEBUG
, "mgmt::disassoc cb");
2044 handle_disassoc_cb(hapd
, mgmt
, len
, ok
);
2046 case WLAN_FC_STYPE_ACTION
:
2047 wpa_printf(MSG_DEBUG
, "mgmt::action cb");
2050 printf("unknown mgmt cb frame subtype %d\n", stype
);
2056 int ieee802_11_get_mib(struct hostapd_data
*hapd
, char *buf
, size_t buflen
)
2063 int ieee802_11_get_mib_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2064 char *buf
, size_t buflen
)
2071 void hostapd_tx_status(struct hostapd_data
*hapd
, const u8
*addr
,
2072 const u8
*buf
, size_t len
, int ack
)
2074 struct sta_info
*sta
;
2075 struct hostapd_iface
*iface
= hapd
->iface
;
2077 sta
= ap_get_sta(hapd
, addr
);
2078 if (sta
== NULL
&& iface
->num_bss
> 1) {
2080 for (j
= 0; j
< iface
->num_bss
; j
++) {
2081 hapd
= iface
->bss
[j
];
2082 sta
= ap_get_sta(hapd
, addr
);
2087 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))
2089 if (sta
->flags
& WLAN_STA_PENDING_POLL
) {
2090 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" %s pending "
2091 "activity poll", MAC2STR(sta
->addr
),
2092 ack
? "ACKed" : "did not ACK");
2094 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
2097 ieee802_1x_tx_status(hapd
, sta
, buf
, len
, ack
);
2101 void hostapd_eapol_tx_status(struct hostapd_data
*hapd
, const u8
*dst
,
2102 const u8
*data
, size_t len
, int ack
)
2104 struct sta_info
*sta
;
2105 struct hostapd_iface
*iface
= hapd
->iface
;
2107 sta
= ap_get_sta(hapd
, dst
);
2108 if (sta
== NULL
&& iface
->num_bss
> 1) {
2110 for (j
= 0; j
< iface
->num_bss
; j
++) {
2111 hapd
= iface
->bss
[j
];
2112 sta
= ap_get_sta(hapd
, dst
);
2117 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
2118 wpa_printf(MSG_DEBUG
, "Ignore TX status for Data frame to STA "
2119 MACSTR
" that is not currently associated",
2124 ieee802_1x_eapol_tx_status(hapd
, sta
, data
, len
, ack
);
2128 void hostapd_client_poll_ok(struct hostapd_data
*hapd
, const u8
*addr
)
2130 struct sta_info
*sta
;
2131 struct hostapd_iface
*iface
= hapd
->iface
;
2133 sta
= ap_get_sta(hapd
, addr
);
2134 if (sta
== NULL
&& iface
->num_bss
> 1) {
2136 for (j
= 0; j
< iface
->num_bss
; j
++) {
2137 hapd
= iface
->bss
[j
];
2138 sta
= ap_get_sta(hapd
, addr
);
2145 if (!(sta
->flags
& WLAN_STA_PENDING_POLL
))
2148 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" ACKed pending "
2149 "activity poll", MAC2STR(sta
->addr
));
2150 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
2154 void ieee802_11_rx_from_unknown(struct hostapd_data
*hapd
, const u8
*src
,
2157 struct sta_info
*sta
;
2159 sta
= ap_get_sta(hapd
, src
);
2160 if (sta
&& (sta
->flags
& WLAN_STA_ASSOC
)) {
2161 if (!hapd
->conf
->wds_sta
)
2164 if (wds
&& !(sta
->flags
& WLAN_STA_WDS
)) {
2165 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for "
2166 "STA " MACSTR
" (aid %u)",
2167 MAC2STR(sta
->addr
), sta
->aid
);
2168 sta
->flags
|= WLAN_STA_WDS
;
2169 hostapd_set_wds_sta(hapd
, sta
->addr
, sta
->aid
, 1);
2174 wpa_printf(MSG_DEBUG
, "Data/PS-poll frame from not associated STA "
2175 MACSTR
, MAC2STR(src
));
2176 if (src
[0] & 0x01) {
2177 /* Broadcast bit set in SA?! Ignore the frame silently. */
2181 if (sta
&& (sta
->flags
& WLAN_STA_ASSOC_REQ_OK
)) {
2182 wpa_printf(MSG_DEBUG
, "Association Response to the STA has "
2183 "already been sent, but no TX status yet known - "
2184 "ignore Class 3 frame issue with " MACSTR
,
2189 if (sta
&& (sta
->flags
& WLAN_STA_AUTH
))
2190 hostapd_drv_sta_disassoc(
2192 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
2194 hostapd_drv_sta_deauth(
2196 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
2200 #endif /* CONFIG_NATIVE_WINDOWS */