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 "drivers/driver.h"
17 #include "common/ieee802_11_defs.h"
18 #include "common/ieee802_11_common.h"
19 #include "common/wpa_ctrl.h"
20 #include "radius/radius.h"
21 #include "radius/radius_client.h"
26 #include "ieee802_11_auth.h"
28 #include "ieee802_1x.h"
32 #include "accounting.h"
33 #include "ap_config.h"
35 #include "p2p_hostapd.h"
36 #include "ap_drv_ops.h"
37 #include "ieee802_11.h"
40 u8
* hostapd_eid_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
45 if (hapd
->iface
->current_rates
== NULL
)
48 *pos
++ = WLAN_EID_SUPP_RATES
;
49 num
= hapd
->iface
->num_rates
;
50 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
)
53 /* rest of the rates are encoded in Extended supported
60 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
;
63 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
64 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
69 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&&
70 hapd
->iface
->num_rates
< 8)
71 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY
;
77 u8
* hostapd_eid_ext_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
82 if (hapd
->iface
->current_rates
== NULL
)
85 num
= hapd
->iface
->num_rates
;
86 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
)
92 *pos
++ = WLAN_EID_EXT_SUPP_RATES
;
95 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
+ 8;
99 continue; /* already in SuppRates IE */
100 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
101 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
106 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&&
107 hapd
->iface
->num_rates
>= 8)
108 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY
;
114 u16
hostapd_own_capab_info(struct hostapd_data
*hapd
, struct sta_info
*sta
,
117 int capab
= WLAN_CAPABILITY_ESS
;
120 if (hapd
->iface
->num_sta_no_short_preamble
== 0 &&
121 hapd
->iconf
->preamble
== SHORT_PREAMBLE
)
122 capab
|= WLAN_CAPABILITY_SHORT_PREAMBLE
;
124 privacy
= hapd
->conf
->ssid
.wep
.keys_set
;
126 if (hapd
->conf
->ieee802_1x
&&
127 (hapd
->conf
->default_wep_key_len
||
128 hapd
->conf
->individual_wep_key_len
))
135 int policy
, def_klen
;
136 if (probe
&& sta
->ssid_probe
) {
137 policy
= sta
->ssid_probe
->security_policy
;
138 def_klen
= sta
->ssid_probe
->wep
.default_len
;
140 policy
= sta
->ssid
->security_policy
;
141 def_klen
= sta
->ssid
->wep
.default_len
;
143 privacy
= policy
!= SECURITY_PLAINTEXT
;
144 if (policy
== SECURITY_IEEE_802_1X
&& def_klen
== 0)
149 capab
|= WLAN_CAPABILITY_PRIVACY
;
151 if (hapd
->iface
->current_mode
&&
152 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
&&
153 hapd
->iface
->num_sta_no_short_slot_time
== 0)
154 capab
|= WLAN_CAPABILITY_SHORT_SLOT_TIME
;
160 void ieee802_11_print_ssid(char *buf
, const u8
*ssid
, u8 len
)
163 if (len
> HOSTAPD_MAX_SSID_LEN
)
164 len
= HOSTAPD_MAX_SSID_LEN
;
165 for (i
= 0; i
< len
; i
++) {
166 if (ssid
[i
] >= 32 && ssid
[i
] < 127)
175 static u16
auth_shared_key(struct hostapd_data
*hapd
, struct sta_info
*sta
,
176 u16 auth_transaction
, const u8
*challenge
,
179 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
181 "authentication (shared key, transaction %d)",
184 if (auth_transaction
== 1) {
185 if (!sta
->challenge
) {
186 /* Generate a pseudo-random challenge */
190 sta
->challenge
= os_zalloc(WLAN_AUTH_CHALLENGE_LEN
);
191 if (sta
->challenge
== NULL
)
192 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
196 os_memcpy(key
, &now
.sec
, 4);
197 os_memcpy(key
+ 4, &r
, 4);
198 rc4_skip(key
, sizeof(key
), 0,
199 sta
->challenge
, WLAN_AUTH_CHALLENGE_LEN
);
204 if (auth_transaction
!= 3)
205 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
208 if (!iswep
|| !sta
->challenge
|| !challenge
||
209 os_memcmp(sta
->challenge
, challenge
, WLAN_AUTH_CHALLENGE_LEN
)) {
210 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
212 "shared key authentication - invalid "
213 "challenge-response");
214 return WLAN_STATUS_CHALLENGE_FAIL
;
217 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
219 "authentication OK (shared key)");
220 #ifdef IEEE80211_REQUIRE_AUTH_ACK
221 /* Station will be marked authenticated if it ACKs the
222 * authentication reply. */
224 sta
->flags
|= WLAN_STA_AUTH
;
225 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
227 os_free(sta
->challenge
);
228 sta
->challenge
= NULL
;
234 static void send_auth_reply(struct hostapd_data
*hapd
,
235 const u8
*dst
, const u8
*bssid
,
236 u16 auth_alg
, u16 auth_transaction
, u16 resp
,
237 const u8
*ies
, size_t ies_len
)
239 struct ieee80211_mgmt
*reply
;
243 rlen
= IEEE80211_HDRLEN
+ sizeof(reply
->u
.auth
) + ies_len
;
244 buf
= os_zalloc(rlen
);
248 reply
= (struct ieee80211_mgmt
*) buf
;
249 reply
->frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
251 os_memcpy(reply
->da
, dst
, ETH_ALEN
);
252 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
253 os_memcpy(reply
->bssid
, bssid
, ETH_ALEN
);
255 reply
->u
.auth
.auth_alg
= host_to_le16(auth_alg
);
256 reply
->u
.auth
.auth_transaction
= host_to_le16(auth_transaction
);
257 reply
->u
.auth
.status_code
= host_to_le16(resp
);
260 os_memcpy(reply
->u
.auth
.variable
, ies
, ies_len
);
262 wpa_printf(MSG_DEBUG
, "authentication reply: STA=" MACSTR
263 " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)",
264 MAC2STR(dst
), auth_alg
, auth_transaction
,
265 resp
, (unsigned long) ies_len
);
266 if (hostapd_drv_send_mlme(hapd
, reply
, rlen
, 0) < 0)
267 perror("send_auth_reply: send");
273 #ifdef CONFIG_IEEE80211R
274 static void handle_auth_ft_finish(void *ctx
, const u8
*dst
, const u8
*bssid
,
275 u16 auth_transaction
, u16 status
,
276 const u8
*ies
, size_t ies_len
)
278 struct hostapd_data
*hapd
= ctx
;
279 struct sta_info
*sta
;
281 send_auth_reply(hapd
, dst
, bssid
, WLAN_AUTH_FT
, auth_transaction
,
282 status
, ies
, ies_len
);
284 if (status
!= WLAN_STATUS_SUCCESS
)
287 sta
= ap_get_sta(hapd
, dst
);
291 hostapd_logger(hapd
, dst
, HOSTAPD_MODULE_IEEE80211
,
292 HOSTAPD_LEVEL_DEBUG
, "authentication OK (FT)");
293 sta
->flags
|= WLAN_STA_AUTH
;
294 mlme_authenticate_indication(hapd
, sta
);
296 #endif /* CONFIG_IEEE80211R */
299 static void handle_auth(struct hostapd_data
*hapd
,
300 const struct ieee80211_mgmt
*mgmt
, size_t len
)
302 u16 auth_alg
, auth_transaction
, status_code
;
303 u16 resp
= WLAN_STATUS_SUCCESS
;
304 struct sta_info
*sta
= NULL
;
307 const u8
*challenge
= NULL
;
308 u32 session_timeout
, acct_interim_interval
;
312 u8 resp_ies
[2 + WLAN_AUTH_CHALLENGE_LEN
];
313 size_t resp_ies_len
= 0;
314 char *identity
= NULL
;
315 char *radius_cui
= NULL
;
317 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
318 printf("handle_auth - too short payload (len=%lu)\n",
319 (unsigned long) len
);
323 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
324 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
325 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
326 fc
= le_to_host16(mgmt
->frame_control
);
328 if (len
>= IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
) +
329 2 + WLAN_AUTH_CHALLENGE_LEN
&&
330 mgmt
->u
.auth
.variable
[0] == WLAN_EID_CHALLENGE
&&
331 mgmt
->u
.auth
.variable
[1] == WLAN_AUTH_CHALLENGE_LEN
)
332 challenge
= &mgmt
->u
.auth
.variable
[2];
334 wpa_printf(MSG_DEBUG
, "authentication: STA=" MACSTR
" auth_alg=%d "
335 "auth_transaction=%d status_code=%d wep=%d%s",
336 MAC2STR(mgmt
->sa
), auth_alg
, auth_transaction
,
337 status_code
, !!(fc
& WLAN_FC_ISWEP
),
338 challenge
? " challenge" : "");
340 if (hapd
->tkip_countermeasures
) {
341 resp
= WLAN_REASON_MICHAEL_MIC_FAILURE
;
345 if (!(((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_OPEN
) &&
346 auth_alg
== WLAN_AUTH_OPEN
) ||
347 #ifdef CONFIG_IEEE80211R
348 (hapd
->conf
->wpa
&& wpa_key_mgmt_ft(hapd
->conf
->wpa_key_mgmt
) &&
349 auth_alg
== WLAN_AUTH_FT
) ||
350 #endif /* CONFIG_IEEE80211R */
351 ((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_SHARED
) &&
352 auth_alg
== WLAN_AUTH_SHARED_KEY
))) {
353 printf("Unsupported authentication algorithm (%d)\n",
355 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
359 if (!(auth_transaction
== 1 ||
360 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 3))) {
361 printf("Unknown authentication transaction number (%d)\n",
363 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
367 if (os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
368 printf("Station " MACSTR
" not allowed to authenticate.\n",
370 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
374 res
= hostapd_allowed_address(hapd
, mgmt
->sa
, (u8
*) mgmt
, len
,
376 &acct_interim_interval
, &vlan_id
,
377 psk
, &has_psk
, &identity
, &radius_cui
);
379 if (res
== HOSTAPD_ACL_REJECT
) {
380 printf("Station " MACSTR
" not allowed to authenticate.\n",
382 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
385 if (res
== HOSTAPD_ACL_PENDING
) {
386 wpa_printf(MSG_DEBUG
, "Authentication frame from " MACSTR
387 " waiting for an external authentication",
389 /* Authentication code will re-send the authentication frame
390 * after it has received (and cached) information from the
391 * external source. */
395 sta
= ap_sta_add(hapd
, mgmt
->sa
);
397 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
402 if (hostapd_get_vlan_id_ifname(hapd
->conf
->vlan
,
404 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
405 HOSTAPD_LEVEL_INFO
, "Invalid VLAN ID "
406 "%d received from RADIUS server",
408 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
411 sta
->vlan_id
= vlan_id
;
412 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
413 HOSTAPD_LEVEL_INFO
, "VLAN ID %d", sta
->vlan_id
);
416 if (has_psk
&& hapd
->conf
->wpa_psk_radius
!= PSK_RADIUS_IGNORED
) {
418 sta
->psk
= os_malloc(PMK_LEN
);
420 os_memcpy(sta
->psk
, psk
, PMK_LEN
);
426 sta
->identity
= identity
;
428 sta
->radius_cui
= radius_cui
;
431 sta
->flags
&= ~WLAN_STA_PREAUTH
;
432 ieee802_1x_notify_pre_auth(sta
->eapol_sm
, 0);
434 if (hapd
->conf
->acct_interim_interval
== 0 && acct_interim_interval
)
435 sta
->acct_interim_interval
= acct_interim_interval
;
436 if (res
== HOSTAPD_ACL_ACCEPT_TIMEOUT
)
437 ap_sta_session_timeout(hapd
, sta
, session_timeout
);
439 ap_sta_no_session_timeout(hapd
, sta
);
443 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
445 "authentication OK (open system)");
446 #ifdef IEEE80211_REQUIRE_AUTH_ACK
447 /* Station will be marked authenticated if it ACKs the
448 * authentication reply. */
450 sta
->flags
|= WLAN_STA_AUTH
;
451 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
452 sta
->auth_alg
= WLAN_AUTH_OPEN
;
453 mlme_authenticate_indication(hapd
, sta
);
456 case WLAN_AUTH_SHARED_KEY
:
457 resp
= auth_shared_key(hapd
, sta
, auth_transaction
, challenge
,
459 sta
->auth_alg
= WLAN_AUTH_SHARED_KEY
;
460 mlme_authenticate_indication(hapd
, sta
);
461 if (sta
->challenge
&& auth_transaction
== 1) {
462 resp_ies
[0] = WLAN_EID_CHALLENGE
;
463 resp_ies
[1] = WLAN_AUTH_CHALLENGE_LEN
;
464 os_memcpy(resp_ies
+ 2, sta
->challenge
,
465 WLAN_AUTH_CHALLENGE_LEN
);
466 resp_ies_len
= 2 + WLAN_AUTH_CHALLENGE_LEN
;
469 #ifdef CONFIG_IEEE80211R
471 sta
->auth_alg
= WLAN_AUTH_FT
;
472 if (sta
->wpa_sm
== NULL
)
473 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
475 if (sta
->wpa_sm
== NULL
) {
476 wpa_printf(MSG_DEBUG
, "FT: Failed to initialize WPA "
478 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
481 wpa_ft_process_auth(sta
->wpa_sm
, mgmt
->bssid
,
482 auth_transaction
, mgmt
->u
.auth
.variable
,
483 len
- IEEE80211_HDRLEN
-
484 sizeof(mgmt
->u
.auth
),
485 handle_auth_ft_finish
, hapd
);
486 /* handle_auth_ft_finish() callback will complete auth. */
488 #endif /* CONFIG_IEEE80211R */
495 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, auth_alg
,
496 auth_transaction
+ 1, resp
, resp_ies
, resp_ies_len
);
500 static int hostapd_get_aid(struct hostapd_data
*hapd
, struct sta_info
*sta
)
504 /* get a unique AID */
506 wpa_printf(MSG_DEBUG
, " old AID %d", sta
->aid
);
510 for (i
= 0; i
< AID_WORDS
; i
++) {
511 if (hapd
->sta_aid
[i
] == (u32
) -1)
513 for (j
= 0; j
< 32; j
++) {
514 if (!(hapd
->sta_aid
[i
] & BIT(j
)))
522 aid
= i
* 32 + j
+ 1;
527 hapd
->sta_aid
[i
] |= BIT(j
);
528 wpa_printf(MSG_DEBUG
, " new AID %d", sta
->aid
);
533 static u16
check_ssid(struct hostapd_data
*hapd
, struct sta_info
*sta
,
534 const u8
*ssid_ie
, size_t ssid_ie_len
)
537 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
539 if (ssid_ie_len
!= hapd
->conf
->ssid
.ssid_len
||
540 os_memcmp(ssid_ie
, hapd
->conf
->ssid
.ssid
, ssid_ie_len
) != 0) {
542 ieee802_11_print_ssid(ssid_txt
, ssid_ie
, ssid_ie_len
);
543 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
545 "Station tried to associate with unknown SSID "
547 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
550 return WLAN_STATUS_SUCCESS
;
554 static u16
check_wmm(struct hostapd_data
*hapd
, struct sta_info
*sta
,
555 const u8
*wmm_ie
, size_t wmm_ie_len
)
557 sta
->flags
&= ~WLAN_STA_WMM
;
559 if (wmm_ie
&& hapd
->conf
->wmm_enabled
) {
560 struct wmm_information_element
*wmm
;
562 if (!hostapd_eid_wmm_valid(hapd
, wmm_ie
, wmm_ie_len
)) {
563 hostapd_logger(hapd
, sta
->addr
,
566 "invalid WMM element in association "
568 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
571 sta
->flags
|= WLAN_STA_WMM
;
572 wmm
= (struct wmm_information_element
*) wmm_ie
;
573 sta
->qosinfo
= wmm
->qos_info
;
575 return WLAN_STATUS_SUCCESS
;
579 static u16
copy_supp_rates(struct hostapd_data
*hapd
, struct sta_info
*sta
,
580 struct ieee802_11_elems
*elems
)
582 if (!elems
->supp_rates
) {
583 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
585 "No supported rates element in AssocReq");
586 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
589 if (elems
->supp_rates_len
+ elems
->ext_supp_rates_len
>
590 sizeof(sta
->supported_rates
)) {
591 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
593 "Invalid supported rates element length %d+%d",
594 elems
->supp_rates_len
,
595 elems
->ext_supp_rates_len
);
596 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
599 sta
->supported_rates_len
= merge_byte_arrays(
600 sta
->supported_rates
, sizeof(sta
->supported_rates
),
601 elems
->supp_rates
, elems
->supp_rates_len
,
602 elems
->ext_supp_rates
, elems
->ext_supp_rates_len
);
604 return WLAN_STATUS_SUCCESS
;
608 static u16
check_assoc_ies(struct hostapd_data
*hapd
, struct sta_info
*sta
,
609 const u8
*ies
, size_t ies_len
, int reassoc
)
611 struct ieee802_11_elems elems
;
616 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 1) == ParseFailed
) {
617 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
618 HOSTAPD_LEVEL_INFO
, "Station sent an invalid "
619 "association request");
620 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
623 resp
= check_ssid(hapd
, sta
, elems
.ssid
, elems
.ssid_len
);
624 if (resp
!= WLAN_STATUS_SUCCESS
)
626 resp
= check_wmm(hapd
, sta
, elems
.wmm
, elems
.wmm_len
);
627 if (resp
!= WLAN_STATUS_SUCCESS
)
629 resp
= copy_supp_rates(hapd
, sta
, &elems
);
630 if (resp
!= WLAN_STATUS_SUCCESS
)
632 #ifdef CONFIG_IEEE80211N
633 resp
= copy_sta_ht_capab(hapd
, sta
, elems
.ht_capabilities
,
634 elems
.ht_capabilities_len
);
635 if (resp
!= WLAN_STATUS_SUCCESS
)
637 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&&
638 !(sta
->flags
& WLAN_STA_HT
)) {
639 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
640 HOSTAPD_LEVEL_INFO
, "Station does not support "
641 "mandatory HT PHY - reject association");
642 return WLAN_STATUS_ASSOC_DENIED_NO_HT
;
644 #endif /* CONFIG_IEEE80211N */
646 #ifdef CONFIG_IEEE80211AC
647 resp
= copy_sta_vht_capab(hapd
, sta
, elems
.vht_capabilities
,
648 elems
.vht_capabilities_len
);
649 if (resp
!= WLAN_STATUS_SUCCESS
)
651 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&&
652 !(sta
->flags
& WLAN_STA_VHT
)) {
653 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
654 HOSTAPD_LEVEL_INFO
, "Station does not support "
655 "mandatory VHT PHY - reject association");
656 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
658 #endif /* CONFIG_IEEE80211AC */
660 if ((hapd
->conf
->wpa
& WPA_PROTO_RSN
) && elems
.rsn_ie
) {
661 wpa_ie
= elems
.rsn_ie
;
662 wpa_ie_len
= elems
.rsn_ie_len
;
663 } else if ((hapd
->conf
->wpa
& WPA_PROTO_WPA
) &&
665 wpa_ie
= elems
.wpa_ie
;
666 wpa_ie_len
= elems
.wpa_ie_len
;
673 sta
->flags
&= ~(WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
| WLAN_STA_WPS2
);
674 if (hapd
->conf
->wps_state
&& elems
.wps_ie
) {
675 wpa_printf(MSG_DEBUG
, "STA included WPS IE in (Re)Association "
676 "Request - assume WPS is used");
677 sta
->flags
|= WLAN_STA_WPS
;
678 wpabuf_free(sta
->wps_ie
);
679 sta
->wps_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
681 if (sta
->wps_ie
&& wps_is_20(sta
->wps_ie
)) {
682 wpa_printf(MSG_DEBUG
, "WPS: STA supports WPS 2.0");
683 sta
->flags
|= WLAN_STA_WPS2
;
687 if (sta
->wps_ie
&& wps_validate_assoc_req(sta
->wps_ie
) < 0) {
688 wpa_printf(MSG_DEBUG
, "WPS: Invalid WPS IE in "
689 "(Re)Association Request - reject");
690 return WLAN_STATUS_INVALID_IE
;
692 } else if (hapd
->conf
->wps_state
&& wpa_ie
== NULL
) {
693 wpa_printf(MSG_DEBUG
, "STA did not include WPA/RSN IE in "
694 "(Re)Association Request - possible WPS use");
695 sta
->flags
|= WLAN_STA_MAYBE_WPS
;
697 #endif /* CONFIG_WPS */
698 if (hapd
->conf
->wpa
&& wpa_ie
== NULL
) {
699 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
701 "No WPA/RSN IE in association request");
702 return WLAN_STATUS_INVALID_IE
;
705 if (hapd
->conf
->wpa
&& wpa_ie
) {
709 if (sta
->wpa_sm
== NULL
)
710 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
712 if (sta
->wpa_sm
== NULL
) {
713 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
715 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
717 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
719 elems
.mdie
, elems
.mdie_len
);
720 if (res
== WPA_INVALID_GROUP
)
721 resp
= WLAN_STATUS_GROUP_CIPHER_NOT_VALID
;
722 else if (res
== WPA_INVALID_PAIRWISE
)
723 resp
= WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID
;
724 else if (res
== WPA_INVALID_AKMP
)
725 resp
= WLAN_STATUS_AKMP_NOT_VALID
;
726 else if (res
== WPA_ALLOC_FAIL
)
727 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
728 #ifdef CONFIG_IEEE80211W
729 else if (res
== WPA_MGMT_FRAME_PROTECTION_VIOLATION
)
730 resp
= WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
731 else if (res
== WPA_INVALID_MGMT_GROUP_CIPHER
)
732 resp
= WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
733 #endif /* CONFIG_IEEE80211W */
734 else if (res
== WPA_INVALID_MDIE
)
735 resp
= WLAN_STATUS_INVALID_MDIE
;
736 else if (res
!= WPA_IE_OK
)
737 resp
= WLAN_STATUS_INVALID_IE
;
738 if (resp
!= WLAN_STATUS_SUCCESS
)
740 #ifdef CONFIG_IEEE80211W
741 if ((sta
->flags
& WLAN_STA_MFP
) && !sta
->sa_query_timed_out
&&
742 sta
->sa_query_count
> 0)
743 ap_check_sa_query_timeout(hapd
, sta
);
744 if ((sta
->flags
& WLAN_STA_MFP
) && !sta
->sa_query_timed_out
&&
745 (!reassoc
|| sta
->auth_alg
!= WLAN_AUTH_FT
)) {
747 * STA has already been associated with MFP and SA
748 * Query timeout has not been reached. Reject the
749 * association attempt temporarily and start SA Query,
750 * if one is not pending.
753 if (sta
->sa_query_count
== 0)
754 ap_sta_start_sa_query(hapd
, sta
);
756 return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
;
759 if (wpa_auth_uses_mfp(sta
->wpa_sm
))
760 sta
->flags
|= WLAN_STA_MFP
;
762 sta
->flags
&= ~WLAN_STA_MFP
;
763 #endif /* CONFIG_IEEE80211W */
765 #ifdef CONFIG_IEEE80211R
766 if (sta
->auth_alg
== WLAN_AUTH_FT
) {
768 wpa_printf(MSG_DEBUG
, "FT: " MACSTR
" tried "
769 "to use association (not "
770 "re-association) with FT auth_alg",
772 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
775 resp
= wpa_ft_validate_reassoc(sta
->wpa_sm
, ies
,
777 if (resp
!= WLAN_STATUS_SUCCESS
)
780 #endif /* CONFIG_IEEE80211R */
782 #ifdef CONFIG_IEEE80211N
783 if ((sta
->flags
& (WLAN_STA_HT
| WLAN_STA_VHT
)) &&
784 wpa_auth_get_pairwise(sta
->wpa_sm
) == WPA_CIPHER_TKIP
) {
785 hostapd_logger(hapd
, sta
->addr
,
786 HOSTAPD_MODULE_IEEE80211
,
788 "Station tried to use TKIP with HT "
790 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
792 #endif /* CONFIG_IEEE80211N */
794 wpa_auth_sta_no_wpa(sta
->wpa_sm
);
798 wpabuf_free(sta
->p2p_ie
);
799 sta
->p2p_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
803 wpabuf_free(sta
->p2p_ie
);
807 p2p_group_notif_assoc(hapd
->p2p_group
, sta
->addr
, ies
, ies_len
);
808 #endif /* CONFIG_P2P */
810 return WLAN_STATUS_SUCCESS
;
814 static void send_deauth(struct hostapd_data
*hapd
, const u8
*addr
,
818 struct ieee80211_mgmt reply
;
820 os_memset(&reply
, 0, sizeof(reply
));
821 reply
.frame_control
=
822 IEEE80211_FC(WLAN_FC_TYPE_MGMT
, WLAN_FC_STYPE_DEAUTH
);
823 os_memcpy(reply
.da
, addr
, ETH_ALEN
);
824 os_memcpy(reply
.sa
, hapd
->own_addr
, ETH_ALEN
);
825 os_memcpy(reply
.bssid
, hapd
->own_addr
, ETH_ALEN
);
827 send_len
= IEEE80211_HDRLEN
+ sizeof(reply
.u
.deauth
);
828 reply
.u
.deauth
.reason_code
= host_to_le16(reason_code
);
830 if (hostapd_drv_send_mlme(hapd
, &reply
, send_len
, 0) < 0)
831 wpa_printf(MSG_INFO
, "Failed to send deauth: %s",
836 static void send_assoc_resp(struct hostapd_data
*hapd
, struct sta_info
*sta
,
837 u16 status_code
, int reassoc
, const u8
*ies
,
841 u8 buf
[sizeof(struct ieee80211_mgmt
) + 1024];
842 struct ieee80211_mgmt
*reply
;
845 os_memset(buf
, 0, sizeof(buf
));
846 reply
= (struct ieee80211_mgmt
*) buf
;
847 reply
->frame_control
=
848 IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
849 (reassoc
? WLAN_FC_STYPE_REASSOC_RESP
:
850 WLAN_FC_STYPE_ASSOC_RESP
));
851 os_memcpy(reply
->da
, sta
->addr
, ETH_ALEN
);
852 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
853 os_memcpy(reply
->bssid
, hapd
->own_addr
, ETH_ALEN
);
855 send_len
= IEEE80211_HDRLEN
;
856 send_len
+= sizeof(reply
->u
.assoc_resp
);
857 reply
->u
.assoc_resp
.capab_info
=
858 host_to_le16(hostapd_own_capab_info(hapd
, sta
, 0));
859 reply
->u
.assoc_resp
.status_code
= host_to_le16(status_code
);
860 reply
->u
.assoc_resp
.aid
= host_to_le16((sta
? sta
->aid
: 0)
861 | BIT(14) | BIT(15));
862 /* Supported rates */
863 p
= hostapd_eid_supp_rates(hapd
, reply
->u
.assoc_resp
.variable
);
864 /* Extended supported rates */
865 p
= hostapd_eid_ext_supp_rates(hapd
, p
);
867 #ifdef CONFIG_IEEE80211R
868 if (status_code
== WLAN_STATUS_SUCCESS
) {
869 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
870 * Transition Information, RSN, [RIC Response] */
871 p
= wpa_sm_write_assoc_resp_ies(sta
->wpa_sm
, p
,
872 buf
+ sizeof(buf
) - p
,
873 sta
->auth_alg
, ies
, ies_len
);
875 #endif /* CONFIG_IEEE80211R */
877 #ifdef CONFIG_IEEE80211W
878 if (status_code
== WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
)
879 p
= hostapd_eid_assoc_comeback_time(hapd
, sta
, p
);
880 #endif /* CONFIG_IEEE80211W */
882 #ifdef CONFIG_IEEE80211N
883 p
= hostapd_eid_ht_capabilities(hapd
, p
);
884 p
= hostapd_eid_ht_operation(hapd
, p
);
885 #endif /* CONFIG_IEEE80211N */
887 #ifdef CONFIG_IEEE80211AC
888 p
= hostapd_eid_vht_capabilities(hapd
, p
);
889 p
= hostapd_eid_vht_operation(hapd
, p
);
890 #endif /* CONFIG_IEEE80211AC */
892 p
= hostapd_eid_ext_capab(hapd
, p
);
893 p
= hostapd_eid_bss_max_idle_period(hapd
, p
);
895 if (sta
->flags
& WLAN_STA_WMM
)
896 p
= hostapd_eid_wmm(hapd
, p
);
899 if ((sta
->flags
& WLAN_STA_WPS
) ||
900 ((sta
->flags
& WLAN_STA_MAYBE_WPS
) && hapd
->conf
->wpa
)) {
901 struct wpabuf
*wps
= wps_build_assoc_resp_ie();
903 os_memcpy(p
, wpabuf_head(wps
), wpabuf_len(wps
));
904 p
+= wpabuf_len(wps
);
908 #endif /* CONFIG_WPS */
912 struct wpabuf
*p2p_resp_ie
;
913 enum p2p_status_code status
;
914 switch (status_code
) {
915 case WLAN_STATUS_SUCCESS
:
916 status
= P2P_SC_SUCCESS
;
918 case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
:
919 status
= P2P_SC_FAIL_LIMIT_REACHED
;
922 status
= P2P_SC_FAIL_INVALID_PARAMS
;
925 p2p_resp_ie
= p2p_group_assoc_resp_ie(hapd
->p2p_group
, status
);
927 os_memcpy(p
, wpabuf_head(p2p_resp_ie
),
928 wpabuf_len(p2p_resp_ie
));
929 p
+= wpabuf_len(p2p_resp_ie
);
930 wpabuf_free(p2p_resp_ie
);
933 #endif /* CONFIG_P2P */
935 #ifdef CONFIG_P2P_MANAGER
936 if (hapd
->conf
->p2p
& P2P_MANAGE
)
937 p
= hostapd_eid_p2p_manage(hapd
, p
);
938 #endif /* CONFIG_P2P_MANAGER */
940 send_len
+= p
- reply
->u
.assoc_resp
.variable
;
942 if (hostapd_drv_send_mlme(hapd
, reply
, send_len
, 0) < 0)
943 wpa_printf(MSG_INFO
, "Failed to send assoc resp: %s",
948 static void handle_assoc(struct hostapd_data
*hapd
,
949 const struct ieee80211_mgmt
*mgmt
, size_t len
,
952 u16 capab_info
, listen_interval
;
953 u16 resp
= WLAN_STATUS_SUCCESS
;
956 struct sta_info
*sta
;
958 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_req
) :
959 sizeof(mgmt
->u
.assoc_req
))) {
960 printf("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
961 "\n", reassoc
, (unsigned long) len
);
966 capab_info
= le_to_host16(mgmt
->u
.reassoc_req
.capab_info
);
967 listen_interval
= le_to_host16(
968 mgmt
->u
.reassoc_req
.listen_interval
);
969 wpa_printf(MSG_DEBUG
, "reassociation request: STA=" MACSTR
970 " capab_info=0x%02x listen_interval=%d current_ap="
972 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
973 MAC2STR(mgmt
->u
.reassoc_req
.current_ap
));
974 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.reassoc_req
));
975 pos
= mgmt
->u
.reassoc_req
.variable
;
977 capab_info
= le_to_host16(mgmt
->u
.assoc_req
.capab_info
);
978 listen_interval
= le_to_host16(
979 mgmt
->u
.assoc_req
.listen_interval
);
980 wpa_printf(MSG_DEBUG
, "association request: STA=" MACSTR
981 " capab_info=0x%02x listen_interval=%d",
982 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
);
983 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.assoc_req
));
984 pos
= mgmt
->u
.assoc_req
.variable
;
987 sta
= ap_get_sta(hapd
, mgmt
->sa
);
988 #ifdef CONFIG_IEEE80211R
989 if (sta
&& sta
->auth_alg
== WLAN_AUTH_FT
&&
990 (sta
->flags
& WLAN_STA_AUTH
) == 0) {
991 wpa_printf(MSG_DEBUG
, "FT: Allow STA " MACSTR
" to associate "
992 "prior to authentication since it is using "
993 "over-the-DS FT", MAC2STR(mgmt
->sa
));
995 #endif /* CONFIG_IEEE80211R */
996 if (sta
== NULL
|| (sta
->flags
& WLAN_STA_AUTH
) == 0) {
997 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
998 HOSTAPD_LEVEL_INFO
, "Station tried to "
999 "associate before authentication "
1000 "(aid=%d flags=0x%x)",
1001 sta
? sta
->aid
: -1,
1002 sta
? sta
->flags
: 0);
1003 send_deauth(hapd
, mgmt
->sa
,
1004 WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA
);
1008 if (hapd
->tkip_countermeasures
) {
1009 resp
= WLAN_REASON_MICHAEL_MIC_FAILURE
;
1013 if (listen_interval
> hapd
->conf
->max_listen_interval
) {
1014 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1015 HOSTAPD_LEVEL_DEBUG
,
1016 "Too large Listen Interval (%d)",
1018 resp
= WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE
;
1022 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
1024 resp
= check_assoc_ies(hapd
, sta
, pos
, left
, reassoc
);
1025 if (resp
!= WLAN_STATUS_SUCCESS
)
1028 if (hostapd_get_aid(hapd
, sta
) < 0) {
1029 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1030 HOSTAPD_LEVEL_INFO
, "No room for more AIDs");
1031 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
1035 sta
->capability
= capab_info
;
1036 sta
->listen_interval
= listen_interval
;
1038 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
1039 sta
->flags
|= WLAN_STA_NONERP
;
1040 for (i
= 0; i
< sta
->supported_rates_len
; i
++) {
1041 if ((sta
->supported_rates
[i
] & 0x7f) > 22) {
1042 sta
->flags
&= ~WLAN_STA_NONERP
;
1046 if (sta
->flags
& WLAN_STA_NONERP
&& !sta
->nonerp_set
) {
1047 sta
->nonerp_set
= 1;
1048 hapd
->iface
->num_sta_non_erp
++;
1049 if (hapd
->iface
->num_sta_non_erp
== 1)
1050 ieee802_11_set_beacons(hapd
->iface
);
1053 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
) &&
1054 !sta
->no_short_slot_time_set
) {
1055 sta
->no_short_slot_time_set
= 1;
1056 hapd
->iface
->num_sta_no_short_slot_time
++;
1057 if (hapd
->iface
->current_mode
->mode
==
1058 HOSTAPD_MODE_IEEE80211G
&&
1059 hapd
->iface
->num_sta_no_short_slot_time
== 1)
1060 ieee802_11_set_beacons(hapd
->iface
);
1063 if (sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
1064 sta
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
1066 sta
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
1068 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
) &&
1069 !sta
->no_short_preamble_set
) {
1070 sta
->no_short_preamble_set
= 1;
1071 hapd
->iface
->num_sta_no_short_preamble
++;
1072 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
1073 && hapd
->iface
->num_sta_no_short_preamble
== 1)
1074 ieee802_11_set_beacons(hapd
->iface
);
1077 #ifdef CONFIG_IEEE80211N
1078 update_ht_state(hapd
, sta
);
1079 #endif /* CONFIG_IEEE80211N */
1081 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1082 HOSTAPD_LEVEL_DEBUG
,
1083 "association OK (aid %d)", sta
->aid
);
1084 /* Station will be marked associated, after it acknowledges AssocResp
1086 sta
->flags
|= WLAN_STA_ASSOC_REQ_OK
;
1088 #ifdef CONFIG_IEEE80211W
1089 if ((sta
->flags
& WLAN_STA_MFP
) && sta
->sa_query_timed_out
) {
1090 wpa_printf(MSG_DEBUG
, "Allowing %sassociation after timed out "
1091 "SA Query procedure", reassoc
? "re" : "");
1092 /* TODO: Send a protected Disassociate frame to the STA using
1093 * the old key and Reason Code "Previous Authentication no
1094 * longer valid". Make sure this is only sent protected since
1095 * unprotected frame would be received by the STA that is now
1096 * trying to associate.
1099 #endif /* CONFIG_IEEE80211W */
1102 os_memcpy(sta
->previous_ap
, mgmt
->u
.reassoc_req
.current_ap
,
1106 if (sta
->last_assoc_req
)
1107 os_free(sta
->last_assoc_req
);
1108 sta
->last_assoc_req
= os_malloc(len
);
1109 if (sta
->last_assoc_req
)
1110 os_memcpy(sta
->last_assoc_req
, mgmt
, len
);
1112 /* Make sure that the previously registered inactivity timer will not
1113 * remove the STA immediately. */
1114 sta
->timeout_next
= STA_NULLFUNC
;
1117 send_assoc_resp(hapd
, sta
, resp
, reassoc
, pos
, left
);
1121 static void handle_disassoc(struct hostapd_data
*hapd
,
1122 const struct ieee80211_mgmt
*mgmt
, size_t len
)
1124 struct sta_info
*sta
;
1126 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.disassoc
)) {
1127 printf("handle_disassoc - too short payload (len=%lu)\n",
1128 (unsigned long) len
);
1132 wpa_printf(MSG_DEBUG
, "disassocation: STA=" MACSTR
" reason_code=%d",
1134 le_to_host16(mgmt
->u
.disassoc
.reason_code
));
1136 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1138 printf("Station " MACSTR
" trying to disassociate, but it "
1139 "is not associated.\n", MAC2STR(mgmt
->sa
));
1143 ap_sta_set_authorized(hapd
, sta
, 0);
1144 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
);
1145 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
1146 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1147 HOSTAPD_LEVEL_INFO
, "disassociated");
1148 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
1149 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
1150 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
1152 accounting_sta_stop(hapd
, sta
);
1153 ieee802_1x_free_station(sta
);
1154 hostapd_drv_sta_remove(hapd
, sta
->addr
);
1156 if (sta
->timeout_next
== STA_NULLFUNC
||
1157 sta
->timeout_next
== STA_DISASSOC
) {
1158 sta
->timeout_next
= STA_DEAUTH
;
1159 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
1160 eloop_register_timeout(AP_DEAUTH_DELAY
, 0, ap_handle_timer
,
1164 mlme_disassociate_indication(
1165 hapd
, sta
, le_to_host16(mgmt
->u
.disassoc
.reason_code
));
1169 static void handle_deauth(struct hostapd_data
*hapd
,
1170 const struct ieee80211_mgmt
*mgmt
, size_t len
)
1172 struct sta_info
*sta
;
1174 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.deauth
)) {
1175 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "handle_deauth - too short "
1176 "payload (len=%lu)", (unsigned long) len
);
1180 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "deauthentication: STA=" MACSTR
1182 MAC2STR(mgmt
->sa
), le_to_host16(mgmt
->u
.deauth
.reason_code
));
1184 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1186 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "Station " MACSTR
" trying "
1187 "to deauthenticate, but it is not authenticated",
1192 ap_sta_set_authorized(hapd
, sta
, 0);
1193 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
|
1194 WLAN_STA_ASSOC_REQ_OK
);
1195 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
1196 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1197 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
1198 mlme_deauthenticate_indication(
1199 hapd
, sta
, le_to_host16(mgmt
->u
.deauth
.reason_code
));
1200 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
1201 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
1202 ap_free_sta(hapd
, sta
);
1206 static void handle_beacon(struct hostapd_data
*hapd
,
1207 const struct ieee80211_mgmt
*mgmt
, size_t len
,
1208 struct hostapd_frame_info
*fi
)
1210 struct ieee802_11_elems elems
;
1212 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.beacon
)) {
1213 printf("handle_beacon - too short payload (len=%lu)\n",
1214 (unsigned long) len
);
1218 (void) ieee802_11_parse_elems(mgmt
->u
.beacon
.variable
,
1219 len
- (IEEE80211_HDRLEN
+
1220 sizeof(mgmt
->u
.beacon
)), &elems
,
1223 ap_list_process_beacon(hapd
->iface
, mgmt
, &elems
, fi
);
1227 #ifdef CONFIG_IEEE80211W
1229 static void hostapd_sa_query_action(struct hostapd_data
*hapd
,
1230 const struct ieee80211_mgmt
*mgmt
,
1235 end
= mgmt
->u
.action
.u
.sa_query_resp
.trans_id
+
1236 WLAN_SA_QUERY_TR_ID_LEN
;
1237 if (((u8
*) mgmt
) + len
< end
) {
1238 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Too short SA Query Action "
1239 "frame (len=%lu)", (unsigned long) len
);
1243 ieee802_11_sa_query_action(hapd
, mgmt
->sa
,
1244 mgmt
->u
.action
.u
.sa_query_resp
.action
,
1245 mgmt
->u
.action
.u
.sa_query_resp
.trans_id
);
1249 static int robust_action_frame(u8 category
)
1251 return category
!= WLAN_ACTION_PUBLIC
&&
1252 category
!= WLAN_ACTION_HT
;
1254 #endif /* CONFIG_IEEE80211W */
1257 static void handle_action(struct hostapd_data
*hapd
,
1258 const struct ieee80211_mgmt
*mgmt
, size_t len
)
1260 #if defined(CONFIG_IEEE80211W) || defined(CONFIG_IEEE80211R)
1261 struct sta_info
*sta
;
1262 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1263 #endif /* CONFIG_IEEE80211W || CONFIG_IEEE80211R */
1265 if (len
< IEEE80211_HDRLEN
+ 1) {
1266 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1267 HOSTAPD_LEVEL_DEBUG
,
1268 "handle_action - too short payload (len=%lu)",
1269 (unsigned long) len
);
1273 #ifdef CONFIG_IEEE80211W
1274 if (sta
&& (sta
->flags
& WLAN_STA_MFP
) &&
1275 !(mgmt
->frame_control
& host_to_le16(WLAN_FC_ISWEP
) &&
1276 robust_action_frame(mgmt
->u
.action
.category
))) {
1277 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1278 HOSTAPD_LEVEL_DEBUG
,
1279 "Dropped unprotected Robust Action frame from "
1283 #endif /* CONFIG_IEEE80211W */
1285 switch (mgmt
->u
.action
.category
) {
1286 #ifdef CONFIG_IEEE80211R
1287 case WLAN_ACTION_FT
:
1289 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
1290 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Ignored FT Action "
1291 "frame from unassociated STA " MACSTR
,
1296 if (wpa_ft_action_rx(sta
->wpa_sm
, (u8
*) &mgmt
->u
.action
,
1297 len
- IEEE80211_HDRLEN
))
1302 #endif /* CONFIG_IEEE80211R */
1303 case WLAN_ACTION_WMM
:
1304 hostapd_wmm_action(hapd
, mgmt
, len
);
1306 #ifdef CONFIG_IEEE80211W
1307 case WLAN_ACTION_SA_QUERY
:
1308 hostapd_sa_query_action(hapd
, mgmt
, len
);
1310 #endif /* CONFIG_IEEE80211W */
1311 case WLAN_ACTION_PUBLIC
:
1312 if (hapd
->public_action_cb
) {
1313 hapd
->public_action_cb(hapd
->public_action_cb_ctx
,
1319 case WLAN_ACTION_VENDOR_SPECIFIC
:
1320 if (hapd
->vendor_action_cb
) {
1321 if (hapd
->vendor_action_cb(hapd
->vendor_action_cb_ctx
,
1323 hapd
->iface
->freq
) == 0)
1329 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1330 HOSTAPD_LEVEL_DEBUG
,
1331 "handle_action - unknown action category %d or invalid "
1333 mgmt
->u
.action
.category
);
1334 if (!(mgmt
->da
[0] & 0x01) && !(mgmt
->u
.action
.category
& 0x80) &&
1335 !(mgmt
->sa
[0] & 0x01)) {
1336 struct ieee80211_mgmt
*resp
;
1339 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
1340 * Return the Action frame to the source without change
1341 * except that MSB of the Category set to 1.
1343 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Return unknown Action "
1344 "frame back to sender");
1345 resp
= os_malloc(len
);
1348 os_memcpy(resp
, mgmt
, len
);
1349 os_memcpy(resp
->da
, resp
->sa
, ETH_ALEN
);
1350 os_memcpy(resp
->sa
, hapd
->own_addr
, ETH_ALEN
);
1351 os_memcpy(resp
->bssid
, hapd
->own_addr
, ETH_ALEN
);
1352 resp
->u
.action
.category
|= 0x80;
1354 if (hostapd_drv_send_mlme(hapd
, resp
, len
, 0) < 0) {
1355 wpa_printf(MSG_ERROR
, "IEEE 802.11: Failed to send "
1364 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
1365 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
1367 * @buf: management frame data (starting from IEEE 802.11 header)
1368 * @len: length of frame data in octets
1369 * @fi: meta data about received frame (signal level, etc.)
1371 * Process all incoming IEEE 802.11 management frames. This will be called for
1372 * each frame received from the kernel driver through wlan#ap interface. In
1373 * addition, it can be called to re-inserted pending frames (e.g., when using
1374 * external RADIUS server as an MAC ACL).
1376 void ieee802_11_mgmt(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
1377 struct hostapd_frame_info
*fi
)
1379 struct ieee80211_mgmt
*mgmt
;
1386 mgmt
= (struct ieee80211_mgmt
*) buf
;
1387 fc
= le_to_host16(mgmt
->frame_control
);
1388 stype
= WLAN_FC_GET_STYPE(fc
);
1390 if (stype
== WLAN_FC_STYPE_BEACON
) {
1391 handle_beacon(hapd
, mgmt
, len
, fi
);
1395 broadcast
= mgmt
->bssid
[0] == 0xff && mgmt
->bssid
[1] == 0xff &&
1396 mgmt
->bssid
[2] == 0xff && mgmt
->bssid
[3] == 0xff &&
1397 mgmt
->bssid
[4] == 0xff && mgmt
->bssid
[5] == 0xff;
1401 /* Invitation responses can be sent with the peer MAC as BSSID */
1402 !((hapd
->conf
->p2p
& P2P_GROUP_OWNER
) &&
1403 stype
== WLAN_FC_STYPE_ACTION
) &&
1404 #endif /* CONFIG_P2P */
1405 os_memcmp(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
) != 0) {
1406 printf("MGMT: BSSID=" MACSTR
" not our address\n",
1407 MAC2STR(mgmt
->bssid
));
1412 if (stype
== WLAN_FC_STYPE_PROBE_REQ
) {
1413 handle_probe_req(hapd
, mgmt
, len
, fi
->ssi_signal
);
1417 if (os_memcmp(mgmt
->da
, hapd
->own_addr
, ETH_ALEN
) != 0) {
1418 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1419 HOSTAPD_LEVEL_DEBUG
,
1420 "MGMT: DA=" MACSTR
" not our address",
1426 case WLAN_FC_STYPE_AUTH
:
1427 wpa_printf(MSG_DEBUG
, "mgmt::auth");
1428 handle_auth(hapd
, mgmt
, len
);
1430 case WLAN_FC_STYPE_ASSOC_REQ
:
1431 wpa_printf(MSG_DEBUG
, "mgmt::assoc_req");
1432 handle_assoc(hapd
, mgmt
, len
, 0);
1434 case WLAN_FC_STYPE_REASSOC_REQ
:
1435 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_req");
1436 handle_assoc(hapd
, mgmt
, len
, 1);
1438 case WLAN_FC_STYPE_DISASSOC
:
1439 wpa_printf(MSG_DEBUG
, "mgmt::disassoc");
1440 handle_disassoc(hapd
, mgmt
, len
);
1442 case WLAN_FC_STYPE_DEAUTH
:
1443 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "mgmt::deauth");
1444 handle_deauth(hapd
, mgmt
, len
);
1446 case WLAN_FC_STYPE_ACTION
:
1447 wpa_printf(MSG_DEBUG
, "mgmt::action");
1448 handle_action(hapd
, mgmt
, len
);
1451 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1452 HOSTAPD_LEVEL_DEBUG
,
1453 "unknown mgmt frame subtype %d", stype
);
1459 static void handle_auth_cb(struct hostapd_data
*hapd
,
1460 const struct ieee80211_mgmt
*mgmt
,
1463 u16 auth_alg
, auth_transaction
, status_code
;
1464 struct sta_info
*sta
;
1467 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
1468 HOSTAPD_LEVEL_NOTICE
,
1469 "did not acknowledge authentication response");
1473 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
1474 printf("handle_auth_cb - too short payload (len=%lu)\n",
1475 (unsigned long) len
);
1479 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
1480 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
1481 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
1483 sta
= ap_get_sta(hapd
, mgmt
->da
);
1485 printf("handle_auth_cb: STA " MACSTR
" not found\n",
1490 if (status_code
== WLAN_STATUS_SUCCESS
&&
1491 ((auth_alg
== WLAN_AUTH_OPEN
&& auth_transaction
== 2) ||
1492 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 4))) {
1493 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1494 HOSTAPD_LEVEL_INFO
, "authenticated");
1495 sta
->flags
|= WLAN_STA_AUTH
;
1500 static void handle_assoc_cb(struct hostapd_data
*hapd
,
1501 const struct ieee80211_mgmt
*mgmt
,
1502 size_t len
, int reassoc
, int ok
)
1505 struct sta_info
*sta
;
1507 struct ieee80211_ht_capabilities ht_cap
;
1509 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_resp
) :
1510 sizeof(mgmt
->u
.assoc_resp
))) {
1511 printf("handle_assoc_cb(reassoc=%d) - too short payload "
1512 "(len=%lu)\n", reassoc
, (unsigned long) len
);
1516 sta
= ap_get_sta(hapd
, mgmt
->da
);
1518 printf("handle_assoc_cb: STA " MACSTR
" not found\n",
1524 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
1525 HOSTAPD_LEVEL_DEBUG
,
1526 "did not acknowledge association response");
1527 sta
->flags
&= ~WLAN_STA_ASSOC_REQ_OK
;
1532 status
= le_to_host16(mgmt
->u
.reassoc_resp
.status_code
);
1534 status
= le_to_host16(mgmt
->u
.assoc_resp
.status_code
);
1536 if (status
!= WLAN_STATUS_SUCCESS
)
1539 /* Stop previous accounting session, if one is started, and allocate
1540 * new session id for the new session. */
1541 accounting_sta_stop(hapd
, sta
);
1543 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1545 "associated (aid %d)",
1548 if (sta
->flags
& WLAN_STA_ASSOC
)
1550 sta
->flags
|= WLAN_STA_ASSOC
;
1551 if ((!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
) ||
1552 sta
->auth_alg
== WLAN_AUTH_FT
) {
1554 * Open, static WEP, or FT protocol; no separate authorization
1557 ap_sta_set_authorized(hapd
, sta
, 1);
1561 mlme_reassociate_indication(hapd
, sta
);
1563 mlme_associate_indication(hapd
, sta
);
1565 #ifdef CONFIG_IEEE80211W
1566 sta
->sa_query_timed_out
= 0;
1567 #endif /* CONFIG_IEEE80211W */
1570 * Remove the STA entry in order to make sure the STA PS state gets
1571 * cleared and configuration gets updated in case of reassociation back
1574 hostapd_drv_sta_remove(hapd
, sta
->addr
);
1576 #ifdef CONFIG_IEEE80211N
1577 if (sta
->flags
& WLAN_STA_HT
)
1578 hostapd_get_ht_capab(hapd
, sta
->ht_capabilities
, &ht_cap
);
1579 #endif /* CONFIG_IEEE80211N */
1581 if (hostapd_sta_add(hapd
, sta
->addr
, sta
->aid
, sta
->capability
,
1582 sta
->supported_rates
, sta
->supported_rates_len
,
1583 sta
->listen_interval
,
1584 sta
->flags
& WLAN_STA_HT
? &ht_cap
: NULL
,
1585 sta
->flags
, sta
->qosinfo
)) {
1586 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1587 HOSTAPD_LEVEL_NOTICE
,
1588 "Could not add STA to kernel driver");
1590 ap_sta_disconnect(hapd
, sta
, sta
->addr
,
1591 WLAN_REASON_DISASSOC_AP_BUSY
);
1596 if (sta
->flags
& WLAN_STA_WDS
)
1597 hostapd_set_wds_sta(hapd
, sta
->addr
, sta
->aid
, 1);
1599 if (sta
->eapol_sm
== NULL
) {
1601 * This STA does not use RADIUS server for EAP authentication,
1602 * so bind it to the selected VLAN interface now, since the
1603 * interface selection is not going to change anymore.
1605 if (ap_sta_bind_vlan(hapd
, sta
, 0) < 0)
1607 } else if (sta
->vlan_id
) {
1608 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
1609 if (ap_sta_bind_vlan(hapd
, sta
, 0) < 0)
1613 hostapd_set_sta_flags(hapd
, sta
);
1615 if (sta
->auth_alg
== WLAN_AUTH_FT
)
1616 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC_FT
);
1618 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
1619 hapd
->new_assoc_sta_cb(hapd
, sta
, !new_assoc
);
1621 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
1624 /* Copy of the association request is not needed anymore */
1625 if (sta
->last_assoc_req
) {
1626 os_free(sta
->last_assoc_req
);
1627 sta
->last_assoc_req
= NULL
;
1632 static void handle_deauth_cb(struct hostapd_data
*hapd
,
1633 const struct ieee80211_mgmt
*mgmt
,
1636 struct sta_info
*sta
;
1637 if (mgmt
->da
[0] & 0x01)
1639 sta
= ap_get_sta(hapd
, mgmt
->da
);
1641 wpa_printf(MSG_DEBUG
, "handle_deauth_cb: STA " MACSTR
1642 " not found", MAC2STR(mgmt
->da
));
1646 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged deauth",
1647 MAC2STR(sta
->addr
));
1649 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
1650 "deauth", MAC2STR(sta
->addr
));
1652 ap_sta_deauth_cb(hapd
, sta
);
1656 static void handle_disassoc_cb(struct hostapd_data
*hapd
,
1657 const struct ieee80211_mgmt
*mgmt
,
1660 struct sta_info
*sta
;
1661 if (mgmt
->da
[0] & 0x01)
1663 sta
= ap_get_sta(hapd
, mgmt
->da
);
1665 wpa_printf(MSG_DEBUG
, "handle_disassoc_cb: STA " MACSTR
1666 " not found", MAC2STR(mgmt
->da
));
1670 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged disassoc",
1671 MAC2STR(sta
->addr
));
1673 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
1674 "disassoc", MAC2STR(sta
->addr
));
1676 ap_sta_disassoc_cb(hapd
, sta
);
1681 * ieee802_11_mgmt_cb - Process management frame TX status callback
1682 * @hapd: hostapd BSS data structure (the BSS from which the management frame
1684 * @buf: management frame data (starting from IEEE 802.11 header)
1685 * @len: length of frame data in octets
1686 * @stype: management frame subtype from frame control field
1687 * @ok: Whether the frame was ACK'ed
1689 void ieee802_11_mgmt_cb(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
1692 const struct ieee80211_mgmt
*mgmt
;
1693 mgmt
= (const struct ieee80211_mgmt
*) buf
;
1696 case WLAN_FC_STYPE_AUTH
:
1697 wpa_printf(MSG_DEBUG
, "mgmt::auth cb");
1698 handle_auth_cb(hapd
, mgmt
, len
, ok
);
1700 case WLAN_FC_STYPE_ASSOC_RESP
:
1701 wpa_printf(MSG_DEBUG
, "mgmt::assoc_resp cb");
1702 handle_assoc_cb(hapd
, mgmt
, len
, 0, ok
);
1704 case WLAN_FC_STYPE_REASSOC_RESP
:
1705 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_resp cb");
1706 handle_assoc_cb(hapd
, mgmt
, len
, 1, ok
);
1708 case WLAN_FC_STYPE_PROBE_RESP
:
1709 wpa_printf(MSG_EXCESSIVE
, "mgmt::proberesp cb");
1711 case WLAN_FC_STYPE_DEAUTH
:
1712 wpa_printf(MSG_DEBUG
, "mgmt::deauth cb");
1713 handle_deauth_cb(hapd
, mgmt
, len
, ok
);
1715 case WLAN_FC_STYPE_DISASSOC
:
1716 wpa_printf(MSG_DEBUG
, "mgmt::disassoc cb");
1717 handle_disassoc_cb(hapd
, mgmt
, len
, ok
);
1719 case WLAN_FC_STYPE_ACTION
:
1720 wpa_printf(MSG_DEBUG
, "mgmt::action cb");
1723 printf("unknown mgmt cb frame subtype %d\n", stype
);
1729 int ieee802_11_get_mib(struct hostapd_data
*hapd
, char *buf
, size_t buflen
)
1736 int ieee802_11_get_mib_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1737 char *buf
, size_t buflen
)
1744 void hostapd_tx_status(struct hostapd_data
*hapd
, const u8
*addr
,
1745 const u8
*buf
, size_t len
, int ack
)
1747 struct sta_info
*sta
;
1748 struct hostapd_iface
*iface
= hapd
->iface
;
1750 sta
= ap_get_sta(hapd
, addr
);
1751 if (sta
== NULL
&& iface
->num_bss
> 1) {
1753 for (j
= 0; j
< iface
->num_bss
; j
++) {
1754 hapd
= iface
->bss
[j
];
1755 sta
= ap_get_sta(hapd
, addr
);
1760 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))
1762 if (sta
->flags
& WLAN_STA_PENDING_POLL
) {
1763 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" %s pending "
1764 "activity poll", MAC2STR(sta
->addr
),
1765 ack
? "ACKed" : "did not ACK");
1767 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
1770 ieee802_1x_tx_status(hapd
, sta
, buf
, len
, ack
);
1774 void hostapd_eapol_tx_status(struct hostapd_data
*hapd
, const u8
*dst
,
1775 const u8
*data
, size_t len
, int ack
)
1777 struct sta_info
*sta
;
1778 struct hostapd_iface
*iface
= hapd
->iface
;
1780 sta
= ap_get_sta(hapd
, dst
);
1781 if (sta
== NULL
&& iface
->num_bss
> 1) {
1783 for (j
= 0; j
< iface
->num_bss
; j
++) {
1784 hapd
= iface
->bss
[j
];
1785 sta
= ap_get_sta(hapd
, dst
);
1790 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
1791 wpa_printf(MSG_DEBUG
, "Ignore TX status for Data frame to STA "
1792 MACSTR
" that is not currently associated",
1797 ieee802_1x_eapol_tx_status(hapd
, sta
, data
, len
, ack
);
1801 void hostapd_client_poll_ok(struct hostapd_data
*hapd
, const u8
*addr
)
1803 struct sta_info
*sta
;
1804 struct hostapd_iface
*iface
= hapd
->iface
;
1806 sta
= ap_get_sta(hapd
, addr
);
1807 if (sta
== NULL
&& iface
->num_bss
> 1) {
1809 for (j
= 0; j
< iface
->num_bss
; j
++) {
1810 hapd
= iface
->bss
[j
];
1811 sta
= ap_get_sta(hapd
, addr
);
1818 if (!(sta
->flags
& WLAN_STA_PENDING_POLL
))
1821 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" ACKed pending "
1822 "activity poll", MAC2STR(sta
->addr
));
1823 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
1827 void ieee802_11_rx_from_unknown(struct hostapd_data
*hapd
, const u8
*src
,
1830 struct sta_info
*sta
;
1832 sta
= ap_get_sta(hapd
, src
);
1833 if (sta
&& (sta
->flags
& WLAN_STA_ASSOC
)) {
1834 if (!hapd
->conf
->wds_sta
)
1837 if (wds
&& !(sta
->flags
& WLAN_STA_WDS
)) {
1838 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for "
1839 "STA " MACSTR
" (aid %u)",
1840 MAC2STR(sta
->addr
), sta
->aid
);
1841 sta
->flags
|= WLAN_STA_WDS
;
1842 hostapd_set_wds_sta(hapd
, sta
->addr
, sta
->aid
, 1);
1847 wpa_printf(MSG_DEBUG
, "Data/PS-poll frame from not associated STA "
1848 MACSTR
, MAC2STR(src
));
1849 if (src
[0] & 0x01) {
1850 /* Broadcast bit set in SA?! Ignore the frame silently. */
1854 if (sta
&& (sta
->flags
& WLAN_STA_ASSOC_REQ_OK
)) {
1855 wpa_printf(MSG_DEBUG
, "Association Response to the STA has "
1856 "already been sent, but no TX status yet known - "
1857 "ignore Class 3 frame issue with " MACSTR
,
1862 if (sta
&& (sta
->flags
& WLAN_STA_AUTH
))
1863 hostapd_drv_sta_disassoc(
1865 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
1867 hostapd_drv_sta_deauth(
1869 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
1873 #endif /* CONFIG_NATIVE_WINDOWS */