2 * hostapd / IEEE 802.11 Management
3 * Copyright (c) 2002-2008, Jouni Malinen <j@w1.fi>
4 * Copyright (c) 2007-2008, Intel Corporation
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
10 * Alternatively, this software may be distributed under the terms of BSD
13 * See README and COPYING for more details.
18 #ifndef CONFIG_NATIVE_WINDOWS
24 #include "ieee802_11.h"
26 #include "hw_features.h"
27 #include "radius/radius.h"
28 #include "radius/radius_client.h"
29 #include "ieee802_11_auth.h"
32 #include "ieee802_1x.h"
36 #include "accounting.h"
41 u8
* hostapd_eid_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
46 if (hapd
->iface
->current_rates
== NULL
)
49 *pos
++ = WLAN_EID_SUPP_RATES
;
50 num
= hapd
->iface
->num_rates
;
52 /* rest of the rates are encoded in Extended supported
59 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
;
62 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
63 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
72 u8
* hostapd_eid_ext_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
77 if (hapd
->iface
->current_rates
== NULL
)
80 num
= hapd
->iface
->num_rates
;
85 *pos
++ = WLAN_EID_EXT_SUPP_RATES
;
88 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
+ 8;
92 continue; /* already in SuppRates IE */
93 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
94 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
103 u8
* hostapd_eid_ht_capabilities_info(struct hostapd_data
*hapd
, u8
*eid
)
105 #ifdef CONFIG_IEEE80211N
106 struct ieee80211_ht_capability
*cap
;
109 if (!hapd
->iconf
->ieee80211n
)
112 *pos
++ = WLAN_EID_HT_CAP
;
113 *pos
++ = sizeof(*cap
);
115 cap
= (struct ieee80211_ht_capability
*) pos
;
116 os_memset(cap
, 0, sizeof(*cap
));
117 SET_2BIT_U8(&cap
->mac_ht_params_info
,
118 MAC_HT_PARAM_INFO_MAX_RX_AMPDU_FACTOR_OFFSET
,
119 MAX_RX_AMPDU_FACTOR_64KB
);
121 cap
->capabilities_info
= host_to_le16(hapd
->iconf
->ht_capab
);
123 cap
->supported_mcs_set
[0] = 0xff;
124 cap
->supported_mcs_set
[1] = 0xff;
129 #else /* CONFIG_IEEE80211N */
131 #endif /* CONFIG_IEEE80211N */
135 u8
* hostapd_eid_ht_operation(struct hostapd_data
*hapd
, u8
*eid
)
137 #ifdef CONFIG_IEEE80211N
138 struct ieee80211_ht_operation
*oper
;
141 if (!hapd
->iconf
->ieee80211n
)
144 *pos
++ = WLAN_EID_HT_OPERATION
;
145 *pos
++ = sizeof(*oper
);
147 oper
= (struct ieee80211_ht_operation
*) pos
;
148 os_memset(oper
, 0, sizeof(*oper
));
150 oper
->control_chan
= hapd
->iconf
->channel
;
151 oper
->operation_mode
= host_to_le16(hapd
->iface
->ht_op_mode
);
152 if (hapd
->iconf
->secondary_channel
== 1)
153 oper
->ht_param
|= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE
|
154 HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH
;
155 if (hapd
->iconf
->secondary_channel
== -1)
156 oper
->ht_param
|= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW
|
157 HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH
;
159 pos
+= sizeof(*oper
);
162 #else /* CONFIG_IEEE80211N */
164 #endif /* CONFIG_IEEE80211N */
168 #ifdef CONFIG_IEEE80211N
172 Set to 0 (HT pure) under the followign conditions
173 - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
174 - all STAs in the BSS are 20 MHz HT in 20 MHz BSS
175 Set to 1 (HT non-member protection) if there may be non-HT STAs
176 in both the primary and the secondary channel
177 Set to 2 if only HT STAs are associated in BSS,
178 however and at least one 20 MHz HT STA is associated
179 Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
180 (currently non-GF HT station is considered as non-HT STA also)
182 int hostapd_ht_operation_update(struct hostapd_iface
*iface
)
184 u16 cur_op_mode
, new_op_mode
;
185 int op_mode_changes
= 0;
187 if (!iface
->conf
->ieee80211n
|| iface
->conf
->ht_op_mode_fixed
)
190 wpa_printf(MSG_DEBUG
, "%s current operation mode=0x%X",
191 __func__
, iface
->ht_op_mode
);
193 if (!(iface
->ht_op_mode
& HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT
)
194 && iface
->num_sta_ht_no_gf
) {
196 HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT
;
198 } else if ((iface
->ht_op_mode
&
199 HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT
) &&
200 iface
->num_sta_ht_no_gf
== 0) {
202 ~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT
;
206 if (!(iface
->ht_op_mode
& HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT
) &&
207 (iface
->num_sta_no_ht
|| iface
->olbc_ht
)) {
208 iface
->ht_op_mode
|= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT
;
210 } else if ((iface
->ht_op_mode
&
211 HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT
) &&
212 (iface
->num_sta_no_ht
== 0 && !iface
->olbc_ht
)) {
214 ~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT
;
218 /* Note: currently we switch to the MIXED op mode if HT non-greenfield
219 * station is associated. Probably it's a theoretical case, since
220 * it looks like all known HT STAs support greenfield.
223 if (iface
->num_sta_no_ht
||
224 (iface
->ht_op_mode
& HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT
))
225 new_op_mode
= OP_MODE_MIXED
;
226 else if ((iface
->conf
->ht_capab
& HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
)
227 && iface
->num_sta_ht_20mhz
)
228 new_op_mode
= OP_MODE_20MHZ_HT_STA_ASSOCED
;
229 else if (iface
->olbc_ht
)
230 new_op_mode
= OP_MODE_MAY_BE_LEGACY_STAS
;
232 new_op_mode
= OP_MODE_PURE
;
234 cur_op_mode
= iface
->ht_op_mode
& HT_INFO_OPERATION_MODE_OP_MODE_MASK
;
235 if (cur_op_mode
!= new_op_mode
) {
236 iface
->ht_op_mode
&= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK
;
237 iface
->ht_op_mode
|= new_op_mode
;
241 wpa_printf(MSG_DEBUG
, "%s new operation mode=0x%X changes=%d",
242 __func__
, iface
->ht_op_mode
, op_mode_changes
);
244 return op_mode_changes
;
247 #endif /* CONFIG_IEEE80211N */
250 u16
hostapd_own_capab_info(struct hostapd_data
*hapd
, struct sta_info
*sta
,
253 int capab
= WLAN_CAPABILITY_ESS
;
256 if (hapd
->iface
->num_sta_no_short_preamble
== 0 &&
257 hapd
->iconf
->preamble
== SHORT_PREAMBLE
)
258 capab
|= WLAN_CAPABILITY_SHORT_PREAMBLE
;
260 privacy
= hapd
->conf
->ssid
.wep
.keys_set
;
262 if (hapd
->conf
->ieee802_1x
&&
263 (hapd
->conf
->default_wep_key_len
||
264 hapd
->conf
->individual_wep_key_len
))
271 int policy
, def_klen
;
272 if (probe
&& sta
->ssid_probe
) {
273 policy
= sta
->ssid_probe
->security_policy
;
274 def_klen
= sta
->ssid_probe
->wep
.default_len
;
276 policy
= sta
->ssid
->security_policy
;
277 def_klen
= sta
->ssid
->wep
.default_len
;
279 privacy
= policy
!= SECURITY_PLAINTEXT
;
280 if (policy
== SECURITY_IEEE_802_1X
&& def_klen
== 0)
285 capab
|= WLAN_CAPABILITY_PRIVACY
;
287 if (hapd
->iface
->current_mode
&&
288 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
&&
289 hapd
->iface
->num_sta_no_short_slot_time
== 0)
290 capab
|= WLAN_CAPABILITY_SHORT_SLOT_TIME
;
296 #ifdef CONFIG_IEEE80211W
297 static u8
* hostapd_eid_assoc_comeback_time(struct hostapd_data
*hapd
,
298 struct sta_info
*sta
, u8
*eid
)
303 *pos
++ = WLAN_EID_ASSOC_COMEBACK_TIME
;
305 timeout
= (hapd
->conf
->assoc_ping_attempts
- sta
->ping_count
+ 1) *
306 hapd
->conf
->assoc_ping_timeout
;
307 WPA_PUT_LE32(pos
, timeout
);
312 #endif /* CONFIG_IEEE80211W */
315 void ieee802_11_print_ssid(char *buf
, const u8
*ssid
, u8 len
)
318 if (len
> HOSTAPD_MAX_SSID_LEN
)
319 len
= HOSTAPD_MAX_SSID_LEN
;
320 for (i
= 0; i
< len
; i
++) {
321 if (ssid
[i
] >= 32 && ssid
[i
] < 127)
330 void ieee802_11_send_deauth(struct hostapd_data
*hapd
, u8
*addr
, u16 reason
)
332 struct ieee80211_mgmt mgmt
;
334 hostapd_logger(hapd
, addr
, HOSTAPD_MODULE_IEEE80211
,
336 "deauthenticate - reason %d", reason
);
337 os_memset(&mgmt
, 0, sizeof(mgmt
));
338 mgmt
.frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
339 WLAN_FC_STYPE_DEAUTH
);
340 os_memcpy(mgmt
.da
, addr
, ETH_ALEN
);
341 os_memcpy(mgmt
.sa
, hapd
->own_addr
, ETH_ALEN
);
342 os_memcpy(mgmt
.bssid
, hapd
->own_addr
, ETH_ALEN
);
343 mgmt
.u
.deauth
.reason_code
= host_to_le16(reason
);
344 if (hostapd_send_mgmt_frame(hapd
, &mgmt
, IEEE80211_HDRLEN
+
345 sizeof(mgmt
.u
.deauth
), 0) < 0)
346 perror("ieee802_11_send_deauth: send");
350 static u16
auth_shared_key(struct hostapd_data
*hapd
, struct sta_info
*sta
,
351 u16 auth_transaction
, u8
*challenge
, int iswep
)
353 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
355 "authentication (shared key, transaction %d)",
358 if (auth_transaction
== 1) {
359 if (!sta
->challenge
) {
360 /* Generate a pseudo-random challenge */
364 sta
->challenge
= os_zalloc(WLAN_AUTH_CHALLENGE_LEN
);
365 if (sta
->challenge
== NULL
)
366 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
370 os_memcpy(key
, &now
, 4);
371 os_memcpy(key
+ 4, &r
, 4);
372 rc4(sta
->challenge
, WLAN_AUTH_CHALLENGE_LEN
,
378 if (auth_transaction
!= 3)
379 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
382 if (!iswep
|| !sta
->challenge
|| !challenge
||
383 os_memcmp(sta
->challenge
, challenge
, WLAN_AUTH_CHALLENGE_LEN
)) {
384 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
386 "shared key authentication - invalid "
387 "challenge-response");
388 return WLAN_STATUS_CHALLENGE_FAIL
;
391 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
393 "authentication OK (shared key)");
394 #ifdef IEEE80211_REQUIRE_AUTH_ACK
395 /* Station will be marked authenticated if it ACKs the
396 * authentication reply. */
398 sta
->flags
|= WLAN_STA_AUTH
;
399 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
401 os_free(sta
->challenge
);
402 sta
->challenge
= NULL
;
408 static void send_auth_reply(struct hostapd_data
*hapd
,
409 const u8
*dst
, const u8
*bssid
,
410 u16 auth_alg
, u16 auth_transaction
, u16 resp
,
411 const u8
*ies
, size_t ies_len
)
413 struct ieee80211_mgmt
*reply
;
417 rlen
= IEEE80211_HDRLEN
+ sizeof(reply
->u
.auth
) + ies_len
;
418 buf
= os_zalloc(rlen
);
422 reply
= (struct ieee80211_mgmt
*) buf
;
423 reply
->frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
425 os_memcpy(reply
->da
, dst
, ETH_ALEN
);
426 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
427 os_memcpy(reply
->bssid
, bssid
, ETH_ALEN
);
429 reply
->u
.auth
.auth_alg
= host_to_le16(auth_alg
);
430 reply
->u
.auth
.auth_transaction
= host_to_le16(auth_transaction
);
431 reply
->u
.auth
.status_code
= host_to_le16(resp
);
434 os_memcpy(reply
->u
.auth
.variable
, ies
, ies_len
);
436 wpa_printf(MSG_DEBUG
, "authentication reply: STA=" MACSTR
437 " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)",
438 MAC2STR(dst
), auth_alg
, auth_transaction
,
439 resp
, (unsigned long) ies_len
);
440 if (hostapd_send_mgmt_frame(hapd
, reply
, rlen
, 0) < 0)
441 perror("send_auth_reply: send");
447 #ifdef CONFIG_IEEE80211R
448 static void handle_auth_ft_finish(void *ctx
, const u8
*dst
, const u8
*bssid
,
449 u16 auth_transaction
, u16 status
,
450 const u8
*ies
, size_t ies_len
)
452 struct hostapd_data
*hapd
= ctx
;
453 struct sta_info
*sta
;
455 send_auth_reply(hapd
, dst
, bssid
, WLAN_AUTH_FT
, auth_transaction
,
456 status
, ies
, ies_len
);
458 if (status
!= WLAN_STATUS_SUCCESS
)
461 sta
= ap_get_sta(hapd
, dst
);
465 hostapd_logger(hapd
, dst
, HOSTAPD_MODULE_IEEE80211
,
466 HOSTAPD_LEVEL_DEBUG
, "authentication OK (FT)");
467 sta
->flags
|= WLAN_STA_AUTH
;
468 mlme_authenticate_indication(hapd
, sta
);
470 #endif /* CONFIG_IEEE80211R */
473 static void handle_auth(struct hostapd_data
*hapd
, struct ieee80211_mgmt
*mgmt
,
476 u16 auth_alg
, auth_transaction
, status_code
;
477 u16 resp
= WLAN_STATUS_SUCCESS
;
478 struct sta_info
*sta
= NULL
;
481 u8
*challenge
= NULL
;
482 u32 session_timeout
, acct_interim_interval
;
484 u8 resp_ies
[2 + WLAN_AUTH_CHALLENGE_LEN
];
485 size_t resp_ies_len
= 0;
487 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
488 printf("handle_auth - too short payload (len=%lu)\n",
489 (unsigned long) len
);
493 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
494 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
495 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
496 fc
= le_to_host16(mgmt
->frame_control
);
498 if (len
>= IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
) +
499 2 + WLAN_AUTH_CHALLENGE_LEN
&&
500 mgmt
->u
.auth
.variable
[0] == WLAN_EID_CHALLENGE
&&
501 mgmt
->u
.auth
.variable
[1] == WLAN_AUTH_CHALLENGE_LEN
)
502 challenge
= &mgmt
->u
.auth
.variable
[2];
504 wpa_printf(MSG_DEBUG
, "authentication: STA=" MACSTR
" auth_alg=%d "
505 "auth_transaction=%d status_code=%d wep=%d%s",
506 MAC2STR(mgmt
->sa
), auth_alg
, auth_transaction
,
507 status_code
, !!(fc
& WLAN_FC_ISWEP
),
508 challenge
? " challenge" : "");
510 if (hapd
->tkip_countermeasures
) {
511 resp
= WLAN_REASON_MICHAEL_MIC_FAILURE
;
515 if (!(((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_OPEN
) &&
516 auth_alg
== WLAN_AUTH_OPEN
) ||
517 #ifdef CONFIG_IEEE80211R
519 (hapd
->conf
->wpa_key_mgmt
&
520 (WPA_KEY_MGMT_FT_IEEE8021X
| WPA_KEY_MGMT_FT_PSK
)) &&
521 auth_alg
== WLAN_AUTH_FT
) ||
522 #endif /* CONFIG_IEEE80211R */
523 ((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_SHARED
) &&
524 auth_alg
== WLAN_AUTH_SHARED_KEY
))) {
525 printf("Unsupported authentication algorithm (%d)\n",
527 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
531 if (!(auth_transaction
== 1 ||
532 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 3))) {
533 printf("Unknown authentication transaction number (%d)\n",
535 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
539 if (os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
540 printf("Station " MACSTR
" not allowed to authenticate.\n",
542 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
546 res
= hostapd_allowed_address(hapd
, mgmt
->sa
, (u8
*) mgmt
, len
,
548 &acct_interim_interval
, &vlan_id
);
549 if (res
== HOSTAPD_ACL_REJECT
) {
550 printf("Station " MACSTR
" not allowed to authenticate.\n",
552 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
555 if (res
== HOSTAPD_ACL_PENDING
) {
556 wpa_printf(MSG_DEBUG
, "Authentication frame from " MACSTR
557 " waiting for an external authentication",
559 /* Authentication code will re-send the authentication frame
560 * after it has received (and cached) information from the
561 * external source. */
565 sta
= ap_sta_add(hapd
, mgmt
->sa
);
567 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
572 if (hostapd_get_vlan_id_ifname(hapd
->conf
->vlan
,
573 sta
->vlan_id
) == NULL
) {
574 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
575 HOSTAPD_LEVEL_INFO
, "Invalid VLAN ID "
576 "%d received from RADIUS server",
578 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
581 sta
->vlan_id
= vlan_id
;
582 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
583 HOSTAPD_LEVEL_INFO
, "VLAN ID %d", sta
->vlan_id
);
586 sta
->flags
&= ~WLAN_STA_PREAUTH
;
587 ieee802_1x_notify_pre_auth(sta
->eapol_sm
, 0);
589 if (hapd
->conf
->radius
->acct_interim_interval
== 0 &&
590 acct_interim_interval
)
591 sta
->acct_interim_interval
= acct_interim_interval
;
592 if (res
== HOSTAPD_ACL_ACCEPT_TIMEOUT
)
593 ap_sta_session_timeout(hapd
, sta
, session_timeout
);
595 ap_sta_no_session_timeout(hapd
, sta
);
599 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
601 "authentication OK (open system)");
602 #ifdef IEEE80211_REQUIRE_AUTH_ACK
603 /* Station will be marked authenticated if it ACKs the
604 * authentication reply. */
606 sta
->flags
|= WLAN_STA_AUTH
;
607 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
608 sta
->auth_alg
= WLAN_AUTH_OPEN
;
609 mlme_authenticate_indication(hapd
, sta
);
612 case WLAN_AUTH_SHARED_KEY
:
613 resp
= auth_shared_key(hapd
, sta
, auth_transaction
, challenge
,
615 sta
->auth_alg
= WLAN_AUTH_SHARED_KEY
;
616 mlme_authenticate_indication(hapd
, sta
);
617 if (sta
->challenge
&& auth_transaction
== 1) {
618 resp_ies
[0] = WLAN_EID_CHALLENGE
;
619 resp_ies
[1] = WLAN_AUTH_CHALLENGE_LEN
;
620 os_memcpy(resp_ies
+ 2, sta
->challenge
,
621 WLAN_AUTH_CHALLENGE_LEN
);
622 resp_ies_len
= 2 + WLAN_AUTH_CHALLENGE_LEN
;
625 #ifdef CONFIG_IEEE80211R
627 sta
->auth_alg
= WLAN_AUTH_FT
;
628 if (sta
->wpa_sm
== NULL
)
629 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
631 if (sta
->wpa_sm
== NULL
) {
632 wpa_printf(MSG_DEBUG
, "FT: Failed to initialize WPA "
634 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
637 wpa_ft_process_auth(sta
->wpa_sm
, mgmt
->bssid
,
638 auth_transaction
, mgmt
->u
.auth
.variable
,
639 len
- IEEE80211_HDRLEN
-
640 sizeof(mgmt
->u
.auth
),
641 handle_auth_ft_finish
, hapd
);
642 /* handle_auth_ft_finish() callback will complete auth. */
644 #endif /* CONFIG_IEEE80211R */
648 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, auth_alg
,
649 auth_transaction
+ 1, resp
, resp_ies
, resp_ies_len
);
653 static void handle_assoc(struct hostapd_data
*hapd
,
654 struct ieee80211_mgmt
*mgmt
, size_t len
, int reassoc
)
656 u16 capab_info
, listen_interval
;
657 u16 resp
= WLAN_STATUS_SUCCESS
;
660 int send_deauth
= 0, send_len
, left
, i
;
661 struct sta_info
*sta
;
662 struct ieee802_11_elems elems
;
663 u8 buf
[sizeof(struct ieee80211_mgmt
) + 512];
664 struct ieee80211_mgmt
*reply
;
666 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_req
) :
667 sizeof(mgmt
->u
.assoc_req
))) {
668 printf("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
669 "\n", reassoc
, (unsigned long) len
);
674 capab_info
= le_to_host16(mgmt
->u
.reassoc_req
.capab_info
);
675 listen_interval
= le_to_host16(
676 mgmt
->u
.reassoc_req
.listen_interval
);
677 wpa_printf(MSG_DEBUG
, "reassociation request: STA=" MACSTR
678 " capab_info=0x%02x listen_interval=%d current_ap="
680 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
681 MAC2STR(mgmt
->u
.reassoc_req
.current_ap
));
682 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.reassoc_req
));
683 pos
= mgmt
->u
.reassoc_req
.variable
;
685 capab_info
= le_to_host16(mgmt
->u
.assoc_req
.capab_info
);
686 listen_interval
= le_to_host16(
687 mgmt
->u
.assoc_req
.listen_interval
);
688 wpa_printf(MSG_DEBUG
, "association request: STA=" MACSTR
689 " capab_info=0x%02x listen_interval=%d",
690 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
);
691 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.assoc_req
));
692 pos
= mgmt
->u
.assoc_req
.variable
;
695 sta
= ap_get_sta(hapd
, mgmt
->sa
);
696 #ifdef CONFIG_IEEE80211R
697 if (sta
&& sta
->auth_alg
== WLAN_AUTH_FT
&&
698 (sta
->flags
& WLAN_STA_AUTH
) == 0) {
699 wpa_printf(MSG_DEBUG
, "FT: Allow STA " MACSTR
" to associate "
700 "prior to authentication since it is using "
701 "over-the-DS FT", MAC2STR(mgmt
->sa
));
703 #endif /* CONFIG_IEEE80211R */
704 if (sta
== NULL
|| (sta
->flags
& WLAN_STA_AUTH
) == 0) {
705 printf("STA " MACSTR
" trying to associate before "
706 "authentication\n", MAC2STR(mgmt
->sa
));
708 printf(" sta: addr=" MACSTR
" aid=%d flags=0x%04x\n",
709 MAC2STR(sta
->addr
), sta
->aid
, sta
->flags
);
712 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
716 if (hapd
->tkip_countermeasures
) {
717 resp
= WLAN_REASON_MICHAEL_MIC_FAILURE
;
721 if (listen_interval
> hapd
->conf
->max_listen_interval
) {
722 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
724 "Too large Listen Interval (%d)",
726 resp
= WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE
;
730 sta
->capability
= capab_info
;
731 sta
->listen_interval
= listen_interval
;
733 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
735 if (ieee802_11_parse_elems(pos
, left
, &elems
, 1) == ParseFailed
||
737 printf("STA " MACSTR
" sent invalid association request\n",
739 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
743 if (elems
.ssid_len
!= hapd
->conf
->ssid
.ssid_len
||
744 os_memcmp(elems
.ssid
, hapd
->conf
->ssid
.ssid
, elems
.ssid_len
) != 0)
747 ieee802_11_print_ssid(ssid_txt
, elems
.ssid
, elems
.ssid_len
);
748 printf("Station " MACSTR
" tried to associate with "
749 "unknown SSID '%s'\n", MAC2STR(sta
->addr
), ssid_txt
);
750 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
754 sta
->flags
&= ~WLAN_STA_WME
;
755 if (elems
.wme
&& hapd
->conf
->wme_enabled
) {
756 if (hostapd_eid_wme_valid(hapd
, elems
.wme
, elems
.wme_len
))
757 hostapd_logger(hapd
, sta
->addr
,
760 "invalid WME element in association "
763 sta
->flags
|= WLAN_STA_WME
;
766 if (!elems
.supp_rates
) {
767 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
769 "No supported rates element in AssocReq");
770 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
774 if (elems
.supp_rates_len
> sizeof(sta
->supported_rates
)) {
775 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
777 "Invalid supported rates element length %d",
778 elems
.supp_rates_len
);
779 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
783 os_memset(sta
->supported_rates
, 0, sizeof(sta
->supported_rates
));
784 os_memcpy(sta
->supported_rates
, elems
.supp_rates
,
785 elems
.supp_rates_len
);
786 sta
->supported_rates_len
= elems
.supp_rates_len
;
788 if (elems
.ext_supp_rates
) {
789 if (elems
.supp_rates_len
+ elems
.ext_supp_rates_len
>
790 sizeof(sta
->supported_rates
)) {
791 hostapd_logger(hapd
, mgmt
->sa
,
792 HOSTAPD_MODULE_IEEE80211
,
794 "Invalid supported rates element length"
795 " %d+%d", elems
.supp_rates_len
,
796 elems
.ext_supp_rates_len
);
797 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
801 os_memcpy(sta
->supported_rates
+ elems
.supp_rates_len
,
802 elems
.ext_supp_rates
, elems
.ext_supp_rates_len
);
803 sta
->supported_rates_len
+= elems
.ext_supp_rates_len
;
806 #ifdef CONFIG_IEEE80211N
807 /* save HT capabilities in the sta object */
808 os_memset(&sta
->ht_capabilities
, 0, sizeof(sta
->ht_capabilities
));
809 if (elems
.ht_capabilities
&&
810 elems
.ht_capabilities_len
>= sizeof(struct ieee80211_ht_capability
)
811 && (sta
->flags
& WLAN_STA_WME
)) {
812 /* note: without WMM capability, treat the sta as non-HT */
813 sta
->flags
|= WLAN_STA_HT
;
814 sta
->ht_capabilities
.id
= WLAN_EID_HT_CAP
;
815 sta
->ht_capabilities
.length
=
816 sizeof(struct ieee80211_ht_capability
);
817 os_memcpy(&sta
->ht_capabilities
.data
,
818 elems
.ht_capabilities
,
819 sizeof(struct ieee80211_ht_capability
));
821 sta
->flags
&= ~WLAN_STA_HT
;
822 #endif /* CONFIG_IEEE80211N */
824 if ((hapd
->conf
->wpa
& WPA_PROTO_RSN
) && elems
.rsn_ie
) {
825 wpa_ie
= elems
.rsn_ie
;
826 wpa_ie_len
= elems
.rsn_ie_len
;
827 } else if ((hapd
->conf
->wpa
& WPA_PROTO_WPA
) &&
829 wpa_ie
= elems
.wpa_ie
;
830 wpa_ie_len
= elems
.wpa_ie_len
;
836 sta
->flags
&= ~(WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
);
837 if (hapd
->conf
->wps_state
&& wpa_ie
== NULL
) {
839 wpa_printf(MSG_DEBUG
, "STA included WPS IE in "
840 "(Re)Association Request - assume WPS is "
842 sta
->flags
|= WLAN_STA_WPS
;
843 wpabuf_free(sta
->wps_ie
);
844 sta
->wps_ie
= wpabuf_alloc_copy(elems
.wps_ie
+ 4,
845 elems
.wps_ie_len
- 4);
847 wpa_printf(MSG_DEBUG
, "STA did not include WPA/RSN IE "
848 "in (Re)Association Request - possible WPS "
850 sta
->flags
|= WLAN_STA_MAYBE_WPS
;
853 #endif /* CONFIG_WPS */
854 if (hapd
->conf
->wpa
&& wpa_ie
== NULL
) {
855 printf("STA " MACSTR
": No WPA/RSN IE in association "
856 "request\n", MAC2STR(sta
->addr
));
857 resp
= WLAN_STATUS_INVALID_IE
;
861 if (hapd
->conf
->wpa
&& wpa_ie
) {
865 if (sta
->wpa_sm
== NULL
)
866 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
868 if (sta
->wpa_sm
== NULL
) {
869 printf("Failed to initialize WPA state machine\n");
870 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
873 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
875 elems
.mdie
, elems
.mdie_len
);
876 if (res
== WPA_INVALID_GROUP
)
877 resp
= WLAN_STATUS_GROUP_CIPHER_NOT_VALID
;
878 else if (res
== WPA_INVALID_PAIRWISE
)
879 resp
= WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID
;
880 else if (res
== WPA_INVALID_AKMP
)
881 resp
= WLAN_STATUS_AKMP_NOT_VALID
;
882 else if (res
== WPA_ALLOC_FAIL
)
883 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
884 #ifdef CONFIG_IEEE80211W
885 else if (res
== WPA_MGMT_FRAME_PROTECTION_VIOLATION
)
886 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
; /* FIX */
887 else if (res
== WPA_INVALID_MGMT_GROUP_CIPHER
)
888 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
; /* FIX */
889 #endif /* CONFIG_IEEE80211W */
890 else if (res
== WPA_INVALID_MDIE
)
891 resp
= WLAN_STATUS_INVALID_MDIE
;
892 else if (res
!= WPA_IE_OK
)
893 resp
= WLAN_STATUS_INVALID_IE
;
894 if (resp
!= WLAN_STATUS_SUCCESS
)
896 #ifdef CONFIG_IEEE80211W
897 if ((sta
->flags
& WLAN_STA_MFP
) && !sta
->ping_timed_out
) {
899 * STA has already been associated with MFP and ping
900 * timeout has not been reached. Reject the
901 * association attempt temporarily and start ping, if
902 * one is not pending.
905 if (sta
->ping_count
== 0)
906 ap_sta_start_ping(hapd
, sta
);
908 resp
= WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
;
912 if (wpa_auth_uses_mfp(sta
->wpa_sm
))
913 sta
->flags
|= WLAN_STA_MFP
;
915 sta
->flags
&= ~WLAN_STA_MFP
;
916 #endif /* CONFIG_IEEE80211W */
918 #ifdef CONFIG_IEEE80211R
919 if (sta
->auth_alg
== WLAN_AUTH_FT
) {
921 wpa_printf(MSG_DEBUG
, "FT: " MACSTR
" tried "
922 "to use association (not "
923 "re-association) with FT auth_alg",
925 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
929 resp
= wpa_ft_validate_reassoc(sta
->wpa_sm
, pos
, left
);
930 if (resp
!= WLAN_STATUS_SUCCESS
)
933 #endif /* CONFIG_IEEE80211R */
935 wpa_auth_sta_no_wpa(sta
->wpa_sm
);
937 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
938 sta
->flags
|= WLAN_STA_NONERP
;
939 for (i
= 0; i
< sta
->supported_rates_len
; i
++) {
940 if ((sta
->supported_rates
[i
] & 0x7f) > 22) {
941 sta
->flags
&= ~WLAN_STA_NONERP
;
945 if (sta
->flags
& WLAN_STA_NONERP
&& !sta
->nonerp_set
) {
947 hapd
->iface
->num_sta_non_erp
++;
948 if (hapd
->iface
->num_sta_non_erp
== 1)
949 ieee802_11_set_beacons(hapd
->iface
);
952 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
) &&
953 !sta
->no_short_slot_time_set
) {
954 sta
->no_short_slot_time_set
= 1;
955 hapd
->iface
->num_sta_no_short_slot_time
++;
956 if (hapd
->iface
->current_mode
->mode
==
957 HOSTAPD_MODE_IEEE80211G
&&
958 hapd
->iface
->num_sta_no_short_slot_time
== 1)
959 ieee802_11_set_beacons(hapd
->iface
);
962 if (sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
963 sta
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
965 sta
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
967 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
) &&
968 !sta
->no_short_preamble_set
) {
969 sta
->no_short_preamble_set
= 1;
970 hapd
->iface
->num_sta_no_short_preamble
++;
971 if (hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
972 && hapd
->iface
->num_sta_no_short_preamble
== 1)
973 ieee802_11_set_beacons(hapd
->iface
);
976 #ifdef CONFIG_IEEE80211N
977 if (sta
->flags
& WLAN_STA_HT
) {
978 u16 ht_capab
= le_to_host16(
979 sta
->ht_capabilities
.data
.capabilities_info
);
980 wpa_printf(MSG_DEBUG
, "HT: STA " MACSTR
" HT Capabilities "
981 "Info: 0x%04x", MAC2STR(sta
->addr
), ht_capab
);
982 if ((ht_capab
& HT_CAP_INFO_GREEN_FIELD
) == 0) {
983 hapd
->iface
->num_sta_ht_no_gf
++;
984 wpa_printf(MSG_DEBUG
, "%s STA " MACSTR
" - no "
985 "greenfield, num of non-gf stations %d",
986 __func__
, MAC2STR(sta
->addr
),
987 hapd
->iface
->num_sta_ht_no_gf
);
989 if ((ht_capab
& HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
) == 0) {
990 hapd
->iface
->num_sta_ht_20mhz
++;
991 wpa_printf(MSG_DEBUG
, "%s STA " MACSTR
" - 20 MHz HT, "
992 "num of 20MHz HT STAs %d",
993 __func__
, MAC2STR(sta
->addr
),
994 hapd
->iface
->num_sta_ht_20mhz
);
997 hapd
->iface
->num_sta_no_ht
++;
998 if (hapd
->iconf
->ieee80211n
) {
999 wpa_printf(MSG_DEBUG
, "%s STA " MACSTR
1000 " - no HT, num of non-HT stations %d",
1001 __func__
, MAC2STR(sta
->addr
),
1002 hapd
->iface
->num_sta_no_ht
);
1006 if (hostapd_ht_operation_update(hapd
->iface
) > 0)
1007 ieee802_11_set_beacons(hapd
->iface
);
1008 #endif /* CONFIG_IEEE80211N */
1010 /* get a unique AID */
1012 wpa_printf(MSG_DEBUG
, " old AID %d", sta
->aid
);
1014 for (sta
->aid
= 1; sta
->aid
<= MAX_AID_TABLE_SIZE
; sta
->aid
++)
1015 if (hapd
->sta_aid
[sta
->aid
- 1] == NULL
)
1017 if (sta
->aid
> MAX_AID_TABLE_SIZE
) {
1019 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
1020 wpa_printf(MSG_ERROR
, " no room for more AIDs");
1023 hapd
->sta_aid
[sta
->aid
- 1] = sta
;
1024 wpa_printf(MSG_DEBUG
, " new AID %d", sta
->aid
);
1028 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1029 HOSTAPD_LEVEL_DEBUG
,
1030 "association OK (aid %d)", sta
->aid
);
1031 /* Station will be marked associated, after it acknowledges AssocResp
1035 os_memcpy(sta
->previous_ap
, mgmt
->u
.reassoc_req
.current_ap
,
1039 if (sta
->last_assoc_req
)
1040 os_free(sta
->last_assoc_req
);
1041 sta
->last_assoc_req
= os_malloc(len
);
1042 if (sta
->last_assoc_req
)
1043 os_memcpy(sta
->last_assoc_req
, mgmt
, len
);
1045 /* Make sure that the previously registered inactivity timer will not
1046 * remove the STA immediately. */
1047 sta
->timeout_next
= STA_NULLFUNC
;
1050 os_memset(buf
, 0, sizeof(buf
));
1051 reply
= (struct ieee80211_mgmt
*) buf
;
1052 reply
->frame_control
=
1053 IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
1054 (send_deauth
? WLAN_FC_STYPE_DEAUTH
:
1055 (reassoc
? WLAN_FC_STYPE_REASSOC_RESP
:
1056 WLAN_FC_STYPE_ASSOC_RESP
)));
1057 os_memcpy(reply
->da
, mgmt
->sa
, ETH_ALEN
);
1058 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
1059 os_memcpy(reply
->bssid
, mgmt
->bssid
, ETH_ALEN
);
1061 send_len
= IEEE80211_HDRLEN
;
1063 send_len
+= sizeof(reply
->u
.deauth
);
1064 reply
->u
.deauth
.reason_code
= host_to_le16(resp
);
1067 send_len
+= sizeof(reply
->u
.assoc_resp
);
1068 reply
->u
.assoc_resp
.capab_info
=
1069 host_to_le16(hostapd_own_capab_info(hapd
, sta
, 0));
1070 reply
->u
.assoc_resp
.status_code
= host_to_le16(resp
);
1071 reply
->u
.assoc_resp
.aid
= host_to_le16((sta
? sta
->aid
: 0)
1072 | BIT(14) | BIT(15));
1073 /* Supported rates */
1074 p
= hostapd_eid_supp_rates(hapd
, reply
->u
.assoc_resp
.variable
);
1075 /* Extended supported rates */
1076 p
= hostapd_eid_ext_supp_rates(hapd
, p
);
1077 if (sta
->flags
& WLAN_STA_WME
)
1078 p
= hostapd_eid_wme(hapd
, p
);
1080 p
= hostapd_eid_ht_capabilities_info(hapd
, p
);
1081 p
= hostapd_eid_ht_operation(hapd
, p
);
1083 #ifdef CONFIG_IEEE80211R
1084 if (resp
== WLAN_STATUS_SUCCESS
) {
1085 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
1086 * Transition Information, RSN */
1087 p
= wpa_sm_write_assoc_resp_ies(sta
->wpa_sm
, p
,
1088 buf
+ sizeof(buf
) - p
,
1091 #endif /* CONFIG_IEEE80211R */
1093 #ifdef CONFIG_IEEE80211W
1094 if (resp
== WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
)
1095 p
= hostapd_eid_assoc_comeback_time(hapd
, sta
, p
);
1096 #endif /* CONFIG_IEEE80211W */
1098 send_len
+= p
- reply
->u
.assoc_resp
.variable
;
1101 if (hostapd_send_mgmt_frame(hapd
, reply
, send_len
, 0) < 0)
1102 perror("handle_assoc: send");
1106 static void handle_disassoc(struct hostapd_data
*hapd
,
1107 struct ieee80211_mgmt
*mgmt
, size_t len
)
1109 struct sta_info
*sta
;
1111 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.disassoc
)) {
1112 printf("handle_disassoc - too short payload (len=%lu)\n",
1113 (unsigned long) len
);
1117 wpa_printf(MSG_DEBUG
, "disassocation: STA=" MACSTR
" reason_code=%d",
1119 le_to_host16(mgmt
->u
.disassoc
.reason_code
));
1121 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1123 printf("Station " MACSTR
" trying to disassociate, but it "
1124 "is not associated.\n", MAC2STR(mgmt
->sa
));
1128 sta
->flags
&= ~WLAN_STA_ASSOC
;
1129 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
1130 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1131 HOSTAPD_LEVEL_INFO
, "disassociated");
1132 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
1133 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
1134 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
1136 accounting_sta_stop(hapd
, sta
);
1137 ieee802_1x_free_station(sta
);
1138 hostapd_sta_remove(hapd
, sta
->addr
);
1140 if (sta
->timeout_next
== STA_NULLFUNC
||
1141 sta
->timeout_next
== STA_DISASSOC
) {
1142 sta
->timeout_next
= STA_DEAUTH
;
1143 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
1144 eloop_register_timeout(AP_DEAUTH_DELAY
, 0, ap_handle_timer
,
1148 mlme_disassociate_indication(
1149 hapd
, sta
, le_to_host16(mgmt
->u
.disassoc
.reason_code
));
1153 static void handle_deauth(struct hostapd_data
*hapd
,
1154 struct ieee80211_mgmt
*mgmt
, size_t len
)
1156 struct sta_info
*sta
;
1158 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.deauth
)) {
1159 printf("handle_deauth - too short payload (len=%lu)\n",
1160 (unsigned long) len
);
1164 wpa_printf(MSG_DEBUG
, "deauthentication: STA=" MACSTR
1167 le_to_host16(mgmt
->u
.deauth
.reason_code
));
1169 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1171 printf("Station " MACSTR
" trying to deauthenticate, but it "
1172 "is not authenticated.\n", MAC2STR(mgmt
->sa
));
1176 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
);
1177 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
1178 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1179 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
1180 mlme_deauthenticate_indication(
1181 hapd
, sta
, le_to_host16(mgmt
->u
.deauth
.reason_code
));
1182 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
1183 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
1184 ap_free_sta(hapd
, sta
);
1188 static void handle_beacon(struct hostapd_data
*hapd
,
1189 struct ieee80211_mgmt
*mgmt
, size_t len
,
1190 struct hostapd_frame_info
*fi
)
1192 struct ieee802_11_elems elems
;
1194 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.beacon
)) {
1195 printf("handle_beacon - too short payload (len=%lu)\n",
1196 (unsigned long) len
);
1200 (void) ieee802_11_parse_elems(mgmt
->u
.beacon
.variable
,
1201 len
- (IEEE80211_HDRLEN
+
1202 sizeof(mgmt
->u
.beacon
)), &elems
,
1205 ap_list_process_beacon(hapd
->iface
, mgmt
, &elems
, fi
);
1209 #ifdef CONFIG_IEEE80211W
1210 static void hostapd_ping_action(struct hostapd_data
*hapd
,
1211 struct ieee80211_mgmt
*mgmt
, size_t len
)
1213 struct sta_info
*sta
;
1217 end
= mgmt
->u
.action
.u
.ping_resp
.trans_id
+ WLAN_PING_TRANS_ID_LEN
;
1218 if (((u8
*) mgmt
) + len
< end
) {
1219 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Too short Ping Action "
1220 "frame (len=%lu)", (unsigned long) len
);
1224 if (mgmt
->u
.action
.u
.ping_resp
.action
!= WLAN_PING_RESPONSE
) {
1225 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Unexpected Ping Action %d",
1226 mgmt
->u
.action
.u
.ping_resp
.action
);
1230 /* MLME-PING.confirm */
1232 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1233 if (sta
== NULL
|| sta
->ping_trans_id
== NULL
) {
1234 wpa_printf(MSG_DEBUG
, "IEEE 802.11: No matching STA with "
1235 "pending ping request found");
1239 for (i
= 0; i
< sta
->ping_count
; i
++) {
1240 if (os_memcmp(sta
->ping_trans_id
+ i
* WLAN_PING_TRANS_ID_LEN
,
1241 mgmt
->u
.action
.u
.ping_resp
.trans_id
,
1242 WLAN_PING_TRANS_ID_LEN
) == 0)
1246 if (i
>= sta
->ping_count
) {
1247 wpa_printf(MSG_DEBUG
, "IEEE 802.11: No matching ping "
1248 "transaction identifier found");
1252 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1253 HOSTAPD_LEVEL_DEBUG
, "Reply to pending ping received");
1254 ap_sta_stop_ping(hapd
, sta
);
1256 #endif /* CONFIG_IEEE80211W */
1259 static void handle_action(struct hostapd_data
*hapd
,
1260 struct ieee80211_mgmt
*mgmt
, size_t len
)
1262 if (len
< IEEE80211_HDRLEN
+ 1) {
1263 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1264 HOSTAPD_LEVEL_DEBUG
,
1265 "handle_action - too short payload (len=%lu)",
1266 (unsigned long) len
);
1270 switch (mgmt
->u
.action
.category
) {
1271 #ifdef CONFIG_IEEE80211R
1272 case WLAN_ACTION_FT
:
1274 struct sta_info
*sta
;
1276 sta
= ap_get_sta(hapd
, mgmt
->sa
);
1277 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
1278 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Ignored FT Action "
1279 "frame from unassociated STA " MACSTR
,
1284 if (wpa_ft_action_rx(sta
->wpa_sm
, (u8
*) &mgmt
->u
.action
,
1285 len
- IEEE80211_HDRLEN
))
1290 #endif /* CONFIG_IEEE80211R */
1291 case WLAN_ACTION_WMM
:
1292 hostapd_wme_action(hapd
, mgmt
, len
);
1294 #ifdef CONFIG_IEEE80211W
1295 case WLAN_ACTION_PING
:
1296 hostapd_ping_action(hapd
, mgmt
, len
);
1298 #endif /* CONFIG_IEEE80211W */
1301 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1302 HOSTAPD_LEVEL_DEBUG
,
1303 "handle_action - unknown action category %d or invalid "
1305 mgmt
->u
.action
.category
);
1306 if (!(mgmt
->da
[0] & 0x01) && !(mgmt
->u
.action
.category
& 0x80) &&
1307 !(mgmt
->sa
[0] & 0x01)) {
1309 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
1310 * Return the Action frame to the source without change
1311 * except that MSB of the Category set to 1.
1313 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Return unknown Action "
1314 "frame back to sender");
1315 os_memcpy(mgmt
->da
, mgmt
->sa
, ETH_ALEN
);
1316 os_memcpy(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
);
1317 os_memcpy(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
);
1318 mgmt
->u
.action
.category
|= 0x80;
1320 hostapd_send_mgmt_frame(hapd
, mgmt
, len
, 0);
1326 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
1327 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
1329 * @buf: management frame data (starting from IEEE 802.11 header)
1330 * @len: length of frame data in octets
1331 * @stype: management frame subtype from frame control field
1333 * Process all incoming IEEE 802.11 management frames. This will be called for
1334 * each frame received from the kernel driver through wlan#ap interface. In
1335 * addition, it can be called to re-inserted pending frames (e.g., when using
1336 * external RADIUS server as an MAC ACL).
1338 void ieee802_11_mgmt(struct hostapd_data
*hapd
, u8
*buf
, size_t len
, u16 stype
,
1339 struct hostapd_frame_info
*fi
)
1341 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) buf
;
1344 if (stype
== WLAN_FC_STYPE_BEACON
) {
1345 handle_beacon(hapd
, mgmt
, len
, fi
);
1349 if (fi
&& fi
->passive_scan
)
1352 broadcast
= mgmt
->bssid
[0] == 0xff && mgmt
->bssid
[1] == 0xff &&
1353 mgmt
->bssid
[2] == 0xff && mgmt
->bssid
[3] == 0xff &&
1354 mgmt
->bssid
[4] == 0xff && mgmt
->bssid
[5] == 0xff;
1357 os_memcmp(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
) != 0) {
1358 printf("MGMT: BSSID=" MACSTR
" not our address\n",
1359 MAC2STR(mgmt
->bssid
));
1364 if (stype
== WLAN_FC_STYPE_PROBE_REQ
) {
1365 handle_probe_req(hapd
, mgmt
, len
);
1369 if (os_memcmp(mgmt
->da
, hapd
->own_addr
, ETH_ALEN
) != 0) {
1370 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1371 HOSTAPD_LEVEL_DEBUG
,
1372 "MGMT: DA=" MACSTR
" not our address",
1378 case WLAN_FC_STYPE_AUTH
:
1379 wpa_printf(MSG_DEBUG
, "mgmt::auth");
1380 handle_auth(hapd
, mgmt
, len
);
1382 case WLAN_FC_STYPE_ASSOC_REQ
:
1383 wpa_printf(MSG_DEBUG
, "mgmt::assoc_req");
1384 handle_assoc(hapd
, mgmt
, len
, 0);
1386 case WLAN_FC_STYPE_REASSOC_REQ
:
1387 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_req");
1388 handle_assoc(hapd
, mgmt
, len
, 1);
1390 case WLAN_FC_STYPE_DISASSOC
:
1391 wpa_printf(MSG_DEBUG
, "mgmt::disassoc");
1392 handle_disassoc(hapd
, mgmt
, len
);
1394 case WLAN_FC_STYPE_DEAUTH
:
1395 wpa_printf(MSG_DEBUG
, "mgmt::deauth");
1396 handle_deauth(hapd
, mgmt
, len
);
1398 case WLAN_FC_STYPE_ACTION
:
1399 wpa_printf(MSG_DEBUG
, "mgmt::action");
1400 handle_action(hapd
, mgmt
, len
);
1403 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
1404 HOSTAPD_LEVEL_DEBUG
,
1405 "unknown mgmt frame subtype %d", stype
);
1411 static void handle_auth_cb(struct hostapd_data
*hapd
,
1412 struct ieee80211_mgmt
*mgmt
,
1415 u16 auth_alg
, auth_transaction
, status_code
;
1416 struct sta_info
*sta
;
1419 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
1420 HOSTAPD_LEVEL_NOTICE
,
1421 "did not acknowledge authentication response");
1425 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
1426 printf("handle_auth_cb - too short payload (len=%lu)\n",
1427 (unsigned long) len
);
1431 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
1432 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
1433 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
1435 sta
= ap_get_sta(hapd
, mgmt
->da
);
1437 printf("handle_auth_cb: STA " MACSTR
" not found\n",
1442 if (status_code
== WLAN_STATUS_SUCCESS
&&
1443 ((auth_alg
== WLAN_AUTH_OPEN
&& auth_transaction
== 2) ||
1444 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 4))) {
1445 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1446 HOSTAPD_LEVEL_INFO
, "authenticated");
1447 sta
->flags
|= WLAN_STA_AUTH
;
1452 static void handle_assoc_cb(struct hostapd_data
*hapd
,
1453 struct ieee80211_mgmt
*mgmt
,
1454 size_t len
, int reassoc
, int ok
)
1457 struct sta_info
*sta
;
1459 struct ht_cap_ie
*ht_cap
= NULL
;
1462 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
1463 HOSTAPD_LEVEL_DEBUG
,
1464 "did not acknowledge association response");
1468 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_resp
) :
1469 sizeof(mgmt
->u
.assoc_resp
))) {
1470 printf("handle_assoc_cb(reassoc=%d) - too short payload "
1471 "(len=%lu)\n", reassoc
, (unsigned long) len
);
1476 status
= le_to_host16(mgmt
->u
.reassoc_resp
.status_code
);
1478 status
= le_to_host16(mgmt
->u
.assoc_resp
.status_code
);
1480 sta
= ap_get_sta(hapd
, mgmt
->da
);
1482 printf("handle_assoc_cb: STA " MACSTR
" not found\n",
1487 if (status
!= WLAN_STATUS_SUCCESS
)
1490 /* Stop previous accounting session, if one is started, and allocate
1491 * new session id for the new session. */
1492 accounting_sta_stop(hapd
, sta
);
1494 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1496 "associated (aid %d)",
1499 if (sta
->flags
& WLAN_STA_ASSOC
)
1501 sta
->flags
|= WLAN_STA_ASSOC
;
1504 mlme_reassociate_indication(hapd
, sta
);
1506 mlme_associate_indication(hapd
, sta
);
1508 #ifdef CONFIG_IEEE80211N
1509 if (sta
->flags
& WLAN_STA_HT
)
1510 ht_cap
= &sta
->ht_capabilities
;
1511 #endif /* CONFIG_IEEE80211N */
1513 #ifdef CONFIG_IEEE80211W
1514 sta
->ping_timed_out
= 0;
1515 #endif /* CONFIG_IEEE80211W */
1517 if (hostapd_sta_add(hapd
->conf
->iface
, hapd
, sta
->addr
, sta
->aid
,
1518 sta
->capability
, sta
->supported_rates
,
1519 sta
->supported_rates_len
, 0, sta
->listen_interval
,
1522 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1523 HOSTAPD_LEVEL_NOTICE
,
1524 "Could not add STA to kernel driver");
1527 if (sta
->eapol_sm
== NULL
) {
1529 * This STA does not use RADIUS server for EAP authentication,
1530 * so bind it to the selected VLAN interface now, since the
1531 * interface selection is not going to change anymore.
1533 ap_sta_bind_vlan(hapd
, sta
, 0);
1534 } else if (sta
->vlan_id
) {
1535 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
1536 ap_sta_bind_vlan(hapd
, sta
, 0);
1538 if (sta
->flags
& WLAN_STA_SHORT_PREAMBLE
) {
1539 hostapd_sta_set_flags(hapd
, sta
->addr
, sta
->flags
,
1540 WLAN_STA_SHORT_PREAMBLE
, ~0);
1542 hostapd_sta_set_flags(hapd
, sta
->addr
, sta
->flags
,
1543 0, ~WLAN_STA_SHORT_PREAMBLE
);
1546 if (sta
->auth_alg
== WLAN_AUTH_FT
)
1547 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC_FT
);
1549 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
1550 hostapd_new_assoc_sta(hapd
, sta
, !new_assoc
);
1552 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
1555 /* Copy of the association request is not needed anymore */
1556 if (sta
->last_assoc_req
) {
1557 os_free(sta
->last_assoc_req
);
1558 sta
->last_assoc_req
= NULL
;
1563 void ieee802_11_mgmt_cb(struct hostapd_data
*hapd
, u8
*buf
, size_t len
,
1566 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) buf
;
1569 case WLAN_FC_STYPE_AUTH
:
1570 wpa_printf(MSG_DEBUG
, "mgmt::auth cb");
1571 handle_auth_cb(hapd
, mgmt
, len
, ok
);
1573 case WLAN_FC_STYPE_ASSOC_RESP
:
1574 wpa_printf(MSG_DEBUG
, "mgmt::assoc_resp cb");
1575 handle_assoc_cb(hapd
, mgmt
, len
, 0, ok
);
1577 case WLAN_FC_STYPE_REASSOC_RESP
:
1578 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_resp cb");
1579 handle_assoc_cb(hapd
, mgmt
, len
, 1, ok
);
1581 case WLAN_FC_STYPE_PROBE_RESP
:
1582 wpa_printf(MSG_DEBUG
, "mgmt::proberesp cb");
1584 case WLAN_FC_STYPE_DEAUTH
:
1587 case WLAN_FC_STYPE_ACTION
:
1588 wpa_printf(MSG_DEBUG
, "mgmt::action cb");
1591 printf("unknown mgmt cb frame subtype %d\n", stype
);
1597 static void ieee80211_tkip_countermeasures_stop(void *eloop_ctx
,
1600 struct hostapd_data
*hapd
= eloop_ctx
;
1601 hapd
->tkip_countermeasures
= 0;
1602 hostapd_set_countermeasures(hapd
, 0);
1603 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_IEEE80211
,
1604 HOSTAPD_LEVEL_INFO
, "TKIP countermeasures ended");
1608 static void ieee80211_tkip_countermeasures_start(struct hostapd_data
*hapd
)
1610 struct sta_info
*sta
;
1612 hostapd_logger(hapd
, NULL
, HOSTAPD_MODULE_IEEE80211
,
1613 HOSTAPD_LEVEL_INFO
, "TKIP countermeasures initiated");
1615 wpa_auth_countermeasures_start(hapd
->wpa_auth
);
1616 hapd
->tkip_countermeasures
= 1;
1617 hostapd_set_countermeasures(hapd
, 1);
1618 wpa_gtk_rekey(hapd
->wpa_auth
);
1619 eloop_cancel_timeout(ieee80211_tkip_countermeasures_stop
, hapd
, NULL
);
1620 eloop_register_timeout(60, 0, ieee80211_tkip_countermeasures_stop
,
1622 for (sta
= hapd
->sta_list
; sta
!= NULL
; sta
= sta
->next
) {
1623 hostapd_sta_deauth(hapd
, sta
->addr
,
1624 WLAN_REASON_MICHAEL_MIC_FAILURE
);
1625 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
|
1626 WLAN_STA_AUTHORIZED
);
1627 hostapd_sta_remove(hapd
, sta
->addr
);
1632 void ieee80211_michael_mic_failure(struct hostapd_data
*hapd
, const u8
*addr
,
1637 if (addr
&& local
) {
1638 struct sta_info
*sta
= ap_get_sta(hapd
, addr
);
1640 wpa_auth_sta_local_mic_failure_report(sta
->wpa_sm
);
1641 hostapd_logger(hapd
, addr
, HOSTAPD_MODULE_IEEE80211
,
1643 "Michael MIC failure detected in "
1645 mlme_michaelmicfailure_indication(hapd
, addr
);
1647 wpa_printf(MSG_DEBUG
,
1648 "MLME-MICHAELMICFAILURE.indication "
1649 "for not associated STA (" MACSTR
1650 ") ignored", MAC2STR(addr
));
1656 if (now
> hapd
->michael_mic_failure
+ 60) {
1657 hapd
->michael_mic_failures
= 1;
1659 hapd
->michael_mic_failures
++;
1660 if (hapd
->michael_mic_failures
> 1)
1661 ieee80211_tkip_countermeasures_start(hapd
);
1663 hapd
->michael_mic_failure
= now
;
1667 int ieee802_11_get_mib(struct hostapd_data
*hapd
, char *buf
, size_t buflen
)
1674 int ieee802_11_get_mib_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1675 char *buf
, size_t buflen
)
1681 #endif /* CONFIG_NATIVE_WINDOWS */