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 #ifdef CONFIG_IEEE80211N
106 u8 * hostapd_eid_ht_capabilities_info(struct hostapd_data *hapd, u8 *eid)
109 os_memcpy(pos, &hapd->conf->ht_capabilities, sizeof(struct ht_cap_ie));
110 pos += sizeof(struct ht_cap_ie);
115 u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid)
118 os_memcpy(pos, &hapd->conf->ht_operation,
119 sizeof(struct ht_operation_ie));
120 pos += sizeof(struct ht_operation_ie);
127 Set to 0 (HT pure) under the followign conditions
128 - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
129 - all STAs in the BSS are 20 MHz HT in 20 MHz BSS
130 Set to 1 (HT non-member protection) if there may be non-HT STAs
131 in both the primary and the secondary channel
132 Set to 2 if only HT STAs are associated in BSS,
133 however and at least one 20 MHz HT STA is associated
134 Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
135 (currently non-GF HT station is considered as non-HT STA also)
137 int hostapd_ht_operation_update(struct hostapd_iface *iface)
139 struct ht_operation_ie *ht_operation;
140 u16 operation_mode = 0;
141 u16 cur_op_mode, new_op_mode;
142 int op_mode_changes = 0;
143 struct hostapd_data *hapd = iface->bss[0];
145 /* TODO: should hapd pointer really be used here? This should most
146 * likely be per radio, not per BSS.. */
148 if (!hapd->conf->ieee80211n || hapd->conf->ht_op_mode_fixed)
151 ht_operation = &hapd->conf->ht_operation;
152 operation_mode = le_to_host16(ht_operation->data.operation_mode);
153 wpa_printf(MSG_DEBUG, "%s current operation mode=0x%X",
154 __func__, operation_mode);
156 if ((operation_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) == 0
157 && iface->num_sta_ht_no_gf) {
158 operation_mode |= HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
160 } else if ((operation_mode &
161 HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&
162 iface->num_sta_ht_no_gf == 0) {
163 operation_mode &= ~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
167 if ((operation_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) == 0
168 && (iface->num_sta_no_ht || iface->olbc_ht)) {
169 operation_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
171 } else if ((operation_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT)
172 && (iface->num_sta_no_ht == 0 && iface->olbc_ht == 0)) {
173 operation_mode &= ~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
177 /* Note: currently we switch to the MIXED op mode if HT non-greenfield
178 * station is associated. Probably it's a theoretical case, since
179 * it looks like all known HT STAs support greenfield.
182 if (iface->num_sta_no_ht ||
183 (operation_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT))
184 new_op_mode = OP_MODE_MIXED;
185 else if ((hapd->conf->ht_capabilities.data.capabilities_info &
186 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) &&
187 iface->num_sta_ht_20mhz)
188 new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED;
189 else if (iface->olbc_ht)
190 new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS;
192 new_op_mode = OP_MODE_PURE;
194 cur_op_mode = operation_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;
195 if (cur_op_mode != new_op_mode) {
196 operation_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK;
197 operation_mode |= new_op_mode;
201 wpa_printf(MSG_DEBUG, "%s new operation mode=0x%X changes=%d",
202 __func__, operation_mode, op_mode_changes);
203 ht_operation->data.operation_mode = host_to_le16(operation_mode);
205 return op_mode_changes;
208 #endif /* CONFIG_IEEE80211N */
211 u16 hostapd_own_capab_info(struct hostapd_data *hapd, struct sta_info *sta,
214 int capab = WLAN_CAPABILITY_ESS;
217 if (hapd->iface->num_sta_no_short_preamble == 0 &&
218 hapd->iconf->preamble == SHORT_PREAMBLE)
219 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
221 privacy = hapd->conf->ssid.wep.keys_set;
223 if (hapd->conf->ieee802_1x &&
224 (hapd->conf->default_wep_key_len ||
225 hapd->conf->individual_wep_key_len))
232 int policy, def_klen;
233 if (probe && sta->ssid_probe) {
234 policy = sta->ssid_probe->security_policy;
235 def_klen = sta->ssid_probe->wep.default_len;
237 policy = sta->ssid->security_policy;
238 def_klen = sta->ssid->wep.default_len;
240 privacy = policy != SECURITY_PLAINTEXT;
241 if (policy == SECURITY_IEEE_802_1X && def_klen == 0)
246 capab |= WLAN_CAPABILITY_PRIVACY;
248 if (hapd->iface->current_mode &&
249 hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G &&
250 hapd->iface->num_sta_no_short_slot_time == 0)
251 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
253 if (hapd->iface->dfs_enable)
254 capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
260 #define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs)
263 static int ieee802_11_parse_vendor_specific(struct hostapd_data *hapd,
264 u8 *pos, size_t elen,
265 struct ieee802_11_elems *elems,
270 /* first 3 bytes in vendor specific information element are the IEEE
271 * OUI of the vendor. The following byte is used a vendor specific
275 wpa_printf(MSG_MSGDUMP, "short vendor specific "
276 "information element ignored (len=%lu)",
277 (unsigned long) elen);
282 oui = WPA_GET_BE24(pos);
285 /* Microsoft/Wi-Fi information elements are further typed and
289 /* Microsoft OUI (00:50:F2) with OUI Type 1:
290 * real WPA information element */
292 elems->wpa_ie_len = elen;
294 case WME_OUI_TYPE: /* this is a Wi-Fi WME info. element */
296 wpa_printf(MSG_MSGDUMP, "short WME "
297 "information element ignored "
299 (unsigned long) elen);
303 case WME_OUI_SUBTYPE_INFORMATION_ELEMENT:
304 case WME_OUI_SUBTYPE_PARAMETER_ELEMENT:
306 elems->wme_len = elen;
308 case WME_OUI_SUBTYPE_TSPEC_ELEMENT:
309 elems->wme_tspec = pos;
310 elems->wme_tspec_len = elen;
313 wpa_printf(MSG_MSGDUMP, "unknown WME "
314 "information element ignored "
315 "(subtype=%d len=%lu)",
316 pos[4], (unsigned long) elen);
321 wpa_printf(MSG_MSGDUMP, "Unknown Microsoft "
322 "information element ignored "
323 "(type=%d len=%lu)\n",
324 pos[3], (unsigned long) elen);
330 wpa_printf(MSG_MSGDUMP, "unknown vendor specific information "
331 "element ignored (vendor OUI %02x:%02x:%02x "
333 pos[0], pos[1], pos[2], (unsigned long) elen);
341 ParseRes ieee802_11_parse_elems(struct hostapd_data *hapd, u8 *start,
343 struct ieee802_11_elems *elems,
350 os_memset(elems, 0, sizeof(*elems));
361 wpa_printf(MSG_DEBUG, "IEEE 802.11 element "
362 "parse failed (id=%d elen=%d "
364 id, elen, (unsigned long) left);
365 wpa_hexdump(MSG_MSGDUMP, "IEs", start, len);
373 elems->ssid_len = elen;
375 case WLAN_EID_SUPP_RATES:
376 elems->supp_rates = pos;
377 elems->supp_rates_len = elen;
379 case WLAN_EID_FH_PARAMS:
380 elems->fh_params = pos;
381 elems->fh_params_len = elen;
383 case WLAN_EID_DS_PARAMS:
384 elems->ds_params = pos;
385 elems->ds_params_len = elen;
387 case WLAN_EID_CF_PARAMS:
388 elems->cf_params = pos;
389 elems->cf_params_len = elen;
393 elems->tim_len = elen;
395 case WLAN_EID_IBSS_PARAMS:
396 elems->ibss_params = pos;
397 elems->ibss_params_len = elen;
399 case WLAN_EID_CHALLENGE:
400 elems->challenge = pos;
401 elems->challenge_len = elen;
403 case WLAN_EID_ERP_INFO:
404 elems->erp_info = pos;
405 elems->erp_info_len = elen;
407 case WLAN_EID_EXT_SUPP_RATES:
408 elems->ext_supp_rates = pos;
409 elems->ext_supp_rates_len = elen;
411 case WLAN_EID_VENDOR_SPECIFIC:
412 if (ieee802_11_parse_vendor_specific(hapd, pos, elen,
419 elems->rsn_ie_len = elen;
421 case WLAN_EID_PWR_CAPABILITY:
422 elems->power_cap = pos;
423 elems->power_cap_len = elen;
425 case WLAN_EID_SUPPORTED_CHANNELS:
426 elems->supp_channels = pos;
427 elems->supp_channels_len = elen;
429 case WLAN_EID_MOBILITY_DOMAIN:
431 elems->mdie_len = elen;
433 case WLAN_EID_FAST_BSS_TRANSITION:
435 elems->ftie_len = elen;
437 case WLAN_EID_HT_CAP:
438 elems->ht_capabilities = pos;
439 elems->ht_capabilities_len = elen;
441 case WLAN_EID_HT_OPERATION:
442 elems->ht_operation = pos;
443 elems->ht_operation_len = elen;
449 wpa_printf(MSG_MSGDUMP, "IEEE 802.11 element parse "
450 "ignored unknown element (id=%d elen=%d)",
462 return unknown ? ParseUnknown : ParseOK;
466 void ieee802_11_print_ssid(char *buf, const u8 *ssid, u8 len)
469 if (len > HOSTAPD_MAX_SSID_LEN)
470 len = HOSTAPD_MAX_SSID_LEN;
471 for (i = 0; i < len; i++) {
472 if (ssid[i] >= 32 && ssid[i] < 127)
481 void ieee802_11_send_deauth(struct hostapd_data *hapd, u8 *addr, u16 reason)
483 struct ieee80211_mgmt mgmt;
486 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
488 "deauthenticate - reason %d", reason);
489 os_snprintf(buf, sizeof(buf), "SEND-DEAUTHENTICATE %d", reason);
490 os_memset(&mgmt, 0, sizeof(mgmt));
491 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
492 WLAN_FC_STYPE_DEAUTH);
493 os_memcpy(mgmt.da, addr, ETH_ALEN);
494 os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
495 os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
496 mgmt.u.deauth.reason_code = host_to_le16(reason);
497 if (hostapd_send_mgmt_frame(hapd, &mgmt, IEEE80211_HDRLEN +
498 sizeof(mgmt.u.deauth), 0) < 0)
499 perror("ieee802_11_send_deauth: send");
503 static void ieee802_11_sta_authenticate(void *eloop_ctx, void *timeout_ctx)
505 struct hostapd_data *hapd = eloop_ctx;
506 struct ieee80211_mgmt mgmt;
509 if (hapd->assoc_ap_state == WAIT_BEACON)
510 hapd->assoc_ap_state = AUTHENTICATE;
511 if (hapd->assoc_ap_state != AUTHENTICATE)
514 ieee802_11_print_ssid(ssid_txt, (u8 *) hapd->assoc_ap_ssid,
515 hapd->assoc_ap_ssid_len);
516 printf("Authenticate with AP " MACSTR " SSID=%s (as station)\n",
517 MAC2STR(hapd->conf->assoc_ap_addr), ssid_txt);
519 os_memset(&mgmt, 0, sizeof(mgmt));
520 mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
522 /* Request TX callback */
523 mgmt.frame_control |= host_to_le16(BIT(1));
524 os_memcpy(mgmt.da, hapd->conf->assoc_ap_addr, ETH_ALEN);
525 os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
526 os_memcpy(mgmt.bssid, hapd->conf->assoc_ap_addr, ETH_ALEN);
527 mgmt.u.auth.auth_alg = host_to_le16(WLAN_AUTH_OPEN);
528 mgmt.u.auth.auth_transaction = host_to_le16(1);
529 mgmt.u.auth.status_code = host_to_le16(0);
530 if (hostapd_send_mgmt_frame(hapd, &mgmt, IEEE80211_HDRLEN +
531 sizeof(mgmt.u.auth), 0) < 0)
532 perror("ieee802_11_sta_authenticate: send");
534 /* Try to authenticate again, if this attempt fails or times out. */
535 eloop_register_timeout(5, 0, ieee802_11_sta_authenticate, hapd, NULL);
539 static void ieee802_11_sta_associate(void *eloop_ctx, void *timeout_ctx)
541 struct hostapd_data *hapd = eloop_ctx;
543 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) buf;
547 if (hapd->assoc_ap_state == AUTHENTICATE)
548 hapd->assoc_ap_state = ASSOCIATE;
549 if (hapd->assoc_ap_state != ASSOCIATE)
552 ieee802_11_print_ssid(ssid_txt, (u8 *) hapd->assoc_ap_ssid,
553 hapd->assoc_ap_ssid_len);
554 printf("Associate with AP " MACSTR " SSID=%s (as station)\n",
555 MAC2STR(hapd->conf->assoc_ap_addr), ssid_txt);
557 os_memset(mgmt, 0, sizeof(*mgmt));
558 mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
559 WLAN_FC_STYPE_ASSOC_REQ);
560 /* Request TX callback */
561 mgmt->frame_control |= host_to_le16(BIT(1));
562 os_memcpy(mgmt->da, hapd->conf->assoc_ap_addr, ETH_ALEN);
563 os_memcpy(mgmt->sa, hapd->own_addr, ETH_ALEN);
564 os_memcpy(mgmt->bssid, hapd->conf->assoc_ap_addr, ETH_ALEN);
565 mgmt->u.assoc_req.capab_info = host_to_le16(0);
566 mgmt->u.assoc_req.listen_interval = host_to_le16(1);
567 p = &mgmt->u.assoc_req.variable[0];
569 *p++ = WLAN_EID_SSID;
570 *p++ = hapd->assoc_ap_ssid_len;
571 os_memcpy(p, hapd->assoc_ap_ssid, hapd->assoc_ap_ssid_len);
572 p += hapd->assoc_ap_ssid_len;
574 p = hostapd_eid_supp_rates(hapd, p);
575 p = hostapd_eid_ext_supp_rates(hapd, p);
577 if (hostapd_send_mgmt_frame(hapd, mgmt, p - (u8 *) mgmt, 0) < 0)
578 perror("ieee802_11_sta_associate: send");
580 /* Try to authenticate again, if this attempt fails or times out. */
581 eloop_register_timeout(5, 0, ieee802_11_sta_associate, hapd, NULL);
585 static u16 auth_shared_key(struct hostapd_data *hapd, struct sta_info *sta,
586 u16 auth_transaction, u8 *challenge, int iswep)
588 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
590 "authentication (shared key, transaction %d)",
593 if (auth_transaction == 1) {
594 if (!sta->challenge) {
595 /* Generate a pseudo-random challenge */
599 sta->challenge = os_zalloc(WLAN_AUTH_CHALLENGE_LEN);
600 if (sta->challenge == NULL)
601 return WLAN_STATUS_UNSPECIFIED_FAILURE;
605 os_memcpy(key, &now, 4);
606 os_memcpy(key + 4, &r, 4);
607 rc4(sta->challenge, WLAN_AUTH_CHALLENGE_LEN,
613 if (auth_transaction != 3)
614 return WLAN_STATUS_UNSPECIFIED_FAILURE;
617 if (!iswep || !sta->challenge || !challenge ||
618 os_memcmp(sta->challenge, challenge, WLAN_AUTH_CHALLENGE_LEN)) {
619 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
621 "shared key authentication - invalid "
622 "challenge-response");
623 return WLAN_STATUS_CHALLENGE_FAIL;
626 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
628 "authentication OK (shared key)");
629 #ifdef IEEE80211_REQUIRE_AUTH_ACK
630 /* Station will be marked authenticated if it ACKs the
631 * authentication reply. */
633 sta->flags |= WLAN_STA_AUTH;
634 wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
636 os_free(sta->challenge);
637 sta->challenge = NULL;
643 static void send_auth_reply(struct hostapd_data *hapd,
644 const u8 *dst, const u8 *bssid,
645 u16 auth_alg, u16 auth_transaction, u16 resp,
646 const u8 *ies, size_t ies_len)
648 struct ieee80211_mgmt *reply;
652 rlen = IEEE80211_HDRLEN + sizeof(reply->u.auth) + ies_len;
653 buf = os_zalloc(rlen);
657 reply = (struct ieee80211_mgmt *) buf;
658 reply->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
660 /* Request TX callback */
661 reply->frame_control |= host_to_le16(BIT(1));
662 os_memcpy(reply->da, dst, ETH_ALEN);
663 os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
664 os_memcpy(reply->bssid, bssid, ETH_ALEN);
666 reply->u.auth.auth_alg = host_to_le16(auth_alg);
667 reply->u.auth.auth_transaction = host_to_le16(auth_transaction);
668 reply->u.auth.status_code = host_to_le16(resp);
671 os_memcpy(reply->u.auth.variable, ies, ies_len);
673 wpa_printf(MSG_DEBUG, "authentication reply: STA=" MACSTR
674 " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu)",
675 MAC2STR(dst), auth_alg, auth_transaction,
676 resp, (unsigned long) ies_len);
677 if (hostapd_send_mgmt_frame(hapd, reply, rlen, 0) < 0)
678 perror("send_auth_reply: send");
684 #ifdef CONFIG_IEEE80211R
685 static void handle_auth_ft_finish(void *ctx, const u8 *dst, const u8 *bssid,
686 u16 auth_transaction, u16 status,
687 const u8 *ies, size_t ies_len)
689 struct hostapd_data *hapd = ctx;
690 struct sta_info *sta;
692 send_auth_reply(hapd, dst, bssid, WLAN_AUTH_FT, auth_transaction,
693 status, ies, ies_len);
695 if (status != WLAN_STATUS_SUCCESS)
698 sta = ap_get_sta(hapd, dst);
702 hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211,
703 HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)");
704 sta->flags |= WLAN_STA_AUTH;
705 mlme_authenticate_indication(hapd, sta);
707 #endif /* CONFIG_IEEE80211R */
710 static void handle_auth(struct hostapd_data *hapd, struct ieee80211_mgmt *mgmt,
713 u16 auth_alg, auth_transaction, status_code;
714 u16 resp = WLAN_STATUS_SUCCESS;
715 struct sta_info *sta = NULL;
718 u8 *challenge = NULL;
719 u32 session_timeout, acct_interim_interval;
721 u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
722 size_t resp_ies_len = 0;
724 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
725 printf("handle_auth - too short payload (len=%lu)\n",
726 (unsigned long) len);
730 auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
731 auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
732 status_code = le_to_host16(mgmt->u.auth.status_code);
733 fc = le_to_host16(mgmt->frame_control);
735 if (len >= IEEE80211_HDRLEN + sizeof(mgmt->u.auth) +
736 2 + WLAN_AUTH_CHALLENGE_LEN &&
737 mgmt->u.auth.variable[0] == WLAN_EID_CHALLENGE &&
738 mgmt->u.auth.variable[1] == WLAN_AUTH_CHALLENGE_LEN)
739 challenge = &mgmt->u.auth.variable[2];
741 wpa_printf(MSG_DEBUG, "authentication: STA=" MACSTR " auth_alg=%d "
742 "auth_transaction=%d status_code=%d wep=%d%s",
743 MAC2STR(mgmt->sa), auth_alg, auth_transaction,
744 status_code, !!(fc & WLAN_FC_ISWEP),
745 challenge ? " challenge" : "");
747 if (hapd->assoc_ap_state == AUTHENTICATE && auth_transaction == 2 &&
748 os_memcmp(mgmt->sa, hapd->conf->assoc_ap_addr, ETH_ALEN) == 0 &&
749 os_memcmp(mgmt->bssid, hapd->conf->assoc_ap_addr, ETH_ALEN) == 0) {
750 if (status_code != 0) {
751 printf("Authentication (as station) with AP "
752 MACSTR " failed (status_code=%d)\n",
753 MAC2STR(hapd->conf->assoc_ap_addr),
757 printf("Authenticated (as station) with AP " MACSTR "\n",
758 MAC2STR(hapd->conf->assoc_ap_addr));
759 ieee802_11_sta_associate(hapd, NULL);
763 if (hapd->tkip_countermeasures) {
764 resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
768 if (!(((hapd->conf->auth_algs & WPA_AUTH_ALG_OPEN) &&
769 auth_alg == WLAN_AUTH_OPEN) ||
770 #ifdef CONFIG_IEEE80211R
772 (hapd->conf->wpa_key_mgmt &
773 (WPA_KEY_MGMT_FT_IEEE8021X | WPA_KEY_MGMT_FT_PSK)) &&
774 auth_alg == WLAN_AUTH_FT) ||
775 #endif /* CONFIG_IEEE80211R */
776 ((hapd->conf->auth_algs & WPA_AUTH_ALG_SHARED) &&
777 auth_alg == WLAN_AUTH_SHARED_KEY))) {
778 printf("Unsupported authentication algorithm (%d)\n",
780 resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
784 if (!(auth_transaction == 1 ||
785 (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 3))) {
786 printf("Unknown authentication transaction number (%d)\n",
788 resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
792 if (os_memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) {
793 printf("Station " MACSTR " not allowed to authenticate.\n",
795 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
799 res = hostapd_allowed_address(hapd, mgmt->sa, (u8 *) mgmt, len,
801 &acct_interim_interval, &vlan_id);
802 if (res == HOSTAPD_ACL_REJECT) {
803 printf("Station " MACSTR " not allowed to authenticate.\n",
805 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
808 if (res == HOSTAPD_ACL_PENDING) {
809 wpa_printf(MSG_DEBUG, "Authentication frame from " MACSTR
810 " waiting for an external authentication",
812 /* Authentication code will re-send the authentication frame
813 * after it has received (and cached) information from the
814 * external source. */
818 sta = ap_sta_add(hapd, mgmt->sa);
820 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
825 if (hostapd_get_vlan_id_ifname(hapd->conf->vlan,
826 sta->vlan_id) == NULL) {
827 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
828 HOSTAPD_LEVEL_INFO, "Invalid VLAN ID "
829 "%d received from RADIUS server",
831 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
834 sta->vlan_id = vlan_id;
835 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
836 HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);
839 sta->flags &= ~WLAN_STA_PREAUTH;
840 ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);
842 if (hapd->conf->radius->acct_interim_interval == 0 &&
843 acct_interim_interval)
844 sta->acct_interim_interval = acct_interim_interval;
845 if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT)
846 ap_sta_session_timeout(hapd, sta, session_timeout);
848 ap_sta_no_session_timeout(hapd, sta);
852 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
854 "authentication OK (open system)");
855 #ifdef IEEE80211_REQUIRE_AUTH_ACK
856 /* Station will be marked authenticated if it ACKs the
857 * authentication reply. */
859 sta->flags |= WLAN_STA_AUTH;
860 wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
861 sta->auth_alg = WLAN_AUTH_OPEN;
862 mlme_authenticate_indication(hapd, sta);
865 case WLAN_AUTH_SHARED_KEY:
866 resp = auth_shared_key(hapd, sta, auth_transaction, challenge,
868 sta->auth_alg = WLAN_AUTH_SHARED_KEY;
869 mlme_authenticate_indication(hapd, sta);
870 if (sta->challenge && auth_transaction == 1) {
871 resp_ies[0] = WLAN_EID_CHALLENGE;
872 resp_ies[1] = WLAN_AUTH_CHALLENGE_LEN;
873 os_memcpy(resp_ies + 2, sta->challenge,
874 WLAN_AUTH_CHALLENGE_LEN);
875 resp_ies_len = 2 + WLAN_AUTH_CHALLENGE_LEN;
878 #ifdef CONFIG_IEEE80211R
880 sta->auth_alg = WLAN_AUTH_FT;
881 if (sta->wpa_sm == NULL)
882 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
884 if (sta->wpa_sm == NULL) {
885 wpa_printf(MSG_DEBUG, "FT: Failed to initialize WPA "
887 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
890 wpa_ft_process_auth(sta->wpa_sm, mgmt->bssid,
891 auth_transaction, mgmt->u.auth.variable,
892 len - IEEE80211_HDRLEN -
893 sizeof(mgmt->u.auth),
894 handle_auth_ft_finish, hapd);
895 /* handle_auth_ft_finish() callback will complete auth. */
897 #endif /* CONFIG_IEEE80211R */
901 send_auth_reply(hapd, mgmt->sa, mgmt->bssid, auth_alg,
902 auth_transaction + 1, resp, resp_ies, resp_ies_len);
906 static void handle_assoc(struct hostapd_data *hapd,
907 struct ieee80211_mgmt *mgmt, size_t len, int reassoc)
909 u16 capab_info, listen_interval;
910 u16 resp = WLAN_STATUS_SUCCESS;
913 int send_deauth = 0, send_len, left, i;
914 struct sta_info *sta;
915 struct ieee802_11_elems elems;
916 u8 buf[sizeof(struct ieee80211_mgmt) + 512];
917 struct ieee80211_mgmt *reply;
919 if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
920 sizeof(mgmt->u.assoc_req))) {
921 printf("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
922 "\n", reassoc, (unsigned long) len);
927 capab_info = le_to_host16(mgmt->u.reassoc_req.capab_info);
928 listen_interval = le_to_host16(
929 mgmt->u.reassoc_req.listen_interval);
930 wpa_printf(MSG_DEBUG, "reassociation request: STA=" MACSTR
931 " capab_info=0x%02x listen_interval=%d current_ap="
933 MAC2STR(mgmt->sa), capab_info, listen_interval,
934 MAC2STR(mgmt->u.reassoc_req.current_ap));
935 left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req));
936 pos = mgmt->u.reassoc_req.variable;
938 capab_info = le_to_host16(mgmt->u.assoc_req.capab_info);
939 listen_interval = le_to_host16(
940 mgmt->u.assoc_req.listen_interval);
941 wpa_printf(MSG_DEBUG, "association request: STA=" MACSTR
942 " capab_info=0x%02x listen_interval=%d",
943 MAC2STR(mgmt->sa), capab_info, listen_interval);
944 left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req));
945 pos = mgmt->u.assoc_req.variable;
948 sta = ap_get_sta(hapd, mgmt->sa);
949 #ifdef CONFIG_IEEE80211R
950 if (sta && sta->auth_alg == WLAN_AUTH_FT &&
951 (sta->flags & WLAN_STA_AUTH) == 0) {
952 wpa_printf(MSG_DEBUG, "FT: Allow STA " MACSTR " to associate "
953 "prior to authentication since it is using "
954 "over-the-DS FT", MAC2STR(mgmt->sa));
956 #endif /* CONFIG_IEEE80211R */
957 if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) {
958 printf("STA " MACSTR " trying to associate before "
959 "authentication\n", MAC2STR(mgmt->sa));
961 printf(" sta: addr=" MACSTR " aid=%d flags=0x%04x\n",
962 MAC2STR(sta->addr), sta->aid, sta->flags);
965 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
969 if (hapd->tkip_countermeasures) {
970 resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
974 if (listen_interval > hapd->conf->max_listen_interval) {
975 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
977 "Too large Listen Interval (%d)",
979 resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
984 os_memcpy(sta->previous_ap, mgmt->u.reassoc_req.current_ap,
988 sta->capability = capab_info;
990 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
992 if (ieee802_11_parse_elems(hapd, pos, left, &elems, 1) == ParseFailed
994 printf("STA " MACSTR " sent invalid association request\n",
996 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1000 if (elems.ssid_len != hapd->conf->ssid.ssid_len ||
1001 os_memcmp(elems.ssid, hapd->conf->ssid.ssid, elems.ssid_len) != 0)
1004 ieee802_11_print_ssid(ssid_txt, elems.ssid, elems.ssid_len);
1005 printf("Station " MACSTR " tried to associate with "
1006 "unknown SSID '%s'\n", MAC2STR(sta->addr), ssid_txt);
1007 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1011 sta->flags &= ~WLAN_STA_WME;
1012 if (elems.wme && hapd->conf->wme_enabled) {
1013 if (hostapd_eid_wme_valid(hapd, elems.wme, elems.wme_len))
1014 hostapd_logger(hapd, sta->addr,
1016 HOSTAPD_LEVEL_DEBUG,
1017 "invalid WME element in association "
1020 sta->flags |= WLAN_STA_WME;
1023 if (!elems.supp_rates) {
1024 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1025 HOSTAPD_LEVEL_DEBUG,
1026 "No supported rates element in AssocReq");
1027 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1031 if (elems.supp_rates_len > sizeof(sta->supported_rates)) {
1032 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1033 HOSTAPD_LEVEL_DEBUG,
1034 "Invalid supported rates element length %d",
1035 elems.supp_rates_len);
1036 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1040 os_memset(sta->supported_rates, 0, sizeof(sta->supported_rates));
1041 os_memcpy(sta->supported_rates, elems.supp_rates,
1042 elems.supp_rates_len);
1043 sta->supported_rates_len = elems.supp_rates_len;
1045 if (elems.ext_supp_rates) {
1046 if (elems.supp_rates_len + elems.ext_supp_rates_len >
1047 sizeof(sta->supported_rates)) {
1048 hostapd_logger(hapd, mgmt->sa,
1049 HOSTAPD_MODULE_IEEE80211,
1050 HOSTAPD_LEVEL_DEBUG,
1051 "Invalid supported rates element length"
1052 " %d+%d", elems.supp_rates_len,
1053 elems.ext_supp_rates_len);
1054 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1058 os_memcpy(sta->supported_rates + elems.supp_rates_len,
1059 elems.ext_supp_rates, elems.ext_supp_rates_len);
1060 sta->supported_rates_len += elems.ext_supp_rates_len;
1063 #ifdef CONFIG_IEEE80211N
1064 /* save HT capabilities in the sta object */
1065 os_memset(&sta->ht_capabilities, 0, sizeof(sta->ht_capabilities));
1066 if (elems.ht_capabilities &&
1067 elems.ht_capabilities_len >= sizeof(struct ieee80211_ht_capability)
1068 && (sta->flags & WLAN_STA_WME)) {
1069 /* note: without WMM capability, treat the sta as non-HT */
1070 sta->flags |= WLAN_STA_HT;
1071 sta->ht_capabilities.id = WLAN_EID_HT_CAP;
1072 sta->ht_capabilities.length =
1073 sizeof(struct ieee80211_ht_capability);
1074 os_memcpy(&sta->ht_capabilities.data,
1075 elems.ht_capabilities,
1076 sizeof(struct ieee80211_ht_capability));
1078 sta->flags &= ~WLAN_STA_HT;
1079 #endif /* CONFIG_IEEE80211N */
1081 if ((hapd->conf->wpa & WPA_PROTO_RSN) && elems.rsn_ie) {
1082 wpa_ie = elems.rsn_ie;
1083 wpa_ie_len = elems.rsn_ie_len;
1084 } else if ((hapd->conf->wpa & WPA_PROTO_WPA) &&
1086 wpa_ie = elems.wpa_ie;
1087 wpa_ie_len = elems.wpa_ie_len;
1092 if (hapd->conf->wpa && wpa_ie == NULL) {
1093 printf("STA " MACSTR ": No WPA/RSN IE in association "
1094 "request\n", MAC2STR(sta->addr));
1095 resp = WLAN_STATUS_INVALID_IE;
1099 if (hapd->conf->wpa && wpa_ie) {
1103 if (sta->wpa_sm == NULL)
1104 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
1106 if (sta->wpa_sm == NULL) {
1107 printf("Failed to initialize WPA state machine\n");
1108 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1111 res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
1113 elems.mdie, elems.mdie_len);
1114 if (res == WPA_INVALID_GROUP)
1115 resp = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
1116 else if (res == WPA_INVALID_PAIRWISE)
1117 resp = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
1118 else if (res == WPA_INVALID_AKMP)
1119 resp = WLAN_STATUS_AKMP_NOT_VALID;
1120 else if (res == WPA_ALLOC_FAIL)
1121 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1122 #ifdef CONFIG_IEEE80211W
1123 else if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION)
1124 resp = WLAN_STATUS_UNSPECIFIED_FAILURE; /* FIX */
1125 else if (res == WPA_INVALID_MGMT_GROUP_CIPHER)
1126 resp = WLAN_STATUS_UNSPECIFIED_FAILURE; /* FIX */
1127 #endif /* CONFIG_IEEE80211W */
1128 else if (res == WPA_INVALID_MDIE)
1129 resp = WLAN_STATUS_INVALID_MDIE;
1130 else if (res != WPA_IE_OK)
1131 resp = WLAN_STATUS_INVALID_IE;
1132 if (resp != WLAN_STATUS_SUCCESS)
1134 #ifdef CONFIG_IEEE80211W
1135 if (wpa_auth_uses_mfp(sta->wpa_sm))
1136 sta->flags |= WLAN_STA_MFP;
1138 sta->flags &= ~WLAN_STA_MFP;
1139 #endif /* CONFIG_IEEE80211W */
1141 #ifdef CONFIG_IEEE80211R
1142 if (sta->auth_alg == WLAN_AUTH_FT) {
1144 wpa_printf(MSG_DEBUG, "FT: " MACSTR " tried "
1145 "to use association (not "
1146 "re-association) with FT auth_alg",
1147 MAC2STR(sta->addr));
1148 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1152 resp = wpa_ft_validate_reassoc(sta->wpa_sm, pos, left);
1153 if (resp != WLAN_STATUS_SUCCESS)
1156 #endif /* CONFIG_IEEE80211R */
1159 if (hapd->iface->dfs_enable &&
1160 hapd->iconf->ieee80211h == SPECT_STRICT_BINDING) {
1161 if (hostapd_check_power_cap(hapd, elems.power_cap,
1162 elems.power_cap_len)) {
1163 resp = WLAN_STATUS_PWR_CAPABILITY_NOT_VALID;
1164 hostapd_logger(hapd, sta->addr,
1165 HOSTAPD_MODULE_IEEE80211,
1166 HOSTAPD_LEVEL_DEBUG,
1167 "Power capabilities of the station not "
1173 if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
1174 sta->flags |= WLAN_STA_NONERP;
1175 for (i = 0; i < sta->supported_rates_len; i++) {
1176 if ((sta->supported_rates[i] & 0x7f) > 22) {
1177 sta->flags &= ~WLAN_STA_NONERP;
1181 if (sta->flags & WLAN_STA_NONERP && !sta->nonerp_set) {
1182 sta->nonerp_set = 1;
1183 hapd->iface->num_sta_non_erp++;
1184 if (hapd->iface->num_sta_non_erp == 1)
1185 ieee802_11_set_beacons(hapd->iface);
1188 if (!(sta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) &&
1189 !sta->no_short_slot_time_set) {
1190 sta->no_short_slot_time_set = 1;
1191 hapd->iface->num_sta_no_short_slot_time++;
1192 if (hapd->iface->current_mode->mode ==
1193 HOSTAPD_MODE_IEEE80211G &&
1194 hapd->iface->num_sta_no_short_slot_time == 1)
1195 ieee802_11_set_beacons(hapd->iface);
1198 if (sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1199 sta->flags |= WLAN_STA_SHORT_PREAMBLE;
1201 sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
1203 if (!(sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
1204 !sta->no_short_preamble_set) {
1205 sta->no_short_preamble_set = 1;
1206 hapd->iface->num_sta_no_short_preamble++;
1207 if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
1208 && hapd->iface->num_sta_no_short_preamble == 1)
1209 ieee802_11_set_beacons(hapd->iface);
1212 #ifdef CONFIG_IEEE80211N
1213 if (sta->flags & WLAN_STA_HT) {
1214 if ((sta->ht_capabilities.data.capabilities_info &
1215 HT_CAP_INFO_GREEN_FIELD) == 0) {
1216 hapd->iface->num_sta_ht_no_gf++;
1217 wpa_printf(MSG_DEBUG, "%s STA " MACSTR " - no "
1218 "greenfield, num of non-gf stations %d",
1219 __func__, MAC2STR(sta->addr),
1220 hapd->iface->num_sta_ht_no_gf);
1222 if ((sta->ht_capabilities.data.capabilities_info &
1223 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) == 0) {
1224 hapd->iface->num_sta_ht_20mhz++;
1225 wpa_printf(MSG_DEBUG, "%s STA " MACSTR " - 20 MHz HT, "
1226 "num of 20MHz HT STAs %d",
1227 __func__, MAC2STR(sta->addr),
1228 hapd->iface->num_sta_ht_20mhz);
1231 hapd->iface->num_sta_no_ht++;
1232 if (hapd->conf->ieee80211n) {
1233 wpa_printf(MSG_DEBUG, "%s STA " MACSTR
1234 " - no HT, num of non-HT stations %d",
1235 __func__, MAC2STR(sta->addr),
1236 hapd->iface->num_sta_no_ht);
1240 if (hostapd_ht_operation_update(hapd->iface) > 0)
1241 ieee802_11_set_beacons(hapd->iface);
1242 #endif /* CONFIG_IEEE80211N */
1244 /* get a unique AID */
1246 wpa_printf(MSG_DEBUG, " old AID %d", sta->aid);
1248 for (sta->aid = 1; sta->aid <= MAX_AID_TABLE_SIZE; sta->aid++)
1249 if (hapd->sta_aid[sta->aid - 1] == NULL)
1251 if (sta->aid > MAX_AID_TABLE_SIZE) {
1253 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1254 wpa_printf(MSG_ERROR, " no room for more AIDs");
1257 hapd->sta_aid[sta->aid - 1] = sta;
1258 wpa_printf(MSG_DEBUG, " new AID %d", sta->aid);
1262 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1263 HOSTAPD_LEVEL_DEBUG,
1264 "association OK (aid %d)", sta->aid);
1265 /* Station will be marked associated, after it acknowledges AssocResp
1268 if (sta->last_assoc_req)
1269 os_free(sta->last_assoc_req);
1270 sta->last_assoc_req = os_malloc(len);
1271 if (sta->last_assoc_req)
1272 os_memcpy(sta->last_assoc_req, mgmt, len);
1274 /* Make sure that the previously registered inactivity timer will not
1275 * remove the STA immediately. */
1276 sta->timeout_next = STA_NULLFUNC;
1279 os_memset(buf, 0, sizeof(buf));
1280 reply = (struct ieee80211_mgmt *) buf;
1281 reply->frame_control =
1282 IEEE80211_FC(WLAN_FC_TYPE_MGMT,
1283 (send_deauth ? WLAN_FC_STYPE_DEAUTH :
1284 (reassoc ? WLAN_FC_STYPE_REASSOC_RESP :
1285 WLAN_FC_STYPE_ASSOC_RESP)));
1286 os_memcpy(reply->da, mgmt->sa, ETH_ALEN);
1287 os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
1288 os_memcpy(reply->bssid, mgmt->bssid, ETH_ALEN);
1290 send_len = IEEE80211_HDRLEN;
1292 send_len += sizeof(reply->u.deauth);
1293 reply->u.deauth.reason_code = host_to_le16(resp);
1296 send_len += sizeof(reply->u.assoc_resp);
1297 reply->u.assoc_resp.capab_info =
1298 host_to_le16(hostapd_own_capab_info(hapd, sta, 0));
1299 reply->u.assoc_resp.status_code = host_to_le16(resp);
1300 reply->u.assoc_resp.aid = host_to_le16((sta ? sta->aid : 0)
1301 | BIT(14) | BIT(15));
1302 /* Supported rates */
1303 p = hostapd_eid_supp_rates(hapd, reply->u.assoc_resp.variable);
1304 /* Extended supported rates */
1305 p = hostapd_eid_ext_supp_rates(hapd, p);
1306 if (sta->flags & WLAN_STA_WME)
1307 p = hostapd_eid_wme(hapd, p);
1309 #ifdef CONFIG_IEEE80211N
1310 if (hapd->conf->ieee80211n) {
1311 p = hostapd_eid_ht_capabilities_info(hapd, p);
1312 p = hostapd_eid_ht_operation(hapd, p);
1314 #endif /* CONFIG_IEEE80211N */
1316 #ifdef CONFIG_IEEE80211R
1317 if (resp == WLAN_STATUS_SUCCESS) {
1318 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
1319 * Transition Information, RSN */
1320 p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, p,
1321 buf + sizeof(buf) - p,
1324 #endif /* CONFIG_IEEE80211R */
1326 send_len += p - reply->u.assoc_resp.variable;
1328 /* Request TX callback */
1329 reply->frame_control |= host_to_le16(BIT(1));
1332 if (hostapd_send_mgmt_frame(hapd, reply, send_len, 0) < 0)
1333 perror("handle_assoc: send");
1337 static void handle_assoc_resp(struct hostapd_data *hapd,
1338 struct ieee80211_mgmt *mgmt, size_t len)
1340 u16 status_code, aid;
1342 if (hapd->assoc_ap_state != ASSOCIATE) {
1343 printf("Unexpected association response received from " MACSTR
1344 "\n", MAC2STR(mgmt->sa));
1348 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_resp)) {
1349 printf("handle_assoc_resp - too short payload (len=%lu)\n",
1350 (unsigned long) len);
1354 if (os_memcmp(mgmt->sa, hapd->conf->assoc_ap_addr, ETH_ALEN) != 0 ||
1355 os_memcmp(mgmt->bssid, hapd->conf->assoc_ap_addr, ETH_ALEN) != 0) {
1356 printf("Received association response from unexpected address "
1357 "(SA=" MACSTR " BSSID=" MACSTR "\n",
1358 MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid));
1362 status_code = le_to_host16(mgmt->u.assoc_resp.status_code);
1363 aid = le_to_host16(mgmt->u.assoc_resp.aid);
1364 aid &= ~(BIT(14) | BIT(15));
1366 if (status_code != 0) {
1367 printf("Association (as station) with AP " MACSTR " failed "
1368 "(status_code=%d)\n",
1369 MAC2STR(hapd->conf->assoc_ap_addr), status_code);
1370 /* Try to authenticate again */
1371 hapd->assoc_ap_state = AUTHENTICATE;
1372 eloop_register_timeout(5, 0, ieee802_11_sta_authenticate,
1376 printf("Associated (as station) with AP " MACSTR " (aid=%d)\n",
1377 MAC2STR(hapd->conf->assoc_ap_addr), aid);
1378 hapd->assoc_ap_aid = aid;
1379 hapd->assoc_ap_state = ASSOCIATED;
1381 if (hostapd_set_assoc_ap(hapd, hapd->conf->assoc_ap_addr)) {
1382 printf("Could not set associated AP address to kernel "
1388 static void handle_disassoc(struct hostapd_data *hapd,
1389 struct ieee80211_mgmt *mgmt, size_t len)
1391 struct sta_info *sta;
1393 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.disassoc)) {
1394 printf("handle_disassoc - too short payload (len=%lu)\n",
1395 (unsigned long) len);
1399 wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d",
1401 le_to_host16(mgmt->u.disassoc.reason_code));
1403 if (hapd->assoc_ap_state != DO_NOT_ASSOC &&
1404 os_memcmp(mgmt->sa, hapd->conf->assoc_ap_addr, ETH_ALEN) == 0) {
1405 printf("Assoc AP " MACSTR " sent disassociation "
1406 "(reason_code=%d) - try to authenticate\n",
1407 MAC2STR(hapd->conf->assoc_ap_addr),
1408 le_to_host16(mgmt->u.disassoc.reason_code));
1409 hapd->assoc_ap_state = AUTHENTICATE;
1410 ieee802_11_sta_authenticate(hapd, NULL);
1411 eloop_register_timeout(0, 500000, ieee802_11_sta_authenticate,
1416 sta = ap_get_sta(hapd, mgmt->sa);
1418 printf("Station " MACSTR " trying to disassociate, but it "
1419 "is not associated.\n", MAC2STR(mgmt->sa));
1423 sta->flags &= ~WLAN_STA_ASSOC;
1424 wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
1425 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1426 HOSTAPD_LEVEL_INFO, "disassociated");
1427 sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
1428 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
1429 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
1431 accounting_sta_stop(hapd, sta);
1432 ieee802_1x_free_station(sta);
1433 hostapd_sta_remove(hapd, sta->addr);
1435 if (sta->timeout_next == STA_NULLFUNC ||
1436 sta->timeout_next == STA_DISASSOC) {
1437 sta->timeout_next = STA_DEAUTH;
1438 eloop_cancel_timeout(ap_handle_timer, hapd, sta);
1439 eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer,
1443 mlme_disassociate_indication(
1444 hapd, sta, le_to_host16(mgmt->u.disassoc.reason_code));
1448 static void handle_deauth(struct hostapd_data *hapd,
1449 struct ieee80211_mgmt *mgmt, size_t len)
1451 struct sta_info *sta;
1453 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.deauth)) {
1454 printf("handle_deauth - too short payload (len=%lu)\n",
1455 (unsigned long) len);
1459 wpa_printf(MSG_DEBUG, "deauthentication: STA=" MACSTR
1462 le_to_host16(mgmt->u.deauth.reason_code));
1464 if (hapd->assoc_ap_state != DO_NOT_ASSOC &&
1465 os_memcmp(mgmt->sa, hapd->conf->assoc_ap_addr, ETH_ALEN) == 0) {
1466 printf("Assoc AP " MACSTR " sent deauthentication "
1467 "(reason_code=%d) - try to authenticate\n",
1468 MAC2STR(hapd->conf->assoc_ap_addr),
1469 le_to_host16(mgmt->u.deauth.reason_code));
1470 hapd->assoc_ap_state = AUTHENTICATE;
1471 eloop_register_timeout(0, 500000, ieee802_11_sta_authenticate,
1476 sta = ap_get_sta(hapd, mgmt->sa);
1478 printf("Station " MACSTR " trying to deauthenticate, but it "
1479 "is not authenticated.\n", MAC2STR(mgmt->sa));
1483 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
1484 wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
1485 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1486 HOSTAPD_LEVEL_DEBUG, "deauthenticated");
1487 mlme_deauthenticate_indication(
1488 hapd, sta, le_to_host16(mgmt->u.deauth.reason_code));
1489 sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
1490 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
1491 ap_free_sta(hapd, sta);
1495 static void handle_beacon(struct hostapd_data *hapd,
1496 struct ieee80211_mgmt *mgmt, size_t len,
1497 struct hostapd_frame_info *fi)
1499 struct ieee802_11_elems elems;
1501 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.beacon)) {
1502 printf("handle_beacon - too short payload (len=%lu)\n",
1503 (unsigned long) len);
1507 (void) ieee802_11_parse_elems(hapd, mgmt->u.beacon.variable,
1508 len - (IEEE80211_HDRLEN +
1509 sizeof(mgmt->u.beacon)), &elems,
1512 if (hapd->assoc_ap_state == WAIT_BEACON &&
1513 os_memcmp(mgmt->sa, hapd->conf->assoc_ap_addr, ETH_ALEN) == 0) {
1514 if (elems.ssid && elems.ssid_len <= 32) {
1515 os_memcpy(hapd->assoc_ap_ssid, elems.ssid,
1517 hapd->assoc_ap_ssid[elems.ssid_len] = '\0';
1518 hapd->assoc_ap_ssid_len = elems.ssid_len;
1520 ieee802_11_sta_authenticate(hapd, NULL);
1523 ap_list_process_beacon(hapd->iface, mgmt, &elems, fi);
1527 static void handle_action(struct hostapd_data *hapd,
1528 struct ieee80211_mgmt *mgmt, size_t len)
1530 if (len < IEEE80211_HDRLEN + 1) {
1531 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1532 HOSTAPD_LEVEL_DEBUG,
1533 "handle_action - too short payload (len=%lu)",
1534 (unsigned long) len);
1538 switch (mgmt->u.action.category) {
1539 #ifdef CONFIG_IEEE80211R
1540 case WLAN_ACTION_FT:
1542 struct sta_info *sta;
1544 sta = ap_get_sta(hapd, mgmt->sa);
1545 if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) {
1546 wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignored FT Action "
1547 "frame from unassociated STA " MACSTR,
1552 if (wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action,
1553 len - IEEE80211_HDRLEN))
1558 #endif /* CONFIG_IEEE80211R */
1559 case WME_ACTION_CATEGORY:
1560 hostapd_wme_action(hapd, mgmt, len);
1564 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1565 HOSTAPD_LEVEL_DEBUG,
1566 "handle_action - unknown action category %d or invalid "
1568 mgmt->u.action.category);
1569 if (!(mgmt->da[0] & 0x01) && !(mgmt->u.action.category & 0x80) &&
1570 !(mgmt->sa[0] & 0x01)) {
1572 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
1573 * Return the Action frame to the source without change
1574 * except that MSB of the Category set to 1.
1576 wpa_printf(MSG_DEBUG, "IEEE 802.11: Return unknown Action "
1577 "frame back to sender");
1578 os_memcpy(mgmt->da, mgmt->sa, ETH_ALEN);
1579 os_memcpy(mgmt->sa, hapd->own_addr, ETH_ALEN);
1580 os_memcpy(mgmt->bssid, hapd->own_addr, ETH_ALEN);
1581 mgmt->u.action.category |= 0x80;
1583 hostapd_send_mgmt_frame(hapd, mgmt, len, 0);
1589 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
1590 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
1592 * @buf: management frame data (starting from IEEE 802.11 header)
1593 * @len: length of frame data in octets
1594 * @stype: management frame subtype from frame control field
1596 * Process all incoming IEEE 802.11 management frames. This will be called for
1597 * each frame received from the kernel driver through wlan#ap interface. In
1598 * addition, it can be called to re-inserted pending frames (e.g., when using
1599 * external RADIUS server as an MAC ACL).
1601 void ieee802_11_mgmt(struct hostapd_data *hapd, u8 *buf, size_t len, u16 stype,
1602 struct hostapd_frame_info *fi)
1604 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) buf;
1607 if (stype == WLAN_FC_STYPE_BEACON) {
1608 handle_beacon(hapd, mgmt, len, fi);
1612 if (fi && fi->passive_scan)
1615 broadcast = mgmt->bssid[0] == 0xff && mgmt->bssid[1] == 0xff &&
1616 mgmt->bssid[2] == 0xff && mgmt->bssid[3] == 0xff &&
1617 mgmt->bssid[4] == 0xff && mgmt->bssid[5] == 0xff;
1620 os_memcmp(mgmt->bssid, hapd->own_addr, ETH_ALEN) != 0 &&
1621 (hapd->assoc_ap_state == DO_NOT_ASSOC ||
1622 os_memcmp(mgmt->bssid, hapd->conf->assoc_ap_addr, ETH_ALEN) != 0))
1624 printf("MGMT: BSSID=" MACSTR " not our address\n",
1625 MAC2STR(mgmt->bssid));
1630 if (stype == WLAN_FC_STYPE_PROBE_REQ) {
1631 handle_probe_req(hapd, mgmt, len);
1635 if (os_memcmp(mgmt->da, hapd->own_addr, ETH_ALEN) != 0) {
1636 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1637 HOSTAPD_LEVEL_DEBUG,
1638 "MGMT: DA=" MACSTR " not our address",
1644 case WLAN_FC_STYPE_AUTH:
1645 wpa_printf(MSG_DEBUG, "mgmt::auth");
1646 handle_auth(hapd, mgmt, len);
1648 case WLAN_FC_STYPE_ASSOC_REQ:
1649 wpa_printf(MSG_DEBUG, "mgmt::assoc_req");
1650 handle_assoc(hapd, mgmt, len, 0);
1652 case WLAN_FC_STYPE_ASSOC_RESP:
1653 wpa_printf(MSG_DEBUG, "mgmt::assoc_resp");
1654 handle_assoc_resp(hapd, mgmt, len);
1656 case WLAN_FC_STYPE_REASSOC_REQ:
1657 wpa_printf(MSG_DEBUG, "mgmt::reassoc_req");
1658 handle_assoc(hapd, mgmt, len, 1);
1660 case WLAN_FC_STYPE_DISASSOC:
1661 wpa_printf(MSG_DEBUG, "mgmt::disassoc");
1662 handle_disassoc(hapd, mgmt, len);
1664 case WLAN_FC_STYPE_DEAUTH:
1665 wpa_printf(MSG_DEBUG, "mgmt::deauth");
1666 handle_deauth(hapd, mgmt, len);
1668 case WLAN_FC_STYPE_ACTION:
1669 wpa_printf(MSG_DEBUG, "mgmt::action");
1670 handle_action(hapd, mgmt, len);
1673 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
1674 HOSTAPD_LEVEL_DEBUG,
1675 "unknown mgmt frame subtype %d", stype);
1681 static void handle_auth_cb(struct hostapd_data *hapd,
1682 struct ieee80211_mgmt *mgmt,
1685 u16 auth_alg, auth_transaction, status_code;
1686 struct sta_info *sta;
1689 hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
1690 HOSTAPD_LEVEL_NOTICE,
1691 "did not acknowledge authentication response");
1695 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
1696 printf("handle_auth_cb - too short payload (len=%lu)\n",
1697 (unsigned long) len);
1701 auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
1702 auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
1703 status_code = le_to_host16(mgmt->u.auth.status_code);
1705 sta = ap_get_sta(hapd, mgmt->da);
1707 printf("handle_auth_cb: STA " MACSTR " not found\n",
1712 if (status_code == WLAN_STATUS_SUCCESS &&
1713 ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) ||
1714 (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) {
1715 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1716 HOSTAPD_LEVEL_INFO, "authenticated");
1717 sta->flags |= WLAN_STA_AUTH;
1722 static void handle_assoc_cb(struct hostapd_data *hapd,
1723 struct ieee80211_mgmt *mgmt,
1724 size_t len, int reassoc, int ok)
1727 struct sta_info *sta;
1729 struct ht_cap_ie *ht_cap = NULL;
1732 hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
1733 HOSTAPD_LEVEL_DEBUG,
1734 "did not acknowledge association response");
1738 if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_resp) :
1739 sizeof(mgmt->u.assoc_resp))) {
1740 printf("handle_assoc_cb(reassoc=%d) - too short payload "
1741 "(len=%lu)\n", reassoc, (unsigned long) len);
1746 status = le_to_host16(mgmt->u.reassoc_resp.status_code);
1748 status = le_to_host16(mgmt->u.assoc_resp.status_code);
1750 sta = ap_get_sta(hapd, mgmt->da);
1752 printf("handle_assoc_cb: STA " MACSTR " not found\n",
1757 if (status != WLAN_STATUS_SUCCESS)
1760 /* Stop previous accounting session, if one is started, and allocate
1761 * new session id for the new session. */
1762 accounting_sta_stop(hapd, sta);
1763 accounting_sta_get_id(hapd, sta);
1765 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1767 "associated (aid %d, accounting session %08X-%08X)",
1768 sta->aid, sta->acct_session_id_hi,
1769 sta->acct_session_id_lo);
1771 if (sta->flags & WLAN_STA_ASSOC)
1773 sta->flags |= WLAN_STA_ASSOC;
1776 mlme_reassociate_indication(hapd, sta);
1778 mlme_associate_indication(hapd, sta);
1780 #ifdef CONFIG_IEEE80211N
1781 if (sta->flags & WLAN_STA_HT)
1782 ht_cap = &sta->ht_capabilities;
1783 #endif /* CONFIG_IEEE80211N */
1785 if (hostapd_sta_add(hapd->conf->iface, hapd, sta->addr, sta->aid,
1786 sta->capability, sta->supported_rates,
1787 sta->supported_rates_len, 0, sta->listen_interval,
1790 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1791 HOSTAPD_LEVEL_NOTICE,
1792 "Could not add STA to kernel driver");
1795 if (sta->eapol_sm == NULL) {
1797 * This STA does not use RADIUS server for EAP authentication,
1798 * so bind it to the selected VLAN interface now, since the
1799 * interface selection is not going to change anymore.
1801 ap_sta_bind_vlan(hapd, sta, 0);
1802 } else if (sta->vlan_id) {
1803 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
1804 ap_sta_bind_vlan(hapd, sta, 0);
1806 if (sta->flags & WLAN_STA_SHORT_PREAMBLE) {
1807 hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
1808 WLAN_STA_SHORT_PREAMBLE, ~0);
1810 hostapd_sta_set_flags(hapd, sta->addr, sta->flags,
1811 0, ~WLAN_STA_SHORT_PREAMBLE);
1814 if (sta->auth_alg == WLAN_AUTH_FT)
1815 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT);
1817 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
1818 hostapd_new_assoc_sta(hapd, sta, !new_assoc);
1820 ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
1823 /* Copy of the association request is not needed anymore */
1824 if (sta->last_assoc_req) {
1825 os_free(sta->last_assoc_req);
1826 sta->last_assoc_req = NULL;
1831 void ieee802_11_mgmt_cb(struct hostapd_data *hapd, u8 *buf, size_t len,
1834 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) buf;
1837 case WLAN_FC_STYPE_AUTH:
1838 wpa_printf(MSG_DEBUG, "mgmt::auth cb");
1839 handle_auth_cb(hapd, mgmt, len, ok);
1841 case WLAN_FC_STYPE_ASSOC_RESP:
1842 wpa_printf(MSG_DEBUG, "mgmt::assoc_resp cb");
1843 handle_assoc_cb(hapd, mgmt, len, 0, ok);
1845 case WLAN_FC_STYPE_REASSOC_RESP:
1846 wpa_printf(MSG_DEBUG, "mgmt::reassoc_resp cb");
1847 handle_assoc_cb(hapd, mgmt, len, 1, ok);
1849 case WLAN_FC_STYPE_PROBE_RESP:
1850 wpa_printf(MSG_DEBUG, "mgmt::proberesp cb");
1852 case WLAN_FC_STYPE_DEAUTH:
1856 printf("unknown mgmt cb frame subtype %d\n", stype);
1862 static void ieee80211_tkip_countermeasures_stop(void *eloop_ctx,
1865 struct hostapd_data *hapd = eloop_ctx;
1866 hapd->tkip_countermeasures = 0;
1867 hostapd_set_countermeasures(hapd, 0);
1868 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
1869 HOSTAPD_LEVEL_INFO, "TKIP countermeasures ended");
1873 static void ieee80211_tkip_countermeasures_start(struct hostapd_data *hapd)
1875 struct sta_info *sta;
1877 hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
1878 HOSTAPD_LEVEL_INFO, "TKIP countermeasures initiated");
1880 wpa_auth_countermeasures_start(hapd->wpa_auth);
1881 hapd->tkip_countermeasures = 1;
1882 hostapd_set_countermeasures(hapd, 1);
1883 wpa_gtk_rekey(hapd->wpa_auth);
1884 eloop_cancel_timeout(ieee80211_tkip_countermeasures_stop, hapd, NULL);
1885 eloop_register_timeout(60, 0, ieee80211_tkip_countermeasures_stop,
1887 for (sta = hapd->sta_list; sta != NULL; sta = sta->next) {
1888 hostapd_sta_deauth(hapd, sta->addr,
1889 WLAN_REASON_MICHAEL_MIC_FAILURE);
1890 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC |
1891 WLAN_STA_AUTHORIZED);
1892 hostapd_sta_remove(hapd, sta->addr);
1897 void ieee80211_michael_mic_failure(struct hostapd_data *hapd, const u8 *addr,
1902 if (addr && local) {
1903 struct sta_info *sta = ap_get_sta(hapd, addr);
1905 wpa_auth_sta_local_mic_failure_report(sta->wpa_sm);
1906 hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
1908 "Michael MIC failure detected in "
1910 mlme_michaelmicfailure_indication(hapd, addr);
1912 wpa_printf(MSG_DEBUG,
1913 "MLME-MICHAELMICFAILURE.indication "
1914 "for not associated STA (" MACSTR
1915 ") ignored", MAC2STR(addr));
1921 if (now > hapd->michael_mic_failure + 60) {
1922 hapd->michael_mic_failures = 1;
1924 hapd->michael_mic_failures++;
1925 if (hapd->michael_mic_failures > 1)
1926 ieee80211_tkip_countermeasures_start(hapd);
1928 hapd->michael_mic_failure = now;
1932 int ieee802_11_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen)
1939 int ieee802_11_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
1940 char *buf, size_t buflen)
1946 #endif /* CONFIG_NATIVE_WINDOWS */