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 */
300 static void handle_auth_sae(struct hostapd_data
*hapd
, struct sta_info
*sta
,
301 const struct ieee80211_mgmt
*mgmt
, size_t len
,
304 u16 resp
= WLAN_STATUS_SUCCESS
;
305 u8
*data
= (u8
*) "TEST"; /* TODO */
308 if (auth_transaction
== 1) {
309 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
311 "start SAE authentication (RX commit)");
312 sta
->sae_state
= SAE_COMMIT
;
313 } else if (auth_transaction
== 2) {
314 if (sta
->sae_state
!= SAE_COMMIT
) {
315 hostapd_logger(hapd
, sta
->addr
,
316 HOSTAPD_MODULE_IEEE80211
,
318 "SAE confirm before commit");
319 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
321 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
323 "SAE authentication (RX confirm)");
324 sta
->flags
|= WLAN_STA_AUTH
;
325 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
326 sta
->auth_alg
= WLAN_AUTH_SAE
;
327 mlme_authenticate_indication(hapd
, sta
);
329 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
331 "unexpected SAE authentication transaction %u",
333 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
336 sta
->auth_alg
= WLAN_AUTH_SAE
;
338 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
339 auth_transaction
, resp
, data
, data_len
);
341 #endif /* CONFIG_SAE */
344 static void handle_auth(struct hostapd_data
*hapd
,
345 const struct ieee80211_mgmt
*mgmt
, size_t len
)
347 u16 auth_alg
, auth_transaction
, status_code
;
348 u16 resp
= WLAN_STATUS_SUCCESS
;
349 struct sta_info
*sta
= NULL
;
352 const u8
*challenge
= NULL
;
353 u32 session_timeout
, acct_interim_interval
;
357 u8 resp_ies
[2 + WLAN_AUTH_CHALLENGE_LEN
];
358 size_t resp_ies_len
= 0;
359 char *identity
= NULL
;
360 char *radius_cui
= NULL
;
362 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
363 printf("handle_auth - too short payload (len=%lu)\n",
364 (unsigned long) len
);
368 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
369 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
370 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
371 fc
= le_to_host16(mgmt
->frame_control
);
373 if (len
>= IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
) +
374 2 + WLAN_AUTH_CHALLENGE_LEN
&&
375 mgmt
->u
.auth
.variable
[0] == WLAN_EID_CHALLENGE
&&
376 mgmt
->u
.auth
.variable
[1] == WLAN_AUTH_CHALLENGE_LEN
)
377 challenge
= &mgmt
->u
.auth
.variable
[2];
379 wpa_printf(MSG_DEBUG
, "authentication: STA=" MACSTR
" auth_alg=%d "
380 "auth_transaction=%d status_code=%d wep=%d%s",
381 MAC2STR(mgmt
->sa
), auth_alg
, auth_transaction
,
382 status_code
, !!(fc
& WLAN_FC_ISWEP
),
383 challenge
? " challenge" : "");
385 if (hapd
->tkip_countermeasures
) {
386 resp
= WLAN_REASON_MICHAEL_MIC_FAILURE
;
390 if (!(((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_OPEN
) &&
391 auth_alg
== WLAN_AUTH_OPEN
) ||
392 #ifdef CONFIG_IEEE80211R
393 (hapd
->conf
->wpa
&& wpa_key_mgmt_ft(hapd
->conf
->wpa_key_mgmt
) &&
394 auth_alg
== WLAN_AUTH_FT
) ||
395 #endif /* CONFIG_IEEE80211R */
397 (hapd
->conf
->wpa
&& wpa_key_mgmt_sae(hapd
->conf
->wpa_key_mgmt
) &&
398 auth_alg
== WLAN_AUTH_SAE
) ||
399 #endif /* CONFIG_SAE */
400 ((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_SHARED
) &&
401 auth_alg
== WLAN_AUTH_SHARED_KEY
))) {
402 printf("Unsupported authentication algorithm (%d)\n",
404 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
408 if (!(auth_transaction
== 1 || auth_alg
== WLAN_AUTH_SAE
||
409 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 3))) {
410 printf("Unknown authentication transaction number (%d)\n",
412 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
416 if (os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
417 printf("Station " MACSTR
" not allowed to authenticate.\n",
419 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
423 res
= hostapd_allowed_address(hapd
, mgmt
->sa
, (u8
*) mgmt
, len
,
425 &acct_interim_interval
, &vlan_id
,
426 psk
, &has_psk
, &identity
, &radius_cui
);
428 if (res
== HOSTAPD_ACL_REJECT
) {
429 printf("Station " MACSTR
" not allowed to authenticate.\n",
431 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
434 if (res
== HOSTAPD_ACL_PENDING
) {
435 wpa_printf(MSG_DEBUG
, "Authentication frame from " MACSTR
436 " waiting for an external authentication",
438 /* Authentication code will re-send the authentication frame
439 * after it has received (and cached) information from the
440 * external source. */
444 sta
= ap_sta_add(hapd
, mgmt
->sa
);
446 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
451 if (hostapd_get_vlan_id_ifname(hapd
->conf
->vlan
,
453 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
454 HOSTAPD_LEVEL_INFO
, "Invalid VLAN ID "
455 "%d received from RADIUS server",
457 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
460 sta
->vlan_id
= vlan_id
;
461 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
462 HOSTAPD_LEVEL_INFO
, "VLAN ID %d", sta
->vlan_id
);
465 if (has_psk
&& hapd
->conf
->wpa_psk_radius
!= PSK_RADIUS_IGNORED
) {
467 sta
->psk
= os_malloc(PMK_LEN
);
469 os_memcpy(sta
->psk
, psk
, PMK_LEN
);
475 sta
->identity
= identity
;
477 sta
->radius_cui
= radius_cui
;
480 sta
->flags
&= ~WLAN_STA_PREAUTH
;
481 ieee802_1x_notify_pre_auth(sta
->eapol_sm
, 0);
483 if (hapd
->conf
->acct_interim_interval
== 0 && acct_interim_interval
)
484 sta
->acct_interim_interval
= acct_interim_interval
;
485 if (res
== HOSTAPD_ACL_ACCEPT_TIMEOUT
)
486 ap_sta_session_timeout(hapd
, sta
, session_timeout
);
488 ap_sta_no_session_timeout(hapd
, sta
);
492 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
494 "authentication OK (open system)");
495 #ifdef IEEE80211_REQUIRE_AUTH_ACK
496 /* Station will be marked authenticated if it ACKs the
497 * authentication reply. */
499 sta
->flags
|= WLAN_STA_AUTH
;
500 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
501 sta
->auth_alg
= WLAN_AUTH_OPEN
;
502 mlme_authenticate_indication(hapd
, sta
);
505 case WLAN_AUTH_SHARED_KEY
:
506 resp
= auth_shared_key(hapd
, sta
, auth_transaction
, challenge
,
508 sta
->auth_alg
= WLAN_AUTH_SHARED_KEY
;
509 mlme_authenticate_indication(hapd
, sta
);
510 if (sta
->challenge
&& auth_transaction
== 1) {
511 resp_ies
[0] = WLAN_EID_CHALLENGE
;
512 resp_ies
[1] = WLAN_AUTH_CHALLENGE_LEN
;
513 os_memcpy(resp_ies
+ 2, sta
->challenge
,
514 WLAN_AUTH_CHALLENGE_LEN
);
515 resp_ies_len
= 2 + WLAN_AUTH_CHALLENGE_LEN
;
518 #ifdef CONFIG_IEEE80211R
520 sta
->auth_alg
= WLAN_AUTH_FT
;
521 if (sta
->wpa_sm
== NULL
)
522 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
524 if (sta
->wpa_sm
== NULL
) {
525 wpa_printf(MSG_DEBUG
, "FT: Failed to initialize WPA "
527 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
530 wpa_ft_process_auth(sta
->wpa_sm
, mgmt
->bssid
,
531 auth_transaction
, mgmt
->u
.auth
.variable
,
532 len
- IEEE80211_HDRLEN
-
533 sizeof(mgmt
->u
.auth
),
534 handle_auth_ft_finish
, hapd
);
535 /* handle_auth_ft_finish() callback will complete auth. */
537 #endif /* CONFIG_IEEE80211R */
540 handle_auth_sae(hapd
, sta
, mgmt
, len
, auth_transaction
);
542 #endif /* CONFIG_SAE */
549 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, auth_alg
,
550 auth_transaction
+ 1, resp
, resp_ies
, resp_ies_len
);
554 static int hostapd_get_aid(struct hostapd_data
*hapd
, struct sta_info
*sta
)
558 /* get a unique AID */
560 wpa_printf(MSG_DEBUG
, " old AID %d", sta
->aid
);
564 for (i
= 0; i
< AID_WORDS
; i
++) {
565 if (hapd
->sta_aid
[i
] == (u32
) -1)
567 for (j
= 0; j
< 32; j
++) {
568 if (!(hapd
->sta_aid
[i
] & BIT(j
)))
576 aid
= i
* 32 + j
+ 1;
581 hapd
->sta_aid
[i
] |= BIT(j
);
582 wpa_printf(MSG_DEBUG
, " new AID %d", sta
->aid
);
587 static u16
check_ssid(struct hostapd_data
*hapd
, struct sta_info
*sta
,
588 const u8
*ssid_ie
, size_t ssid_ie_len
)
591 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
593 if (ssid_ie_len
!= hapd
->conf
->ssid
.ssid_len
||
594 os_memcmp(ssid_ie
, hapd
->conf
->ssid
.ssid
, ssid_ie_len
) != 0) {
596 ieee802_11_print_ssid(ssid_txt
, ssid_ie
, ssid_ie_len
);
597 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
599 "Station tried to associate with unknown SSID "
601 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
604 return WLAN_STATUS_SUCCESS
;
608 static u16
check_wmm(struct hostapd_data
*hapd
, struct sta_info
*sta
,
609 const u8
*wmm_ie
, size_t wmm_ie_len
)
611 sta
->flags
&= ~WLAN_STA_WMM
;
613 if (wmm_ie
&& hapd
->conf
->wmm_enabled
) {
614 struct wmm_information_element
*wmm
;
616 if (!hostapd_eid_wmm_valid(hapd
, wmm_ie
, wmm_ie_len
)) {
617 hostapd_logger(hapd
, sta
->addr
,
620 "invalid WMM element in association "
622 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
625 sta
->flags
|= WLAN_STA_WMM
;
626 wmm
= (struct wmm_information_element
*) wmm_ie
;
627 sta
->qosinfo
= wmm
->qos_info
;
629 return WLAN_STATUS_SUCCESS
;
633 static u16
copy_supp_rates(struct hostapd_data
*hapd
, struct sta_info
*sta
,
634 struct ieee802_11_elems
*elems
)
636 if (!elems
->supp_rates
) {
637 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
639 "No supported rates element in AssocReq");
640 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
643 if (elems
->supp_rates_len
+ elems
->ext_supp_rates_len
>
644 sizeof(sta
->supported_rates
)) {
645 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
647 "Invalid supported rates element length %d+%d",
648 elems
->supp_rates_len
,
649 elems
->ext_supp_rates_len
);
650 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
653 sta
->supported_rates_len
= merge_byte_arrays(
654 sta
->supported_rates
, sizeof(sta
->supported_rates
),
655 elems
->supp_rates
, elems
->supp_rates_len
,
656 elems
->ext_supp_rates
, elems
->ext_supp_rates_len
);
658 return WLAN_STATUS_SUCCESS
;
662 static u16
check_assoc_ies(struct hostapd_data
*hapd
, struct sta_info
*sta
,
663 const u8
*ies
, size_t ies_len
, int reassoc
)
665 struct ieee802_11_elems elems
;
670 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 1) == ParseFailed
) {
671 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
672 HOSTAPD_LEVEL_INFO
, "Station sent an invalid "
673 "association request");
674 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
677 resp
= check_ssid(hapd
, sta
, elems
.ssid
, elems
.ssid_len
);
678 if (resp
!= WLAN_STATUS_SUCCESS
)
680 resp
= check_wmm(hapd
, sta
, elems
.wmm
, elems
.wmm_len
);
681 if (resp
!= WLAN_STATUS_SUCCESS
)
683 resp
= copy_supp_rates(hapd
, sta
, &elems
);
684 if (resp
!= WLAN_STATUS_SUCCESS
)
686 #ifdef CONFIG_IEEE80211N
687 resp
= copy_sta_ht_capab(hapd
, sta
, elems
.ht_capabilities
,
688 elems
.ht_capabilities_len
);
689 if (resp
!= WLAN_STATUS_SUCCESS
)
691 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&&
692 !(sta
->flags
& WLAN_STA_HT
)) {
693 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
694 HOSTAPD_LEVEL_INFO
, "Station does not support "
695 "mandatory HT PHY - reject association");
696 return WLAN_STATUS_ASSOC_DENIED_NO_HT
;
698 #endif /* CONFIG_IEEE80211N */
700 #ifdef CONFIG_IEEE80211AC
701 resp
= copy_sta_vht_capab(hapd
, sta
, elems
.vht_capabilities
,
702 elems
.vht_capabilities_len
);
703 if (resp
!= WLAN_STATUS_SUCCESS
)
705 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&&
706 !(sta
->flags
& WLAN_STA_VHT
)) {
707 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
708 HOSTAPD_LEVEL_INFO
, "Station does not support "
709 "mandatory VHT PHY - reject association");
710 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
712 #endif /* CONFIG_IEEE80211AC */
714 if ((hapd
->conf
->wpa
& WPA_PROTO_RSN
) && elems
.rsn_ie
) {
715 wpa_ie
= elems
.rsn_ie
;
716 wpa_ie_len
= elems
.rsn_ie_len
;
717 } else if ((hapd
->conf
->wpa
& WPA_PROTO_WPA
) &&
719 wpa_ie
= elems
.wpa_ie
;
720 wpa_ie_len
= elems
.wpa_ie_len
;
727 sta
->flags
&= ~(WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
| WLAN_STA_WPS2
);
728 if (hapd
->conf
->wps_state
&& elems
.wps_ie
) {
729 wpa_printf(MSG_DEBUG
, "STA included WPS IE in (Re)Association "
730 "Request - assume WPS is used");
731 sta
->flags
|= WLAN_STA_WPS
;
732 wpabuf_free(sta
->wps_ie
);
733 sta
->wps_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
735 if (sta
->wps_ie
&& wps_is_20(sta
->wps_ie
)) {
736 wpa_printf(MSG_DEBUG
, "WPS: STA supports WPS 2.0");
737 sta
->flags
|= WLAN_STA_WPS2
;
741 if (sta
->wps_ie
&& wps_validate_assoc_req(sta
->wps_ie
) < 0) {
742 wpa_printf(MSG_DEBUG
, "WPS: Invalid WPS IE in "
743 "(Re)Association Request - reject");
744 return WLAN_STATUS_INVALID_IE
;
746 } else if (hapd
->conf
->wps_state
&& wpa_ie
== NULL
) {
747 wpa_printf(MSG_DEBUG
, "STA did not include WPA/RSN IE in "
748 "(Re)Association Request - possible WPS use");
749 sta
->flags
|= WLAN_STA_MAYBE_WPS
;
751 #endif /* CONFIG_WPS */
752 if (hapd
->conf
->wpa
&& wpa_ie
== NULL
) {
753 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
755 "No WPA/RSN IE in association request");
756 return WLAN_STATUS_INVALID_IE
;
759 if (hapd
->conf
->wpa
&& wpa_ie
) {
763 if (sta
->wpa_sm
== NULL
)
764 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
766 if (sta
->wpa_sm
== NULL
) {
767 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
769 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
771 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
773 elems
.mdie
, elems
.mdie_len
);
774 if (res
== WPA_INVALID_GROUP
)
775 resp
= WLAN_STATUS_GROUP_CIPHER_NOT_VALID
;
776 else if (res
== WPA_INVALID_PAIRWISE
)
777 resp
= WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID
;
778 else if (res
== WPA_INVALID_AKMP
)
779 resp
= WLAN_STATUS_AKMP_NOT_VALID
;
780 else if (res
== WPA_ALLOC_FAIL
)
781 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
782 #ifdef CONFIG_IEEE80211W
783 else if (res
== WPA_MGMT_FRAME_PROTECTION_VIOLATION
)
784 resp
= WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
785 else if (res
== WPA_INVALID_MGMT_GROUP_CIPHER
)
786 resp
= WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
787 #endif /* CONFIG_IEEE80211W */
788 else if (res
== WPA_INVALID_MDIE
)
789 resp
= WLAN_STATUS_INVALID_MDIE
;
790 else if (res
!= WPA_IE_OK
)
791 resp
= WLAN_STATUS_INVALID_IE
;
792 if (resp
!= WLAN_STATUS_SUCCESS
)
794 #ifdef CONFIG_IEEE80211W
795 if ((sta
->flags
& WLAN_STA_MFP
) && !sta
->sa_query_timed_out
&&
796 sta
->sa_query_count
> 0)
797 ap_check_sa_query_timeout(hapd
, sta
);
798 if ((sta
->flags
& WLAN_STA_MFP
) && !sta
->sa_query_timed_out
&&
799 (!reassoc
|| sta
->auth_alg
!= WLAN_AUTH_FT
)) {
801 * STA has already been associated with MFP and SA
802 * Query timeout has not been reached. Reject the
803 * association attempt temporarily and start SA Query,
804 * if one is not pending.
807 if (sta
->sa_query_count
== 0)
808 ap_sta_start_sa_query(hapd
, sta
);
810 return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
;
813 if (wpa_auth_uses_mfp(sta
->wpa_sm
))
814 sta
->flags
|= WLAN_STA_MFP
;
816 sta
->flags
&= ~WLAN_STA_MFP
;
817 #endif /* CONFIG_IEEE80211W */
819 #ifdef CONFIG_IEEE80211R
820 if (sta
->auth_alg
== WLAN_AUTH_FT
) {
822 wpa_printf(MSG_DEBUG
, "FT: " MACSTR
" tried "
823 "to use association (not "
824 "re-association) with FT auth_alg",
826 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
829 resp
= wpa_ft_validate_reassoc(sta
->wpa_sm
, ies
,
831 if (resp
!= WLAN_STATUS_SUCCESS
)
834 #endif /* CONFIG_IEEE80211R */
837 if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
838 sta
->auth_alg
!= WLAN_AUTH_SAE
) {
839 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
" tried to use "
840 "SAE AKM after non-SAE auth_alg %u",
841 MAC2STR(sta
->addr
), sta
->auth_alg
);
842 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
844 #endif /* CONFIG_SAE */
846 #ifdef CONFIG_IEEE80211N
847 if ((sta
->flags
& (WLAN_STA_HT
| WLAN_STA_VHT
)) &&
848 wpa_auth_get_pairwise(sta
->wpa_sm
) == WPA_CIPHER_TKIP
) {
849 hostapd_logger(hapd
, sta
->addr
,
850 HOSTAPD_MODULE_IEEE80211
,
852 "Station tried to use TKIP with HT "
854 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
856 #endif /* CONFIG_IEEE80211N */
858 wpa_auth_sta_no_wpa(sta
->wpa_sm
);
862 wpabuf_free(sta
->p2p_ie
);
863 sta
->p2p_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
867 wpabuf_free(sta
->p2p_ie
);
871 p2p_group_notif_assoc(hapd
->p2p_group
, sta
->addr
, ies
, ies_len
);
872 #endif /* CONFIG_P2P */
874 return WLAN_STATUS_SUCCESS
;
878 static void send_deauth(struct hostapd_data
*hapd
, const u8
*addr
,
882 struct ieee80211_mgmt reply
;
884 os_memset(&reply
, 0, sizeof(reply
));
885 reply
.frame_control
=
886 IEEE80211_FC(WLAN_FC_TYPE_MGMT
, WLAN_FC_STYPE_DEAUTH
);
887 os_memcpy(reply
.da
, addr
, ETH_ALEN
);
888 os_memcpy(reply
.sa
, hapd
->own_addr
, ETH_ALEN
);
889 os_memcpy(reply
.bssid
, hapd
->own_addr
, ETH_ALEN
);
891 send_len
= IEEE80211_HDRLEN
+ sizeof(reply
.u
.deauth
);
892 reply
.u
.deauth
.reason_code
= host_to_le16(reason_code
);
894 if (hostapd_drv_send_mlme(hapd
, &reply
, send_len
, 0) < 0)
895 wpa_printf(MSG_INFO
, "Failed to send deauth: %s",
900 static void send_assoc_resp(struct hostapd_data
*hapd
, struct sta_info
*sta
,
901 u16 status_code
, int reassoc
, const u8
*ies
,
905 u8 buf
[sizeof(struct ieee80211_mgmt
) + 1024];
906 struct ieee80211_mgmt
*reply
;
909 os_memset(buf
, 0, sizeof(buf
));
910 reply
= (struct ieee80211_mgmt
*) buf
;
911 reply
->frame_control
=
912 IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
913 (reassoc
? WLAN_FC_STYPE_REASSOC_RESP
:
914 WLAN_FC_STYPE_ASSOC_RESP
));
915 os_memcpy(reply
->da
, sta
->addr
, ETH_ALEN
);
916 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
917 os_memcpy(reply
->bssid
, hapd
->own_addr
, ETH_ALEN
);
919 send_len
= IEEE80211_HDRLEN
;
920 send_len
+= sizeof(reply
->u
.assoc_resp
);
921 reply
->u
.assoc_resp
.capab_info
=
922 host_to_le16(hostapd_own_capab_info(hapd
, sta
, 0));
923 reply
->u
.assoc_resp
.status_code
= host_to_le16(status_code
);
924 reply
->u
.assoc_resp
.aid
= host_to_le16((sta
? sta
->aid
: 0)
925 | BIT(14) | BIT(15));
926 /* Supported rates */
927 p
= hostapd_eid_supp_rates(hapd
, reply
->u
.assoc_resp
.variable
);
928 /* Extended supported rates */
929 p
= hostapd_eid_ext_supp_rates(hapd
, p
);
931 #ifdef CONFIG_IEEE80211R
932 if (status_code
== WLAN_STATUS_SUCCESS
) {
933 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
934 * Transition Information, RSN, [RIC Response] */
935 p
= wpa_sm_write_assoc_resp_ies(sta
->wpa_sm
, p
,
936 buf
+ sizeof(buf
) - p
,
937 sta
->auth_alg
, ies
, ies_len
);
939 #endif /* CONFIG_IEEE80211R */
941 #ifdef CONFIG_IEEE80211W
942 if (status_code
== WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
)
943 p
= hostapd_eid_assoc_comeback_time(hapd
, sta
, p
);
944 #endif /* CONFIG_IEEE80211W */
946 #ifdef CONFIG_IEEE80211N
947 p
= hostapd_eid_ht_capabilities(hapd
, p
);
948 p
= hostapd_eid_ht_operation(hapd
, p
);
949 #endif /* CONFIG_IEEE80211N */
951 #ifdef CONFIG_IEEE80211AC
952 p
= hostapd_eid_vht_capabilities(hapd
, p
);
953 p
= hostapd_eid_vht_operation(hapd
, p
);
954 #endif /* CONFIG_IEEE80211AC */
956 p
= hostapd_eid_ext_capab(hapd
, p
);
957 p
= hostapd_eid_bss_max_idle_period(hapd
, p
);
959 if (sta
->flags
& WLAN_STA_WMM
)
960 p
= hostapd_eid_wmm(hapd
, p
);
963 if ((sta
->flags
& WLAN_STA_WPS
) ||
964 ((sta
->flags
& WLAN_STA_MAYBE_WPS
) && hapd
->conf
->wpa
)) {
965 struct wpabuf
*wps
= wps_build_assoc_resp_ie();
967 os_memcpy(p
, wpabuf_head(wps
), wpabuf_len(wps
));
968 p
+= wpabuf_len(wps
);
972 #endif /* CONFIG_WPS */
976 struct wpabuf
*p2p_resp_ie
;
977 enum p2p_status_code status
;
978 switch (status_code
) {
979 case WLAN_STATUS_SUCCESS
:
980 status
= P2P_SC_SUCCESS
;
982 case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
:
983 status
= P2P_SC_FAIL_LIMIT_REACHED
;
986 status
= P2P_SC_FAIL_INVALID_PARAMS
;
989 p2p_resp_ie
= p2p_group_assoc_resp_ie(hapd
->p2p_group
, status
);
991 os_memcpy(p
, wpabuf_head(p2p_resp_ie
),
992 wpabuf_len(p2p_resp_ie
));
993 p
+= wpabuf_len(p2p_resp_ie
);
994 wpabuf_free(p2p_resp_ie
);
997 #endif /* CONFIG_P2P */
999 #ifdef CONFIG_P2P_MANAGER
1000 if (hapd
->conf
->p2p
& P2P_MANAGE
)
1001 p
= hostapd_eid_p2p_manage(hapd
, p
);
1002 #endif /* CONFIG_P2P_MANAGER */
1004 send_len
+= p
- reply
->u
.assoc_resp
.variable
;
1006 if (hostapd_drv_send_mlme(hapd
, reply
, send_len
, 0) < 0)
1007 wpa_printf(MSG_INFO
, "Failed to send assoc resp: %s",
1012 static void handle_assoc(struct hostapd_data
*hapd
,
1013 const struct ieee80211_mgmt
*mgmt
, size_t len
,
1016 u16 capab_info
, listen_interval
;
1017 u16 resp
= WLAN_STATUS_SUCCESS
;
1020 struct sta_info
*sta
;
1022 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_req
) :
1023 sizeof(mgmt
->u
.assoc_req
))) {
1024 printf("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
1025 "\n", reassoc
, (unsigned long) len
);
1030 capab_info
= le_to_host16(mgmt
->u
.reassoc_req
.capab_info
);
1031 listen_interval
= le_to_host16(
1032 mgmt
->u
.reassoc_req
.listen_interval
);
1033 wpa_printf(MSG_DEBUG
, "reassociation request: STA=" MACSTR
1034 " capab_info=0x%02x listen_interval=%d current_ap="
1036 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
1037 MAC2STR(mgmt
->u
.reassoc_req
.current_ap
));
1038 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.reassoc_req
));
1039 pos
= mgmt
->u
.reassoc_req
.variable
;
1041 capab_info
= le_to_host16(mgmt
->u
.assoc_req
.capab_info
);
1042 listen_interval
= le_to_host16(
1043 mgmt
->u
.assoc_req
.listen_interval
);
1044 wpa_printf(MSG_DEBUG
, "association request: STA=" MACSTR
1045 " capab_info=0x%02x listen_interval=%d",
1046 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
);
1047 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.assoc_req
));
1048 pos
= mgmt
->u
.assoc_req
.variable
;
1051 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1052 #ifdef CONFIG_IEEE80211R
1053 if (sta
&& sta
->auth_alg
== WLAN_AUTH_FT
&&
1054 (sta
->flags
& WLAN_STA_AUTH
) == 0) {
1055 wpa_printf(MSG_DEBUG
, "FT: Allow STA " MACSTR
" to associate "
1056 "prior to authentication since it is using "
1057 "over-the-DS FT", MAC2STR(mgmt
->sa
));
1059 #endif /* CONFIG_IEEE80211R */
1060 if (sta
== NULL
|| (sta
->flags
& WLAN_STA_AUTH
) == 0) {
1061 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1062 HOSTAPD_LEVEL_INFO
, "Station tried to "
1063 "associate before authentication "
1064 "(aid=%d flags=0x%x)",
1065 sta
? sta
->aid
: -1,
1066 sta
? sta
->flags
: 0);
1067 send_deauth(hapd
, mgmt
->sa
,
1068 WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA
);
1072 if (hapd
->tkip_countermeasures
) {
1073 resp
= WLAN_REASON_MICHAEL_MIC_FAILURE
;
1077 if (listen_interval
> hapd
->conf
->max_listen_interval
) {
1078 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1079 HOSTAPD_LEVEL_DEBUG
,
1080 "Too large Listen Interval (%d)",
1082 resp
= WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE
;
1086 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
1088 resp
= check_assoc_ies(hapd
, sta
, pos
, left
, reassoc
);
1089 if (resp
!= WLAN_STATUS_SUCCESS
)
1092 if (hostapd_get_aid(hapd
, sta
) < 0) {
1093 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1094 HOSTAPD_LEVEL_INFO
, "No room for more AIDs");
1095 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
1099 sta
->capability
= capab_info
;
1100 sta
->listen_interval
= listen_interval
;
1102 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
1103 sta
->flags
|= WLAN_STA_NONERP
;
1104 for (i
= 0; i
< sta
->supported_rates_len
; i
++) {
1105 if ((sta
->supported_rates
[i
] & 0x7f) > 22) {
1106 sta
->flags
&= ~WLAN_STA_NONERP
;
1110 if (sta
->flags
& WLAN_STA_NONERP
&& !sta
->nonerp_set
) {
1111 sta
->nonerp_set
= 1;
1112 hapd
->iface
->num_sta_non_erp
++;
1113 if (hapd
->iface
->num_sta_non_erp
== 1)
1114 ieee802_11_set_beacons(hapd
->iface
);
1117 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
) &&
1118 !sta
->no_short_slot_time_set
) {
1119 sta
->no_short_slot_time_set
= 1;
1120 hapd
->iface
->num_sta_no_short_slot_time
++;
1121 if (hapd
->iface
->current_mode
->mode
==
1122 HOSTAPD_MODE_IEEE80211G
&&
1123 hapd
->iface
->num_sta_no_short_slot_time
== 1)
1124 ieee802_11_set_beacons(hapd
->iface
);
1127 if (sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
1128 sta
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
1130 sta
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
1132 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
) &&
1133 !sta
->no_short_preamble_set
) {
1134 sta
->no_short_preamble_set
= 1;
1135 hapd
->iface
->num_sta_no_short_preamble
++;
1136 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
1137 && hapd
->iface
->num_sta_no_short_preamble
== 1)
1138 ieee802_11_set_beacons(hapd
->iface
);
1141 #ifdef CONFIG_IEEE80211N
1142 update_ht_state(hapd
, sta
);
1143 #endif /* CONFIG_IEEE80211N */
1145 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1146 HOSTAPD_LEVEL_DEBUG
,
1147 "association OK (aid %d)", sta
->aid
);
1148 /* Station will be marked associated, after it acknowledges AssocResp
1150 sta
->flags
|= WLAN_STA_ASSOC_REQ_OK
;
1152 #ifdef CONFIG_IEEE80211W
1153 if ((sta
->flags
& WLAN_STA_MFP
) && sta
->sa_query_timed_out
) {
1154 wpa_printf(MSG_DEBUG
, "Allowing %sassociation after timed out "
1155 "SA Query procedure", reassoc
? "re" : "");
1156 /* TODO: Send a protected Disassociate frame to the STA using
1157 * the old key and Reason Code "Previous Authentication no
1158 * longer valid". Make sure this is only sent protected since
1159 * unprotected frame would be received by the STA that is now
1160 * trying to associate.
1163 #endif /* CONFIG_IEEE80211W */
1166 os_memcpy(sta
->previous_ap
, mgmt
->u
.reassoc_req
.current_ap
,
1170 if (sta
->last_assoc_req
)
1171 os_free(sta
->last_assoc_req
);
1172 sta
->last_assoc_req
= os_malloc(len
);
1173 if (sta
->last_assoc_req
)
1174 os_memcpy(sta
->last_assoc_req
, mgmt
, len
);
1176 /* Make sure that the previously registered inactivity timer will not
1177 * remove the STA immediately. */
1178 sta
->timeout_next
= STA_NULLFUNC
;
1181 send_assoc_resp(hapd
, sta
, resp
, reassoc
, pos
, left
);
1185 static void handle_disassoc(struct hostapd_data
*hapd
,
1186 const struct ieee80211_mgmt
*mgmt
, size_t len
)
1188 struct sta_info
*sta
;
1190 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.disassoc
)) {
1191 printf("handle_disassoc - too short payload (len=%lu)\n",
1192 (unsigned long) len
);
1196 wpa_printf(MSG_DEBUG
, "disassocation: STA=" MACSTR
" reason_code=%d",
1198 le_to_host16(mgmt
->u
.disassoc
.reason_code
));
1200 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1202 printf("Station " MACSTR
" trying to disassociate, but it "
1203 "is not associated.\n", MAC2STR(mgmt
->sa
));
1207 ap_sta_set_authorized(hapd
, sta
, 0);
1208 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
);
1209 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
1210 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1211 HOSTAPD_LEVEL_INFO
, "disassociated");
1212 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
1213 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
1214 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
1216 accounting_sta_stop(hapd
, sta
);
1217 ieee802_1x_free_station(sta
);
1218 hostapd_drv_sta_remove(hapd
, sta
->addr
);
1220 if (sta
->timeout_next
== STA_NULLFUNC
||
1221 sta
->timeout_next
== STA_DISASSOC
) {
1222 sta
->timeout_next
= STA_DEAUTH
;
1223 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
1224 eloop_register_timeout(AP_DEAUTH_DELAY
, 0, ap_handle_timer
,
1228 mlme_disassociate_indication(
1229 hapd
, sta
, le_to_host16(mgmt
->u
.disassoc
.reason_code
));
1233 static void handle_deauth(struct hostapd_data
*hapd
,
1234 const struct ieee80211_mgmt
*mgmt
, size_t len
)
1236 struct sta_info
*sta
;
1238 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.deauth
)) {
1239 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "handle_deauth - too short "
1240 "payload (len=%lu)", (unsigned long) len
);
1244 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "deauthentication: STA=" MACSTR
1246 MAC2STR(mgmt
->sa
), le_to_host16(mgmt
->u
.deauth
.reason_code
));
1248 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1250 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "Station " MACSTR
" trying "
1251 "to deauthenticate, but it is not authenticated",
1256 ap_sta_set_authorized(hapd
, sta
, 0);
1257 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
|
1258 WLAN_STA_ASSOC_REQ_OK
);
1259 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
1260 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1261 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
1262 mlme_deauthenticate_indication(
1263 hapd
, sta
, le_to_host16(mgmt
->u
.deauth
.reason_code
));
1264 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
1265 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
1266 ap_free_sta(hapd
, sta
);
1270 static void handle_beacon(struct hostapd_data
*hapd
,
1271 const struct ieee80211_mgmt
*mgmt
, size_t len
,
1272 struct hostapd_frame_info
*fi
)
1274 struct ieee802_11_elems elems
;
1276 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.beacon
)) {
1277 printf("handle_beacon - too short payload (len=%lu)\n",
1278 (unsigned long) len
);
1282 (void) ieee802_11_parse_elems(mgmt
->u
.beacon
.variable
,
1283 len
- (IEEE80211_HDRLEN
+
1284 sizeof(mgmt
->u
.beacon
)), &elems
,
1287 ap_list_process_beacon(hapd
->iface
, mgmt
, &elems
, fi
);
1291 #ifdef CONFIG_IEEE80211W
1293 static void hostapd_sa_query_action(struct hostapd_data
*hapd
,
1294 const struct ieee80211_mgmt
*mgmt
,
1299 end
= mgmt
->u
.action
.u
.sa_query_resp
.trans_id
+
1300 WLAN_SA_QUERY_TR_ID_LEN
;
1301 if (((u8
*) mgmt
) + len
< end
) {
1302 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Too short SA Query Action "
1303 "frame (len=%lu)", (unsigned long) len
);
1307 ieee802_11_sa_query_action(hapd
, mgmt
->sa
,
1308 mgmt
->u
.action
.u
.sa_query_resp
.action
,
1309 mgmt
->u
.action
.u
.sa_query_resp
.trans_id
);
1313 static int robust_action_frame(u8 category
)
1315 return category
!= WLAN_ACTION_PUBLIC
&&
1316 category
!= WLAN_ACTION_HT
;
1318 #endif /* CONFIG_IEEE80211W */
1321 static void handle_action(struct hostapd_data
*hapd
,
1322 const struct ieee80211_mgmt
*mgmt
, size_t len
)
1324 #if defined(CONFIG_IEEE80211W) || defined(CONFIG_IEEE80211R)
1325 struct sta_info
*sta
;
1326 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1327 #endif /* CONFIG_IEEE80211W || CONFIG_IEEE80211R */
1329 if (len
< IEEE80211_HDRLEN
+ 1) {
1330 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1331 HOSTAPD_LEVEL_DEBUG
,
1332 "handle_action - too short payload (len=%lu)",
1333 (unsigned long) len
);
1337 #ifdef CONFIG_IEEE80211W
1338 if (sta
&& (sta
->flags
& WLAN_STA_MFP
) &&
1339 !(mgmt
->frame_control
& host_to_le16(WLAN_FC_ISWEP
) &&
1340 robust_action_frame(mgmt
->u
.action
.category
))) {
1341 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1342 HOSTAPD_LEVEL_DEBUG
,
1343 "Dropped unprotected Robust Action frame from "
1347 #endif /* CONFIG_IEEE80211W */
1349 switch (mgmt
->u
.action
.category
) {
1350 #ifdef CONFIG_IEEE80211R
1351 case WLAN_ACTION_FT
:
1353 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
1354 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Ignored FT Action "
1355 "frame from unassociated STA " MACSTR
,
1360 if (wpa_ft_action_rx(sta
->wpa_sm
, (u8
*) &mgmt
->u
.action
,
1361 len
- IEEE80211_HDRLEN
))
1366 #endif /* CONFIG_IEEE80211R */
1367 case WLAN_ACTION_WMM
:
1368 hostapd_wmm_action(hapd
, mgmt
, len
);
1370 #ifdef CONFIG_IEEE80211W
1371 case WLAN_ACTION_SA_QUERY
:
1372 hostapd_sa_query_action(hapd
, mgmt
, len
);
1374 #endif /* CONFIG_IEEE80211W */
1375 case WLAN_ACTION_PUBLIC
:
1376 if (hapd
->public_action_cb
) {
1377 hapd
->public_action_cb(hapd
->public_action_cb_ctx
,
1383 case WLAN_ACTION_VENDOR_SPECIFIC
:
1384 if (hapd
->vendor_action_cb
) {
1385 if (hapd
->vendor_action_cb(hapd
->vendor_action_cb_ctx
,
1387 hapd
->iface
->freq
) == 0)
1393 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1394 HOSTAPD_LEVEL_DEBUG
,
1395 "handle_action - unknown action category %d or invalid "
1397 mgmt
->u
.action
.category
);
1398 if (!(mgmt
->da
[0] & 0x01) && !(mgmt
->u
.action
.category
& 0x80) &&
1399 !(mgmt
->sa
[0] & 0x01)) {
1400 struct ieee80211_mgmt
*resp
;
1403 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
1404 * Return the Action frame to the source without change
1405 * except that MSB of the Category set to 1.
1407 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Return unknown Action "
1408 "frame back to sender");
1409 resp
= os_malloc(len
);
1412 os_memcpy(resp
, mgmt
, len
);
1413 os_memcpy(resp
->da
, resp
->sa
, ETH_ALEN
);
1414 os_memcpy(resp
->sa
, hapd
->own_addr
, ETH_ALEN
);
1415 os_memcpy(resp
->bssid
, hapd
->own_addr
, ETH_ALEN
);
1416 resp
->u
.action
.category
|= 0x80;
1418 if (hostapd_drv_send_mlme(hapd
, resp
, len
, 0) < 0) {
1419 wpa_printf(MSG_ERROR
, "IEEE 802.11: Failed to send "
1428 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
1429 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
1431 * @buf: management frame data (starting from IEEE 802.11 header)
1432 * @len: length of frame data in octets
1433 * @fi: meta data about received frame (signal level, etc.)
1435 * Process all incoming IEEE 802.11 management frames. This will be called for
1436 * each frame received from the kernel driver through wlan#ap interface. In
1437 * addition, it can be called to re-inserted pending frames (e.g., when using
1438 * external RADIUS server as an MAC ACL).
1440 void ieee802_11_mgmt(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
1441 struct hostapd_frame_info
*fi
)
1443 struct ieee80211_mgmt
*mgmt
;
1450 mgmt
= (struct ieee80211_mgmt
*) buf
;
1451 fc
= le_to_host16(mgmt
->frame_control
);
1452 stype
= WLAN_FC_GET_STYPE(fc
);
1454 if (stype
== WLAN_FC_STYPE_BEACON
) {
1455 handle_beacon(hapd
, mgmt
, len
, fi
);
1459 broadcast
= mgmt
->bssid
[0] == 0xff && mgmt
->bssid
[1] == 0xff &&
1460 mgmt
->bssid
[2] == 0xff && mgmt
->bssid
[3] == 0xff &&
1461 mgmt
->bssid
[4] == 0xff && mgmt
->bssid
[5] == 0xff;
1465 /* Invitation responses can be sent with the peer MAC as BSSID */
1466 !((hapd
->conf
->p2p
& P2P_GROUP_OWNER
) &&
1467 stype
== WLAN_FC_STYPE_ACTION
) &&
1468 #endif /* CONFIG_P2P */
1469 os_memcmp(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
) != 0) {
1470 printf("MGMT: BSSID=" MACSTR
" not our address\n",
1471 MAC2STR(mgmt
->bssid
));
1476 if (stype
== WLAN_FC_STYPE_PROBE_REQ
) {
1477 handle_probe_req(hapd
, mgmt
, len
, fi
->ssi_signal
);
1481 if (os_memcmp(mgmt
->da
, hapd
->own_addr
, ETH_ALEN
) != 0) {
1482 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1483 HOSTAPD_LEVEL_DEBUG
,
1484 "MGMT: DA=" MACSTR
" not our address",
1490 case WLAN_FC_STYPE_AUTH
:
1491 wpa_printf(MSG_DEBUG
, "mgmt::auth");
1492 handle_auth(hapd
, mgmt
, len
);
1494 case WLAN_FC_STYPE_ASSOC_REQ
:
1495 wpa_printf(MSG_DEBUG
, "mgmt::assoc_req");
1496 handle_assoc(hapd
, mgmt
, len
, 0);
1498 case WLAN_FC_STYPE_REASSOC_REQ
:
1499 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_req");
1500 handle_assoc(hapd
, mgmt
, len
, 1);
1502 case WLAN_FC_STYPE_DISASSOC
:
1503 wpa_printf(MSG_DEBUG
, "mgmt::disassoc");
1504 handle_disassoc(hapd
, mgmt
, len
);
1506 case WLAN_FC_STYPE_DEAUTH
:
1507 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "mgmt::deauth");
1508 handle_deauth(hapd
, mgmt
, len
);
1510 case WLAN_FC_STYPE_ACTION
:
1511 wpa_printf(MSG_DEBUG
, "mgmt::action");
1512 handle_action(hapd
, mgmt
, len
);
1515 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1516 HOSTAPD_LEVEL_DEBUG
,
1517 "unknown mgmt frame subtype %d", stype
);
1523 static void handle_auth_cb(struct hostapd_data
*hapd
,
1524 const struct ieee80211_mgmt
*mgmt
,
1527 u16 auth_alg
, auth_transaction
, status_code
;
1528 struct sta_info
*sta
;
1531 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
1532 HOSTAPD_LEVEL_NOTICE
,
1533 "did not acknowledge authentication response");
1537 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
1538 printf("handle_auth_cb - too short payload (len=%lu)\n",
1539 (unsigned long) len
);
1543 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
1544 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
1545 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
1547 sta
= ap_get_sta(hapd
, mgmt
->da
);
1549 printf("handle_auth_cb: STA " MACSTR
" not found\n",
1554 if (status_code
== WLAN_STATUS_SUCCESS
&&
1555 ((auth_alg
== WLAN_AUTH_OPEN
&& auth_transaction
== 2) ||
1556 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 4))) {
1557 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1558 HOSTAPD_LEVEL_INFO
, "authenticated");
1559 sta
->flags
|= WLAN_STA_AUTH
;
1564 static void handle_assoc_cb(struct hostapd_data
*hapd
,
1565 const struct ieee80211_mgmt
*mgmt
,
1566 size_t len
, int reassoc
, int ok
)
1569 struct sta_info
*sta
;
1571 struct ieee80211_ht_capabilities ht_cap
;
1573 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_resp
) :
1574 sizeof(mgmt
->u
.assoc_resp
))) {
1575 printf("handle_assoc_cb(reassoc=%d) - too short payload "
1576 "(len=%lu)\n", reassoc
, (unsigned long) len
);
1580 sta
= ap_get_sta(hapd
, mgmt
->da
);
1582 printf("handle_assoc_cb: STA " MACSTR
" not found\n",
1588 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
1589 HOSTAPD_LEVEL_DEBUG
,
1590 "did not acknowledge association response");
1591 sta
->flags
&= ~WLAN_STA_ASSOC_REQ_OK
;
1596 status
= le_to_host16(mgmt
->u
.reassoc_resp
.status_code
);
1598 status
= le_to_host16(mgmt
->u
.assoc_resp
.status_code
);
1600 if (status
!= WLAN_STATUS_SUCCESS
)
1603 /* Stop previous accounting session, if one is started, and allocate
1604 * new session id for the new session. */
1605 accounting_sta_stop(hapd
, sta
);
1607 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1609 "associated (aid %d)",
1612 if (sta
->flags
& WLAN_STA_ASSOC
)
1614 sta
->flags
|= WLAN_STA_ASSOC
;
1615 if ((!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
) ||
1616 sta
->auth_alg
== WLAN_AUTH_FT
) {
1618 * Open, static WEP, or FT protocol; no separate authorization
1621 ap_sta_set_authorized(hapd
, sta
, 1);
1625 mlme_reassociate_indication(hapd
, sta
);
1627 mlme_associate_indication(hapd
, sta
);
1629 #ifdef CONFIG_IEEE80211W
1630 sta
->sa_query_timed_out
= 0;
1631 #endif /* CONFIG_IEEE80211W */
1634 * Remove the STA entry in order to make sure the STA PS state gets
1635 * cleared and configuration gets updated in case of reassociation back
1638 hostapd_drv_sta_remove(hapd
, sta
->addr
);
1640 #ifdef CONFIG_IEEE80211N
1641 if (sta
->flags
& WLAN_STA_HT
)
1642 hostapd_get_ht_capab(hapd
, sta
->ht_capabilities
, &ht_cap
);
1643 #endif /* CONFIG_IEEE80211N */
1645 if (hostapd_sta_add(hapd
, sta
->addr
, sta
->aid
, sta
->capability
,
1646 sta
->supported_rates
, sta
->supported_rates_len
,
1647 sta
->listen_interval
,
1648 sta
->flags
& WLAN_STA_HT
? &ht_cap
: NULL
,
1649 sta
->flags
, sta
->qosinfo
)) {
1650 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1651 HOSTAPD_LEVEL_NOTICE
,
1652 "Could not add STA to kernel driver");
1654 ap_sta_disconnect(hapd
, sta
, sta
->addr
,
1655 WLAN_REASON_DISASSOC_AP_BUSY
);
1660 if (sta
->flags
& WLAN_STA_WDS
)
1661 hostapd_set_wds_sta(hapd
, sta
->addr
, sta
->aid
, 1);
1663 if (sta
->eapol_sm
== NULL
) {
1665 * This STA does not use RADIUS server for EAP authentication,
1666 * so bind it to the selected VLAN interface now, since the
1667 * interface selection is not going to change anymore.
1669 if (ap_sta_bind_vlan(hapd
, sta
, 0) < 0)
1671 } else if (sta
->vlan_id
) {
1672 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
1673 if (ap_sta_bind_vlan(hapd
, sta
, 0) < 0)
1677 hostapd_set_sta_flags(hapd
, sta
);
1679 if (sta
->auth_alg
== WLAN_AUTH_FT
)
1680 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC_FT
);
1682 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
1683 hapd
->new_assoc_sta_cb(hapd
, sta
, !new_assoc
);
1685 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
1688 /* Copy of the association request is not needed anymore */
1689 if (sta
->last_assoc_req
) {
1690 os_free(sta
->last_assoc_req
);
1691 sta
->last_assoc_req
= NULL
;
1696 static void handle_deauth_cb(struct hostapd_data
*hapd
,
1697 const struct ieee80211_mgmt
*mgmt
,
1700 struct sta_info
*sta
;
1701 if (mgmt
->da
[0] & 0x01)
1703 sta
= ap_get_sta(hapd
, mgmt
->da
);
1705 wpa_printf(MSG_DEBUG
, "handle_deauth_cb: STA " MACSTR
1706 " not found", MAC2STR(mgmt
->da
));
1710 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged deauth",
1711 MAC2STR(sta
->addr
));
1713 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
1714 "deauth", MAC2STR(sta
->addr
));
1716 ap_sta_deauth_cb(hapd
, sta
);
1720 static void handle_disassoc_cb(struct hostapd_data
*hapd
,
1721 const struct ieee80211_mgmt
*mgmt
,
1724 struct sta_info
*sta
;
1725 if (mgmt
->da
[0] & 0x01)
1727 sta
= ap_get_sta(hapd
, mgmt
->da
);
1729 wpa_printf(MSG_DEBUG
, "handle_disassoc_cb: STA " MACSTR
1730 " not found", MAC2STR(mgmt
->da
));
1734 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged disassoc",
1735 MAC2STR(sta
->addr
));
1737 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
1738 "disassoc", MAC2STR(sta
->addr
));
1740 ap_sta_disassoc_cb(hapd
, sta
);
1745 * ieee802_11_mgmt_cb - Process management frame TX status callback
1746 * @hapd: hostapd BSS data structure (the BSS from which the management frame
1748 * @buf: management frame data (starting from IEEE 802.11 header)
1749 * @len: length of frame data in octets
1750 * @stype: management frame subtype from frame control field
1751 * @ok: Whether the frame was ACK'ed
1753 void ieee802_11_mgmt_cb(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
1756 const struct ieee80211_mgmt
*mgmt
;
1757 mgmt
= (const struct ieee80211_mgmt
*) buf
;
1760 case WLAN_FC_STYPE_AUTH
:
1761 wpa_printf(MSG_DEBUG
, "mgmt::auth cb");
1762 handle_auth_cb(hapd
, mgmt
, len
, ok
);
1764 case WLAN_FC_STYPE_ASSOC_RESP
:
1765 wpa_printf(MSG_DEBUG
, "mgmt::assoc_resp cb");
1766 handle_assoc_cb(hapd
, mgmt
, len
, 0, ok
);
1768 case WLAN_FC_STYPE_REASSOC_RESP
:
1769 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_resp cb");
1770 handle_assoc_cb(hapd
, mgmt
, len
, 1, ok
);
1772 case WLAN_FC_STYPE_PROBE_RESP
:
1773 wpa_printf(MSG_EXCESSIVE
, "mgmt::proberesp cb");
1775 case WLAN_FC_STYPE_DEAUTH
:
1776 wpa_printf(MSG_DEBUG
, "mgmt::deauth cb");
1777 handle_deauth_cb(hapd
, mgmt
, len
, ok
);
1779 case WLAN_FC_STYPE_DISASSOC
:
1780 wpa_printf(MSG_DEBUG
, "mgmt::disassoc cb");
1781 handle_disassoc_cb(hapd
, mgmt
, len
, ok
);
1783 case WLAN_FC_STYPE_ACTION
:
1784 wpa_printf(MSG_DEBUG
, "mgmt::action cb");
1787 printf("unknown mgmt cb frame subtype %d\n", stype
);
1793 int ieee802_11_get_mib(struct hostapd_data
*hapd
, char *buf
, size_t buflen
)
1800 int ieee802_11_get_mib_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1801 char *buf
, size_t buflen
)
1808 void hostapd_tx_status(struct hostapd_data
*hapd
, const u8
*addr
,
1809 const u8
*buf
, size_t len
, int ack
)
1811 struct sta_info
*sta
;
1812 struct hostapd_iface
*iface
= hapd
->iface
;
1814 sta
= ap_get_sta(hapd
, addr
);
1815 if (sta
== NULL
&& iface
->num_bss
> 1) {
1817 for (j
= 0; j
< iface
->num_bss
; j
++) {
1818 hapd
= iface
->bss
[j
];
1819 sta
= ap_get_sta(hapd
, addr
);
1824 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))
1826 if (sta
->flags
& WLAN_STA_PENDING_POLL
) {
1827 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" %s pending "
1828 "activity poll", MAC2STR(sta
->addr
),
1829 ack
? "ACKed" : "did not ACK");
1831 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
1834 ieee802_1x_tx_status(hapd
, sta
, buf
, len
, ack
);
1838 void hostapd_eapol_tx_status(struct hostapd_data
*hapd
, const u8
*dst
,
1839 const u8
*data
, size_t len
, int ack
)
1841 struct sta_info
*sta
;
1842 struct hostapd_iface
*iface
= hapd
->iface
;
1844 sta
= ap_get_sta(hapd
, dst
);
1845 if (sta
== NULL
&& iface
->num_bss
> 1) {
1847 for (j
= 0; j
< iface
->num_bss
; j
++) {
1848 hapd
= iface
->bss
[j
];
1849 sta
= ap_get_sta(hapd
, dst
);
1854 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
1855 wpa_printf(MSG_DEBUG
, "Ignore TX status for Data frame to STA "
1856 MACSTR
" that is not currently associated",
1861 ieee802_1x_eapol_tx_status(hapd
, sta
, data
, len
, ack
);
1865 void hostapd_client_poll_ok(struct hostapd_data
*hapd
, const u8
*addr
)
1867 struct sta_info
*sta
;
1868 struct hostapd_iface
*iface
= hapd
->iface
;
1870 sta
= ap_get_sta(hapd
, addr
);
1871 if (sta
== NULL
&& iface
->num_bss
> 1) {
1873 for (j
= 0; j
< iface
->num_bss
; j
++) {
1874 hapd
= iface
->bss
[j
];
1875 sta
= ap_get_sta(hapd
, addr
);
1882 if (!(sta
->flags
& WLAN_STA_PENDING_POLL
))
1885 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" ACKed pending "
1886 "activity poll", MAC2STR(sta
->addr
));
1887 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
1891 void ieee802_11_rx_from_unknown(struct hostapd_data
*hapd
, const u8
*src
,
1894 struct sta_info
*sta
;
1896 sta
= ap_get_sta(hapd
, src
);
1897 if (sta
&& (sta
->flags
& WLAN_STA_ASSOC
)) {
1898 if (!hapd
->conf
->wds_sta
)
1901 if (wds
&& !(sta
->flags
& WLAN_STA_WDS
)) {
1902 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for "
1903 "STA " MACSTR
" (aid %u)",
1904 MAC2STR(sta
->addr
), sta
->aid
);
1905 sta
->flags
|= WLAN_STA_WDS
;
1906 hostapd_set_wds_sta(hapd
, sta
->addr
, sta
->aid
, 1);
1911 wpa_printf(MSG_DEBUG
, "Data/PS-poll frame from not associated STA "
1912 MACSTR
, MAC2STR(src
));
1913 if (src
[0] & 0x01) {
1914 /* Broadcast bit set in SA?! Ignore the frame silently. */
1918 if (sta
&& (sta
->flags
& WLAN_STA_ASSOC_REQ_OK
)) {
1919 wpa_printf(MSG_DEBUG
, "Association Response to the STA has "
1920 "already been sent, but no TX status yet known - "
1921 "ignore Class 3 frame issue with " MACSTR
,
1926 if (sta
&& (sta
->flags
& WLAN_STA_AUTH
))
1927 hostapd_drv_sta_disassoc(
1929 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
1931 hostapd_drv_sta_deauth(
1933 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
1937 #endif /* CONFIG_NATIVE_WINDOWS */