2 * hostapd / IEEE 802.11 Management
3 * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
15 #include "utils/includes.h"
17 #ifndef CONFIG_NATIVE_WINDOWS
19 #include "utils/common.h"
20 #include "utils/eloop.h"
21 #include "crypto/crypto.h"
22 #include "drivers/driver.h"
23 #include "common/ieee802_11_defs.h"
24 #include "common/ieee802_11_common.h"
25 #include "common/wpa_ctrl.h"
26 #include "radius/radius.h"
27 #include "radius/radius_client.h"
30 #include "ieee802_11_auth.h"
32 #include "ieee802_1x.h"
36 #include "accounting.h"
37 #include "ap_config.h"
39 #include "ieee802_11.h"
42 u8
* hostapd_eid_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
47 if (hapd
->iface
->current_rates
== NULL
)
50 *pos
++ = WLAN_EID_SUPP_RATES
;
51 num
= hapd
->iface
->num_rates
;
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
)
73 u8
* hostapd_eid_ext_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
78 if (hapd
->iface
->current_rates
== NULL
)
81 num
= hapd
->iface
->num_rates
;
86 *pos
++ = WLAN_EID_EXT_SUPP_RATES
;
89 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
+ 8;
93 continue; /* already in SuppRates IE */
94 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
95 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
104 u16
hostapd_own_capab_info(struct hostapd_data
*hapd
, struct sta_info
*sta
,
107 int capab
= WLAN_CAPABILITY_ESS
;
110 if (hapd
->iface
->num_sta_no_short_preamble
== 0 &&
111 hapd
->iconf
->preamble
== SHORT_PREAMBLE
)
112 capab
|= WLAN_CAPABILITY_SHORT_PREAMBLE
;
114 privacy
= hapd
->conf
->ssid
.wep
.keys_set
;
116 if (hapd
->conf
->ieee802_1x
&&
117 (hapd
->conf
->default_wep_key_len
||
118 hapd
->conf
->individual_wep_key_len
))
125 int policy
, def_klen
;
126 if (probe
&& sta
->ssid_probe
) {
127 policy
= sta
->ssid_probe
->security_policy
;
128 def_klen
= sta
->ssid_probe
->wep
.default_len
;
130 policy
= sta
->ssid
->security_policy
;
131 def_klen
= sta
->ssid
->wep
.default_len
;
133 privacy
= policy
!= SECURITY_PLAINTEXT
;
134 if (policy
== SECURITY_IEEE_802_1X
&& def_klen
== 0)
139 capab
|= WLAN_CAPABILITY_PRIVACY
;
141 if (hapd
->iface
->current_mode
&&
142 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
&&
143 hapd
->iface
->num_sta_no_short_slot_time
== 0)
144 capab
|= WLAN_CAPABILITY_SHORT_SLOT_TIME
;
150 #ifdef CONFIG_IEEE80211W
151 static u8
* hostapd_eid_assoc_comeback_time(struct hostapd_data
*hapd
,
152 struct sta_info
*sta
, u8
*eid
)
156 struct os_time now
, passed
;
158 *pos
++ = WLAN_EID_TIMEOUT_INTERVAL
;
160 *pos
++ = WLAN_TIMEOUT_ASSOC_COMEBACK
;
162 os_time_sub(&now
, &sta
->sa_query_start
, &passed
);
163 tu
= (passed
.sec
* 1000000 + passed
.usec
) / 1024;
164 if (hapd
->conf
->assoc_sa_query_max_timeout
> tu
)
165 timeout
= hapd
->conf
->assoc_sa_query_max_timeout
- tu
;
168 if (timeout
< hapd
->conf
->assoc_sa_query_max_timeout
)
169 timeout
++; /* add some extra time for local timers */
170 WPA_PUT_LE32(pos
, timeout
);
175 #endif /* CONFIG_IEEE80211W */
178 void ieee802_11_print_ssid(char *buf
, const u8
*ssid
, u8 len
)
181 if (len
> HOSTAPD_MAX_SSID_LEN
)
182 len
= HOSTAPD_MAX_SSID_LEN
;
183 for (i
= 0; i
< len
; i
++) {
184 if (ssid
[i
] >= 32 && ssid
[i
] < 127)
194 * ieee802_11_send_deauth - Send Deauthentication frame
195 * @hapd: hostapd BSS data
196 * @addr: Address of the destination STA
197 * @reason: Reason code for Deauthentication
199 void ieee802_11_send_deauth(struct hostapd_data
*hapd
, const u8
*addr
,
202 struct ieee80211_mgmt mgmt
;
204 hostapd_logger(hapd
, addr
, HOSTAPD_MODULE_IEEE80211
,
206 "deauthenticate - reason %d", reason
);
207 os_memset(&mgmt
, 0, sizeof(mgmt
));
208 mgmt
.frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
209 WLAN_FC_STYPE_DEAUTH
);
210 os_memcpy(mgmt
.da
, addr
, ETH_ALEN
);
211 os_memcpy(mgmt
.sa
, hapd
->own_addr
, ETH_ALEN
);
212 os_memcpy(mgmt
.bssid
, hapd
->own_addr
, ETH_ALEN
);
213 mgmt
.u
.deauth
.reason_code
= host_to_le16(reason
);
214 if (hapd
->drv
.send_mgmt_frame(hapd
, &mgmt
, IEEE80211_HDRLEN
+
215 sizeof(mgmt
.u
.deauth
)) < 0)
216 perror("ieee802_11_send_deauth: send");
220 static u16
auth_shared_key(struct hostapd_data
*hapd
, struct sta_info
*sta
,
221 u16 auth_transaction
, const u8
*challenge
,
224 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
226 "authentication (shared key, transaction %d)",
229 if (auth_transaction
== 1) {
230 if (!sta
->challenge
) {
231 /* Generate a pseudo-random challenge */
235 sta
->challenge
= os_zalloc(WLAN_AUTH_CHALLENGE_LEN
);
236 if (sta
->challenge
== NULL
)
237 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
241 os_memcpy(key
, &now
, 4);
242 os_memcpy(key
+ 4, &r
, 4);
243 rc4_skip(key
, sizeof(key
), 0,
244 sta
->challenge
, WLAN_AUTH_CHALLENGE_LEN
);
249 if (auth_transaction
!= 3)
250 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
253 if (!iswep
|| !sta
->challenge
|| !challenge
||
254 os_memcmp(sta
->challenge
, challenge
, WLAN_AUTH_CHALLENGE_LEN
)) {
255 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
257 "shared key authentication - invalid "
258 "challenge-response");
259 return WLAN_STATUS_CHALLENGE_FAIL
;
262 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
264 "authentication OK (shared key)");
265 #ifdef IEEE80211_REQUIRE_AUTH_ACK
266 /* Station will be marked authenticated if it ACKs the
267 * authentication reply. */
269 sta
->flags
|= WLAN_STA_AUTH
;
270 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
272 os_free(sta
->challenge
);
273 sta
->challenge
= NULL
;
279 static void send_auth_reply(struct hostapd_data
*hapd
,
280 const u8
*dst
, const u8
*bssid
,
281 u16 auth_alg
, u16 auth_transaction
, u16 resp
,
282 const u8
*ies
, size_t ies_len
)
284 struct ieee80211_mgmt
*reply
;
288 rlen
= IEEE80211_HDRLEN
+ sizeof(reply
->u
.auth
) + ies_len
;
289 buf
= os_zalloc(rlen
);
293 reply
= (struct ieee80211_mgmt
*) buf
;
294 reply
->frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
296 os_memcpy(reply
->da
, dst
, ETH_ALEN
);
297 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
298 os_memcpy(reply
->bssid
, bssid
, ETH_ALEN
);
300 reply
->u
.auth
.auth_alg
= host_to_le16(auth_alg
);
301 reply
->u
.auth
.auth_transaction
= host_to_le16(auth_transaction
);
302 reply
->u
.auth
.status_code
= host_to_le16(resp
);
305 os_memcpy(reply
->u
.auth
.variable
, ies
, ies_len
);
307 wpa_printf(MSG_DEBUG
, "authentication reply: STA=" MACSTR
308 " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)",
309 MAC2STR(dst
), auth_alg
, auth_transaction
,
310 resp
, (unsigned long) ies_len
);
311 if (hapd
->drv
.send_mgmt_frame(hapd
, reply
, rlen
) < 0)
312 perror("send_auth_reply: send");
318 #ifdef CONFIG_IEEE80211R
319 static void handle_auth_ft_finish(void *ctx
, const u8
*dst
, const u8
*bssid
,
320 u16 auth_transaction
, u16 status
,
321 const u8
*ies
, size_t ies_len
)
323 struct hostapd_data
*hapd
= ctx
;
324 struct sta_info
*sta
;
326 send_auth_reply(hapd
, dst
, bssid
, WLAN_AUTH_FT
, auth_transaction
,
327 status
, ies
, ies_len
);
329 if (status
!= WLAN_STATUS_SUCCESS
)
332 sta
= ap_get_sta(hapd
, dst
);
336 hostapd_logger(hapd
, dst
, HOSTAPD_MODULE_IEEE80211
,
337 HOSTAPD_LEVEL_DEBUG
, "authentication OK (FT)");
338 sta
->flags
|= WLAN_STA_AUTH
;
339 mlme_authenticate_indication(hapd
, sta
);
341 #endif /* CONFIG_IEEE80211R */
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
;
355 u8 resp_ies
[2 + WLAN_AUTH_CHALLENGE_LEN
];
356 size_t resp_ies_len
= 0;
358 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
359 printf("handle_auth - too short payload (len=%lu)\n",
360 (unsigned long) len
);
364 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
365 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
366 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
367 fc
= le_to_host16(mgmt
->frame_control
);
369 if (len
>= IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
) +
370 2 + WLAN_AUTH_CHALLENGE_LEN
&&
371 mgmt
->u
.auth
.variable
[0] == WLAN_EID_CHALLENGE
&&
372 mgmt
->u
.auth
.variable
[1] == WLAN_AUTH_CHALLENGE_LEN
)
373 challenge
= &mgmt
->u
.auth
.variable
[2];
375 wpa_printf(MSG_DEBUG
, "authentication: STA=" MACSTR
" auth_alg=%d "
376 "auth_transaction=%d status_code=%d wep=%d%s",
377 MAC2STR(mgmt
->sa
), auth_alg
, auth_transaction
,
378 status_code
, !!(fc
& WLAN_FC_ISWEP
),
379 challenge
? " challenge" : "");
381 if (hapd
->tkip_countermeasures
) {
382 resp
= WLAN_REASON_MICHAEL_MIC_FAILURE
;
386 if (!(((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_OPEN
) &&
387 auth_alg
== WLAN_AUTH_OPEN
) ||
388 #ifdef CONFIG_IEEE80211R
390 (hapd
->conf
->wpa_key_mgmt
&
391 (WPA_KEY_MGMT_FT_IEEE8021X
| WPA_KEY_MGMT_FT_PSK
)) &&
392 auth_alg
== WLAN_AUTH_FT
) ||
393 #endif /* CONFIG_IEEE80211R */
394 ((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_SHARED
) &&
395 auth_alg
== WLAN_AUTH_SHARED_KEY
))) {
396 printf("Unsupported authentication algorithm (%d)\n",
398 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
402 if (!(auth_transaction
== 1 ||
403 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 3))) {
404 printf("Unknown authentication transaction number (%d)\n",
406 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
410 if (os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
411 printf("Station " MACSTR
" not allowed to authenticate.\n",
413 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
417 res
= hostapd_allowed_address(hapd
, mgmt
->sa
, (u8
*) mgmt
, len
,
419 &acct_interim_interval
, &vlan_id
);
420 if (res
== HOSTAPD_ACL_REJECT
) {
421 printf("Station " MACSTR
" not allowed to authenticate.\n",
423 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
426 if (res
== HOSTAPD_ACL_PENDING
) {
427 wpa_printf(MSG_DEBUG
, "Authentication frame from " MACSTR
428 " waiting for an external authentication",
430 /* Authentication code will re-send the authentication frame
431 * after it has received (and cached) information from the
432 * external source. */
436 sta
= ap_sta_add(hapd
, mgmt
->sa
);
438 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
443 if (hostapd_get_vlan_id_ifname(hapd
->conf
->vlan
,
445 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
446 HOSTAPD_LEVEL_INFO
, "Invalid VLAN ID "
447 "%d received from RADIUS server",
449 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
452 sta
->vlan_id
= vlan_id
;
453 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
454 HOSTAPD_LEVEL_INFO
, "VLAN ID %d", sta
->vlan_id
);
457 sta
->flags
&= ~WLAN_STA_PREAUTH
;
458 ieee802_1x_notify_pre_auth(sta
->eapol_sm
, 0);
460 if (hapd
->conf
->acct_interim_interval
== 0 && acct_interim_interval
)
461 sta
->acct_interim_interval
= acct_interim_interval
;
462 if (res
== HOSTAPD_ACL_ACCEPT_TIMEOUT
)
463 ap_sta_session_timeout(hapd
, sta
, session_timeout
);
465 ap_sta_no_session_timeout(hapd
, sta
);
469 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
471 "authentication OK (open system)");
472 #ifdef IEEE80211_REQUIRE_AUTH_ACK
473 /* Station will be marked authenticated if it ACKs the
474 * authentication reply. */
476 sta
->flags
|= WLAN_STA_AUTH
;
477 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
478 sta
->auth_alg
= WLAN_AUTH_OPEN
;
479 mlme_authenticate_indication(hapd
, sta
);
482 case WLAN_AUTH_SHARED_KEY
:
483 resp
= auth_shared_key(hapd
, sta
, auth_transaction
, challenge
,
485 sta
->auth_alg
= WLAN_AUTH_SHARED_KEY
;
486 mlme_authenticate_indication(hapd
, sta
);
487 if (sta
->challenge
&& auth_transaction
== 1) {
488 resp_ies
[0] = WLAN_EID_CHALLENGE
;
489 resp_ies
[1] = WLAN_AUTH_CHALLENGE_LEN
;
490 os_memcpy(resp_ies
+ 2, sta
->challenge
,
491 WLAN_AUTH_CHALLENGE_LEN
);
492 resp_ies_len
= 2 + WLAN_AUTH_CHALLENGE_LEN
;
495 #ifdef CONFIG_IEEE80211R
497 sta
->auth_alg
= WLAN_AUTH_FT
;
498 if (sta
->wpa_sm
== NULL
)
499 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
501 if (sta
->wpa_sm
== NULL
) {
502 wpa_printf(MSG_DEBUG
, "FT: Failed to initialize WPA "
504 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
507 wpa_ft_process_auth(sta
->wpa_sm
, mgmt
->bssid
,
508 auth_transaction
, mgmt
->u
.auth
.variable
,
509 len
- IEEE80211_HDRLEN
-
510 sizeof(mgmt
->u
.auth
),
511 handle_auth_ft_finish
, hapd
);
512 /* handle_auth_ft_finish() callback will complete auth. */
514 #endif /* CONFIG_IEEE80211R */
518 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, auth_alg
,
519 auth_transaction
+ 1, resp
, resp_ies
, resp_ies_len
);
523 static int hostapd_get_aid(struct hostapd_data
*hapd
, struct sta_info
*sta
)
527 /* get a unique AID */
529 wpa_printf(MSG_DEBUG
, " old AID %d", sta
->aid
);
533 for (i
= 0; i
< AID_WORDS
; i
++) {
534 if (hapd
->sta_aid
[i
] == (u32
) -1)
536 for (j
= 0; j
< 32; j
++) {
537 if (!(hapd
->sta_aid
[i
] & BIT(j
)))
545 aid
= i
* 32 + j
+ 1;
550 hapd
->sta_aid
[i
] |= BIT(j
);
551 wpa_printf(MSG_DEBUG
, " new AID %d", sta
->aid
);
556 static u16
check_ssid(struct hostapd_data
*hapd
, struct sta_info
*sta
,
557 const u8
*ssid_ie
, size_t ssid_ie_len
)
560 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
562 if (ssid_ie_len
!= hapd
->conf
->ssid
.ssid_len
||
563 os_memcmp(ssid_ie
, hapd
->conf
->ssid
.ssid
, ssid_ie_len
) != 0) {
565 ieee802_11_print_ssid(ssid_txt
, ssid_ie
, ssid_ie_len
);
566 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
568 "Station tried to associate with unknown SSID "
570 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
573 return WLAN_STATUS_SUCCESS
;
577 static u16
check_wmm(struct hostapd_data
*hapd
, struct sta_info
*sta
,
578 const u8
*wmm_ie
, size_t wmm_ie_len
)
580 sta
->flags
&= ~WLAN_STA_WMM
;
581 if (wmm_ie
&& hapd
->conf
->wmm_enabled
) {
582 if (hostapd_eid_wmm_valid(hapd
, wmm_ie
, wmm_ie_len
))
583 hostapd_logger(hapd
, sta
->addr
,
586 "invalid WMM element in association "
589 sta
->flags
|= WLAN_STA_WMM
;
591 return WLAN_STATUS_SUCCESS
;
595 static u16
copy_supp_rates(struct hostapd_data
*hapd
, struct sta_info
*sta
,
596 struct ieee802_11_elems
*elems
)
598 if (!elems
->supp_rates
) {
599 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
601 "No supported rates element in AssocReq");
602 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
605 if (elems
->supp_rates_len
> sizeof(sta
->supported_rates
)) {
606 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
608 "Invalid supported rates element length %d",
609 elems
->supp_rates_len
);
610 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
613 os_memset(sta
->supported_rates
, 0, sizeof(sta
->supported_rates
));
614 os_memcpy(sta
->supported_rates
, elems
->supp_rates
,
615 elems
->supp_rates_len
);
616 sta
->supported_rates_len
= elems
->supp_rates_len
;
618 if (elems
->ext_supp_rates
) {
619 if (elems
->supp_rates_len
+ elems
->ext_supp_rates_len
>
620 sizeof(sta
->supported_rates
)) {
621 hostapd_logger(hapd
, sta
->addr
,
622 HOSTAPD_MODULE_IEEE80211
,
624 "Invalid supported rates element length"
625 " %d+%d", elems
->supp_rates_len
,
626 elems
->ext_supp_rates_len
);
627 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
630 os_memcpy(sta
->supported_rates
+ elems
->supp_rates_len
,
631 elems
->ext_supp_rates
, elems
->ext_supp_rates_len
);
632 sta
->supported_rates_len
+= elems
->ext_supp_rates_len
;
635 return WLAN_STATUS_SUCCESS
;
639 static u16
check_assoc_ies(struct hostapd_data
*hapd
, struct sta_info
*sta
,
640 const u8
*ies
, size_t ies_len
, int reassoc
)
642 struct ieee802_11_elems elems
;
647 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 1) == ParseFailed
) {
648 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
649 HOSTAPD_LEVEL_INFO
, "Station sent an invalid "
650 "association request");
651 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
654 resp
= check_ssid(hapd
, sta
, elems
.ssid
, elems
.ssid_len
);
655 if (resp
!= WLAN_STATUS_SUCCESS
)
657 resp
= check_wmm(hapd
, sta
, elems
.wmm
, elems
.wmm_len
);
658 if (resp
!= WLAN_STATUS_SUCCESS
)
660 resp
= copy_supp_rates(hapd
, sta
, &elems
);
661 if (resp
!= WLAN_STATUS_SUCCESS
)
663 #ifdef CONFIG_IEEE80211N
664 resp
= copy_sta_ht_capab(sta
, elems
.ht_capabilities
,
665 elems
.ht_capabilities_len
);
666 if (resp
!= WLAN_STATUS_SUCCESS
)
668 #endif /* CONFIG_IEEE80211N */
670 if ((hapd
->conf
->wpa
& WPA_PROTO_RSN
) && elems
.rsn_ie
) {
671 wpa_ie
= elems
.rsn_ie
;
672 wpa_ie_len
= elems
.rsn_ie_len
;
673 } else if ((hapd
->conf
->wpa
& WPA_PROTO_WPA
) &&
675 wpa_ie
= elems
.wpa_ie
;
676 wpa_ie_len
= elems
.wpa_ie_len
;
683 sta
->flags
&= ~(WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
);
684 if (hapd
->conf
->wps_state
&& wpa_ie
== NULL
) {
686 wpa_printf(MSG_DEBUG
, "STA included WPS IE in "
687 "(Re)Association Request - assume WPS is "
689 sta
->flags
|= WLAN_STA_WPS
;
690 wpabuf_free(sta
->wps_ie
);
691 sta
->wps_ie
= wpabuf_alloc_copy(elems
.wps_ie
+ 4,
692 elems
.wps_ie_len
- 4);
694 wpa_printf(MSG_DEBUG
, "STA did not include WPA/RSN IE "
695 "in (Re)Association Request - possible WPS "
697 sta
->flags
|= WLAN_STA_MAYBE_WPS
;
700 #endif /* CONFIG_WPS */
701 if (hapd
->conf
->wpa
&& wpa_ie
== NULL
) {
702 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
704 "No WPA/RSN IE in association request");
705 return WLAN_STATUS_INVALID_IE
;
708 if (hapd
->conf
->wpa
&& wpa_ie
) {
712 if (sta
->wpa_sm
== NULL
)
713 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
715 if (sta
->wpa_sm
== NULL
) {
716 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
718 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
720 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
722 elems
.mdie
, elems
.mdie_len
);
723 if (res
== WPA_INVALID_GROUP
)
724 resp
= WLAN_STATUS_GROUP_CIPHER_NOT_VALID
;
725 else if (res
== WPA_INVALID_PAIRWISE
)
726 resp
= WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID
;
727 else if (res
== WPA_INVALID_AKMP
)
728 resp
= WLAN_STATUS_AKMP_NOT_VALID
;
729 else if (res
== WPA_ALLOC_FAIL
)
730 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
731 #ifdef CONFIG_IEEE80211W
732 else if (res
== WPA_MGMT_FRAME_PROTECTION_VIOLATION
)
733 resp
= WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
734 else if (res
== WPA_INVALID_MGMT_GROUP_CIPHER
)
735 resp
= WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
736 #endif /* CONFIG_IEEE80211W */
737 else if (res
== WPA_INVALID_MDIE
)
738 resp
= WLAN_STATUS_INVALID_MDIE
;
739 else if (res
!= WPA_IE_OK
)
740 resp
= WLAN_STATUS_INVALID_IE
;
741 if (resp
!= WLAN_STATUS_SUCCESS
)
743 #ifdef CONFIG_IEEE80211W
744 if ((sta
->flags
& WLAN_STA_MFP
) && !sta
->sa_query_timed_out
&&
745 sta
->sa_query_count
> 0)
746 ap_check_sa_query_timeout(hapd
, sta
);
747 if ((sta
->flags
& WLAN_STA_MFP
) && !sta
->sa_query_timed_out
&&
748 (!reassoc
|| sta
->auth_alg
!= WLAN_AUTH_FT
)) {
750 * STA has already been associated with MFP and SA
751 * Query timeout has not been reached. Reject the
752 * association attempt temporarily and start SA Query,
753 * if one is not pending.
756 if (sta
->sa_query_count
== 0)
757 ap_sta_start_sa_query(hapd
, sta
);
759 return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
;
762 if (wpa_auth_uses_mfp(sta
->wpa_sm
))
763 sta
->flags
|= WLAN_STA_MFP
;
765 sta
->flags
&= ~WLAN_STA_MFP
;
766 #endif /* CONFIG_IEEE80211W */
768 #ifdef CONFIG_IEEE80211R
769 if (sta
->auth_alg
== WLAN_AUTH_FT
) {
771 wpa_printf(MSG_DEBUG
, "FT: " MACSTR
" tried "
772 "to use association (not "
773 "re-association) with FT auth_alg",
775 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
778 resp
= wpa_ft_validate_reassoc(sta
->wpa_sm
, ies
,
780 if (resp
!= WLAN_STATUS_SUCCESS
)
783 #endif /* CONFIG_IEEE80211R */
785 #ifdef CONFIG_IEEE80211N
786 if ((sta
->flags
& WLAN_STA_HT
) &&
787 wpa_auth_get_pairwise(sta
->wpa_sm
) == WPA_CIPHER_TKIP
) {
788 hostapd_logger(hapd
, sta
->addr
,
789 HOSTAPD_MODULE_IEEE80211
,
791 "Station tried to use TKIP with HT "
793 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
795 #endif /* CONFIG_IEEE80211N */
797 wpa_auth_sta_no_wpa(sta
->wpa_sm
);
799 return WLAN_STATUS_SUCCESS
;
803 static void send_deauth(struct hostapd_data
*hapd
, const u8
*addr
,
807 struct ieee80211_mgmt reply
;
809 os_memset(&reply
, 0, sizeof(reply
));
810 reply
.frame_control
=
811 IEEE80211_FC(WLAN_FC_TYPE_MGMT
, WLAN_FC_STYPE_DEAUTH
);
812 os_memcpy(reply
.da
, addr
, ETH_ALEN
);
813 os_memcpy(reply
.sa
, hapd
->own_addr
, ETH_ALEN
);
814 os_memcpy(reply
.bssid
, hapd
->own_addr
, ETH_ALEN
);
816 send_len
= IEEE80211_HDRLEN
+ sizeof(reply
.u
.deauth
);
817 reply
.u
.deauth
.reason_code
= host_to_le16(reason_code
);
819 if (hapd
->drv
.send_mgmt_frame(hapd
, &reply
, send_len
) < 0)
820 wpa_printf(MSG_INFO
, "Failed to send deauth: %s",
825 static void send_assoc_resp(struct hostapd_data
*hapd
, struct sta_info
*sta
,
826 u16 status_code
, int reassoc
, const u8
*ies
,
830 u8 buf
[sizeof(struct ieee80211_mgmt
) + 1024];
831 struct ieee80211_mgmt
*reply
;
834 os_memset(buf
, 0, sizeof(buf
));
835 reply
= (struct ieee80211_mgmt
*) buf
;
836 reply
->frame_control
=
837 IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
838 (reassoc
? WLAN_FC_STYPE_REASSOC_RESP
:
839 WLAN_FC_STYPE_ASSOC_RESP
));
840 os_memcpy(reply
->da
, sta
->addr
, ETH_ALEN
);
841 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
842 os_memcpy(reply
->bssid
, hapd
->own_addr
, ETH_ALEN
);
844 send_len
= IEEE80211_HDRLEN
;
845 send_len
+= sizeof(reply
->u
.assoc_resp
);
846 reply
->u
.assoc_resp
.capab_info
=
847 host_to_le16(hostapd_own_capab_info(hapd
, sta
, 0));
848 reply
->u
.assoc_resp
.status_code
= host_to_le16(status_code
);
849 reply
->u
.assoc_resp
.aid
= host_to_le16((sta
? sta
->aid
: 0)
850 | BIT(14) | BIT(15));
851 /* Supported rates */
852 p
= hostapd_eid_supp_rates(hapd
, reply
->u
.assoc_resp
.variable
);
853 /* Extended supported rates */
854 p
= hostapd_eid_ext_supp_rates(hapd
, p
);
855 if (sta
->flags
& WLAN_STA_WMM
)
856 p
= hostapd_eid_wmm(hapd
, p
);
858 #ifdef CONFIG_IEEE80211N
859 p
= hostapd_eid_ht_capabilities(hapd
, p
);
860 p
= hostapd_eid_ht_operation(hapd
, p
);
861 #endif /* CONFIG_IEEE80211N */
863 #ifdef CONFIG_IEEE80211R
864 if (status_code
== WLAN_STATUS_SUCCESS
) {
865 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
866 * Transition Information, RSN, [RIC Response] */
867 p
= wpa_sm_write_assoc_resp_ies(sta
->wpa_sm
, p
,
868 buf
+ sizeof(buf
) - p
,
869 sta
->auth_alg
, ies
, ies_len
);
871 #endif /* CONFIG_IEEE80211R */
873 #ifdef CONFIG_IEEE80211W
874 if (status_code
== WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
)
875 p
= hostapd_eid_assoc_comeback_time(hapd
, sta
, p
);
876 #endif /* CONFIG_IEEE80211W */
878 send_len
+= p
- reply
->u
.assoc_resp
.variable
;
880 if (hapd
->drv
.send_mgmt_frame(hapd
, reply
, send_len
) < 0)
881 wpa_printf(MSG_INFO
, "Failed to send assoc resp: %s",
886 static void handle_assoc(struct hostapd_data
*hapd
,
887 const struct ieee80211_mgmt
*mgmt
, size_t len
,
890 u16 capab_info
, listen_interval
;
891 u16 resp
= WLAN_STATUS_SUCCESS
;
894 struct sta_info
*sta
;
896 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_req
) :
897 sizeof(mgmt
->u
.assoc_req
))) {
898 printf("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
899 "\n", reassoc
, (unsigned long) len
);
904 capab_info
= le_to_host16(mgmt
->u
.reassoc_req
.capab_info
);
905 listen_interval
= le_to_host16(
906 mgmt
->u
.reassoc_req
.listen_interval
);
907 wpa_printf(MSG_DEBUG
, "reassociation request: STA=" MACSTR
908 " capab_info=0x%02x listen_interval=%d current_ap="
910 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
911 MAC2STR(mgmt
->u
.reassoc_req
.current_ap
));
912 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.reassoc_req
));
913 pos
= mgmt
->u
.reassoc_req
.variable
;
915 capab_info
= le_to_host16(mgmt
->u
.assoc_req
.capab_info
);
916 listen_interval
= le_to_host16(
917 mgmt
->u
.assoc_req
.listen_interval
);
918 wpa_printf(MSG_DEBUG
, "association request: STA=" MACSTR
919 " capab_info=0x%02x listen_interval=%d",
920 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
);
921 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.assoc_req
));
922 pos
= mgmt
->u
.assoc_req
.variable
;
925 sta
= ap_get_sta(hapd
, mgmt
->sa
);
926 #ifdef CONFIG_IEEE80211R
927 if (sta
&& sta
->auth_alg
== WLAN_AUTH_FT
&&
928 (sta
->flags
& WLAN_STA_AUTH
) == 0) {
929 wpa_printf(MSG_DEBUG
, "FT: Allow STA " MACSTR
" to associate "
930 "prior to authentication since it is using "
931 "over-the-DS FT", MAC2STR(mgmt
->sa
));
933 #endif /* CONFIG_IEEE80211R */
934 if (sta
== NULL
|| (sta
->flags
& WLAN_STA_AUTH
) == 0) {
935 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
936 HOSTAPD_LEVEL_INFO
, "Station tried to "
937 "associate before authentication "
938 "(aid=%d flags=0x%x)",
940 sta
? sta
->flags
: 0);
941 send_deauth(hapd
, mgmt
->sa
,
942 WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA
);
946 if (hapd
->tkip_countermeasures
) {
947 resp
= WLAN_REASON_MICHAEL_MIC_FAILURE
;
951 if (listen_interval
> hapd
->conf
->max_listen_interval
) {
952 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
954 "Too large Listen Interval (%d)",
956 resp
= WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE
;
960 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
962 resp
= check_assoc_ies(hapd
, sta
, pos
, left
, reassoc
);
963 if (resp
!= WLAN_STATUS_SUCCESS
)
966 if (hostapd_get_aid(hapd
, sta
) < 0) {
967 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
968 HOSTAPD_LEVEL_INFO
, "No room for more AIDs");
969 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
973 sta
->capability
= capab_info
;
974 sta
->listen_interval
= listen_interval
;
976 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
977 sta
->flags
|= WLAN_STA_NONERP
;
978 for (i
= 0; i
< sta
->supported_rates_len
; i
++) {
979 if ((sta
->supported_rates
[i
] & 0x7f) > 22) {
980 sta
->flags
&= ~WLAN_STA_NONERP
;
984 if (sta
->flags
& WLAN_STA_NONERP
&& !sta
->nonerp_set
) {
986 hapd
->iface
->num_sta_non_erp
++;
987 if (hapd
->iface
->num_sta_non_erp
== 1)
988 ieee802_11_set_beacons(hapd
->iface
);
991 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
) &&
992 !sta
->no_short_slot_time_set
) {
993 sta
->no_short_slot_time_set
= 1;
994 hapd
->iface
->num_sta_no_short_slot_time
++;
995 if (hapd
->iface
->current_mode
->mode
==
996 HOSTAPD_MODE_IEEE80211G
&&
997 hapd
->iface
->num_sta_no_short_slot_time
== 1)
998 ieee802_11_set_beacons(hapd
->iface
);
1001 if (sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
1002 sta
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
1004 sta
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
1006 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
) &&
1007 !sta
->no_short_preamble_set
) {
1008 sta
->no_short_preamble_set
= 1;
1009 hapd
->iface
->num_sta_no_short_preamble
++;
1010 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
1011 && hapd
->iface
->num_sta_no_short_preamble
== 1)
1012 ieee802_11_set_beacons(hapd
->iface
);
1015 #ifdef CONFIG_IEEE80211N
1016 update_ht_state(hapd
, sta
);
1017 #endif /* CONFIG_IEEE80211N */
1019 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1020 HOSTAPD_LEVEL_DEBUG
,
1021 "association OK (aid %d)", sta
->aid
);
1022 /* Station will be marked associated, after it acknowledges AssocResp
1025 #ifdef CONFIG_IEEE80211W
1026 if ((sta
->flags
& WLAN_STA_MFP
) && sta
->sa_query_timed_out
) {
1027 wpa_printf(MSG_DEBUG
, "Allowing %sassociation after timed out "
1028 "SA Query procedure", reassoc
? "re" : "");
1029 /* TODO: Send a protected Disassociate frame to the STA using
1030 * the old key and Reason Code "Previous Authentication no
1031 * longer valid". Make sure this is only sent protected since
1032 * unprotected frame would be received by the STA that is now
1033 * trying to associate.
1036 #endif /* CONFIG_IEEE80211W */
1039 os_memcpy(sta
->previous_ap
, mgmt
->u
.reassoc_req
.current_ap
,
1043 if (sta
->last_assoc_req
)
1044 os_free(sta
->last_assoc_req
);
1045 sta
->last_assoc_req
= os_malloc(len
);
1046 if (sta
->last_assoc_req
)
1047 os_memcpy(sta
->last_assoc_req
, mgmt
, len
);
1049 /* Make sure that the previously registered inactivity timer will not
1050 * remove the STA immediately. */
1051 sta
->timeout_next
= STA_NULLFUNC
;
1054 send_assoc_resp(hapd
, sta
, resp
, reassoc
, pos
, left
);
1058 static void handle_disassoc(struct hostapd_data
*hapd
,
1059 const struct ieee80211_mgmt
*mgmt
, size_t len
)
1061 struct sta_info
*sta
;
1063 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.disassoc
)) {
1064 printf("handle_disassoc - too short payload (len=%lu)\n",
1065 (unsigned long) len
);
1069 wpa_printf(MSG_DEBUG
, "disassocation: STA=" MACSTR
" reason_code=%d",
1071 le_to_host16(mgmt
->u
.disassoc
.reason_code
));
1073 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1075 printf("Station " MACSTR
" trying to disassociate, but it "
1076 "is not associated.\n", MAC2STR(mgmt
->sa
));
1080 sta
->flags
&= ~WLAN_STA_ASSOC
;
1081 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, AP_STA_DISCONNECTED MACSTR
,
1082 MAC2STR(sta
->addr
));
1083 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
1084 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1085 HOSTAPD_LEVEL_INFO
, "disassociated");
1086 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
1087 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
1088 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
1090 accounting_sta_stop(hapd
, sta
);
1091 ieee802_1x_free_station(sta
);
1092 hapd
->drv
.sta_remove(hapd
, sta
->addr
);
1094 if (sta
->timeout_next
== STA_NULLFUNC
||
1095 sta
->timeout_next
== STA_DISASSOC
) {
1096 sta
->timeout_next
= STA_DEAUTH
;
1097 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
1098 eloop_register_timeout(AP_DEAUTH_DELAY
, 0, ap_handle_timer
,
1102 mlme_disassociate_indication(
1103 hapd
, sta
, le_to_host16(mgmt
->u
.disassoc
.reason_code
));
1107 static void handle_deauth(struct hostapd_data
*hapd
,
1108 const struct ieee80211_mgmt
*mgmt
, size_t len
)
1110 struct sta_info
*sta
;
1112 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.deauth
)) {
1113 printf("handle_deauth - too short payload (len=%lu)\n",
1114 (unsigned long) len
);
1118 wpa_printf(MSG_DEBUG
, "deauthentication: STA=" MACSTR
1121 le_to_host16(mgmt
->u
.deauth
.reason_code
));
1123 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1125 printf("Station " MACSTR
" trying to deauthenticate, but it "
1126 "is not authenticated.\n", MAC2STR(mgmt
->sa
));
1130 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
);
1131 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, AP_STA_DISCONNECTED MACSTR
,
1132 MAC2STR(sta
->addr
));
1133 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
1134 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1135 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
1136 mlme_deauthenticate_indication(
1137 hapd
, sta
, le_to_host16(mgmt
->u
.deauth
.reason_code
));
1138 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
1139 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
1140 ap_free_sta(hapd
, sta
);
1144 static void handle_beacon(struct hostapd_data
*hapd
,
1145 const struct ieee80211_mgmt
*mgmt
, size_t len
,
1146 struct hostapd_frame_info
*fi
)
1148 struct ieee802_11_elems elems
;
1150 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.beacon
)) {
1151 printf("handle_beacon - too short payload (len=%lu)\n",
1152 (unsigned long) len
);
1156 (void) ieee802_11_parse_elems(mgmt
->u
.beacon
.variable
,
1157 len
- (IEEE80211_HDRLEN
+
1158 sizeof(mgmt
->u
.beacon
)), &elems
,
1161 ap_list_process_beacon(hapd
->iface
, mgmt
, &elems
, fi
);
1165 #ifdef CONFIG_IEEE80211W
1167 /* MLME-SAQuery.request */
1168 void ieee802_11_send_sa_query_req(struct hostapd_data
*hapd
,
1169 const u8
*addr
, const u8
*trans_id
)
1171 struct ieee80211_mgmt mgmt
;
1174 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Sending SA Query Request to "
1175 MACSTR
, MAC2STR(addr
));
1176 wpa_hexdump(MSG_DEBUG
, "IEEE 802.11: SA Query Transaction ID",
1177 trans_id
, WLAN_SA_QUERY_TR_ID_LEN
);
1179 os_memset(&mgmt
, 0, sizeof(mgmt
));
1180 mgmt
.frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
1181 WLAN_FC_STYPE_ACTION
);
1182 os_memcpy(mgmt
.da
, addr
, ETH_ALEN
);
1183 os_memcpy(mgmt
.sa
, hapd
->own_addr
, ETH_ALEN
);
1184 os_memcpy(mgmt
.bssid
, hapd
->own_addr
, ETH_ALEN
);
1185 mgmt
.u
.action
.category
= WLAN_ACTION_SA_QUERY
;
1186 mgmt
.u
.action
.u
.sa_query_req
.action
= WLAN_SA_QUERY_REQUEST
;
1187 os_memcpy(mgmt
.u
.action
.u
.sa_query_req
.trans_id
, trans_id
,
1188 WLAN_SA_QUERY_TR_ID_LEN
);
1189 end
= mgmt
.u
.action
.u
.sa_query_req
.trans_id
+ WLAN_SA_QUERY_TR_ID_LEN
;
1190 if (hapd
->drv
.send_mgmt_frame(hapd
, &mgmt
, end
- (u8
*) &mgmt
) < 0)
1191 perror("ieee802_11_send_sa_query_req: send");
1195 static void hostapd_sa_query_action(struct hostapd_data
*hapd
,
1196 const struct ieee80211_mgmt
*mgmt
,
1199 struct sta_info
*sta
;
1203 end
= mgmt
->u
.action
.u
.sa_query_resp
.trans_id
+
1204 WLAN_SA_QUERY_TR_ID_LEN
;
1205 if (((u8
*) mgmt
) + len
< end
) {
1206 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Too short SA Query Action "
1207 "frame (len=%lu)", (unsigned long) len
);
1211 if (mgmt
->u
.action
.u
.sa_query_resp
.action
!= WLAN_SA_QUERY_RESPONSE
) {
1212 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Unexpected SA Query "
1213 "Action %d", mgmt
->u
.action
.u
.sa_query_resp
.action
);
1217 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Received SA Query Response from "
1218 MACSTR
, MAC2STR(mgmt
->sa
));
1219 wpa_hexdump(MSG_DEBUG
, "IEEE 802.11: SA Query Transaction ID",
1220 mgmt
->u
.action
.u
.sa_query_resp
.trans_id
,
1221 WLAN_SA_QUERY_TR_ID_LEN
);
1223 /* MLME-SAQuery.confirm */
1225 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1226 if (sta
== NULL
|| sta
->sa_query_trans_id
== NULL
) {
1227 wpa_printf(MSG_DEBUG
, "IEEE 802.11: No matching STA with "
1228 "pending SA Query request found");
1232 for (i
= 0; i
< sta
->sa_query_count
; i
++) {
1233 if (os_memcmp(sta
->sa_query_trans_id
+
1234 i
* WLAN_SA_QUERY_TR_ID_LEN
,
1235 mgmt
->u
.action
.u
.sa_query_resp
.trans_id
,
1236 WLAN_SA_QUERY_TR_ID_LEN
) == 0)
1240 if (i
>= sta
->sa_query_count
) {
1241 wpa_printf(MSG_DEBUG
, "IEEE 802.11: No matching SA Query "
1242 "transaction identifier found");
1246 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1247 HOSTAPD_LEVEL_DEBUG
,
1248 "Reply to pending SA Query received");
1249 ap_sta_stop_sa_query(hapd
, sta
);
1253 static int robust_action_frame(u8 category
)
1255 return category
!= WLAN_ACTION_PUBLIC
&&
1256 category
!= WLAN_ACTION_HT
;
1258 #endif /* CONFIG_IEEE80211W */
1261 static void handle_action(struct hostapd_data
*hapd
,
1262 const struct ieee80211_mgmt
*mgmt
, size_t len
)
1264 struct sta_info
*sta
;
1266 if (len
< IEEE80211_HDRLEN
+ 1) {
1267 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1268 HOSTAPD_LEVEL_DEBUG
,
1269 "handle_action - too short payload (len=%lu)",
1270 (unsigned long) len
);
1274 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1275 #ifdef CONFIG_IEEE80211W
1276 if (sta
&& (sta
->flags
& WLAN_STA_MFP
) &&
1277 !(mgmt
->frame_control
& host_to_le16(WLAN_FC_ISWEP
) &&
1278 robust_action_frame(mgmt
->u
.action
.category
))) {
1279 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1280 HOSTAPD_LEVEL_DEBUG
,
1281 "Dropped unprotected Robust Action frame from "
1285 #endif /* CONFIG_IEEE80211W */
1287 switch (mgmt
->u
.action
.category
) {
1288 #ifdef CONFIG_IEEE80211R
1289 case WLAN_ACTION_FT
:
1291 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
1292 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Ignored FT Action "
1293 "frame from unassociated STA " MACSTR
,
1298 if (wpa_ft_action_rx(sta
->wpa_sm
, (u8
*) &mgmt
->u
.action
,
1299 len
- IEEE80211_HDRLEN
))
1304 #endif /* CONFIG_IEEE80211R */
1305 case WLAN_ACTION_WMM
:
1306 hostapd_wmm_action(hapd
, mgmt
, len
);
1308 #ifdef CONFIG_IEEE80211W
1309 case WLAN_ACTION_SA_QUERY
:
1310 hostapd_sa_query_action(hapd
, mgmt
, len
);
1312 #endif /* CONFIG_IEEE80211W */
1315 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1316 HOSTAPD_LEVEL_DEBUG
,
1317 "handle_action - unknown action category %d or invalid "
1319 mgmt
->u
.action
.category
);
1320 if (!(mgmt
->da
[0] & 0x01) && !(mgmt
->u
.action
.category
& 0x80) &&
1321 !(mgmt
->sa
[0] & 0x01)) {
1322 struct ieee80211_mgmt
*resp
;
1325 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
1326 * Return the Action frame to the source without change
1327 * except that MSB of the Category set to 1.
1329 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Return unknown Action "
1330 "frame back to sender");
1331 resp
= os_malloc(len
);
1334 os_memcpy(resp
, mgmt
, len
);
1335 os_memcpy(resp
->da
, resp
->sa
, ETH_ALEN
);
1336 os_memcpy(resp
->sa
, hapd
->own_addr
, ETH_ALEN
);
1337 os_memcpy(resp
->bssid
, hapd
->own_addr
, ETH_ALEN
);
1338 resp
->u
.action
.category
|= 0x80;
1340 hapd
->drv
.send_mgmt_frame(hapd
, resp
, len
);
1347 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
1348 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
1350 * @buf: management frame data (starting from IEEE 802.11 header)
1351 * @len: length of frame data in octets
1352 * @fi: meta data about received frame (signal level, etc.)
1354 * Process all incoming IEEE 802.11 management frames. This will be called for
1355 * each frame received from the kernel driver through wlan#ap interface. In
1356 * addition, it can be called to re-inserted pending frames (e.g., when using
1357 * external RADIUS server as an MAC ACL).
1359 void ieee802_11_mgmt(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
1360 struct hostapd_frame_info
*fi
)
1362 struct ieee80211_mgmt
*mgmt
;
1366 mgmt
= (struct ieee80211_mgmt
*) buf
;
1367 fc
= le_to_host16(mgmt
->frame_control
);
1368 stype
= WLAN_FC_GET_STYPE(fc
);
1370 if (stype
== WLAN_FC_STYPE_BEACON
) {
1371 handle_beacon(hapd
, mgmt
, len
, fi
);
1375 broadcast
= mgmt
->bssid
[0] == 0xff && mgmt
->bssid
[1] == 0xff &&
1376 mgmt
->bssid
[2] == 0xff && mgmt
->bssid
[3] == 0xff &&
1377 mgmt
->bssid
[4] == 0xff && mgmt
->bssid
[5] == 0xff;
1380 os_memcmp(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
) != 0) {
1381 printf("MGMT: BSSID=" MACSTR
" not our address\n",
1382 MAC2STR(mgmt
->bssid
));
1387 if (stype
== WLAN_FC_STYPE_PROBE_REQ
) {
1388 handle_probe_req(hapd
, mgmt
, len
);
1392 if (os_memcmp(mgmt
->da
, hapd
->own_addr
, ETH_ALEN
) != 0) {
1393 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1394 HOSTAPD_LEVEL_DEBUG
,
1395 "MGMT: DA=" MACSTR
" not our address",
1401 case WLAN_FC_STYPE_AUTH
:
1402 wpa_printf(MSG_DEBUG
, "mgmt::auth");
1403 handle_auth(hapd
, mgmt
, len
);
1405 case WLAN_FC_STYPE_ASSOC_REQ
:
1406 wpa_printf(MSG_DEBUG
, "mgmt::assoc_req");
1407 handle_assoc(hapd
, mgmt
, len
, 0);
1409 case WLAN_FC_STYPE_REASSOC_REQ
:
1410 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_req");
1411 handle_assoc(hapd
, mgmt
, len
, 1);
1413 case WLAN_FC_STYPE_DISASSOC
:
1414 wpa_printf(MSG_DEBUG
, "mgmt::disassoc");
1415 handle_disassoc(hapd
, mgmt
, len
);
1417 case WLAN_FC_STYPE_DEAUTH
:
1418 wpa_printf(MSG_DEBUG
, "mgmt::deauth");
1419 handle_deauth(hapd
, mgmt
, len
);
1421 case WLAN_FC_STYPE_ACTION
:
1422 wpa_printf(MSG_DEBUG
, "mgmt::action");
1423 handle_action(hapd
, mgmt
, len
);
1426 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1427 HOSTAPD_LEVEL_DEBUG
,
1428 "unknown mgmt frame subtype %d", stype
);
1434 static void handle_auth_cb(struct hostapd_data
*hapd
,
1435 const struct ieee80211_mgmt
*mgmt
,
1438 u16 auth_alg
, auth_transaction
, status_code
;
1439 struct sta_info
*sta
;
1442 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
1443 HOSTAPD_LEVEL_NOTICE
,
1444 "did not acknowledge authentication response");
1448 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
1449 printf("handle_auth_cb - too short payload (len=%lu)\n",
1450 (unsigned long) len
);
1454 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
1455 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
1456 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
1458 sta
= ap_get_sta(hapd
, mgmt
->da
);
1460 printf("handle_auth_cb: STA " MACSTR
" not found\n",
1465 if (status_code
== WLAN_STATUS_SUCCESS
&&
1466 ((auth_alg
== WLAN_AUTH_OPEN
&& auth_transaction
== 2) ||
1467 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 4))) {
1468 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1469 HOSTAPD_LEVEL_INFO
, "authenticated");
1470 sta
->flags
|= WLAN_STA_AUTH
;
1475 static void handle_assoc_cb(struct hostapd_data
*hapd
,
1476 const struct ieee80211_mgmt
*mgmt
,
1477 size_t len
, int reassoc
, int ok
)
1480 struct sta_info
*sta
;
1482 struct ieee80211_ht_capabilities ht_cap
;
1485 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
1486 HOSTAPD_LEVEL_DEBUG
,
1487 "did not acknowledge association response");
1491 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_resp
) :
1492 sizeof(mgmt
->u
.assoc_resp
))) {
1493 printf("handle_assoc_cb(reassoc=%d) - too short payload "
1494 "(len=%lu)\n", reassoc
, (unsigned long) len
);
1499 status
= le_to_host16(mgmt
->u
.reassoc_resp
.status_code
);
1501 status
= le_to_host16(mgmt
->u
.assoc_resp
.status_code
);
1503 sta
= ap_get_sta(hapd
, mgmt
->da
);
1505 printf("handle_assoc_cb: STA " MACSTR
" not found\n",
1510 if (status
!= WLAN_STATUS_SUCCESS
)
1513 /* Stop previous accounting session, if one is started, and allocate
1514 * new session id for the new session. */
1515 accounting_sta_stop(hapd
, sta
);
1517 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1519 "associated (aid %d)",
1522 if (sta
->flags
& WLAN_STA_ASSOC
)
1524 sta
->flags
|= WLAN_STA_ASSOC
;
1525 if (!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
) {
1526 /* Open or static WEP; no separate authorization */
1527 sta
->flags
|= WLAN_STA_AUTHORIZED
;
1528 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
1529 AP_STA_CONNECTED MACSTR
, MAC2STR(sta
->addr
));
1533 mlme_reassociate_indication(hapd
, sta
);
1535 mlme_associate_indication(hapd
, sta
);
1537 #ifdef CONFIG_IEEE80211W
1538 sta
->sa_query_timed_out
= 0;
1539 #endif /* CONFIG_IEEE80211W */
1542 * Remove the STA entry in order to make sure the STA PS state gets
1543 * cleared and configuration gets updated in case of reassociation back
1546 hapd
->drv
.sta_remove(hapd
, sta
->addr
);
1548 #ifdef CONFIG_IEEE80211N
1549 if (sta
->flags
& WLAN_STA_HT
)
1550 hostapd_get_ht_capab(hapd
, sta
->ht_capabilities
, &ht_cap
);
1551 #endif /* CONFIG_IEEE80211N */
1553 if (hapd
->drv
.sta_add(hapd
->conf
->iface
, hapd
, sta
->addr
, sta
->aid
,
1554 sta
->capability
, sta
->supported_rates
,
1555 sta
->supported_rates_len
, sta
->listen_interval
,
1556 sta
->flags
& WLAN_STA_HT
? &ht_cap
: NULL
)) {
1557 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1558 HOSTAPD_LEVEL_NOTICE
,
1559 "Could not add STA to kernel driver");
1562 if (sta
->eapol_sm
== NULL
) {
1564 * This STA does not use RADIUS server for EAP authentication,
1565 * so bind it to the selected VLAN interface now, since the
1566 * interface selection is not going to change anymore.
1568 ap_sta_bind_vlan(hapd
, sta
, 0);
1569 } else if (sta
->vlan_id
) {
1570 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
1571 ap_sta_bind_vlan(hapd
, sta
, 0);
1574 hapd
->drv
.set_sta_flags(hapd
, sta
);
1576 if (sta
->auth_alg
== WLAN_AUTH_FT
)
1577 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC_FT
);
1579 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
1580 hapd
->new_assoc_sta_cb(hapd
, sta
, !new_assoc
);
1582 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
1585 /* Copy of the association request is not needed anymore */
1586 if (sta
->last_assoc_req
) {
1587 os_free(sta
->last_assoc_req
);
1588 sta
->last_assoc_req
= NULL
;
1594 * ieee802_11_mgmt_cb - Process management frame TX status callback
1595 * @hapd: hostapd BSS data structure (the BSS from which the management frame
1597 * @buf: management frame data (starting from IEEE 802.11 header)
1598 * @len: length of frame data in octets
1599 * @stype: management frame subtype from frame control field
1600 * @ok: Whether the frame was ACK'ed
1602 void ieee802_11_mgmt_cb(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
1605 const struct ieee80211_mgmt
*mgmt
;
1606 mgmt
= (const struct ieee80211_mgmt
*) buf
;
1609 case WLAN_FC_STYPE_AUTH
:
1610 wpa_printf(MSG_DEBUG
, "mgmt::auth cb");
1611 handle_auth_cb(hapd
, mgmt
, len
, ok
);
1613 case WLAN_FC_STYPE_ASSOC_RESP
:
1614 wpa_printf(MSG_DEBUG
, "mgmt::assoc_resp cb");
1615 handle_assoc_cb(hapd
, mgmt
, len
, 0, ok
);
1617 case WLAN_FC_STYPE_REASSOC_RESP
:
1618 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_resp cb");
1619 handle_assoc_cb(hapd
, mgmt
, len
, 1, ok
);
1621 case WLAN_FC_STYPE_PROBE_RESP
:
1622 wpa_printf(MSG_DEBUG
, "mgmt::proberesp cb");
1624 case WLAN_FC_STYPE_DEAUTH
:
1627 case WLAN_FC_STYPE_ACTION
:
1628 wpa_printf(MSG_DEBUG
, "mgmt::action cb");
1631 printf("unknown mgmt cb frame subtype %d\n", stype
);
1637 int ieee802_11_get_mib(struct hostapd_data
*hapd
, char *buf
, size_t buflen
)
1644 int ieee802_11_get_mib_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1645 char *buf
, size_t buflen
)
1652 void hostapd_tx_status(struct hostapd_data
*hapd
, const u8
*addr
,
1653 const u8
*buf
, size_t len
, int ack
)
1655 struct sta_info
*sta
;
1656 struct hostapd_iface
*iface
= hapd
->iface
;
1658 sta
= ap_get_sta(hapd
, addr
);
1659 if (sta
== NULL
&& iface
->num_bss
> 1) {
1661 for (j
= 0; j
< iface
->num_bss
; j
++) {
1662 hapd
= iface
->bss
[j
];
1663 sta
= ap_get_sta(hapd
, addr
);
1670 if (sta
->flags
& WLAN_STA_PENDING_POLL
) {
1671 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" %s pending "
1672 "activity poll", MAC2STR(sta
->addr
),
1673 ack
? "ACKed" : "did not ACK");
1675 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
1678 ieee802_1x_tx_status(hapd
, sta
, buf
, len
, ack
);
1682 void ieee802_11_rx_from_unknown(struct hostapd_data
*hapd
, const u8
*src
,
1685 struct sta_info
*sta
;
1687 sta
= ap_get_sta(hapd
, src
);
1688 if (sta
&& (sta
->flags
& WLAN_STA_ASSOC
)) {
1689 if (wds
&& !(sta
->flags
& WLAN_STA_WDS
)) {
1690 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for "
1691 "STA " MACSTR
" (aid %u)",
1692 MAC2STR(sta
->addr
), sta
->aid
);
1693 sta
->flags
|= WLAN_STA_WDS
;
1694 hapd
->drv
.set_wds_sta(hapd
, sta
->addr
, sta
->aid
, 1);
1699 wpa_printf(MSG_DEBUG
, "Data/PS-poll frame from not associated STA "
1700 MACSTR
, MAC2STR(src
));
1701 if (sta
&& (sta
->flags
& WLAN_STA_AUTH
))
1702 hapd
->drv
.sta_disassoc(
1704 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
1706 hapd
->drv
.sta_deauth(
1708 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
1712 #endif /* CONFIG_NATIVE_WINDOWS */