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"
38 #include "ieee802_11h.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 u8 * hostapd_eid_ht_capabilities_info(struct hostapd_data *hapd, u8 *eid)
106 #ifdef CONFIG_IEEE80211N
107 struct ieee80211_ht_capability *cap;
110 if (!hapd->iconf->ieee80211n)
113 *pos++ = WLAN_EID_HT_CAP;
114 *pos++ = sizeof(*cap);
116 cap = (struct ieee80211_ht_capability *) pos;
117 os_memset(cap, 0, sizeof(*cap));
118 SET_2BIT_U8(&cap->mac_ht_params_info,
119 MAC_HT_PARAM_INFO_MAX_RX_AMPDU_FACTOR_OFFSET,
120 MAX_RX_AMPDU_FACTOR_64KB);
122 cap->capabilities_info = host_to_le16(hapd->iconf->ht_capab);
124 cap->supported_mcs_set[0] = 0xff;
125 cap->supported_mcs_set[1] = 0xff;
130 #else /* CONFIG_IEEE80211N */
132 #endif /* CONFIG_IEEE80211N */
136 u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid)
138 #ifdef CONFIG_IEEE80211N
139 struct ieee80211_ht_operation *oper;
142 if (!hapd->iconf->ieee80211n)
145 *pos++ = WLAN_EID_HT_OPERATION;
146 *pos++ = sizeof(*oper);
148 oper = (struct ieee80211_ht_operation *) pos;
149 os_memset(oper, 0, sizeof(*oper));
151 oper->operation_mode = host_to_le16(hapd->iface->ht_op_mode);
153 pos += sizeof(*oper);
156 #else /* CONFIG_IEEE80211N */
158 #endif /* CONFIG_IEEE80211N */
162 #ifdef CONFIG_IEEE80211N
166 Set to 0 (HT pure) under the followign conditions
167 - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
168 - all STAs in the BSS are 20 MHz HT in 20 MHz BSS
169 Set to 1 (HT non-member protection) if there may be non-HT STAs
170 in both the primary and the secondary channel
171 Set to 2 if only HT STAs are associated in BSS,
172 however and at least one 20 MHz HT STA is associated
173 Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
174 (currently non-GF HT station is considered as non-HT STA also)
176 int hostapd_ht_operation_update(struct hostapd_iface *iface)
178 u16 cur_op_mode, new_op_mode;
179 int op_mode_changes = 0;
181 if (!iface->conf->ieee80211n || iface->conf->ht_op_mode_fixed)
184 wpa_printf(MSG_DEBUG, "%s current operation mode=0x%X",
185 __func__, iface->ht_op_mode);
187 if (!(iface->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)
188 && iface->num_sta_ht_no_gf) {
190 HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
192 } else if ((iface->ht_op_mode &
193 HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&
194 iface->num_sta_ht_no_gf == 0) {
196 ~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
200 if (!(iface->ht_op_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
201 (iface->num_sta_no_ht || iface->olbc_ht)) {
202 iface->ht_op_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
204 } else if ((iface->ht_op_mode &
205 HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
206 (iface->num_sta_no_ht == 0 && !iface->olbc_ht)) {
208 ~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
212 /* Note: currently we switch to the MIXED op mode if HT non-greenfield
213 * station is associated. Probably it's a theoretical case, since
214 * it looks like all known HT STAs support greenfield.
217 if (iface->num_sta_no_ht ||
218 (iface->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT))
219 new_op_mode = OP_MODE_MIXED;
220 else if ((iface->conf->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)
221 && iface->num_sta_ht_20mhz)
222 new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED;
223 else if (iface->olbc_ht)
224 new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS;
226 new_op_mode = OP_MODE_PURE;
228 cur_op_mode = iface->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;
229 if (cur_op_mode != new_op_mode) {
230 iface->ht_op_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK;
231 iface->ht_op_mode |= new_op_mode;
235 wpa_printf(MSG_DEBUG, "%s new operation mode=0x%X changes=%d",
236 __func__, iface->ht_op_mode, op_mode_changes);
238 return op_mode_changes;
241 #endif /* CONFIG_IEEE80211N */
244 u16 hostapd_own_capab_info(struct hostapd_data *hapd, struct sta_info *sta,
247 int capab = WLAN_CAPABILITY_ESS;
250 if (hapd->iface->num_sta_no_short_preamble == 0 &&
251 hapd->iconf->preamble == SHORT_PREAMBLE)
252 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
254 privacy = hapd->conf->ssid.wep.keys_set;
256 if (hapd->conf->ieee802_1x &&
257 (hapd->conf->default_wep_key_len ||
258 hapd->conf->individual_wep_key_len))
265 int policy, def_klen;
266 if (probe && sta->ssid_probe) {
267 policy = sta->ssid_probe->security_policy;
268 def_klen = sta->ssid_probe->wep.default_len;
270 policy = sta->ssid->security_policy;
271 def_klen = sta->ssid->wep.default_len;
273 privacy = policy != SECURITY_PLAINTEXT;
274 if (policy == SECURITY_IEEE_802_1X && def_klen == 0)
279 capab |= WLAN_CAPABILITY_PRIVACY;
281 if (hapd->iface->current_mode &&
282 hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G &&
283 hapd->iface->num_sta_no_short_slot_time == 0)
284 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
286 if (hapd->iface->dfs_enable)
287 capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
293 #ifdef CONFIG_IEEE80211W
294 static u8 * hostapd_eid_assoc_comeback_time(struct hostapd_data *hapd,
295 struct sta_info *sta, u8 *eid)
300 *pos++ = WLAN_EID_ASSOC_COMEBACK_TIME;
302 timeout = (hapd->conf->assoc_ping_attempts - sta->ping_count + 1) *
303 hapd->conf->assoc_ping_timeout;
304 WPA_PUT_LE32(pos, timeout);
309 #endif /* CONFIG_IEEE80211W */
312 void ieee802_11_print_ssid(char *buf, const u8 *ssid, u8 len)
315 if (len > HOSTAPD_MAX_SSID_LEN)
316 len = HOSTAPD_MAX_SSID_LEN;
317 for (i = 0; i < len; i++) {
318 if (ssid[i] >= 32 && ssid[i] < 127)
327 void ieee802_11_send_deauth(struct hostapd_data *hapd, u8 *addr, u16 reason)
329 struct ieee80211_mgmt mgmt;
331 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
333 "deauthenticate - reason %d", reason);
334 os_memset(&mgmt, 0, sizeof(mgmt));
335 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
336 WLAN_FC_STYPE_DEAUTH);
337 os_memcpy(mgmt.da, addr, ETH_ALEN);
338 os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
339 os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
340 mgmt.u.deauth.reason_code = host_to_le16(reason);
341 if (hostapd_send_mgmt_frame(hapd, &mgmt, IEEE80211_HDRLEN +
342 sizeof(mgmt.u.deauth), 0) < 0)
343 perror("ieee802_11_send_deauth: send");
347 static void ieee802_11_sta_authenticate(void *eloop_ctx, void *timeout_ctx)
349 struct hostapd_data *hapd = eloop_ctx;
350 struct ieee80211_mgmt mgmt;
353 if (hapd->assoc_ap_state == WAIT_BEACON)
354 hapd->assoc_ap_state = AUTHENTICATE;
355 if (hapd->assoc_ap_state != AUTHENTICATE)
358 ieee802_11_print_ssid(ssid_txt, (u8 *) hapd->assoc_ap_ssid,
359 hapd->assoc_ap_ssid_len);
360 printf("Authenticate with AP " MACSTR " SSID=%s (as station)\n",
361 MAC2STR(hapd->conf->assoc_ap_addr), ssid_txt);
363 os_memset(&mgmt, 0, sizeof(mgmt));
364 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
366 os_memcpy(mgmt.da, hapd->conf->assoc_ap_addr, ETH_ALEN);
367 os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
368 os_memcpy(mgmt.bssid, hapd->conf->assoc_ap_addr, ETH_ALEN);
369 mgmt.u.auth.auth_alg = host_to_le16(WLAN_AUTH_OPEN);
370 mgmt.u.auth.auth_transaction = host_to_le16(1);
371 mgmt.u.auth.status_code = host_to_le16(0);
372 if (hostapd_send_mgmt_frame(hapd, &mgmt, IEEE80211_HDRLEN +
373 sizeof(mgmt.u.auth), 0) < 0)
374 perror("ieee802_11_sta_authenticate: send");
376 /* Try to authenticate again, if this attempt fails or times out. */
377 eloop_register_timeout(5, 0, ieee802_11_sta_authenticate, hapd, NULL);
381 static void ieee802_11_sta_associate(void *eloop_ctx, void *timeout_ctx)
383 struct hostapd_data *hapd = eloop_ctx;
385 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) buf;
389 if (hapd->assoc_ap_state == AUTHENTICATE)
390 hapd->assoc_ap_state = ASSOCIATE;
391 if (hapd->assoc_ap_state != ASSOCIATE)
394 ieee802_11_print_ssid(ssid_txt, (u8 *) hapd->assoc_ap_ssid,
395 hapd->assoc_ap_ssid_len);
396 printf("Associate with AP " MACSTR " SSID=%s (as station)\n",
397 MAC2STR(hapd->conf->assoc_ap_addr), ssid_txt);
399 os_memset(mgmt, 0, sizeof(*mgmt));
400 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
401 WLAN_FC_STYPE_ASSOC_REQ);
402 os_memcpy(mgmt->da, hapd->conf->assoc_ap_addr, ETH_ALEN);
403 os_memcpy(mgmt->sa, hapd->own_addr, ETH_ALEN);
404 os_memcpy(mgmt->bssid, hapd->conf->assoc_ap_addr, ETH_ALEN);
405 mgmt->u.assoc_req.capab_info = host_to_le16(0);
406 mgmt->u.assoc_req.listen_interval = host_to_le16(1);
407 p = &mgmt->u.assoc_req.variable[0];
409 *p++ = WLAN_EID_SSID;
410 *p++ = hapd->assoc_ap_ssid_len;
411 os_memcpy(p, hapd->assoc_ap_ssid, hapd->assoc_ap_ssid_len);
412 p += hapd->assoc_ap_ssid_len;
414 p = hostapd_eid_supp_rates(hapd, p);
415 p = hostapd_eid_ext_supp_rates(hapd, p);
417 if (hostapd_send_mgmt_frame(hapd, mgmt, p - (u8 *) mgmt, 0) < 0)
418 perror("ieee802_11_sta_associate: send");
420 /* Try to authenticate again, if this attempt fails or times out. */
421 eloop_register_timeout(5, 0, ieee802_11_sta_associate, hapd, NULL);
425 static u16 auth_shared_key(struct hostapd_data *hapd, struct sta_info *sta,
426 u16 auth_transaction, u8 *challenge, int iswep)
428 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
430 "authentication (shared key, transaction %d)",
433 if (auth_transaction == 1) {
434 if (!sta->challenge) {
435 /* Generate a pseudo-random challenge */
439 sta->challenge = os_zalloc(WLAN_AUTH_CHALLENGE_LEN);
440 if (sta->challenge == NULL)
441 return WLAN_STATUS_UNSPECIFIED_FAILURE;
445 os_memcpy(key, &now, 4);
446 os_memcpy(key + 4, &r, 4);
447 rc4(sta->challenge, WLAN_AUTH_CHALLENGE_LEN,
453 if (auth_transaction != 3)
454 return WLAN_STATUS_UNSPECIFIED_FAILURE;
457 if (!iswep || !sta->challenge || !challenge ||
458 os_memcmp(sta->challenge, challenge, WLAN_AUTH_CHALLENGE_LEN)) {
459 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
461 "shared key authentication - invalid "
462 "challenge-response");
463 return WLAN_STATUS_CHALLENGE_FAIL;
466 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
468 "authentication OK (shared key)");
469 #ifdef IEEE80211_REQUIRE_AUTH_ACK
470 /* Station will be marked authenticated if it ACKs the
471 * authentication reply. */
473 sta->flags |= WLAN_STA_AUTH;
474 wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
476 os_free(sta->challenge);
477 sta->challenge = NULL;
483 static void send_auth_reply(struct hostapd_data *hapd,
484 const u8 *dst, const u8 *bssid,
485 u16 auth_alg, u16 auth_transaction, u16 resp,
486 const u8 *ies, size_t ies_len)
488 struct ieee80211_mgmt *reply;
492 rlen = IEEE80211_HDRLEN + sizeof(reply->u.auth) + ies_len;
493 buf = os_zalloc(rlen);
497 reply = (struct ieee80211_mgmt *) buf;
498 reply->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
500 os_memcpy(reply->da, dst, ETH_ALEN);
501 os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
502 os_memcpy(reply->bssid, bssid, ETH_ALEN);
504 reply->u.auth.auth_alg = host_to_le16(auth_alg);
505 reply->u.auth.auth_transaction = host_to_le16(auth_transaction);
506 reply->u.auth.status_code = host_to_le16(resp);
509 os_memcpy(reply->u.auth.variable, ies, ies_len);
511 wpa_printf(MSG_DEBUG, "authentication reply: STA=" MACSTR
512 " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)",
513 MAC2STR(dst), auth_alg, auth_transaction,
514 resp, (unsigned long) ies_len);
515 if (hostapd_send_mgmt_frame(hapd, reply, rlen, 0) < 0)
516 perror("send_auth_reply: send");
522 #ifdef CONFIG_IEEE80211R
523 static void handle_auth_ft_finish(void *ctx, const u8 *dst, const u8 *bssid,
524 u16 auth_transaction, u16 status,
525 const u8 *ies, size_t ies_len)
527 struct hostapd_data *hapd = ctx;
528 struct sta_info *sta;
530 send_auth_reply(hapd, dst, bssid, WLAN_AUTH_FT, auth_transaction,
531 status, ies, ies_len);
533 if (status != WLAN_STATUS_SUCCESS)
536 sta = ap_get_sta(hapd, dst);
540 hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211,
541 HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)");
542 sta->flags |= WLAN_STA_AUTH;
543 mlme_authenticate_indication(hapd, sta);
545 #endif /* CONFIG_IEEE80211R */
548 static void handle_auth(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt,
551 u16 auth_alg, auth_transaction, status_code;
552 u16 resp = WLAN_STATUS_SUCCESS;
553 struct sta_info *sta = NULL;
556 u8 *challenge = NULL;
557 u32 session_timeout, acct_interim_interval;
559 u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
560 size_t resp_ies_len = 0;
562 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
563 printf("handle_auth - too short payload (len=%lu)\n",
564 (unsigned long) len);
568 auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
569 auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
570 status_code = le_to_host16(mgmt->u.auth.status_code);
571 fc = le_to_host16(mgmt->frame_control);
573 if (len >= IEEE80211_HDRLEN + sizeof(mgmt->u.auth) +
574 2 + WLAN_AUTH_CHALLENGE_LEN &&
575 mgmt->u.auth.variable[0] == WLAN_EID_CHALLENGE &&
576 mgmt->u.auth.variable[1] == WLAN_AUTH_CHALLENGE_LEN)
577 challenge = &mgmt->u.auth.variable[2];
579 wpa_printf(MSG_DEBUG, "authentication: STA=" MACSTR " auth_alg=%d "
580 "auth_transaction=%d status_code=%d wep=%d%s",
581 MAC2STR(mgmt->sa), auth_alg, auth_transaction,
582 status_code, !!(fc & WLAN_FC_ISWEP),
583 challenge ? " challenge" : "");
585 if (hapd->assoc_ap_state == AUTHENTICATE && auth_transaction == 2 &&
586 os_memcmp(mgmt->sa, hapd->conf->assoc_ap_addr, ETH_ALEN) == 0 &&
587 os_memcmp(mgmt->bssid, hapd->conf->assoc_ap_addr, ETH_ALEN) == 0) {
588 if (status_code != 0) {
589 printf("Authentication (as station) with AP "
590 MACSTR " failed (status_code=%d)\n",
591 MAC2STR(hapd->conf->assoc_ap_addr),
595 printf("Authenticated (as station) with AP " MACSTR "\n",
596 MAC2STR(hapd->conf->assoc_ap_addr));
597 ieee802_11_sta_associate(hapd, NULL);
601 if (hapd->tkip_countermeasures) {
602 resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
606 if (!(((hapd->conf->auth_algs & WPA_AUTH_ALG_OPEN) &&
607 auth_alg == WLAN_AUTH_OPEN) ||
608 #ifdef CONFIG_IEEE80211R
610 (hapd->conf->wpa_key_mgmt &
611 (WPA_KEY_MGMT_FT_IEEE8021X | WPA_KEY_MGMT_FT_PSK)) &&
612 auth_alg == WLAN_AUTH_FT) ||
613 #endif /* CONFIG_IEEE80211R */
614 ((hapd->conf->auth_algs & WPA_AUTH_ALG_SHARED) &&
615 auth_alg == WLAN_AUTH_SHARED_KEY))) {
616 printf("Unsupported authentication algorithm (%d)\n",
618 resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
622 if (!(auth_transaction == 1 ||
623 (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 3))) {
624 printf("Unknown authentication transaction number (%d)\n",
626 resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
630 if (os_memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) {
631 printf("Station " MACSTR " not allowed to authenticate.\n",
633 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
637 res = hostapd_allowed_address(hapd, mgmt->sa, (u8 *) mgmt, len,
639 &acct_interim_interval, &vlan_id);
640 if (res == HOSTAPD_ACL_REJECT) {
641 printf("Station " MACSTR " not allowed to authenticate.\n",
643 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
646 if (res == HOSTAPD_ACL_PENDING) {
647 wpa_printf(MSG_DEBUG, "Authentication frame from " MACSTR
648 " waiting for an external authentication",
650 /* Authentication code will re-send the authentication frame
651 * after it has received (and cached) information from the
652 * external source. */
656 sta = ap_sta_add(hapd, mgmt->sa);
658 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
663 if (hostapd_get_vlan_id_ifname(hapd->conf->vlan,
664 sta->vlan_id) == NULL) {
665 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
666 HOSTAPD_LEVEL_INFO, "Invalid VLAN ID "
667 "%d received from RADIUS server",
669 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
672 sta->vlan_id = vlan_id;
673 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
674 HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);
677 sta->flags &= ~WLAN_STA_PREAUTH;
678 ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);
680 if (hapd->conf->radius->acct_interim_interval == 0 &&
681 acct_interim_interval)
682 sta->acct_interim_interval = acct_interim_interval;
683 if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT)
684 ap_sta_session_timeout(hapd, sta, session_timeout);
686 ap_sta_no_session_timeout(hapd, sta);
690 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
692 "authentication OK (open system)");
693 #ifdef IEEE80211_REQUIRE_AUTH_ACK
694 /* Station will be marked authenticated if it ACKs the
695 * authentication reply. */
697 sta->flags |= WLAN_STA_AUTH;
698 wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
699 sta->auth_alg = WLAN_AUTH_OPEN;
700 mlme_authenticate_indication(hapd, sta);
703 case WLAN_AUTH_SHARED_KEY:
704 resp = auth_shared_key(hapd, sta, auth_transaction, challenge,
706 sta->auth_alg = WLAN_AUTH_SHARED_KEY;
707 mlme_authenticate_indication(hapd, sta);
708 if (sta->challenge && auth_transaction == 1) {
709 resp_ies[0] = WLAN_EID_CHALLENGE;
710 resp_ies[1] = WLAN_AUTH_CHALLENGE_LEN;
711 os_memcpy(resp_ies + 2, sta->challenge,
712 WLAN_AUTH_CHALLENGE_LEN);
713 resp_ies_len = 2 + WLAN_AUTH_CHALLENGE_LEN;
716 #ifdef CONFIG_IEEE80211R
718 sta->auth_alg = WLAN_AUTH_FT;
719 if (sta->wpa_sm == NULL)
720 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
722 if (sta->wpa_sm == NULL) {
723 wpa_printf(MSG_DEBUG, "FT: Failed to initialize WPA "
725 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
728 wpa_ft_process_auth(sta->wpa_sm, mgmt->bssid,
729 auth_transaction, mgmt->u.auth.variable,
730 len - IEEE80211_HDRLEN -
731 sizeof(mgmt->u.auth),
732 handle_auth_ft_finish, hapd);
733 /* handle_auth_ft_finish() callback will complete auth. */
735 #endif /* CONFIG_IEEE80211R */
739 send_auth_reply(hapd, mgmt->sa, mgmt->bssid, auth_alg,
740 auth_transaction + 1, resp, resp_ies, resp_ies_len);
744 static void handle_assoc(struct hostapd_data *hapd,
745 struct ieee80211_mgmt *mgmt, size_t len, int reassoc)
747 u16 capab_info, listen_interval;
748 u16 resp = WLAN_STATUS_SUCCESS;
751 int send_deauth = 0, send_len, left, i;
752 struct sta_info *sta;
753 struct ieee802_11_elems elems;
754 u8 buf[sizeof(struct ieee80211_mgmt) + 512];
755 struct ieee80211_mgmt *reply;
757 if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
758 sizeof(mgmt->u.assoc_req))) {
759 printf("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
760 "\n", reassoc, (unsigned long) len);
765 capab_info = le_to_host16(mgmt->u.reassoc_req.capab_info);
766 listen_interval = le_to_host16(
767 mgmt->u.reassoc_req.listen_interval);
768 wpa_printf(MSG_DEBUG, "reassociation request: STA=" MACSTR
769 " capab_info=0x%02x listen_interval=%d current_ap="
771 MAC2STR(mgmt->sa), capab_info, listen_interval,
772 MAC2STR(mgmt->u.reassoc_req.current_ap));
773 left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req));
774 pos = mgmt->u.reassoc_req.variable;
776 capab_info = le_to_host16(mgmt->u.assoc_req.capab_info);
777 listen_interval = le_to_host16(
778 mgmt->u.assoc_req.listen_interval);
779 wpa_printf(MSG_DEBUG, "association request: STA=" MACSTR
780 " capab_info=0x%02x listen_interval=%d",
781 MAC2STR(mgmt->sa), capab_info, listen_interval);
782 left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req));
783 pos = mgmt->u.assoc_req.variable;
786 sta = ap_get_sta(hapd, mgmt->sa);
787 #ifdef CONFIG_IEEE80211R
788 if (sta && sta->auth_alg == WLAN_AUTH_FT &&
789 (sta->flags & WLAN_STA_AUTH) == 0) {
790 wpa_printf(MSG_DEBUG, "FT: Allow STA " MACSTR " to associate "
791 "prior to authentication since it is using "
792 "over-the-DS FT", MAC2STR(mgmt->sa));
794 #endif /* CONFIG_IEEE80211R */
795 if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) {
796 printf("STA " MACSTR " trying to associate before "
797 "authentication\n", MAC2STR(mgmt->sa));
799 printf(" sta: addr=" MACSTR " aid=%d flags=0x%04x\n",
800 MAC2STR(sta->addr), sta->aid, sta->flags);
803 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
807 if (hapd->tkip_countermeasures) {
808 resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
812 if (listen_interval > hapd->conf->max_listen_interval) {
813 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
815 "Too large Listen Interval (%d)",
817 resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
821 sta->capability = capab_info;
823 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
825 if (ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed ||
827 printf("STA " MACSTR " sent invalid association request\n",
829 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
833 if (elems.ssid_len != hapd->conf->ssid.ssid_len ||
834 os_memcmp(elems.ssid, hapd->conf->ssid.ssid, elems.ssid_len) != 0)
837 ieee802_11_print_ssid(ssid_txt, elems.ssid, elems.ssid_len);
838 printf("Station " MACSTR " tried to associate with "
839 "unknown SSID '%s'\n", MAC2STR(sta->addr), ssid_txt);
840 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
844 sta->flags &= ~WLAN_STA_WME;
845 if (elems.wme && hapd->conf->wme_enabled) {
846 if (hostapd_eid_wme_valid(hapd, elems.wme, elems.wme_len))
847 hostapd_logger(hapd, sta->addr,
850 "invalid WME element in association "
853 sta->flags |= WLAN_STA_WME;
856 if (!elems.supp_rates) {
857 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
859 "No supported rates element in AssocReq");
860 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
864 if (elems.supp_rates_len > sizeof(sta->supported_rates)) {
865 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
867 "Invalid supported rates element length %d",
868 elems.supp_rates_len);
869 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
873 os_memset(sta->supported_rates, 0, sizeof(sta->supported_rates));
874 os_memcpy(sta->supported_rates, elems.supp_rates,
875 elems.supp_rates_len);
876 sta->supported_rates_len = elems.supp_rates_len;
878 if (elems.ext_supp_rates) {
879 if (elems.supp_rates_len + elems.ext_supp_rates_len >
880 sizeof(sta->supported_rates)) {
881 hostapd_logger(hapd, mgmt->sa,
882 HOSTAPD_MODULE_IEEE80211,
884 "Invalid supported rates element length"
885 " %d+%d", elems.supp_rates_len,
886 elems.ext_supp_rates_len);
887 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
891 os_memcpy(sta->supported_rates + elems.supp_rates_len,
892 elems.ext_supp_rates, elems.ext_supp_rates_len);
893 sta->supported_rates_len += elems.ext_supp_rates_len;
896 #ifdef CONFIG_IEEE80211N
897 /* save HT capabilities in the sta object */
898 os_memset(&sta->ht_capabilities, 0, sizeof(sta->ht_capabilities));
899 if (elems.ht_capabilities &&
900 elems.ht_capabilities_len >= sizeof(struct ieee80211_ht_capability)
901 && (sta->flags & WLAN_STA_WME)) {
902 /* note: without WMM capability, treat the sta as non-HT */
903 sta->flags |= WLAN_STA_HT;
904 sta->ht_capabilities.id = WLAN_EID_HT_CAP;
905 sta->ht_capabilities.length =
906 sizeof(struct ieee80211_ht_capability);
907 os_memcpy(&sta->ht_capabilities.data,
908 elems.ht_capabilities,
909 sizeof(struct ieee80211_ht_capability));
911 sta->flags &= ~WLAN_STA_HT;
912 #endif /* CONFIG_IEEE80211N */
914 if ((hapd->conf->wpa & WPA_PROTO_RSN) && elems.rsn_ie) {
915 wpa_ie = elems.rsn_ie;
916 wpa_ie_len = elems.rsn_ie_len;
917 } else if ((hapd->conf->wpa & WPA_PROTO_WPA) &&
919 wpa_ie = elems.wpa_ie;
920 wpa_ie_len = elems.wpa_ie_len;
925 if (hapd->conf->wpa && wpa_ie == NULL) {
926 printf("STA " MACSTR ": No WPA/RSN IE in association "
927 "request\n", MAC2STR(sta->addr));
928 resp = WLAN_STATUS_INVALID_IE;
932 if (hapd->conf->wpa && wpa_ie) {
936 if (sta->wpa_sm == NULL)
937 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
939 if (sta->wpa_sm == NULL) {
940 printf("Failed to initialize WPA state machine\n");
941 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
944 res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
946 elems.mdie, elems.mdie_len);
947 if (res == WPA_INVALID_GROUP)
948 resp = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
949 else if (res == WPA_INVALID_PAIRWISE)
950 resp = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
951 else if (res == WPA_INVALID_AKMP)
952 resp = WLAN_STATUS_AKMP_NOT_VALID;
953 else if (res == WPA_ALLOC_FAIL)
954 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
955 #ifdef CONFIG_IEEE80211W
956 else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION)
957 resp = WLAN_STATUS_UNSPECIFIED_FAILURE; /* FIX */
958 else if (res == WPA_INVALID_MGMT_GROUP_CIPHER)
959 resp = WLAN_STATUS_UNSPECIFIED_FAILURE; /* FIX */
960 #endif /* CONFIG_IEEE80211W */
961 else if (res == WPA_INVALID_MDIE)
962 resp = WLAN_STATUS_INVALID_MDIE;
963 else if (res != WPA_IE_OK)
964 resp = WLAN_STATUS_INVALID_IE;
965 if (resp != WLAN_STATUS_SUCCESS)
967 #ifdef CONFIG_IEEE80211W
968 if ((sta->flags & WLAN_STA_MFP) && !sta->ping_timed_out) {
970 * STA has already been associated with MFP and ping
971 * timeout has not been reached. Reject the
972 * association attempt temporarily and start ping, if
973 * one is not pending.
976 if (sta->ping_count == 0)
977 ap_sta_start_ping(hapd, sta);
979 resp = WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY;
983 if (wpa_auth_uses_mfp(sta->wpa_sm))
984 sta->flags |= WLAN_STA_MFP;
986 sta->flags &= ~WLAN_STA_MFP;
987 #endif /* CONFIG_IEEE80211W */
989 #ifdef CONFIG_IEEE80211R
990 if (sta->auth_alg == WLAN_AUTH_FT) {
992 wpa_printf(MSG_DEBUG, "FT: " MACSTR " tried "
993 "to use association (not "
994 "re-association) with FT auth_alg",
996 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1000 resp = wpa_ft_validate_reassoc(sta->wpa_sm, pos, left);
1001 if (resp != WLAN_STATUS_SUCCESS)
1004 #endif /* CONFIG_IEEE80211R */
1007 if (hapd->iface->dfs_enable &&
1008 hapd->iconf->ieee80211h == SPECT_STRICT_BINDING) {
1009 if (hostapd_check_power_cap(hapd, elems.power_cap,
1010 elems.power_cap_len)) {
1011 resp = WLAN_STATUS_PWR_CAPABILITY_NOT_VALID;
1012 hostapd_logger(hapd, sta->addr,
1013 HOSTAPD_MODULE_IEEE80211,
1014 HOSTAPD_LEVEL_DEBUG,
1015 "Power capabilities of the station not "
1021 if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
1022 sta->flags |= WLAN_STA_NONERP;
1023 for (i = 0; i < sta->supported_rates_len; i++) {
1024 if ((sta->supported_rates[i] & 0x7f) > 22) {
1025 sta->flags &= ~WLAN_STA_NONERP;
1029 if (sta->flags & WLAN_STA_NONERP && !sta->nonerp_set) {
1030 sta->nonerp_set = 1;
1031 hapd->iface->num_sta_non_erp++;
1032 if (hapd->iface->num_sta_non_erp == 1)
1033 ieee802_11_set_beacons(hapd->iface);
1036 if (!(sta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) &&
1037 !sta->no_short_slot_time_set) {
1038 sta->no_short_slot_time_set = 1;
1039 hapd->iface->num_sta_no_short_slot_time++;
1040 if (hapd->iface->current_mode->mode ==
1041 HOSTAPD_MODE_IEEE80211G &&
1042 hapd->iface->num_sta_no_short_slot_time == 1)
1043 ieee802_11_set_beacons(hapd->iface);
1046 if (sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1047 sta->flags |= WLAN_STA_SHORT_PREAMBLE;
1049 sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
1051 if (!(sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
1052 !sta->no_short_preamble_set) {
1053 sta->no_short_preamble_set = 1;
1054 hapd->iface->num_sta_no_short_preamble++;
1055 if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
1056 && hapd->iface->num_sta_no_short_preamble == 1)
1057 ieee802_11_set_beacons(hapd->iface);
1060 #ifdef CONFIG_IEEE80211N
1061 if (sta->flags & WLAN_STA_HT) {
1062 if ((sta->ht_capabilities.data.capabilities_info &
1063 HT_CAP_INFO_GREEN_FIELD) == 0) {
1064 hapd->iface->num_sta_ht_no_gf++;
1065 wpa_printf(MSG_DEBUG, "%s STA " MACSTR " - no "
1066 "greenfield, num of non-gf stations %d",
1067 __func__, MAC2STR(sta->addr),
1068 hapd->iface->num_sta_ht_no_gf);
1070 if ((sta->ht_capabilities.data.capabilities_info &
1071 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) == 0) {
1072 hapd->iface->num_sta_ht_20mhz++;
1073 wpa_printf(MSG_DEBUG, "%s STA " MACSTR " - 20 MHz HT, "
1074 "num of 20MHz HT STAs %d",
1075 __func__, MAC2STR(sta->addr),
1076 hapd->iface->num_sta_ht_20mhz);
1079 hapd->iface->num_sta_no_ht++;
1080 if (hapd->iconf->ieee80211n) {
1081 wpa_printf(MSG_DEBUG, "%s STA " MACSTR
1082 " - no HT, num of non-HT stations %d",
1083 __func__, MAC2STR(sta->addr),
1084 hapd->iface->num_sta_no_ht);
1088 if (hostapd_ht_operation_update(hapd->iface) > 0)
1089 ieee802_11_set_beacons(hapd->iface);
1090 #endif /* CONFIG_IEEE80211N */
1092 /* get a unique AID */
1094 wpa_printf(MSG_DEBUG, " old AID %d", sta->aid);
1096 for (sta->aid = 1; sta->aid <= MAX_AID_TABLE_SIZE; sta->aid++)
1097 if (hapd->sta_aid[sta->aid - 1] == NULL)
1099 if (sta->aid > MAX_AID_TABLE_SIZE) {
1101 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1102 wpa_printf(MSG_ERROR, " no room for more AIDs");
1105 hapd->sta_aid[sta->aid - 1] = sta;
1106 wpa_printf(MSG_DEBUG, " new AID %d", sta->aid);
1110 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1111 HOSTAPD_LEVEL_DEBUG,
1112 "association OK (aid %d)", sta->aid);
1113 /* Station will be marked associated, after it acknowledges AssocResp
1117 os_memcpy(sta->previous_ap, mgmt->u.reassoc_req.current_ap,
1121 if (sta->last_assoc_req)
1122 os_free(sta->last_assoc_req);
1123 sta->last_assoc_req = os_malloc(len);
1124 if (sta->last_assoc_req)
1125 os_memcpy(sta->last_assoc_req, mgmt, len);
1127 /* Make sure that the previously registered inactivity timer will not
1128 * remove the STA immediately. */
1129 sta->timeout_next = STA_NULLFUNC;
1132 os_memset(buf, 0, sizeof(buf));
1133 reply = (struct ieee80211_mgmt *) buf;
1134 reply->frame_control =
1135 IEEE80211_FC(WLAN_FC_TYPE_MGMT,
1136 (send_deauth ? WLAN_FC_STYPE_DEAUTH :
1137 (reassoc ? WLAN_FC_STYPE_REASSOC_RESP :
1138 WLAN_FC_STYPE_ASSOC_RESP)));
1139 os_memcpy(reply->da, mgmt->sa, ETH_ALEN);
1140 os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
1141 os_memcpy(reply->bssid, mgmt->bssid, ETH_ALEN);
1143 send_len = IEEE80211_HDRLEN;
1145 send_len += sizeof(reply->u.deauth);
1146 reply->u.deauth.reason_code = host_to_le16(resp);
1149 send_len += sizeof(reply->u.assoc_resp);
1150 reply->u.assoc_resp.capab_info =
1151 host_to_le16(hostapd_own_capab_info(hapd, sta, 0));
1152 reply->u.assoc_resp.status_code = host_to_le16(resp);
1153 reply->u.assoc_resp.aid = host_to_le16((sta ? sta->aid : 0)
1154 | BIT(14) | BIT(15));
1155 /* Supported rates */
1156 p = hostapd_eid_supp_rates(hapd, reply->u.assoc_resp.variable);
1157 /* Extended supported rates */
1158 p = hostapd_eid_ext_supp_rates(hapd, p);
1159 if (sta->flags & WLAN_STA_WME)
1160 p = hostapd_eid_wme(hapd, p);
1162 p = hostapd_eid_ht_capabilities_info(hapd, p);
1163 p = hostapd_eid_ht_operation(hapd, p);
1165 #ifdef CONFIG_IEEE80211R
1166 if (resp == WLAN_STATUS_SUCCESS) {
1167 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
1168 * Transition Information, RSN */
1169 p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, p,
1170 buf + sizeof(buf) - p,
1173 #endif /* CONFIG_IEEE80211R */
1175 #ifdef CONFIG_IEEE80211W
1176 if (resp == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY)
1177 p = hostapd_eid_assoc_comeback_time(hapd, sta, p);
1178 #endif /* CONFIG_IEEE80211W */
1180 send_len += p - reply->u.assoc_resp.variable;
1183 if (hostapd_send_mgmt_frame(hapd, reply, send_len, 0) < 0)
1184 perror("handle_assoc: send");
1188 static void handle_assoc_resp(struct hostapd_data *hapd,
1189 struct ieee80211_mgmt *mgmt, size_t len)
1191 u16 status_code, aid;
1193 if (hapd->assoc_ap_state != ASSOCIATE) {
1194 printf("Unexpected association response received from " MACSTR
1195 "\n", MAC2STR(mgmt->sa));
1199 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_resp)) {
1200 printf("handle_assoc_resp - too short payload (len=%lu)\n",
1201 (unsigned long) len);
1205 if (os_memcmp(mgmt->sa, hapd->conf->assoc_ap_addr, ETH_ALEN) != 0 ||
1206 os_memcmp(mgmt->bssid, hapd->conf->assoc_ap_addr, ETH_ALEN) != 0) {
1207 printf("Received association response from unexpected address "
1208 "(SA=" MACSTR " BSSID=" MACSTR "\n",
1209 MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid));
1213 status_code = le_to_host16(mgmt->u.assoc_resp.status_code);
1214 aid = le_to_host16(mgmt->u.assoc_resp.aid);
1215 aid &= ~(BIT(14) | BIT(15));
1217 if (status_code != 0) {
1218 printf("Association (as station) with AP " MACSTR " failed "
1219 "(status_code=%d)\n",
1220 MAC2STR(hapd->conf->assoc_ap_addr), status_code);
1221 /* Try to authenticate again */
1222 hapd->assoc_ap_state = AUTHENTICATE;
1223 eloop_register_timeout(5, 0, ieee802_11_sta_authenticate,
1227 printf("Associated (as station) with AP " MACSTR " (aid=%d)\n",
1228 MAC2STR(hapd->conf->assoc_ap_addr), aid);
1229 hapd->assoc_ap_aid = aid;
1230 hapd->assoc_ap_state = ASSOCIATED;
1232 if (hostapd_set_assoc_ap(hapd, hapd->conf->assoc_ap_addr)) {
1233 printf("Could not set associated AP address to kernel "
1239 static void handle_disassoc(struct hostapd_data *hapd,
1240 struct ieee80211_mgmt *mgmt, size_t len)
1242 struct sta_info *sta;
1244 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.disassoc)) {
1245 printf("handle_disassoc - too short payload (len=%lu)\n",
1246 (unsigned long) len);
1250 wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d",
1252 le_to_host16(mgmt->u.disassoc.reason_code));
1254 if (hapd->assoc_ap_state != DO_NOT_ASSOC &&
1255 os_memcmp(mgmt->sa, hapd->conf->assoc_ap_addr, ETH_ALEN) == 0) {
1256 printf("Assoc AP " MACSTR " sent disassociation "
1257 "(reason_code=%d) - try to authenticate\n",
1258 MAC2STR(hapd->conf->assoc_ap_addr),
1259 le_to_host16(mgmt->u.disassoc.reason_code));
1260 hapd->assoc_ap_state = AUTHENTICATE;
1261 ieee802_11_sta_authenticate(hapd, NULL);
1262 eloop_register_timeout(0, 500000, ieee802_11_sta_authenticate,
1267 sta = ap_get_sta(hapd, mgmt->sa);
1269 printf("Station " MACSTR " trying to disassociate, but it "
1270 "is not associated.\n", MAC2STR(mgmt->sa));
1274 sta->flags &= ~WLAN_STA_ASSOC;
1275 wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
1276 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1277 HOSTAPD_LEVEL_INFO, "disassociated");
1278 sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
1279 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
1280 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
1282 accounting_sta_stop(hapd, sta);
1283 ieee802_1x_free_station(sta);
1284 hostapd_sta_remove(hapd, sta->addr);
1286 if (sta->timeout_next == STA_NULLFUNC ||
1287 sta->timeout_next == STA_DISASSOC) {
1288 sta->timeout_next = STA_DEAUTH;
1289 eloop_cancel_timeout(ap_handle_timer, hapd, sta);
1290 eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer,
1294 mlme_disassociate_indication(
1295 hapd, sta, le_to_host16(mgmt->u.disassoc.reason_code));
1299 static void handle_deauth(struct hostapd_data *hapd,
1300 struct ieee80211_mgmt *mgmt, size_t len)
1302 struct sta_info *sta;
1304 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.deauth)) {
1305 printf("handle_deauth - too short payload (len=%lu)\n",
1306 (unsigned long) len);
1310 wpa_printf(MSG_DEBUG, "deauthentication: STA=" MACSTR
1313 le_to_host16(mgmt->u.deauth.reason_code));
1315 if (hapd->assoc_ap_state != DO_NOT_ASSOC &&
1316 os_memcmp(mgmt->sa, hapd->conf->assoc_ap_addr, ETH_ALEN) == 0) {
1317 printf("Assoc AP " MACSTR " sent deauthentication "
1318 "(reason_code=%d) - try to authenticate\n",
1319 MAC2STR(hapd->conf->assoc_ap_addr),
1320 le_to_host16(mgmt->u.deauth.reason_code));
1321 hapd->assoc_ap_state = AUTHENTICATE;
1322 eloop_register_timeout(0, 500000, ieee802_11_sta_authenticate,
1327 sta = ap_get_sta(hapd, mgmt->sa);
1329 printf("Station " MACSTR " trying to deauthenticate, but it "
1330 "is not authenticated.\n", MAC2STR(mgmt->sa));
1334 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
1335 wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
1336 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1337 HOSTAPD_LEVEL_DEBUG, "deauthenticated");
1338 mlme_deauthenticate_indication(
1339 hapd, sta, le_to_host16(mgmt->u.deauth.reason_code));
1340 sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
1341 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
1342 ap_free_sta(hapd, sta);
1346 static void handle_beacon(struct hostapd_data *hapd,
1347 struct ieee80211_mgmt *mgmt, size_t len,
1348 struct hostapd_frame_info *fi)
1350 struct ieee802_11_elems elems;
1352 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.beacon)) {
1353 printf("handle_beacon - too short payload (len=%lu)\n",
1354 (unsigned long) len);
1358 (void) ieee802_11_parse_elems(mgmt->u.beacon.variable,
1359 len - (IEEE80211_HDRLEN +
1360 sizeof(mgmt->u.beacon)), &elems,
1363 if (hapd->assoc_ap_state == WAIT_BEACON &&
1364 os_memcmp(mgmt->sa, hapd->conf->assoc_ap_addr, ETH_ALEN) == 0) {
1365 if (elems.ssid && elems.ssid_len <= 32) {
1366 os_memcpy(hapd->assoc_ap_ssid, elems.ssid,
1368 hapd->assoc_ap_ssid[elems.ssid_len] = '\0';
1369 hapd->assoc_ap_ssid_len = elems.ssid_len;
1371 ieee802_11_sta_authenticate(hapd, NULL);
1374 ap_list_process_beacon(hapd->iface, mgmt, &elems, fi);
1378 #ifdef CONFIG_IEEE80211W
1379 static void hostapd_ping_action(struct hostapd_data *hapd,
1380 struct ieee80211_mgmt *mgmt, size_t len)
1382 struct sta_info *sta;
1386 end = mgmt->u.action.u.ping_resp.trans_id + WLAN_PING_TRANS_ID_LEN;
1387 if (((u8 *) mgmt) + len < end) {
1388 wpa_printf(MSG_DEBUG, "IEEE 802.11: Too short Ping Action "
1389 "frame (len=%lu)", (unsigned long) len);
1393 if (mgmt->u.action.u.ping_resp.action != WLAN_PING_RESPONSE) {
1394 wpa_printf(MSG_DEBUG, "IEEE 802.11: Unexpected Ping Action %d",
1395 mgmt->u.action.u.ping_resp.action);
1399 /* MLME-PING.confirm */
1401 sta = ap_get_sta(hapd, mgmt->sa);
1402 if (sta == NULL || sta->ping_trans_id == NULL) {
1403 wpa_printf(MSG_DEBUG, "IEEE 802.11: No matching STA with "
1404 "pending ping request found");
1408 for (i = 0; i < sta->ping_count; i++) {
1409 if (os_memcmp(sta->ping_trans_id + i * WLAN_PING_TRANS_ID_LEN,
1410 mgmt->u.action.u.ping_resp.trans_id,
1411 WLAN_PING_TRANS_ID_LEN) == 0)
1415 if (i >= sta->ping_count) {
1416 wpa_printf(MSG_DEBUG, "IEEE 802.11: No matching ping "
1417 "transaction identifier found");
1421 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1422 HOSTAPD_LEVEL_DEBUG, "Reply to pending ping received");
1423 ap_sta_stop_ping(hapd, sta);
1425 #endif /* CONFIG_IEEE80211W */
1428 static void handle_action(struct hostapd_data *hapd,
1429 struct ieee80211_mgmt *mgmt, size_t len)
1431 if (len < IEEE80211_HDRLEN + 1) {
1432 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1433 HOSTAPD_LEVEL_DEBUG,
1434 "handle_action - too short payload (len=%lu)",
1435 (unsigned long) len);
1439 switch (mgmt->u.action.category) {
1440 #ifdef CONFIG_IEEE80211R
1441 case WLAN_ACTION_FT:
1443 struct sta_info *sta;
1445 sta = ap_get_sta(hapd, mgmt->sa);
1446 if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) {
1447 wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignored FT Action "
1448 "frame from unassociated STA " MACSTR,
1453 if (wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action,
1454 len - IEEE80211_HDRLEN))
1459 #endif /* CONFIG_IEEE80211R */
1460 case WLAN_ACTION_WMM:
1461 hostapd_wme_action(hapd, mgmt, len);
1463 #ifdef CONFIG_IEEE80211W
1464 case WLAN_ACTION_PING:
1465 hostapd_ping_action(hapd, mgmt, len);
1467 #endif /* CONFIG_IEEE80211W */
1470 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1471 HOSTAPD_LEVEL_DEBUG,
1472 "handle_action - unknown action category %d or invalid "
1474 mgmt->u.action.category);
1475 if (!(mgmt->da[0] & 0x01) && !(mgmt->u.action.category & 0x80) &&
1476 !(mgmt->sa[0] & 0x01)) {
1478 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
1479 * Return the Action frame to the source without change
1480 * except that MSB of the Category set to 1.
1482 wpa_printf(MSG_DEBUG, "IEEE 802.11: Return unknown Action "
1483 "frame back to sender");
1484 os_memcpy(mgmt->da, mgmt->sa, ETH_ALEN);
1485 os_memcpy(mgmt->sa, hapd->own_addr, ETH_ALEN);
1486 os_memcpy(mgmt->bssid, hapd->own_addr, ETH_ALEN);
1487 mgmt->u.action.category |= 0x80;
1489 hostapd_send_mgmt_frame(hapd, mgmt, len, 0);
1495 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
1496 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
1498 * @buf: management frame data (starting from IEEE 802.11 header)
1499 * @len: length of frame data in octets
1500 * @stype: management frame subtype from frame control field
1502 * Process all incoming IEEE 802.11 management frames. This will be called for
1503 * each frame received from the kernel driver through wlan#ap interface. In
1504 * addition, it can be called to re-inserted pending frames (e.g., when using
1505 * external RADIUS server as an MAC ACL).
1507 void ieee802_11_mgmt(struct hostapd_data *hapd, u8 *buf, size_t len, u16 stype,
1508 struct hostapd_frame_info *fi)
1510 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) buf;
1513 if (stype == WLAN_FC_STYPE_BEACON) {
1514 handle_beacon(hapd, mgmt, len, fi);
1518 if (fi && fi->passive_scan)
1521 broadcast = mgmt->bssid[0] == 0xff && mgmt->bssid[1] == 0xff &&
1522 mgmt->bssid[2] == 0xff && mgmt->bssid[3] == 0xff &&
1523 mgmt->bssid[4] == 0xff && mgmt->bssid[5] == 0xff;
1526 os_memcmp(mgmt->bssid, hapd->own_addr, ETH_ALEN) != 0 &&
1527 (hapd->assoc_ap_state == DO_NOT_ASSOC ||
1528 os_memcmp(mgmt->bssid, hapd->conf->assoc_ap_addr, ETH_ALEN) != 0))
1530 printf("MGMT: BSSID=" MACSTR " not our address\n",
1531 MAC2STR(mgmt->bssid));
1536 if (stype == WLAN_FC_STYPE_PROBE_REQ) {
1537 handle_probe_req(hapd, mgmt, len);
1541 if (os_memcmp(mgmt->da, hapd->own_addr, ETH_ALEN) != 0) {
1542 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1543 HOSTAPD_LEVEL_DEBUG,
1544 "MGMT: DA=" MACSTR " not our address",
1550 case WLAN_FC_STYPE_AUTH:
1551 wpa_printf(MSG_DEBUG, "mgmt::auth");
1552 handle_auth(hapd, mgmt, len);
1554 case WLAN_FC_STYPE_ASSOC_REQ:
1555 wpa_printf(MSG_DEBUG, "mgmt::assoc_req");
1556 handle_assoc(hapd, mgmt, len, 0);
1558 case WLAN_FC_STYPE_ASSOC_RESP:
1559 wpa_printf(MSG_DEBUG, "mgmt::assoc_resp");
1560 handle_assoc_resp(hapd, mgmt, len);
1562 case WLAN_FC_STYPE_REASSOC_REQ:
1563 wpa_printf(MSG_DEBUG, "mgmt::reassoc_req");
1564 handle_assoc(hapd, mgmt, len, 1);
1566 case WLAN_FC_STYPE_DISASSOC:
1567 wpa_printf(MSG_DEBUG, "mgmt::disassoc");
1568 handle_disassoc(hapd, mgmt, len);
1570 case WLAN_FC_STYPE_DEAUTH:
1571 wpa_printf(MSG_DEBUG, "mgmt::deauth");
1572 handle_deauth(hapd, mgmt, len);
1574 case WLAN_FC_STYPE_ACTION:
1575 wpa_printf(MSG_DEBUG, "mgmt::action");
1576 handle_action(hapd, mgmt, len);
1579 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1580 HOSTAPD_LEVEL_DEBUG,
1581 "unknown mgmt frame subtype %d", stype);
1587 static void handle_auth_cb(struct hostapd_data *hapd,
1588 struct ieee80211_mgmt *mgmt,
1591 u16 auth_alg, auth_transaction, status_code;
1592 struct sta_info *sta;
1595 hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
1596 HOSTAPD_LEVEL_NOTICE,
1597 "did not acknowledge authentication response");
1601 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
1602 printf("handle_auth_cb - too short payload (len=%lu)\n",
1603 (unsigned long) len);
1607 auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
1608 auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
1609 status_code = le_to_host16(mgmt->u.auth.status_code);
1611 sta = ap_get_sta(hapd, mgmt->da);
1613 printf("handle_auth_cb: STA " MACSTR " not found\n",
1618 if (status_code == WLAN_STATUS_SUCCESS &&
1619 ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) ||
1620 (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) {
1621 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1622 HOSTAPD_LEVEL_INFO, "authenticated");
1623 sta->flags |= WLAN_STA_AUTH;
1628 static void handle_assoc_cb(struct hostapd_data *hapd,
1629 struct ieee80211_mgmt *mgmt,
1630 size_t len, int reassoc, int ok)
1633 struct sta_info *sta;
1635 struct ht_cap_ie *ht_cap = NULL;
1638 hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
1639 HOSTAPD_LEVEL_DEBUG,
1640 "did not acknowledge association response");
1644 if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_resp) :
1645 sizeof(mgmt->u.assoc_resp))) {
1646 printf("handle_assoc_cb(reassoc=%d) - too short payload "
1647 "(len=%lu)\n", reassoc, (unsigned long) len);
1652 status = le_to_host16(mgmt->u.reassoc_resp.status_code);
1654 status = le_to_host16(mgmt->u.assoc_resp.status_code);
1656 sta = ap_get_sta(hapd, mgmt->da);
1658 printf("handle_assoc_cb: STA " MACSTR " not found\n",
1663 if (status != WLAN_STATUS_SUCCESS)
1666 /* Stop previous accounting session, if one is started, and allocate
1667 * new session id for the new session. */
1668 accounting_sta_stop(hapd, sta);
1669 accounting_sta_get_id(hapd, sta);
1671 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1673 "associated (aid %d, accounting session %08X-%08X)",
1674 sta->aid, sta->acct_session_id_hi,
1675 sta->acct_session_id_lo);
1677 if (sta->flags & WLAN_STA_ASSOC)
1679 sta->flags |= WLAN_STA_ASSOC;
1682 mlme_reassociate_indication(hapd, sta);
1684 mlme_associate_indication(hapd, sta);
1686 #ifdef CONFIG_IEEE80211N
1687 if (sta->flags & WLAN_STA_HT)
1688 ht_cap = &sta->ht_capabilities;
1689 #endif /* CONFIG_IEEE80211N */
1691 #ifdef CONFIG_IEEE80211W
1692 sta->ping_timed_out = 0;
1693 #endif /* CONFIG_IEEE80211W */
1695 if (hostapd_sta_add(hapd->conf->iface, hapd, sta->addr, sta->aid,
1696 sta->capability, sta->supported_rates,
1697 sta->supported_rates_len, 0, sta->listen_interval,
1700 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1701 HOSTAPD_LEVEL_NOTICE,
1702 "Could not add STA to kernel driver");
1705 if (sta->eapol_sm == NULL) {
1707 * This STA does not use RADIUS server for EAP authentication,
1708 * so bind it to the selected VLAN interface now, since the
1709 * interface selection is not going to change anymore.
1711 ap_sta_bind_vlan(hapd, sta, 0);
1712 } else if (sta->vlan_id) {
1713 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
1714 ap_sta_bind_vlan(hapd, sta, 0);
1716 if (sta->flags & WLAN_STA_SHORT_PREAMBLE) {
1717 hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
1718 WLAN_STA_SHORT_PREAMBLE, ~0);
1720 hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
1721 0, ~WLAN_STA_SHORT_PREAMBLE);
1724 if (sta->auth_alg == WLAN_AUTH_FT)
1725 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT);
1727 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
1728 hostapd_new_assoc_sta(hapd, sta, !new_assoc);
1730 ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
1733 /* Copy of the association request is not needed anymore */
1734 if (sta->last_assoc_req) {
1735 os_free(sta->last_assoc_req);
1736 sta->last_assoc_req = NULL;
1741 void ieee802_11_mgmt_cb(struct hostapd_data *hapd, u8 *buf, size_t len,
1744 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) buf;
1747 case WLAN_FC_STYPE_AUTH:
1748 wpa_printf(MSG_DEBUG, "mgmt::auth cb");
1749 handle_auth_cb(hapd, mgmt, len, ok);
1751 case WLAN_FC_STYPE_ASSOC_RESP:
1752 wpa_printf(MSG_DEBUG, "mgmt::assoc_resp cb");
1753 handle_assoc_cb(hapd, mgmt, len, 0, ok);
1755 case WLAN_FC_STYPE_REASSOC_RESP:
1756 wpa_printf(MSG_DEBUG, "mgmt::reassoc_resp cb");
1757 handle_assoc_cb(hapd, mgmt, len, 1, ok);
1759 case WLAN_FC_STYPE_PROBE_RESP:
1760 wpa_printf(MSG_DEBUG, "mgmt::proberesp cb");
1762 case WLAN_FC_STYPE_DEAUTH:
1765 case WLAN_FC_STYPE_ACTION:
1766 wpa_printf(MSG_DEBUG, "mgmt::action cb");
1769 printf("unknown mgmt cb frame subtype %d\n", stype);
1775 static void ieee80211_tkip_countermeasures_stop(void *eloop_ctx,
1778 struct hostapd_data *hapd = eloop_ctx;
1779 hapd->tkip_countermeasures = 0;
1780 hostapd_set_countermeasures(hapd, 0);
1781 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
1782 HOSTAPD_LEVEL_INFO, "TKIP countermeasures ended");
1786 static void ieee80211_tkip_countermeasures_start(struct hostapd_data *hapd)
1788 struct sta_info *sta;
1790 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
1791 HOSTAPD_LEVEL_INFO, "TKIP countermeasures initiated");
1793 wpa_auth_countermeasures_start(hapd->wpa_auth);
1794 hapd->tkip_countermeasures = 1;
1795 hostapd_set_countermeasures(hapd, 1);
1796 wpa_gtk_rekey(hapd->wpa_auth);
1797 eloop_cancel_timeout(ieee80211_tkip_countermeasures_stop, hapd, NULL);
1798 eloop_register_timeout(60, 0, ieee80211_tkip_countermeasures_stop,
1800 for (sta = hapd->sta_list; sta != NULL; sta = sta->next) {
1801 hostapd_sta_deauth(hapd, sta->addr,
1802 WLAN_REASON_MICHAEL_MIC_FAILURE);
1803 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC |
1804 WLAN_STA_AUTHORIZED);
1805 hostapd_sta_remove(hapd, sta->addr);
1810 void ieee80211_michael_mic_failure(struct hostapd_data *hapd, const u8 *addr,
1815 if (addr && local) {
1816 struct sta_info *sta = ap_get_sta(hapd, addr);
1818 wpa_auth_sta_local_mic_failure_report(sta->wpa_sm);
1819 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
1821 "Michael MIC failure detected in "
1823 mlme_michaelmicfailure_indication(hapd, addr);
1825 wpa_printf(MSG_DEBUG,
1826 "MLME-MICHAELMICFAILURE.indication "
1827 "for not associated STA (" MACSTR
1828 ") ignored", MAC2STR(addr));
1834 if (now > hapd->michael_mic_failure + 60) {
1835 hapd->michael_mic_failures = 1;
1837 hapd->michael_mic_failures++;
1838 if (hapd->michael_mic_failures > 1)
1839 ieee80211_tkip_countermeasures_start(hapd);
1841 hapd->michael_mic_failure = now;
1845 int ieee802_11_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen)
1852 int ieee802_11_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
1853 char *buf, size_t buflen)
1859 #endif /* CONFIG_NATIVE_WINDOWS */