sme.c revision d5e4923d04122f81300fa68fb07d64ede28fd44d
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant - SME 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/eloop.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_common.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eapol_supp/eapol_supp_sm.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/wpa_common.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "rsn_supp/wpa.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "rsn_supp/pmksa_cache.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_supplicant_i.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "driver_i.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpas_glue.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps_supplicant.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_supplicant.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "notify.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "bss.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "scan.h" 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "sme.h" 2904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "hs20_supplicant.h" 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define SME_AUTH_TIMEOUT 5 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define SME_ASSOC_TIMEOUT 5 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_auth_timer(void *eloop_ctx, void *timeout_ctx); 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx); 3604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void sme_obss_scan_timeout(void *eloop_ctx, void *timeout_ctx); 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_stop_sa_query(struct wpa_supplicant *wpa_s); 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 42d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE 43d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 44d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s) 45d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 46d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpabuf *buf; 47d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 48d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt buf = wpabuf_alloc(4 + 2); 49d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (buf == NULL) 50d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return NULL; 51d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 52d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_le16(buf, 1); /* Transaction seq# */ 53d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS); 54d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_le16(buf, 19); /* Finite Cyclic Group */ 55d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* TODO: Anti-Clogging Token (if requested) */ 56d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* TODO: Scalar */ 57d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* TODO: Element */ 58d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 59d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return buf; 60d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 61d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 62d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 63d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic struct wpabuf * sme_auth_build_sae_confirm(struct wpa_supplicant *wpa_s) 64d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 65d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpabuf *buf; 66d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 67d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt buf = wpabuf_alloc(4 + 2); 68d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (buf == NULL) 69d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return NULL; 70d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 71d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_le16(buf, 2); /* Transaction seq# */ 72d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS); 73d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_put_le16(buf, wpa_s->sme.sae_send_confirm); 74d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->sme.sae_send_confirm++; 75d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* TODO: Confirm */ 76d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 77d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return buf; 78d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 79d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 80d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */ 81d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 82d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 83d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic void sme_send_authentication(struct wpa_supplicant *wpa_s, 84d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpa_bss *bss, struct wpa_ssid *ssid, 85d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int start) 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_auth_params params; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *old_ssid; 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ie; 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *md = NULL; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i, bssid_changed; 96d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpabuf *resp = NULL; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bss == NULL) { 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_ERROR, "SME: No scan result available for " 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "the network"); 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_bss = bss; 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->reassociate = 0; 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.freq = bss->freq; 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.bssid = bss->bssid; 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssid = bss->ssid; 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssid_len = bss->ssid_len; 1131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.p2p = ssid->p2p_group; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.ssid_len != params.ssid_len || 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(wpa_s->sme.ssid, params.ssid, params.ssid_len) != 0) 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.prev_bssid_set = 0; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.freq = params.freq; 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->sme.ssid, params.ssid, params.ssid_len); 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ssid_len = params.ssid_len; 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.auth_alg = WPA_AUTH_ALG_OPEN; 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) { 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->leap) { 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->non_leap == 0) 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.auth_alg = WPA_AUTH_ALG_LEAP; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.auth_alg |= WPA_AUTH_ALG_LEAP; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */ 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.auth_alg); 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->auth_alg) { 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.auth_alg = ssid->auth_alg; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: " 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "0x%x", params.auth_alg); 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 141d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE 142d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_key_mgmt_sae(ssid->key_mgmt)) { 143d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt const u8 *rsn; 144d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpa_ie_data ied; 145d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 146d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN); 147d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (rsn && 148d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ied) == 0) { 149d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_key_mgmt_sae(ied.key_mgmt)) { 150d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "Using SAE auth_alg"); 151d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt params.auth_alg = WPA_AUTH_ALG_SAE; 152d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 153d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 154d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 155d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */ 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < NUM_WEP_KEYS; i++) { 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid->wep_key_len[i]) 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wep_key[i] = ssid->wep_key[i]; 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wep_key_len[i] = ssid->wep_key_len[i]; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wep_tx_keyidx = ssid->wep_tx_keyidx; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid_changed = !is_zero_ether_addr(wpa_s->bssid); 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(wpa_s->bssid, 0, ETH_ALEN); 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN); 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid_changed) 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_bssid_changed(wpa_s); 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) || 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_bss_get_ie(bss, WLAN_EID_RSN)) && 1721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_key_mgmt_wpa(ssid->key_mgmt)) { 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int try_opportunistic; 174d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt try_opportunistic = (ssid->proactive_key_caching < 0 ? 175d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->conf->okc : 176d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt ssid->proactive_key_caching) && 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (ssid->proto & WPA_PROTO_RSN); 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid, 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid, 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt try_opportunistic) == 0) 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1); 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie); 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_supplicant_set_suites(wpa_s, bss, ssid, 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie, 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &wpa_s->sme.assoc_req_ie_len)) { 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_WARNING, "SME: Failed to set WPA " 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "key management and encryption suites"); 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 19061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && 19161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) { 19261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* 19361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * Both WPA and non-WPA IEEE 802.1X enabled in configuration - 19461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * use non-WPA since the scan results did not indicate that the 19561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * AP is using WPA or WPA2. 19661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 19761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_supplicant_set_non_wpa_policy(wpa_s, ssid); 19861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->sme.assoc_req_ie_len = 0; 1991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) { 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie); 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_supplicant_set_suites(wpa_s, NULL, ssid, 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie, 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &wpa_s->sme.assoc_req_ie_len)) { 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_WARNING, "SME: Failed to set WPA " 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "key management and encryption suites (no " 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "scan results)"); 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) { 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *wps_ie; 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid)); 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wps_ie && wpabuf_len(wps_ie) <= 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(wpa_s->sme.assoc_req_ie)) { 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len = wpabuf_len(wps_ie); 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->sme.assoc_req_ie, wpabuf_head(wps_ie), 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len); 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len = 0; 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(wps_ie); 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_non_wpa_policy(wpa_s, ssid); 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */ 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_non_wpa_policy(wpa_s, ssid); 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len = 0; 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN); 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN) 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt md = ie + 2; 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0); 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (md) { 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Prepare for the next transition */ 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ft_prepare_auth_request(wpa_s->wpa, ie); 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (md && wpa_key_mgmt_ft(ssid->key_mgmt)) { 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.assoc_req_ie_len + 5 < 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizeof(wpa_s->sme.assoc_req_ie)) { 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct rsn_mdie *mdie; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos = wpa_s->sme.assoc_req_ie + 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = WLAN_EID_MOBILITY_DOMAIN; 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = sizeof(*mdie); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mdie = (struct rsn_mdie *) pos; 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(mdie->mobility_domain, md, 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MOBILITY_DOMAIN_ID_LEN); 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mdie->ft_capab = md[MOBILITY_DOMAIN_ID_LEN]; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len += 5; 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.ft_used && 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcmp(md, wpa_s->sme.mobility_domain, 2) == 0 && 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_has_ptk(wpa_s->wpa)) { 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying to use FT " 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "over-the-air"); 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.auth_alg = WPA_AUTH_ALG_FT; 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ie = wpa_s->sme.ft_ies; 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ie_len = wpa_s->sme.ft_ies_len; 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 266d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->sme.mfp = ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ? 267d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->conf->pmf : ssid->ieee80211w; 268d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_s->sme.mfp != NO_MGMT_FRAME_PROTECTION) { 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN); 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ie_data _ie; 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &_ie) == 0 && 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt _ie.capabilities & 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) { 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Selected AP supports " 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "MFP: require MFP"); 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.mfp = MGMT_FRAME_PROTECTION_REQUIRED; 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->global->p2p) { 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos; 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len; 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = sizeof(wpa_s->sme.assoc_req_ie) - 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len; 2891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len, 2901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ssid->p2p_group); 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res >= 0) 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie_len += res; 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */ 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 29604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_HS20 29704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->conf->hs20) { 29804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpabuf *hs20; 29904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt hs20 = wpabuf_alloc(20); 30004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (hs20) { 30104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpas_hs20_add_indication(hs20); 30204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(wpa_s->sme.assoc_req_ie + 30304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.assoc_req_ie_len, 30404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_head(hs20), wpabuf_len(hs20)); 30504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.assoc_req_ie_len += wpabuf_len(hs20); 30604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_free(hs20); 30704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 30804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 30904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_HS20 */ 31004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 3111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_INTERWORKING 3121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->conf->interworking) { 3131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u8 *pos = wpa_s->sme.assoc_req_ie; 3141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->sme.assoc_req_ie_len > 0 && pos[0] == WLAN_EID_RSN) 3151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt pos += 2 + pos[1]; 3161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt os_memmove(pos + 6, pos, 3171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->sme.assoc_req_ie_len - 3181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt (pos - wpa_s->sme.assoc_req_ie)); 3191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_s->sme.assoc_req_ie_len += 6; 3201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *pos++ = WLAN_EID_EXT_CAPAB; 3211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *pos++ = 4; 3221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *pos++ = 0x00; 3231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *pos++ = 0x00; 3241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *pos++ = 0x00; 3251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *pos++ = 0x80; /* Bit 31 - Interworking */ 3261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 3271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_INTERWORKING */ 3281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 329d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE 330d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (params.auth_alg == WPA_AUTH_ALG_SAE) { 331d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (start) 332d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt resp = sme_auth_build_sae_commit(wpa_s); 333d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt else 334d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt resp = sme_auth_build_sae_confirm(wpa_s); 335d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (resp == NULL) 336d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 337d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt params.sae_data = wpabuf_head(resp); 338d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt params.sae_data_len = wpabuf_len(resp); 339d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->sme.sae_state = start ? SME_SAE_COMMIT : SME_SAE_CONFIRM; 340d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 341d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */ 342d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 3431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_supplicant_cancel_sched_scan(wpa_s); 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_cancel_scan(wpa_s); 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "SME: Trying to authenticate with " MACSTR 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid), 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_ssid_txt(params.ssid, params.ssid_len), params.freq); 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_clear_keys(wpa_s, bss->bssid); 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING); 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt old_ssid = wpa_s->current_ssid; 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid = ssid; 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid); 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_initiate_eapol(wpa_s); 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (old_ssid != wpa_s->current_ssid) 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_network_changed(wpa_s); 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.auth_alg = params.auth_alg; 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_authenticate(wpa_s, ¶ms) < 0) { 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "SME: Authentication request to the " 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "driver failed"); 3631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpas_connection_failed(wpa_s, bss->bssid); 364c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_supplicant_mark_disassoc(wpa_s); 365d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_free(resp); 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(SME_AUTH_TIMEOUT, 0, sme_auth_timer, wpa_s, 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL); 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Association will be started based on the authentication event from 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the driver. 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 376d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 377d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpabuf_free(resp); 378d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 379d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 380d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 381d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtvoid sme_authenticate(struct wpa_supplicant *wpa_s, 382d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt struct wpa_bss *bss, struct wpa_ssid *ssid) 383d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 384d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->sme.sae_state = SME_SAE_INIT; 385d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->sme.sae_send_confirm = 0; 386d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt sme_send_authentication(wpa_s, bss, ssid, 1); 387d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 388d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 389d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 390d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE 391d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 392d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic int sme_sae_process_commit(struct wpa_supplicant *wpa_s, const u8 *data, 393d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt size_t len) 394d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 395d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* Check Finite Cyclic Group */ 396d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (len < 2) 397d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 398d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (WPA_GET_LE16(data) != 19) { 399d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_printf(MSG_DEBUG, "SAE: Unsupported Finite Cyclic Group %u", 400d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt WPA_GET_LE16(data)); 401d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 402d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 403d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 404d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* TODO */ 405d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 406d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 407d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 408d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 409d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 410d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic int sme_sae_process_confirm(struct wpa_supplicant *wpa_s, const u8 *data, 411d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt size_t len) 412d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 413d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt u16 rc; 414d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 415d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (len < 2) 416d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 417d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt rc = WPA_GET_LE16(data); 418d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_printf(MSG_DEBUG, "SAE: peer-send-confirm %u", rc); 419d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 420d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* TODO */ 421d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 422d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt} 423d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 424d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 425d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtstatic int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction, 426d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt u16 status_code, const u8 *data, size_t len) 427d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{ 428d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE authentication transaction %u " 429d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "status code %u", auth_transaction, status_code); 430d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_hexdump(MSG_DEBUG, "SME: SAE fields", data, len); 431d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 432d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (status_code != WLAN_STATUS_SUCCESS) 433d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 434d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 435d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (auth_transaction == 1) { 436d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME SAE commit"); 437d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_s->current_bss == NULL || 438d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->current_ssid == NULL) 439d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 440d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_s->sme.sae_state != SME_SAE_COMMIT) 441d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 442d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (sme_sae_process_commit(wpa_s, data, len) < 0) 443d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 444d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt sme_send_authentication(wpa_s, wpa_s->current_bss, 445d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->current_ssid, 0); 446d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 0; 447d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } else if (auth_transaction == 2) { 448d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME SAE confirm"); 449d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (wpa_s->sme.sae_state != SME_SAE_CONFIRM) 450d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 451d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (sme_sae_process_confirm(wpa_s, data, len) < 0) 452d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 453d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return 1; 454d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 455d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 456d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 458d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */ 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data) 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ssid == NULL) { 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication event " 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "when network is not selected"); 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state != WPA_AUTHENTICATING) { 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication event " 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "when not in authenticating state"); 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(wpa_s->pending_bssid, data->auth.peer, ETH_ALEN) != 0) { 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication with " 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "unexpected peer " MACSTR, 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(data->auth.peer)); 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication response: peer=" MACSTR 485d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt " auth_type=%d auth_transaction=%d status_code=%d", 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MAC2STR(data->auth.peer), data->auth.auth_type, 487d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt data->auth.auth_transaction, data->auth.status_code); 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "SME: Authentication response IEs", 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->auth.ies, data->auth.ies_len); 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL); 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 493d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE 494d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (data->auth.auth_type == WLAN_AUTH_SAE) { 495d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt int res; 496d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt res = sme_sae_auth(wpa_s, data->auth.auth_transaction, 497d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt data->auth.status_code, data->auth.ies, 498d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt data->auth.ies_len); 499d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (res < 0) { 500d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 501d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); 502d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 503d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 504d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (res != 1) 505d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 506d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 507d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */ 508d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->auth.status_code != WLAN_STATUS_SUCCESS) { 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication failed (status " 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "code %d)", data->auth.status_code); 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->auth.status_code != 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG || 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.auth_alg == data->auth.auth_type || 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid->auth_alg == WPA_AUTH_ALG_LEAP) { 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 51804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (data->auth.auth_type) { 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_AUTH_OPEN: 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_SHARED; 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying SHARED auth"); 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_associate(wpa_s, wpa_s->current_bss, 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid); 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_AUTH_SHARED_KEY: 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_LEAP; 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying LEAP auth"); 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_associate(wpa_s, wpa_s->current_bss, 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->current_ssid); 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->auth.auth_type == WLAN_AUTH_FT) { 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data edata; 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&edata, 0, sizeof(edata)); 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt edata.ft_ies.ies = data->auth.ies; 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt edata.ft_ies.ies_len = data->auth.ies_len; 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(edata.ft_ies.target_ap, data->auth.peer, ETH_ALEN); 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_event(wpa_s, EVENT_FT_RESPONSE, &edata); 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_associate(wpa_s, ssid->mode, data->auth.peer, 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->auth.auth_type); 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode, 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *bssid, u16 auth_type) 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_driver_associate_params params; 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_11_elems elems; 565c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#ifdef CONFIG_HT_OVERRIDES 566c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt struct ieee80211_ht_capabilities htcaps; 567c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt struct ieee80211_ht_capabilities htcaps_mask; 568c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#endif /* CONFIG_HT_OVERRIDES */ 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.bssid = bssid; 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssid = wpa_s->sme.ssid; 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssid_len = wpa_s->sme.ssid_len; 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.freq = wpa_s->sme.freq; 57504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params.bg_scan_period = wpa_s->current_ssid ? 57604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->current_ssid->bg_scan_period : -1; 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wpa_ie = wpa_s->sme.assoc_req_ie_len ? 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.assoc_req_ie : NULL; 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wpa_ie_len = wpa_s->sme.assoc_req_ie_len; 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.pairwise_suite = cipher_suite2driver(wpa_s->pairwise_cipher); 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.group_suite = cipher_suite2driver(wpa_s->group_cipher); 582c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#ifdef CONFIG_HT_OVERRIDES 583c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memset(&htcaps, 0, sizeof(htcaps)); 584c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt os_memset(&htcaps_mask, 0, sizeof(htcaps_mask)); 585c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt params.htcaps = (u8 *) &htcaps; 586c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt params.htcaps_mask = (u8 *) &htcaps_mask; 587c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_supplicant_apply_ht_overrides(wpa_s, wpa_s->current_ssid, ¶ms); 588c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#endif /* CONFIG_HT_OVERRIDES */ 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (auth_type == WLAN_AUTH_FT && wpa_s->sme.ft_ies) { 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wpa_ie = wpa_s->sme.ft_ies; 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.wpa_ie_len = wpa_s->sme.ft_ies_len; 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */ 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.mode = mode; 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.mgmt_frame_protection = wpa_s->sme.mfp; 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.prev_bssid_set) 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.prev_bssid = wpa_s->sme.prev_bssid; 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid), 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.ssid ? wpa_ssid_txt(params.ssid, params.ssid_len) : "", 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.freq); 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING); 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params.wpa_ie == NULL || 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ieee802_11_parse_elems(params.wpa_ie, params.wpa_ie_len, &elems, 0) 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt < 0) { 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Could not parse own IEs?!"); 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&elems, 0, sizeof(elems)); 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (elems.rsn_ie) { 6141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.wpa_proto = WPA_PROTO_RSN; 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.rsn_ie - 2, 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems.rsn_ie_len + 2); 6171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else if (elems.wpa_ie) { 6181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt params.wpa_proto = WPA_PROTO_WPA; 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.wpa_ie - 2, 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems.wpa_ie_len + 2); 6211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } else 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0); 6231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group) 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.p2p = 1; 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->parent->set_sta_uapsd) 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.uapsd = wpa_s->parent->sta_uapsd; 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params.uapsd = -1; 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_associate(wpa_s, ¶ms) < 0) { 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "SME: Association request to the " 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "driver failed"); 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 63504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(SME_ASSOC_TIMEOUT, 0, sme_assoc_timer, wpa_s, 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL); 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md, 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *ies, size_t ies_len) 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (md == NULL || ies == NULL) { 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Remove mobility domain"); 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_s->sme.ft_ies); 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ft_ies = NULL; 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ft_ies_len = 0; 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ft_used = 0; 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->sme.mobility_domain, md, MOBILITY_DOMAIN_ID_LEN); 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "SME: FT IEs", ies, ies_len); 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_s->sme.ft_ies); 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ft_ies = os_malloc(ies_len); 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.ft_ies == NULL) 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->sme.ft_ies, ies, ies_len); 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ft_ies_len = ies_len; 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_deauth(struct wpa_supplicant *wpa_s) 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int bssid_changed; 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bssid_changed = !is_zero_ether_addr(wpa_s->bssid); 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid, 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_REASON_DEAUTH_LEAVING) < 0) { 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "SME: Deauth request to the driver " 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed"); 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.prev_bssid_set = 0; 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(wpa_s->bssid, 0, ETH_ALEN); 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bssid_changed) 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_notify_bssid_changed(wpa_s); 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_event_assoc_reject(struct wpa_supplicant *wpa_s, 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data *data) 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association with " MACSTR " failed: " 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "status code %d", MAC2STR(wpa_s->pending_bssid), 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->assoc_reject.status_code); 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL); 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * For now, unconditionally terminate the previous authentication. In 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * theory, this should not be needed, but mac80211 gets quite confused 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * if the authentication is left pending.. Some roaming cases might 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * benefit from using the previous authentication, so this could be 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * optimized in the future. 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_deauth(wpa_s); 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_event_auth_timed_out(struct wpa_supplicant *wpa_s, 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data *data) 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication timed out"); 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 716c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt wpa_supplicant_mark_disassoc(wpa_s); 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s, 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data *data) 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association timed out"); 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_connection_failed(wpa_s, wpa_s->pending_bssid); 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_mark_disassoc(wpa_s); 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_event_disassoc(struct wpa_supplicant *wpa_s, 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union wpa_event_data *data) 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Disassociation event received"); 7331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (wpa_s->sme.prev_bssid_set) { 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * cfg80211/mac80211 can get into somewhat confused state if 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the AP only disassociates us and leaves us in authenticated 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * state. For now, force the state to be cleared to avoid 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * confusing errors if we try to associate with the AP again. 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Deauthenticate to clear " 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "driver state"); 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_drv_deauthenticate(wpa_s, wpa_s->sme.prev_bssid, 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WLAN_REASON_DEAUTH_LEAVING); 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_auth_timer(void *eloop_ctx, void *timeout_ctx) 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state == WPA_AUTHENTICATING) { 7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_DEBUG, "SME: Authentication timeout"); 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_deauth(wpa_s); 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx) 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state == WPA_ASSOCIATING) { 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_DEBUG, "SME: Association timeout"); 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_deauth(wpa_s); 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_state_changed(struct wpa_supplicant *wpa_s) 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Make sure timers are cleaned up appropriately. */ 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state != WPA_ASSOCIATING) 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL); 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state != WPA_AUTHENTICATING) 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL); 7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_disassoc_while_authenticating(struct wpa_supplicant *wpa_s, 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *prev_pending_bssid) 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * mac80211-workaround to force deauth on failed auth cmd, 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * requires us to remain in authenticating state to allow the 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * second authentication attempt to be continued properly. 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Allow pending authentication " 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "to proceed after disconnection event"); 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING); 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(wpa_s->pending_bssid, prev_pending_bssid, ETH_ALEN); 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Re-arm authentication timer in case auth fails for whatever reason. 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL); 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(SME_AUTH_TIMEOUT, 0, sme_auth_timer, wpa_s, 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL); 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_deinit(struct wpa_supplicant *wpa_s) 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_s->sme.ft_ies); 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ft_ies = NULL; 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.ft_ies_len = 0; 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_stop_sa_query(wpa_s); 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL); 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL); 81104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_cancel_timeout(sme_obss_scan_timeout, wpa_s, NULL); 81204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 81304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 81404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 81504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void sme_send_2040_bss_coex(struct wpa_supplicant *wpa_s, 81604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *chan_list, u8 num_channels, 81704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 num_intol) 81804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 81904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct ieee80211_2040_bss_coex_ie *bc_ie; 82004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct ieee80211_2040_intol_chan_report *ic_report; 82104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpabuf *buf; 82204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 82304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "SME: Send 20/40 BSS Coexistence to " MACSTR, 82404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt MAC2STR(wpa_s->bssid)); 82504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 82604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt buf = wpabuf_alloc(2 + /* action.category + action_code */ 82704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sizeof(struct ieee80211_2040_bss_coex_ie) + 82804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sizeof(struct ieee80211_2040_intol_chan_report) + 82904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt num_channels); 83004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (buf == NULL) 83104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 83204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 83304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC); 83404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_put_u8(buf, WLAN_PA_20_40_BSS_COEX); 83504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 83604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt bc_ie = wpabuf_put(buf, sizeof(*bc_ie)); 83704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt bc_ie->element_id = WLAN_EID_20_40_BSS_COEXISTENCE; 83804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt bc_ie->length = 1; 83904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (num_intol) 84004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt bc_ie->coex_param |= WLAN_20_40_BSS_COEX_20MHZ_WIDTH_REQ; 84104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 84204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (num_channels > 0) { 84304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ic_report = wpabuf_put(buf, sizeof(*ic_report)); 84404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ic_report->element_id = WLAN_EID_20_40_BSS_INTOLERANT; 84504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ic_report->length = num_channels + 1; 84604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ic_report->op_class = 0; 84704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memcpy(wpabuf_put(buf, num_channels), chan_list, 84804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt num_channels); 84904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 85004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 85104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid, 85204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->own_addr, wpa_s->bssid, 85304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_head(buf), wpabuf_len(buf), 0) < 0) { 85404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_msg(wpa_s, MSG_INFO, 85504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "SME: Failed to send 20/40 BSS Coexistence frame"); 85604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 85704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 85804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpabuf_free(buf); 85904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 86004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 86104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 86204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/** 86304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * enum wpas_band - Frequency band 86404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @WPAS_BAND_2GHZ: 2.4 GHz ISM band 86504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @WPAS_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz) 86604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 86704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtenum wpas_band { 86804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt WPAS_BAND_2GHZ, 86904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt WPAS_BAND_5GHZ, 87004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt WPAS_BAND_INVALID 87104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}; 87204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 87304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/** 87404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * freq_to_channel - Convert frequency into channel info 87504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @channel: Buffer for returning channel number 87604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Returns: Band (2 or 5 GHz) 87704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 87804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic enum wpas_band freq_to_channel(int freq, u8 *channel) 87904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 88004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt enum wpas_band band = (freq <= 2484) ? WPAS_BAND_2GHZ : WPAS_BAND_5GHZ; 88104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 chan = 0; 88204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 88304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (freq >= 2412 && freq <= 2472) 88404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt chan = (freq - 2407) / 5; 88504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt else if (freq == 2484) 88604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt chan = 14; 88704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt else if (freq >= 5180 && freq <= 5805) 88804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt chan = (freq - 5000) / 5; 88904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 89004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt *channel = chan; 89104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return band; 89204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 89304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 89404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 89504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint sme_proc_obss_scan(struct wpa_supplicant *wpa_s) 89604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 89704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_bss *bss; 89804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *ie; 89904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u16 ht_cap; 90004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 chan_list[P2P_MAX_CHANNELS], channel; 90104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u8 num_channels = 0, num_intol = 0, i; 90204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 90304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpa_s->sme.sched_obss_scan) 90404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 0; 90504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 90604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.sched_obss_scan = 0; 90704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpa_s->current_bss || wpa_s->wpa_state != WPA_COMPLETED) 90804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 90904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 91004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* 91104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Check whether AP uses regulatory triplet or channel triplet in 91204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * country info. Right now the operating class of the BSS channel 91304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * width trigger event is "unknown" (IEEE Std 802.11-2012 10.15.12), 91404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * based on the assumption that operating class triplet is not used in 91504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * beacon frame. If the First Channel Number/Operating Extension 91604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Identifier octet has a positive integer value of 201 or greater, 91704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * then its operating class triplet. 91804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * 91904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * TODO: If Supported Operating Classes element is present in beacon 92004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * frame, have to lookup operating class in Annex E and fill them in 92104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * 2040 coex frame. 92204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */ 92304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ie = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_COUNTRY); 92404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ie && (ie[1] >= 6) && (ie[5] >= 201)) 92504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 92604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 92704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memset(chan_list, 0, sizeof(chan_list)); 92804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 92904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { 93004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Skip other band bss */ 93104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (freq_to_channel(bss->freq, &channel) != WPAS_BAND_2GHZ) 93204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt continue; 93304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 93404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ie = wpa_bss_get_ie(bss, WLAN_EID_HT_CAP); 93504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ht_cap = (ie && (ie[1] == 26)) ? WPA_GET_LE16(ie + 2) : 0; 93604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 93704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!ht_cap || (ht_cap & HT_CAP_INFO_40MHZ_INTOLERANT)) { 93804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Check whether the channel is already considered */ 93904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (i = 0; i < num_channels; i++) { 94004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (channel == chan_list[i]) 94104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 94204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 94304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (i != num_channels) 94404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt continue; 94504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 94604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (ht_cap & HT_CAP_INFO_40MHZ_INTOLERANT) 94704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt num_intol++; 94804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 94904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt chan_list[num_channels++] = channel; 95004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 95104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 95204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 95304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sme_send_2040_bss_coex(wpa_s, chan_list, num_channels, num_intol); 95404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return 1; 95504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 95604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 95704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 95804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes, 95904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u16 num_modes, 96004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt enum hostapd_hw_mode mode) 96104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 96204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt u16 i; 96304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 96404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (i = 0; i < num_modes; i++) { 96504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (modes[i].mode == mode) 96604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return &modes[i]; 96704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 96804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 96904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return NULL; 97004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 97104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 97204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 97304949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpa_setband_scan_freqs_list(struct wpa_supplicant *wpa_s, 97404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt enum hostapd_hw_mode band, 97504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_driver_scan_params *params) 97604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 97704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Include only supported channels for the specified band */ 97804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct hostapd_hw_modes *mode; 97904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt int count, i; 98004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 98104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, band); 98204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (mode == NULL) { 98304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* No channels supported in this band - use empty list */ 98404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params->freqs = os_zalloc(sizeof(int)); 98504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 98604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 98704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 98861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt params->freqs = os_calloc(mode->num_channels + 1, sizeof(int)); 98904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (params->freqs == NULL) 99004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 99104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt for (count = 0, i = 0; i < mode->num_channels; i++) { 99204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED) 99304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt continue; 99404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt params->freqs[count++] = mode->channels[i].freq; 99504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 99604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 99704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 99804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 99904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void sme_obss_scan_timeout(void *eloop_ctx, void *timeout_ctx) 100004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 100104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 100204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_driver_scan_params params; 100304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 100404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!wpa_s->current_bss) { 100504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "SME OBSS: Ignore scan request"); 100604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 100704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 100804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 100904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_memset(¶ms, 0, sizeof(params)); 101004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_setband_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G, ¶ms); 101104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "SME OBSS: Request an OBSS scan"); 101204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 101304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_supplicant_trigger_scan(wpa_s, ¶ms)) 101404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "SME OBSS: Failed to trigger scan"); 101504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt else 101604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.sched_obss_scan = 1; 101704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt os_free(params.freqs); 101804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 101904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_register_timeout(wpa_s->sme.obss_scan_int, 0, 102004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sme_obss_scan_timeout, wpa_s, NULL); 102104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt} 102204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 102304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 102404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid sme_sched_obss_scan(struct wpa_supplicant *wpa_s, int enable) 102504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{ 102604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt const u8 *ie; 102704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_bss *bss = wpa_s->current_bss; 102804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt struct wpa_ssid *ssid = wpa_s->current_ssid; 102961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_hw_modes *hw_mode = NULL; 103061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int i; 103104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 103204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_cancel_timeout(sme_obss_scan_timeout, wpa_s, NULL); 103304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.sched_obss_scan = 0; 103404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!enable) 103504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; 103604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 1037d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt /* 1038d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * Schedule OBSS scan if driver is using station SME in wpa_supplicant 1039d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * or it expects OBSS scan to be performed by wpa_supplicant. 1040d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt */ 1041d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (!((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) || 1042d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (wpa_s->drv_flags & WPA_DRIVER_FLAGS_OBSS_SCAN)) || 1043d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt ssid == NULL || ssid->mode != IEEE80211_MODE_INFRA) 1044d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return; 104504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 104661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (!wpa_s->hw.modes) 104761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 104861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 104961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* only HT caps in 11g mode are relevant */ 105061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt for (i = 0; i < wpa_s->hw.num_modes; i++) { 105161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt hw_mode = &wpa_s->hw.modes[i]; 105261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (hw_mode->mode == HOSTAPD_MODE_IEEE80211G) 105361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 105461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 105561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 105661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Driver does not support HT40 for 11g or doesn't have 11g. */ 105761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (i == wpa_s->hw.num_modes || !hw_mode || 105861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt !(hw_mode->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) 105961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return; 106004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 106104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (bss == NULL || bss->freq < 2400 || bss->freq > 2500) 106204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; /* Not associated on 2.4 GHz band */ 106304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 106404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Check whether AP supports HT40 */ 106504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ie = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_HT_CAP); 106604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!ie || ie[1] < 2 || 106704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt !(WPA_GET_LE16(ie + 2) & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) 106804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; /* AP does not support HT40 */ 106904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 107004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt ie = wpa_bss_get_ie(wpa_s->current_bss, 107104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS); 107204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (!ie || ie[1] < 14) 107304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return; /* AP does not request OBSS scans */ 107404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt 107504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.obss_scan_int = WPA_GET_LE16(ie + 6); 107604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (wpa_s->sme.obss_scan_int < 10) { 107704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "SME: Invalid OBSS Scan Interval %u " 107804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt "replaced with the minimum 10 sec", 107904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.obss_scan_int); 108004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.obss_scan_int = 10; 108104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt } 108204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_printf(MSG_DEBUG, "SME: OBSS Scan Interval %u sec", 108304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt wpa_s->sme.obss_scan_int); 108404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt eloop_register_timeout(wpa_s->sme.obss_scan_int, 0, 108504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sme_obss_scan_timeout, wpa_s, NULL); 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const unsigned int sa_query_max_timeout = 1000; 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const unsigned int sa_query_retry_timeout = 201; 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int sme_check_sa_query_timeout(struct wpa_supplicant *wpa_s) 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 tu; 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct os_time now, passed; 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&now); 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_time_sub(&now, &wpa_s->sme.sa_query_start, &passed); 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tu = (passed.sec * 1000000 + passed.usec) / 1024; 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sa_query_max_timeout < tu) { 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: SA Query timed out"); 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_stop_sa_query(wpa_s); 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_supplicant_deauthenticate( 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s, WLAN_REASON_PREV_AUTH_NOT_VALID); 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_send_sa_query_req(struct wpa_supplicant *wpa_s, 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *trans_id) 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 req[2 + WLAN_SA_QUERY_TR_ID_LEN]; 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Sending SA Query Request to " 11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR, MAC2STR(wpa_s->bssid)); 11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "SME: SA Query Transaction ID", 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt trans_id, WLAN_SA_QUERY_TR_ID_LEN); 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req[0] = WLAN_ACTION_SA_QUERY; 11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt req[1] = WLAN_SA_QUERY_REQUEST; 11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(req + 2, trans_id, WLAN_SA_QUERY_TR_ID_LEN); 11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid, 11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->own_addr, wpa_s->bssid, 11261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt req, sizeof(req), 0) < 0) 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_msg(wpa_s, MSG_INFO, "SME: Failed to send SA Query " 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Request"); 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_sa_query_timer(void *eloop_ctx, void *timeout_ctx) 11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_supplicant *wpa_s = eloop_ctx; 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int timeout, sec, usec; 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *trans_id, *nbuf; 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.sa_query_count > 0 && 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_check_sa_query_timeout(wpa_s)) 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 114261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt nbuf = os_realloc_array(wpa_s->sme.sa_query_trans_id, 114361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_s->sme.sa_query_count + 1, 114461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt WLAN_SA_QUERY_TR_ID_LEN); 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (nbuf == NULL) 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.sa_query_count == 0) { 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Starting a new SA Query procedure */ 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_time(&wpa_s->sme.sa_query_start); 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt trans_id = nbuf + wpa_s->sme.sa_query_count * WLAN_SA_QUERY_TR_ID_LEN; 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.sa_query_trans_id = nbuf; 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.sa_query_count++; 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN); 11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout = sa_query_retry_timeout; 11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sec = ((timeout / 1000) * 1024) / 1000; 11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt usec = (timeout % 1000) * 1024; 11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(sec, usec, sme_sa_query_timer, wpa_s, NULL); 11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association SA Query attempt %d", 11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.sa_query_count); 11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_send_sa_query_req(wpa_s, trans_id); 11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void sme_start_sa_query(struct wpa_supplicant *wpa_s) 11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_sa_query_timer(wpa_s, NULL); 11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic void sme_stop_sa_query(struct wpa_supplicant *wpa_s) 11768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(sme_sa_query_timer, wpa_s, NULL); 11788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(wpa_s->sme.sa_query_trans_id); 11798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.sa_query_trans_id = NULL; 11808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_s->sme.sa_query_count = 0; 11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_event_unprot_disconnect(struct wpa_supplicant *wpa_s, const u8 *sa, 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *da, u16 reason_code) 11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 11878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpa_ssid *ssid; 11888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) 11908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->wpa_state != WPA_COMPLETED) 11928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssid = wpa_s->current_ssid; 1194d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (ssid == NULL || 1195d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ? 1196d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_s->conf->pmf : ssid->ieee80211w) == NO_MGMT_FRAME_PROTECTION) 11978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 11988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(sa, wpa_s->bssid, ETH_ALEN) != 0) 11998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (reason_code != WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA && 12018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reason_code != WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA) 12028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.sa_query_count > 0) 12048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Unprotected disconnect dropped - " 12078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "possible AP/STA state mismatch - trigger SA Query"); 12088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_start_sa_query(wpa_s); 12098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid sme_sa_query_rx(struct wpa_supplicant *wpa_s, const u8 *sa, 12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len) 12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_s->sme.sa_query_trans_id == NULL || 12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len < 1 + WLAN_SA_QUERY_TR_ID_LEN || 12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data[0] != WLAN_SA_QUERY_RESPONSE) 12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Received SA Query response from " 12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt MACSTR " (trans_id %02x%02x)", MAC2STR(sa), data[1], data[2]); 12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(sa, wpa_s->bssid, ETH_ALEN) != 0) 12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < wpa_s->sme.sa_query_count; i++) { 12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_memcmp(wpa_s->sme.sa_query_trans_id + 12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i * WLAN_SA_QUERY_TR_ID_LEN, 12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data + 1, WLAN_SA_QUERY_TR_ID_LEN) == 0) 12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i >= wpa_s->sme.sa_query_count) { 12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: No matching SA Query " 12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "transaction identifier found"); 12378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 12388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_dbg(wpa_s, MSG_DEBUG, "SME: Reply to pending SA Query received " 12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "from " MACSTR, MAC2STR(sa)); 12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sme_stop_sa_query(wpa_s); 12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */ 1246