wpa_supplicant.c revision 444d567b27731d8572ef37697dd12fd1c37c2f24
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA Supplicant
3c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Copyright (c) 2003-2012, 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 * This file implements functions for registering and unregistering
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * %wpa_supplicant interfaces. In addition, this file contains number of
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * functions for managing network connections.
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h"
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h"
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/random.h"
171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "crypto/sha1.h"
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eapol_supp/eapol_supp_sm.h"
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_peer/eap.h"
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_server/eap_methods.h"
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "rsn_supp/wpa.h"
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eloop.h"
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config.h"
2461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "utils/ext_password.h"
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "l2_packet/l2_packet.h"
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_supplicant_i.h"
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "driver_i.h"
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ctrl_iface.h"
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "pcsc_funcs.h"
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/version.h"
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "rsn_supp/preauth.h"
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "rsn_supp/pmksa_cache.h"
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/wpa_ctrl.h"
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h"
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p/p2p.h"
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "blacklist.h"
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpas_glue.h"
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps_supplicant.h"
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ibss_rsn.h"
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "sme.h"
411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "gas_query.h"
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap.h"
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_supplicant.h"
4461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "wifi_display.h"
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "notify.h"
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "bgscan.h"
4704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "autoscan.h"
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "bss.h"
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "scan.h"
501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#include "offchannel.h"
5104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#include "hs20_supplicant.h"
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char *wpa_supplicant_version =
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"wpa_supplicant v" VERSION_STR "\n"
55a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt"Copyright (c) 2003-2013, Jouni Malinen <j@w1.fi> and contributors";
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char *wpa_supplicant_license =
58c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt"This software may be distributed under the terms of the BSD license.\n"
59c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt"See README for more details.\n"
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_TLS_OPENSSL
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"\nThis product includes software developed by the OpenSSL Project\n"
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"for use in the OpenSSL Toolkit (http://www.openssl.org/)\n"
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_TLS_OPENSSL */
648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt;
658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_STDOUT_DEBUG
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Long text divided into parts in order to fit in C89 strings size limits. */
688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char *wpa_supplicant_full_license1 =
69c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt"";
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char *wpa_supplicant_full_license2 =
71c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt"This software may be distributed under the terms of the BSD license.\n"
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"\n"
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"Redistribution and use in source and binary forms, with or without\n"
748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"modification, are permitted provided that the following conditions are\n"
758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"met:\n"
768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"\n";
778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char *wpa_supplicant_full_license3 =
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"1. Redistributions of source code must retain the above copyright\n"
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"   notice, this list of conditions and the following disclaimer.\n"
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"\n"
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"2. Redistributions in binary form must reproduce the above copyright\n"
828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"   notice, this list of conditions and the following disclaimer in the\n"
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"   documentation and/or other materials provided with the distribution.\n"
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"\n";
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char *wpa_supplicant_full_license4 =
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"   names of its contributors may be used to endorse or promote products\n"
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"   derived from this software without specific prior written permission.\n"
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"\n"
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n";
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char *wpa_supplicant_full_license5 =
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt"\n";
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_STDOUT_DEBUG */
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtextern int wpa_debug_level;
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtextern int wpa_debug_show_keys;
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtextern int wpa_debug_timestamp;
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtextern struct wpa_driver_ops *wpa_drivers[];
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* Configure default/group WEP keys for static WEP */
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i, set = 0;
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < NUM_WEP_KEYS; i++) {
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->wep_key_len[i] == 0)
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		set = 1;
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_set_key(wpa_s, WPA_ALG_WEP, NULL,
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				i, i == ssid->wep_tx_keyidx, NULL, 0,
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				ssid->wep_key[i], ssid->wep_key_len[i]);
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return set;
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s,
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   struct wpa_ssid *ssid)
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 key[32];
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t keylen;
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum wpa_alg alg;
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 seq[6] = { 0 };
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* IBSS/WPA-None uses only one key (Group) for both receiving and
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * sending unicast and multicast packets. */
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->mode != WPAS_MODE_IBSS) {
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid mode %d (not "
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"IBSS/ad-hoc) for WPA-None", ssid->mode);
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!ssid->psk_set) {
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "WPA: No PSK configured for "
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"WPA-None");
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (wpa_s->group_cipher) {
1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_CIPHER_CCMP:
1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(key, ssid->psk, 16);
1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		keylen = 16;
1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		alg = WPA_ALG_CCMP;
1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
15861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	case WPA_CIPHER_GCMP:
15961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		os_memcpy(key, ssid->psk, 16);
16061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		keylen = 16;
16161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		alg = WPA_ALG_GCMP;
16261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		break;
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_CIPHER_TKIP:
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* WPA-None uses the same Michael MIC key for both TX and RX */
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(key, ssid->psk, 16 + 8);
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(key + 16 + 8, ssid->psk + 16, 8);
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		keylen = 32;
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		alg = WPA_ALG_TKIP;
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid group cipher %d for "
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"WPA-None", wpa_s->group_cipher);
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* TODO: should actually remember the previously used seq#, both for TX
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * and RX from each STA.. */
1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpa_drv_set_key(wpa_s, alg, NULL, 0, 1, seq, 6, key, keylen);
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_timeout(void *eloop_ctx, void *timeout_ctx)
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = eloop_ctx;
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *bssid = wpa_s->bssid;
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (is_zero_ether_addr(bssid))
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bssid = wpa_s->pending_bssid;
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_msg(wpa_s, MSG_INFO, "Authentication with " MACSTR " timed out.",
1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		MAC2STR(bssid));
1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_blacklist_add(wpa_s, bssid);
1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_notify_disassoc(wpa_s->wpa);
193d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->reassociate = 1;
1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * If we timed out, the AP or the local radio may be busy.
1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * So, wait a second until scanning again.
1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_req_scan(wpa_s, 1, 0);
20161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
20237d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt	wpas_p2p_continue_after_scan(wpa_s);
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_req_auth_timeout - Schedule a timeout for authentication
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sec: Number of seconds after which to time out authentication
2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @usec: Number of microseconds after which to time out authentication
2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to schedule a timeout for the current authentication
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * attempt.
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s,
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     int sec, int usec)
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf && wpa_s->conf->ap_scan == 0 &&
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED))
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Setting authentication timeout: %d sec "
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"%d usec", sec, usec);
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_register_timeout(sec, usec, wpa_supplicant_timeout, wpa_s, NULL);
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_cancel_auth_timeout - Cancel authentication timeout
2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to cancel authentication timeout scheduled with
2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_req_auth_timeout() and it is called when authentication has
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * been completed.
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *wpa_s)
2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling authentication timeout");
2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_blacklist_del(wpa_s, wpa_s->bssid);
2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_initiate_eapol - Configure EAPOL state machine
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to configure EAPOL state machine based on the selected
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authentication mode.
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct eapol_config eapol_conf;
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid = wpa_s->current_ssid;
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IBSS_RSN
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->mode == WPAS_MODE_IBSS &&
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * RSN IBSS authentication is per-STA and we can disable the
2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * per-BSSID EAPOL authentication.
2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IBSS_RSN */
2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_portControl(wpa_s->eapol, Auto);
2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&eapol_conf, 0, sizeof(eapol_conf));
2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_conf.accept_802_1x_keys = 1;
2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_conf.required_keys = 0;
2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_UNICAST) {
2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eapol_conf.required_keys |= EAPOL_REQUIRE_KEY_UNICAST;
2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_BROADCAST) {
2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eapol_conf.required_keys |=
2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				EAPOL_REQUIRE_KEY_BROADCAST;
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->conf && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED))
2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eapol_conf.required_keys = 0;
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf)
2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_conf.workaround = ssid->eap_workaround;
3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_conf.eap_disabled =
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		!wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) &&
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt != WPA_KEY_MGMT_WPS;
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_set_non_wpa_policy - Set WPA parameters to non-WPA mode
3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid: Configuration data for the network
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to configure WPA state machine and related parameters
3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to a mode where WPA is not enabled. This is called as part of the
3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authentication configuration when the selected network does not use WPA.
3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       struct wpa_ssid *ssid)
3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_WPS;
3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)
3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_NO_WPA;
3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->group_cipher = WPA_CIPHER_NONE;
3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->mgmt_group_cipher = 0;
3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < NUM_WEP_KEYS; i++) {
3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->wep_key_len[i] > 5) {
3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->pairwise_cipher = WPA_CIPHER_WEP104;
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->group_cipher = WPA_CIPHER_WEP104;
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (ssid->wep_key_len[i] > 0) {
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->pairwise_cipher = WPA_CIPHER_WEP40;
3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->group_cipher = WPA_CIPHER_WEP40;
3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED, 0);
3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 wpa_s->pairwise_cipher);
3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 wpa_s->mgmt_group_cipher);
3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pmksa_cache_clear_current(wpa_s->wpa);
3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
36204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid free_hw_features(struct wpa_supplicant *wpa_s)
3631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
3641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int i;
3651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->hw.modes == NULL)
3661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return;
3671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	for (i = 0; i < wpa_s->hw.num_modes; i++) {
3691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		os_free(wpa_s->hw.modes[i].channels);
3701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		os_free(wpa_s->hw.modes[i].rates);
3711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
3721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	os_free(wpa_s->hw.modes);
3741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_s->hw.modes = NULL;
3751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
3761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bgscan_deinit(wpa_s);
38104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	autoscan_deinit(wpa_s);
3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	scard_deinit(wpa_s->scard);
3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->scard = NULL;
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_scard_ctx(wpa_s->wpa, NULL);
3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_register_scard_ctx(wpa_s->eapol, NULL);
3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	l2_packet_deinit(wpa_s->l2);
3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->l2 = NULL;
3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->l2_br) {
3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		l2_packet_deinit(wpa_s->l2_br);
3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->l2_br = NULL;
3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf != NULL) {
3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpa_ssid *ssid;
3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_notify_network_removed(wpa_s, ssid);
3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(wpa_s->confname);
4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->confname = NULL;
4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_eapol(wpa_s->wpa, NULL);
4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_deinit(wpa_s->eapol);
4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->eapol = NULL;
4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	rsn_preauth_deinit(wpa_s->wpa);
4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TDLS
4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_tdls_deinit(wpa_s->wpa);
4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TDLS */
4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pmksa_candidate_free(wpa_s->wpa);
4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_deinit(wpa_s->wpa);
4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->wpa = NULL;
4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_blacklist_clear(wpa_s);
4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_bss_deinit(wpa_s);
4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_cancel_scan(wpa_s);
4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_cancel_auth_timeout(wpa_s);
4211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	eloop_cancel_timeout(wpa_supplicant_stop_countermeasures, wpa_s, NULL);
4221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
4231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	eloop_cancel_timeout(wpa_supplicant_delayed_mic_error_report,
4241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			     wpa_s, NULL);
4251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_wps_deinit(wpa_s);
4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_free(wpa_s->pending_eapol_rx);
4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->pending_eapol_rx = NULL;
4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IBSS_RSN
4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ibss_rsn_deinit(wpa_s->ibss_rsn);
4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->ibss_rsn = NULL;
4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IBSS_RSN */
4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sme_deinit(wpa_s);
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_ap_deinit(wpa_s);
4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_p2p_deinit(wpa_s);
4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_OFFCHANNEL
4481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	offchannel_deinit(wpa_s);
4491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_OFFCHANNEL */
4501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
4511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_supplicant_cancel_sched_scan(wpa_s);
4521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(wpa_s->next_scan_freqs);
4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->next_scan_freqs = NULL;
4551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
4561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	gas_query_deinit(wpa_s->gas);
4571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_s->gas = NULL;
4581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
4591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	free_hw_features(wpa_s);
46004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
46104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	os_free(wpa_s->bssid_filter);
46204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->bssid_filter = NULL;
46304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
464d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	os_free(wpa_s->disallow_aps_bssid);
465d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	wpa_s->disallow_aps_bssid = NULL;
466d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	os_free(wpa_s->disallow_aps_ssid);
467d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	wpa_s->disallow_aps_ssid = NULL;
468d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
46904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wnm_bss_keep_alive_deinit(wpa_s);
47061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
47161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	ext_password_deinit(wpa_s->ext_pw);
47261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_s->ext_pw = NULL;
47361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
47461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpabuf_free(wpa_s->last_gas_resp);
4759bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt
4769bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	os_free(wpa_s->last_scan_res);
4779bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	wpa_s->last_scan_res = NULL;
4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_clear_keys - Clear keys configured for the driver
4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: Previously used BSSID or %NULL if not available
4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function clears the encryption keys that has been previously configured
4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * for the driver.
4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr)
4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->keys_cleared) {
4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Some drivers (e.g., ndiswrapper & NDIS drivers) seem to have
4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * timing issues with keys being cleared just before new keys
4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * are set or just after association or something similar. This
4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * shows up in group key handshake failing often because of the
4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * client not receiving the first encrypted packets correctly.
4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * Skipping some of the extra key clearing steps seems to help
4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * in completing group key handshake more reliably. */
4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "No keys have been configured - "
5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"skip key clearing");
5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* MLME-DELETEKEYS.request */
5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 0, 0, NULL, 0, NULL, 0);
5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL, 0);
5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL, 0);
5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL, 0);
5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL, 0);
5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 5, 0, NULL, 0, NULL, 0);
5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (addr) {
5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_set_key(wpa_s, WPA_ALG_NONE, addr, 0, 0, NULL, 0, NULL,
5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				0);
5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* MLME-SETPROTECTION.request(None) */
5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_mlme_setprotection(
5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s, addr,
5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MLME_SETPROTECTION_PROTECT_TYPE_NONE,
5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->keys_cleared = 1;
5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_state_txt - Get the connection state name as a text string
5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @state: State (wpa_state; WPA_*)
5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: The state name as a printable text string
5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char * wpa_supplicant_state_txt(enum wpa_states state)
5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (state) {
5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_DISCONNECTED:
5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "DISCONNECTED";
5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_INACTIVE:
5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "INACTIVE";
5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_INTERFACE_DISABLED:
5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "INTERFACE_DISABLED";
5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_SCANNING:
5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "SCANNING";
5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_AUTHENTICATING:
5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "AUTHENTICATING";
5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_ASSOCIATING:
5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "ASSOCIATING";
5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_ASSOCIATED:
5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "ASSOCIATED";
5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_4WAY_HANDSHAKE:
5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "4WAY_HANDSHAKE";
5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_GROUP_HANDSHAKE:
5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "GROUP_HANDSHAKE";
5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_COMPLETED:
5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "COMPLETED";
5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "UNKNOWN";
5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_BGSCAN
5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_start_bgscan(struct wpa_supplicant *wpa_s)
5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpas_driver_bss_selection(wpa_s))
5651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return;
5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->current_ssid == wpa_s->bgscan_ssid)
5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bgscan_deinit(wpa_s);
5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->current_ssid && wpa_s->current_ssid->bgscan) {
5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (bgscan_init(wpa_s, wpa_s->current_ssid)) {
5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"bgscan");
5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/*
5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * Live without bgscan; it is only used as a roaming
5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * optimization, so the initial connection is not
5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * affected.
5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 */
57961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		} else {
58061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			struct wpa_scan_results *scan_res;
5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->bgscan_ssid = wpa_s->current_ssid;
58261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL,
58361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt								   0);
58461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (scan_res) {
58561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				bgscan_notify_scan(wpa_s, scan_res);
58661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_scan_results_free(scan_res);
58761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
58861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		}
5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else
5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->bgscan_ssid = NULL;
5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_stop_bgscan(struct wpa_supplicant *wpa_s)
5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->bgscan_ssid != NULL) {
5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bgscan_deinit(wpa_s);
5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->bgscan_ssid = NULL;
5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_BGSCAN */
6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
60504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpa_supplicant_start_autoscan(struct wpa_supplicant *wpa_s)
60604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
60704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (autoscan_init(wpa_s, 0))
60804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize autoscan");
60904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
61004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
61104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
61204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpa_supplicant_stop_autoscan(struct wpa_supplicant *wpa_s)
61304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
61404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	autoscan_deinit(wpa_s);
61504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
61604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
61704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
61804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid wpa_supplicant_reinit_autoscan(struct wpa_supplicant *wpa_s)
61904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
62004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->wpa_state == WPA_DISCONNECTED ||
62104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	    wpa_s->wpa_state == WPA_SCANNING) {
62204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		autoscan_deinit(wpa_s);
62304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_supplicant_start_autoscan(wpa_s);
62404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
62504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
62604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
62704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_set_state - Set current connection state
6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @state: The new connection state
6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called whenever the connection state changes, e.g.,
6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * association is completed for WPA/WPA2 4-Way Handshake is started.
6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      enum wpa_states state)
6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum wpa_states old_state = wpa_s->wpa_state;
6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "State: %s -> %s",
6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_state_txt(wpa_s->wpa_state),
6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_state_txt(state));
6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
64598f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt#ifdef ANDROID_P2P
6467db4ef75f0190d98dbc84f8968ede3ac0ae29571Irfan Sheriff	if(state == WPA_ASSOCIATED && wpa_s->current_ssid) {
6477db4ef75f0190d98dbc84f8968ede3ac0ae29571Irfan Sheriff		wpa_s->current_ssid->assoc_retry = 0;
6487db4ef75f0190d98dbc84f8968ede3ac0ae29571Irfan Sheriff	}
64998f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt#endif /* ANDROID_P2P */
65098f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt
6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (state != WPA_SCANNING)
6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_notify_scanning(wpa_s, 0);
6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (state == WPA_COMPLETED && wpa_s->new_connection) {
6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpa_ssid *ssid = wpa_s->current_ssid;
656700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- Connection to "
658f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt			MACSTR " completed (auth) [id=%d id_str=%s]",
659f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt			MAC2STR(wpa_s->bssid),
6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ssid ? ssid->id : -1,
6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ssid && ssid->id_str ? ssid->id_str : "");
6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
66361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpas_clear_temp_disabled(wpa_s, ssid, 1);
664d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_s->extra_blacklist_count = 0;
6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->new_connection = 0;
6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_set_operstate(wpa_s, 1);
6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef IEEE8021X_EAPOL
6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_set_supp_port(wpa_s, 1);
6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */
6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->after_wps = 0;
6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_completed(wpa_s);
6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
67404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
67504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		sme_sched_obss_scan(wpa_s, 1);
6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING ||
6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   state == WPA_ASSOCIATED) {
6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->new_connection = 1;
6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_set_operstate(wpa_s, 0);
6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef IEEE8021X_EAPOL
6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_set_supp_port(wpa_s, 0);
6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */
68304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		sme_sched_obss_scan(wpa_s, 0);
6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->wpa_state = state;
6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_BGSCAN
6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (state == WPA_COMPLETED)
6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_start_bgscan(wpa_s);
6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_stop_bgscan(wpa_s);
6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_BGSCAN */
6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
69404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (state == WPA_AUTHENTICATING)
69504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_supplicant_stop_autoscan(wpa_s);
69604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
69704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
69804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_supplicant_start_autoscan(wpa_s);
69904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->wpa_state != old_state) {
7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->wpa_state == WPA_COMPLETED ||
7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    old_state == WPA_COMPLETED)
7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_notify_auth_changed(wpa_s);
7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_terminate_proc(struct wpa_global *global)
7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int pending = 0;
7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = global->ifaces;
7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (wpa_s) {
7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpas_wps_terminate_pending(wpa_s) == 1)
7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pending = 1;
7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s = wpa_s->next;
7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pending)
7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_terminate();
7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_terminate(int sig, void *signal_ctx)
7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_global *global = signal_ctx;
7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_terminate_proc(global);
7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s)
7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum wpa_states old_state = wpa_s->wpa_state;
7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->pairwise_cipher = 0;
7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->group_cipher = 0;
7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->mgmt_group_cipher = 0;
7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->key_mgmt = 0;
7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->wpa_state != WPA_INTERFACE_DISABLED)
74304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->wpa_state != old_state)
7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_reload_configuration - Reload configuration data
7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success or -1 if configuration parsing failed
7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to request that the configuration data is reloaded
7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (e.g., after configuration file change). This function is reloading
7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * configuration only for one interface, so this may need to be called multiple
7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * times if %wpa_supplicant is controlling multiple interfaces and all
7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * interfaces need reconfiguration.
7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_config *conf;
7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int reconf_ctrl;
7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int old_ap_scan;
7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->confname == NULL)
7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf = wpa_config_read(wpa_s->confname);
7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (conf == NULL) {
7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Failed to parse the configuration "
7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"file '%s' - exiting", wpa_s->confname);
7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->changed_parameters = (unsigned int) -1;
7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reconf_ctrl = !!conf->ctrl_interface != !!wpa_s->conf->ctrl_interface
7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		|| (conf->ctrl_interface && wpa_s->conf->ctrl_interface &&
7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    os_strcmp(conf->ctrl_interface,
7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      wpa_s->conf->ctrl_interface) != 0);
7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (reconf_ctrl && wpa_s->ctrl_iface) {
7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->ctrl_iface = NULL;
7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_invalidate_cached_session(wpa_s->eapol);
7881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->current_ssid) {
7891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_supplicant_deauthenticate(wpa_s,
7901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					      WLAN_REASON_DEAUTH_LEAVING);
7911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * TODO: should notify EAPOL SM about changes in opensc_engine_path,
7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * pkcs11_engine_path, pkcs11_module_path.
7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * Clear forced success to clear EAP state for next
8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * authentication.
8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_config(wpa_s->wpa, NULL);
8061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	rsn_preauth_deinit(wpa_s->wpa);
8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	old_ap_scan = wpa_s->conf->ap_scan;
8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_free(wpa_s->conf);
8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->conf = conf;
8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (old_ap_scan != wpa_s->conf->ap_scan)
8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_ap_scan_changed(wpa_s);
8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (reconf_ctrl)
8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_update_config(wpa_s);
8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_clear_status(wpa_s);
82204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_supplicant_enabled_networks(wpa_s)) {
8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->reassociate = 1;
8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_req_scan(wpa_s, 0, 0);
8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Reconfiguration completed");
8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_reconfig(int sig, void *signal_ctx)
8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_global *global = signal_ctx;
8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s;
8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Signal %d received - reconfiguring",
8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			sig);
8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_reload_configuration(wpa_s) < 0) {
8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_terminate_proc(global);
8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtenum wpa_key_mgmt key_mgmt2driver(int key_mgmt)
8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (key_mgmt) {
8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_KEY_MGMT_NONE:
8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return KEY_MGMT_NONE;
8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_KEY_MGMT_IEEE8021X_NO_WPA:
8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return KEY_MGMT_802_1X_NO_WPA;
8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_KEY_MGMT_IEEE8021X:
8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return KEY_MGMT_802_1X;
8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_KEY_MGMT_WPA_NONE:
8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return KEY_MGMT_WPA_NONE;
8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_KEY_MGMT_FT_IEEE8021X:
8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return KEY_MGMT_FT_802_1X;
8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_KEY_MGMT_FT_PSK:
8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return KEY_MGMT_FT_PSK;
8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_KEY_MGMT_IEEE8021X_SHA256:
8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return KEY_MGMT_802_1X_SHA256;
8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_KEY_MGMT_PSK_SHA256:
8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return KEY_MGMT_PSK_SHA256;
8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_KEY_MGMT_WPS:
8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return KEY_MGMT_WPS;
8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_KEY_MGMT_PSK:
8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return KEY_MGMT_PSK;
8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s,
8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 struct wpa_ssid *ssid,
8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 struct wpa_ie_data *ie)
8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret = wpa_sm_parse_own_wpa_ie(wpa_s->wpa, ie);
8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret) {
8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret == -2) {
8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_msg(wpa_s, MSG_INFO, "WPA: Failed to parse WPA IE "
8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"from association info");
8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Using WPA IE from AssocReq to set "
8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"cipher suites");
8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!(ie->group_cipher & ssid->group_cipher)) {
8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled group "
8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"cipher 0x%x (mask 0x%x) - reject",
8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ie->group_cipher, ssid->group_cipher);
8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!(ie->pairwise_cipher & ssid->pairwise_cipher)) {
8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled pairwise "
8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"cipher 0x%x (mask 0x%x) - reject",
8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ie->pairwise_cipher, ssid->pairwise_cipher);
8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!(ie->key_mgmt & ssid->key_mgmt)) {
9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled key "
9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"management 0x%x (mask 0x%x) - reject",
9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ie->key_mgmt, ssid->key_mgmt);
9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!(ie->capabilities & WPA_CAPABILITY_MFPC) &&
909d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	    (ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
910d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	     wpa_s->conf->pmf : ssid->ieee80211w) ==
911d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	    MGMT_FRAME_PROTECTION_REQUIRED) {
9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP "
9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"that does not support management frame protection - "
9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"reject");
9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_set_suites - Set authentication and encryption parameters
9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @bss: Scan results for the selected BSS, or %NULL if not available
9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid: Configuration data for the selected network
9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_ie: Buffer for the WPA/RSN IE
9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_ie_len: Maximum wpa_ie buffer size on input. This is changed to be the
9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * used buffer length in case the functions returns success.
9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success or -1 on failure
9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to configure authentication and encryption parameters
9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * based on the network configuration and scan result for the selected BSS (if
9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * available).
9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      struct wpa_bss *bss, struct wpa_ssid *ssid,
9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      u8 *wpa_ie, size_t *wpa_ie_len)
9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ie_data ie;
9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int sel, proto;
9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *bss_wpa, *bss_rsn;
9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss) {
9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else
9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss_wpa = bss_rsn = NULL;
9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss_rsn && (ssid->proto & WPA_PROTO_RSN) &&
9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie) == 0 &&
9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (ie.group_cipher & ssid->group_cipher) &&
9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (ie.pairwise_cipher & ssid->pairwise_cipher) &&
9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (ie.key_mgmt & ssid->key_mgmt)) {
9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using IEEE 802.11i/D9.0");
9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		proto = WPA_PROTO_RSN;
9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (bss_wpa && (ssid->proto & WPA_PROTO_WPA) &&
9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   wpa_parse_wpa_ie(bss_wpa, 2 +bss_wpa[1], &ie) == 0 &&
9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   (ie.group_cipher & ssid->group_cipher) &&
9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   (ie.pairwise_cipher & ssid->pairwise_cipher) &&
9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   (ie.key_mgmt & ssid->key_mgmt)) {
9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using IEEE 802.11i/D3.0");
9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		proto = WPA_PROTO_WPA;
9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (bss) {
9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select WPA/RSN");
9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->proto & WPA_PROTO_RSN)
9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			proto = WPA_PROTO_RSN;
9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else
9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			proto = WPA_PROTO_WPA;
9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_suites_from_ai(wpa_s, ssid, &ie) < 0) {
9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memset(&ie, 0, sizeof(ie));
9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ie.group_cipher = ssid->group_cipher;
9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ie.pairwise_cipher = ssid->pairwise_cipher;
9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ie.key_mgmt = ssid->key_mgmt;
9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ie.mgmt_group_cipher =
9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION ?
9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				WPA_CIPHER_AES_128_CMAC : 0;
9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Set cipher suites "
9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"based on configuration");
9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else
9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			proto = ie.proto;
9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected cipher suites: group %d "
9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"pairwise %d key_mgmt %d proto %d",
9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ie.group_cipher, ie.pairwise_cipher, ie.key_mgmt, proto);
9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->ieee80211w) {
9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected mgmt group cipher %d",
9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ie.mgmt_group_cipher);
9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_s->wpa_proto = proto;
10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, proto);
10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 !!(ssid->proto & WPA_PROTO_RSN));
10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss || !wpa_s->ap_ies_from_associnfo) {
10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 bss_wpa ? 2 + bss_wpa[1] : 0) ||
10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 bss_rsn ? 2 + bss_rsn[1] : 0))
10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sel = ie.group_cipher & ssid->group_cipher;
1013a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	wpa_s->group_cipher = wpa_pick_group_cipher(sel);
1014a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (wpa_s->group_cipher < 0) {
10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select group "
10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"cipher");
10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1019a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s",
1020a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		wpa_cipher_txt(wpa_s->group_cipher));
10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sel = ie.pairwise_cipher & ssid->pairwise_cipher;
1023a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(sel, 1);
1024a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (wpa_s->pairwise_cipher < 0) {
10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select pairwise "
10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"cipher");
10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1029a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK %s",
1030a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		wpa_cipher_txt(wpa_s->pairwise_cipher));
10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sel = ie.key_mgmt & ssid->key_mgmt;
1033d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE
1034d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE))
1035d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE);
1036d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */
10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (0) {
10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) {
10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/802.1X");
10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (sel & WPA_KEY_MGMT_FT_PSK) {
10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_FT_PSK;
10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/PSK");
10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
1046d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#ifdef CONFIG_SAE
1047d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	} else if (sel & WPA_KEY_MGMT_SAE) {
1048d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
1049d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT SAE");
1050d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	} else if (sel & WPA_KEY_MGMT_FT_SAE) {
1051d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_FT_SAE;
1052d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT FT/SAE");
1053d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt#endif /* CONFIG_SAE */
10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (sel & WPA_KEY_MGMT_IEEE8021X_SHA256) {
10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG,
10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"WPA: using KEY_MGMT 802.1X with SHA256");
10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (sel & WPA_KEY_MGMT_PSK_SHA256) {
10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG,
10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"WPA: using KEY_MGMT PSK with SHA256");
10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (sel & WPA_KEY_MGMT_IEEE8021X) {
10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT 802.1X");
10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (sel & WPA_KEY_MGMT_PSK) {
10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-PSK");
10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (sel & WPA_KEY_MGMT_WPA_NONE) {
10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_WPA_NONE;
10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-NONE");
10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select "
10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"authenticated key management type");
10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 wpa_s->pairwise_cipher);
10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sel = ie.mgmt_group_cipher;
1086d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if ((ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1087d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	     wpa_s->conf->pmf : ssid->ieee80211w) == NO_MGMT_FRAME_PROTECTION ||
10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    !(ie.capabilities & WPA_CAPABILITY_MFPC))
10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		sel = 0;
10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (sel & WPA_CIPHER_AES_128_CMAC) {
10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"AES-128-CMAC");
10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->mgmt_group_cipher = 0;
10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 wpa_s->mgmt_group_cipher);
1100d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP,
1101d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			 (ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1102d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			  wpa_s->conf->pmf : ssid->ieee80211w));
11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {
11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to generate WPA IE");
11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN);
11121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifndef CONFIG_NO_PBKDF2
11131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (bss && ssid->bssid_set && ssid->ssid_len == 0 &&
11141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    ssid->passphrase) {
11151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			u8 psk[PMK_LEN];
111661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		        pbkdf2_sha1(ssid->passphrase, bss->ssid, bss->ssid_len,
111761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				    4096, psk, PMK_LEN);
11181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		        wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
11191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					psk, PMK_LEN);
11201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
11211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
11221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_NO_PBKDF2 */
112361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_EXT_PASSWORD
112461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (ssid->ext_psk) {
112561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			struct wpabuf *pw = ext_password_get(wpa_s->ext_pw,
112661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt							     ssid->ext_psk);
112761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			char pw_str[64 + 1];
112861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			u8 psk[PMK_LEN];
112961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
113061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (pw == NULL) {
113161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_msg(wpa_s, MSG_INFO, "EXT PW: No PSK "
113261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					"found from external storage");
113361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				return -1;
113461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
113561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
113661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (wpabuf_len(pw) < 8 || wpabuf_len(pw) > 64) {
113761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_msg(wpa_s, MSG_INFO, "EXT PW: Unexpected "
113861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					"PSK length %d in external storage",
113961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					(int) wpabuf_len(pw));
114061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				ext_password_free(pw);
114161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				return -1;
114261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
114361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
114461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			os_memcpy(pw_str, wpabuf_head(pw), wpabuf_len(pw));
114561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			pw_str[wpabuf_len(pw)] = '\0';
114661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
114761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifndef CONFIG_NO_PBKDF2
114861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (wpabuf_len(pw) >= 8 && wpabuf_len(pw) < 64 && bss)
114961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			{
115061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				pbkdf2_sha1(pw_str, bss->ssid, bss->ssid_len,
115161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					    4096, psk, PMK_LEN);
115261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				os_memset(pw_str, 0, sizeof(pw_str));
115361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_hexdump_key(MSG_MSGDUMP, "PSK (from "
115461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt						"external passphrase)",
115561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt						psk, PMK_LEN);
115661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
115761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			} else
115861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_NO_PBKDF2 */
115961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (wpabuf_len(pw) == 2 * PMK_LEN) {
116061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				if (hexstr2bin(pw_str, psk, PMK_LEN) < 0) {
116161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					wpa_msg(wpa_s, MSG_INFO, "EXT PW: "
116261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt						"Invalid PSK hex string");
116361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					os_memset(pw_str, 0, sizeof(pw_str));
116461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					ext_password_free(pw);
116561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					return -1;
116661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				}
116761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
116861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			} else {
116961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_msg(wpa_s, MSG_INFO, "EXT PW: No suitable "
117061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					"PSK available");
117161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				os_memset(pw_str, 0, sizeof(pw_str));
117261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				ext_password_free(pw);
117361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				return -1;
117461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
117561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
117661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			os_memset(pw_str, 0, sizeof(pw_str));
117761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			ext_password_free(pw);
117861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		}
117961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_EXT_PASSWORD */
11801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	} else
11818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
11828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1187444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidtstatic void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
1188a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt{
1189444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	*pos = 0x00;
1190a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
1191444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	switch (idx) {
1192444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	case 0: /* Bits 0-7 */
1193444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		break;
1194444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	case 1: /* Bits 8-15 */
1195444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		break;
1196444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	case 2: /* Bits 16-23 */
1197444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt#ifdef CONFIG_WNM
1198444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		*pos |= 0x02; /* Bit 17 - WNM-Sleep Mode */
1199444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		*pos |= 0x08; /* Bit 19 - BSS Transition */
1200444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt#endif /* CONFIG_WNM */
1201444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		break;
1202444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	case 3: /* Bits 24-31 */
1203444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt#ifdef CONFIG_WNM
1204444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		*pos |= 0x02; /* Bit 25 - SSID List */
1205444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt#endif /* CONFIG_WNM */
1206a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#ifdef CONFIG_INTERWORKING
1207444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		if (wpa_s->conf->interworking)
1208444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt			*pos |= 0x80; /* Bit 31 - Interworking */
1209a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt#endif /* CONFIG_INTERWORKING */
1210444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		break;
1211444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	case 4: /* Bits 32-39 */
1212444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		break;
1213444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	case 5: /* Bits 40-47 */
1214444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		break;
1215444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	case 6: /* Bits 48-55 */
1216444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		break;
1217444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	}
1218444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt}
1219a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
1220a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
1221444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidtint wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf)
1222444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt{
1223444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	u8 *pos = buf;
1224444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	u8 len = 4, i;
1225444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt
1226444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	if (len < wpa_s->extended_capa_len)
1227444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		len = wpa_s->extended_capa_len;
1228a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
1229a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	*pos++ = WLAN_EID_EXT_CAPAB;
1230444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	*pos++ = len;
1231444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	for (i = 0; i < len; i++, pos++) {
1232444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		wpas_ext_capab_byte(wpa_s, pos, i);
1233444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt
1234444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		if (i < wpa_s->extended_capa_len) {
1235444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt			*pos &= ~wpa_s->extended_capa_mask[i];
1236444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt			*pos |= wpa_s->extended_capa[i];
1237444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		}
1238444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	}
1239444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt
1240444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	while (len > 0 && buf[1 + len] == 0) {
1241444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		len--;
1242444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		buf[1] = len;
1243444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	}
1244444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	if (len == 0)
1245444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		return 0;
1246a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
1247444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	return 2 + len;
1248a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt}
1249a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
1250a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_associate - Request association
12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @bss: Scan results for the selected BSS, or %NULL if not available
12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid: Configuration data for the selected network
12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to request %wpa_supplicant to associate with a BSS.
12588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
12598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
12608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      struct wpa_bss *bss, struct wpa_ssid *ssid)
12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 wpa_ie[200];
12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t wpa_ie_len;
12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int use_crypt, ret, i, bssid_changed;
12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int algs = WPA_AUTH_ALG_OPEN;
12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum wpa_cipher cipher_pairwise, cipher_group;
12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_driver_associate_params params;
12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wep_keys_set = 0;
12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_driver_capa capa;
12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int assoc_failed = 0;
12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *old_ssid;
1272a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	u8 ext_capab[10];
1273a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	int ext_capab_len;
1274c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#ifdef CONFIG_HT_OVERRIDES
1275c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	struct ieee80211_ht_capabilities htcaps;
1276c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	struct ieee80211_ht_capabilities htcaps_mask;
1277c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#endif /* CONFIG_HT_OVERRIDES */
12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IBSS_RSN
12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ibss_rsn_deinit(wpa_s->ibss_rsn);
12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->ibss_rsn = NULL;
12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IBSS_RSN */
1283c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#ifdef ANDROID_P2P
1284c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	int freq = 0;
1285c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#endif
12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) {
12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_msg(wpa_s, MSG_INFO, "Driver does not support AP "
12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"mode");
12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return;
12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1295aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt		if (wpa_supplicant_create_ap(wpa_s, ssid) < 0) {
1296aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt			wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
1297aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt			return;
1298aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt		}
12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->current_bss = bss;
13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_AP */
13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "AP mode support not included in "
13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"the build");
13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TDLS
13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss)
13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_tdls_ap_ies(wpa_s->wpa, (const u8 *) (bss + 1),
13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				bss->ie_len);
13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TDLS */
13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    ssid->mode == IEEE80211_MODE_INFRA) {
13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		sme_authenticate(wpa_s, bss, ssid);
13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&params, 0, sizeof(params));
13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->reassociate = 0;
13211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (bss && !wpas_driver_bss_selection(wpa_s)) {
13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		const u8 *ie, *md = NULL;
13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			" (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid),
13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq);
13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memset(wpa_s->bssid, 0, ETH_ALEN);
13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (bssid_changed)
13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_notify_bssid_changed(wpa_s);
13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			md = ie + 2;
13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (md) {
13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* Prepare for the next transition */
13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if ((ssid->ssid == NULL || ssid->ssid_len == 0) &&
13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   wpa_s->conf->ap_scan == 2 &&
13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Use ap_scan==1 style network selection to find the network
13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
1349d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_s->scan_req = MANUAL_SCAN_REQ;
13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->reassociate = 1;
13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_req_scan(wpa_s, 0, 0);
13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_supplicant_cancel_sched_scan(wpa_s);
13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_cancel_scan(wpa_s);
13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Starting new association, so clear the possibly used WPA IE from the
13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * previous association. */
13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL
13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->leap) {
13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (ssid->non_leap == 0)
13708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				algs = WPA_AUTH_ALG_LEAP;
13718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			else
13728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				algs |= WPA_AUTH_ALG_LEAP;
13738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */
13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs);
13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->auth_alg) {
13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		algs = ssid->auth_alg;
13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: "
13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"0x%x", algs);
13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
13851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    wpa_key_mgmt_wpa(ssid->key_mgmt)) {
13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int try_opportunistic;
1387d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		try_opportunistic = (ssid->proactive_key_caching < 0 ?
1388d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt				     wpa_s->conf->okc :
1389d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt				     ssid->proactive_key_caching) &&
13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			(ssid->proto & WPA_PROTO_RSN);
13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
1392700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt					    ssid, try_opportunistic) == 0)
13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1);
13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_ie_len = sizeof(wpa_ie);
13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      wpa_ie, &wpa_ie_len)) {
13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"key management and encryption suites");
13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return;
14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
140161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	} else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && bss &&
140261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		   wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
140361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		/*
140461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		 * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
140561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		 * use non-WPA since the scan results did not indicate that the
140661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		 * AP is using WPA or WPA2.
140761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		 */
140861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
140961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_ie_len = 0;
141061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_s->wpa_proto = 0;
14111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	} else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_ie_len = sizeof(wpa_ie);
14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      wpa_ie, &wpa_ie_len)) {
14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"key management and encryption suites (no "
14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"scan results)");
14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return;
14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpabuf *wps_ie;
14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps_ie && wpabuf_len(wps_ie) <= sizeof(wpa_ie)) {
14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_ie_len = wpabuf_len(wps_ie);
14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else
14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_ie_len = 0;
14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(wps_ie);
14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY))
14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.wps = WPS_MODE_PRIVACY;
14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else
14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.wps = WPS_MODE_OPEN;
14351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_s->wpa_proto = 0;
14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_ie_len = 0;
14401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_s->wpa_proto = 0;
14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p) {
14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		u8 *pos;
14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		size_t len;
14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int res;
14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = wpa_ie + wpa_ie_len;
14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len = sizeof(wpa_ie) - wpa_ie_len;
145004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
145104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					    ssid->p2p_group);
14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (res >= 0)
14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_ie_len += res;
14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->cross_connect_disallowed = 0;
14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss) {
14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpabuf *p2p;
14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p) {
14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->cross_connect_disallowed =
14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				p2p_get_cross_connect_disallowed(p2p);
14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpabuf_free(p2p);
14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: WLAN AP %s cross "
14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"connection",
14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s->cross_connect_disallowed ?
14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"disallows" : "allows");
14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
147204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_HS20
147304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->conf->hs20) {
147404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		struct wpabuf *hs20;
147504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		hs20 = wpabuf_alloc(20);
147604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (hs20) {
147704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpas_hs20_add_indication(hs20);
147804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			os_memcpy(wpa_ie + wpa_ie_len, wpabuf_head(hs20),
147904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				  wpabuf_len(hs20));
148004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_ie_len += wpabuf_len(hs20);
148104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpabuf_free(hs20);
148204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
148304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
148404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_HS20 */
148504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
1486a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab);
1487a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (ext_capab_len > 0) {
14881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		u8 *pos = wpa_ie;
14891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)
14901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			pos += 2 + pos[1];
1491a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		os_memmove(pos + ext_capab_len, pos,
1492a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			   wpa_ie_len - (pos - wpa_ie));
1493a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		wpa_ie_len += ext_capab_len;
1494a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		os_memcpy(pos, ext_capab, ext_capab_len);
14951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
14961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	use_crypt = 1;
1499a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	cipher_pairwise = wpa_cipher_to_suite_driver(wpa_s->pairwise_cipher);
1500a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	cipher_group = wpa_cipher_to_suite_driver(wpa_s->group_cipher);
15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			use_crypt = 0;
15058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_set_wep_keys(wpa_s, ssid)) {
15068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			use_crypt = 1;
15078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wep_keys_set = 1;
15088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		use_crypt = 0;
15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL
15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if ((ssid->eapol_flags &
15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		      EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 &&
15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    !wep_keys_set) {
15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			use_crypt = 0;
15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* Assume that dynamic WEP-104 keys will be used and
15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * set cipher suites in order for drivers to expect
15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * encryption. */
15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			cipher_pairwise = cipher_group = CIPHER_WEP104;
15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */
15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Set the key before (and later after) association */
15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss) {
15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.ssid = bss->ssid;
15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.ssid_len = bss->ssid_len;
153804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
153904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_printf(MSG_DEBUG, "Limit connection to BSSID "
154004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   MACSTR " freq=%u MHz based on scan results "
154104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   "(bssid_set=%d)",
154204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   MAC2STR(bss->bssid), bss->freq,
154304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   ssid->bssid_set);
15441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			params.bssid = bss->bssid;
15451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			params.freq = bss->freq;
15461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.ssid = ssid->ssid;
15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.ssid_len = ssid->ssid_len;
15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1551c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1552c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&
1553c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	    wpa_s->conf->ap_scan == 2) {
1554c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		params.bssid = ssid->bssid;
1555c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		params.fixed_bssid = 1;
1556c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
1557c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->mode == WPAS_MODE_IBSS && ssid->frequency > 0 &&
15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    params.freq == 0)
15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.freq = ssid->frequency; /* Initial channel for IBSS */
15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.wpa_ie = wpa_ie;
15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.wpa_ie_len = wpa_ie_len;
15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.pairwise_suite = cipher_pairwise;
15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.group_suite = cipher_group;
15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.key_mgmt_suite = key_mgmt2driver(wpa_s->key_mgmt);
15661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	params.wpa_proto = wpa_s->wpa_proto;
15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.auth_alg = algs;
15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.mode = ssid->mode;
156904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	params.bg_scan_period = ssid->bg_scan_period;
15708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < NUM_WEP_KEYS; i++) {
15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->wep_key_len[i])
15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.wep_key[i] = ssid->wep_key[i];
15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.wep_key_len[i] = ssid->wep_key_len[i];
15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.wep_tx_keyidx = ssid->wep_tx_keyidx;
15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
15788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (params.key_mgmt_suite == KEY_MGMT_PSK ||
15798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     params.key_mgmt_suite == KEY_MGMT_FT_PSK)) {
15808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.passphrase = ssid->passphrase;
15818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->psk_set)
15828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.psk = ssid->psk;
15838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.drop_unencrypted = use_crypt;
15868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
1588d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	params.mgmt_frame_protection =
1589d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1590d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_s->conf->pmf : ssid->ieee80211w;
1591d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
15928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
15938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpa_ie_data ie;
15948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
15958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    ie.capabilities &
15968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
15978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected AP supports "
15988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"MFP: require MFP");
15998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.mgmt_frame_protection =
16008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				MGMT_FRAME_PROTECTION_REQUIRED;
16018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
16028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
16048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	params.p2p = ssid->p2p_group;
16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->parent->set_sta_uapsd)
16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.uapsd = wpa_s->parent->sta_uapsd;
16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.uapsd = -1;
16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1612c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#ifdef CONFIG_HT_OVERRIDES
1613c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	os_memset(&htcaps, 0, sizeof(htcaps));
1614c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
1615c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	params.htcaps = (u8 *) &htcaps;
1616c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	params.htcaps_mask = (u8 *) &htcaps_mask;
1617c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
1618c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#endif /* CONFIG_HT_OVERRIDES */
1619c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
16201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef ANDROID_P2P
16211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	/* If multichannel concurrency is not supported, check for any frequency
16221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 * conflict and take appropriate action.
16231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 */
1624c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) &&
1625c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		((freq = wpa_drv_shared_freq(wpa_s)) > 0) && (freq != params.freq)) {
1626c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		wpa_printf(MSG_DEBUG, "Shared interface with conflicting frequency found (%d != %d)"
16271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt																, freq, params.freq);
1628d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		if (wpas_p2p_handle_frequency_conflicts(wpa_s, params.freq, ssid) < 0)
1629687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt			return;
16301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
16311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif
16321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	ret = wpa_drv_associate(wpa_s, &params);
16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret < 0) {
16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"failed");
16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SANE_ERROR_CODES) {
16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/*
16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * The driver is known to mean what is saying, so we
16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * can stop right here; the association will not
16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * succeed.
16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 */
16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
164304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return;
16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* try to continue anyway; new association will be tried again
16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * after timeout */
16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		assoc_failed = 1;
16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Set the key after the association just in case association
16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * cleared the previously configured key. */
16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* No need to timeout authentication since there is no key
16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * management. */
16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_cancel_auth_timeout(wpa_s);
16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IBSS_RSN
16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (ssid->mode == WPAS_MODE_IBSS &&
16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * RSN IBSS authentication is per-STA and we can disable the
16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * per-BSSID authentication.
16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_cancel_auth_timeout(wpa_s);
16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IBSS_RSN */
16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Timeout for IEEE 802.11 authentication and association */
16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int timeout = 60;
16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (assoc_failed) {
16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* give IBSS a bit more time */
16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5;
16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (wpa_s->conf->ap_scan == 1) {
16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* give IBSS a bit more time */
16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10;
16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wep_keys_set && wpa_drv_get_capa(wpa_s, &capa) == 0 &&
16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    capa.flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC) {
16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Set static WEP keys again */
16878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_set_wep_keys(wpa_s, ssid);
16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * Do not allow EAP session resumption between different
16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * network configurations.
16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_invalidate_cached_session(wpa_s->eapol);
16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	old_ssid = wpa_s->current_ssid;
16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->current_ssid = ssid;
16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->current_bss = bss;
17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_initiate_eapol(wpa_s);
17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (old_ssid != wpa_s->current_ssid)
17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_network_changed(wpa_s);
17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s,
17088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					    const u8 *addr)
17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *old_ssid;
17118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_clear_keys(wpa_s, addr);
17138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	old_ssid = wpa_s->current_ssid;
171461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_supplicant_mark_disassoc(wpa_s);
17158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_config(wpa_s->wpa, NULL);
17168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (old_ssid != wpa_s->current_ssid)
17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_network_changed(wpa_s);
17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
17208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
17218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
17248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_deauthenticate - Deauthenticate the current connection
17258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
17268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @reason_code: IEEE 802.11 reason code for the deauthenticate frame
17278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
17288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to request %wpa_supplicant to deauthenticate from the
17298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * current AP.
17308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
17318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
17328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   int reason_code)
17338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
17348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 *addr = NULL;
173504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	union wpa_event_data event;
1736d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	int zero_addr = 0;
1737d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
1738d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
1739d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		" pending_bssid=" MACSTR " reason=%d state=%s",
1740d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
1741d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state));
17428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1743d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (!is_zero_ether_addr(wpa_s->bssid))
17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		addr = wpa_s->bssid;
1745d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	else if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
1746d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		 (wpa_s->wpa_state == WPA_AUTHENTICATING ||
1747d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		  wpa_s->wpa_state == WPA_ASSOCIATING))
1748d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		addr = wpa_s->pending_bssid;
1749d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
1750d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		/*
1751d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		 * When using driver-based BSS selection, we may not know the
1752d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		 * BSSID with which we are currently trying to associate. We
1753d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		 * need to notify the driver of this disconnection even in such
1754d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		 * a case, so use the all zeros address here.
1755d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		 */
1756d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		addr = wpa_s->bssid;
1757d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		zero_addr = 1;
1758d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	}
1759d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
1760f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_TDLS
1761f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	wpa_tdls_teardown_peers(wpa_s->wpa);
1762f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_TDLS */
1763f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
1764d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (addr) {
1765d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_drv_deauthenticate(wpa_s, addr, reason_code);
176604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_memset(&event, 0, sizeof(event));
176704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		event.deauth_info.reason_code = (u16) reason_code;
176804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		event.deauth_info.locally_generated = 1;
176904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
1770d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		if (zero_addr)
1771d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			addr = NULL;
17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_clear_connection(wpa_s, addr);
17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
17768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17772f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidtstatic void wpa_supplicant_enable_one_network(struct wpa_supplicant *wpa_s,
17782f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt					      struct wpa_ssid *ssid)
17792f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt{
17802f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	if (!ssid || !ssid->disabled || ssid->disabled == 2)
17812f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt		return;
17822f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt
17832f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	ssid->disabled = 0;
17842f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	wpas_clear_temp_disabled(wpa_s, ssid, 1);
17852f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	wpas_notify_network_enabled_changed(wpa_s, ssid);
17862f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt
17872f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	/*
17882f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	 * Try to reassociate since there is no current configuration and a new
17892f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	 * network was made available.
17902f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	 */
17912f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	if (!wpa_s->current_ssid)
17922f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt		wpa_s->reassociate = 1;
17932f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt}
17942f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt
17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_enable_network - Mark a configured network as enabled
17988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid: wpa_ssid structure for a configured network or %NULL
18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Enables the specified network or all networks if no network specified.
18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   struct wpa_ssid *ssid)
18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL) {
18072f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt		for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
18082f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt			wpa_supplicant_enable_one_network(wpa_s, ssid);
18092f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	} else
18102f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt		wpa_supplicant_enable_one_network(wpa_s, ssid);
18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18122f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	if (wpa_s->reassociate) {
18132f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt		if (wpa_s->sched_scanning) {
18142f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt			wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to add "
18152f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt				   "new network to scan filters");
18162f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt			wpa_supplicant_cancel_sched_scan(wpa_s);
18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18192f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt		wpa_supplicant_req_scan(wpa_s, 0, 0);
18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_disable_network - Mark a configured network as disabled
18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid: wpa_ssid structure for a configured network or %NULL
18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Disables the specified network or all networks if no network specified.
18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    struct wpa_ssid *ssid)
18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *other_ssid;
18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int was_disabled;
18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL) {
18382f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt		if (wpa_s->sched_scanning)
18392f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt			wpa_supplicant_cancel_sched_scan(wpa_s);
18402f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt
18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (other_ssid = wpa_s->conf->ssid; other_ssid;
18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     other_ssid = other_ssid->next) {
18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			was_disabled = other_ssid->disabled;
18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (was_disabled == 2)
18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				continue; /* do not change persistent P2P group
18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   * data */
18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			other_ssid->disabled = 1;
18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (was_disabled != other_ssid->disabled)
18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpas_notify_network_enabled_changed(
18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					wpa_s, other_ssid);
18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->current_ssid)
1855d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			wpa_supplicant_deauthenticate(
18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s, WLAN_REASON_DEAUTH_LEAVING);
18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (ssid->disabled != 2) {
18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid == wpa_s->current_ssid)
1859d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			wpa_supplicant_deauthenticate(
18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s, WLAN_REASON_DEAUTH_LEAVING);
18618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		was_disabled = ssid->disabled;
18638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid->disabled = 1;
18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18662f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt		if (was_disabled != ssid->disabled) {
18678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_notify_network_enabled_changed(wpa_s, ssid);
18682f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt			if (wpa_s->sched_scanning) {
18692f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt				wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan "
18702f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt					   "to remove network from filters");
18712f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt				wpa_supplicant_cancel_sched_scan(wpa_s);
18722f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt				wpa_supplicant_req_scan(wpa_s, 0, 0);
18732f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt			}
18742f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt		}
18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_select_network - Attempt association with a network
18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid: wpa_ssid structure for a configured network or %NULL for any network
18838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
18848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   struct wpa_ssid *ssid)
18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *other_ssid;
1889c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	int disconnected = 0;
18908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1891c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
1892d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		wpa_supplicant_deauthenticate(
18938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1894c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		disconnected = 1;
1895c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
18968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
189761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (ssid)
189861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpas_clear_temp_disabled(wpa_s, ssid, 1);
189961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * Mark all other networks disabled or mark all networks enabled if no
19028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * network specified.
19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (other_ssid = wpa_s->conf->ssid; other_ssid;
19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     other_ssid = other_ssid->next) {
19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int was_disabled = other_ssid->disabled;
19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (was_disabled == 2)
19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue; /* do not change persistent P2P group data */
19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
191161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (was_disabled && !other_ssid->disabled)
191261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (was_disabled != other_ssid->disabled)
19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_notify_network_enabled_changed(wpa_s, other_ssid);
19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
19171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
19181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid) {
19191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		/* We are already associated with the selected network */
19201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_printf(MSG_DEBUG, "Already associated with the "
19211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			   "selected network - do nothing");
19221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return;
19231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
19241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1925c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (ssid)
1926c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		wpa_s->current_ssid = ssid;
192775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpa_s->connect_without_scan = NULL;
19288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->disconnected = 0;
19298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->reassociate = 1;
19304b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt
19314b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	if (wpa_supplicant_fast_associate(wpa_s) != 1)
19324b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt		wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
19338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid)
19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_network_selected(wpa_s, ssid);
19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_set_ap_scan - Set AP scan mode for interface
19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ap_scan: AP scan mode
19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 if succeed or -1 if ap_scan has an invalid value
19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int old_ap_scan;
19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ap_scan < 0 || ap_scan > 2)
19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1954114c3866dda61e84385bb5327f0acf727f2156daDmitry Shmidt#ifdef ANDROID
19551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (ap_scan == 2 && ap_scan != wpa_s->conf->ap_scan &&
19561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    wpa_s->wpa_state >= WPA_ASSOCIATING &&
19571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    wpa_s->wpa_state < WPA_COMPLETED) {
19581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_printf(MSG_ERROR, "ap_scan = %d (%d) rejected while "
19591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			   "associating", wpa_s->conf->ap_scan, ap_scan);
1960114c3866dda61e84385bb5327f0acf727f2156daDmitry Shmidt		return 0;
1961114c3866dda61e84385bb5327f0acf727f2156daDmitry Shmidt	}
19621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* ANDROID */
1963114c3866dda61e84385bb5327f0acf727f2156daDmitry Shmidt
19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	old_ap_scan = wpa_s->conf->ap_scan;
19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->conf->ap_scan = ap_scan;
19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (old_ap_scan != wpa_s->conf->ap_scan)
19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_ap_scan_changed(wpa_s);
19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_set_bss_expiration_age - Set BSS entry expiration age
19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @expire_age: Expiration age in seconds
19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 if succeed or -1 if expire_age has an invalid value
19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  unsigned int bss_expire_age)
19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss_expire_age < 10) {
19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration age %u",
19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss_expire_age);
19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration age: %d sec",
19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss_expire_age);
19918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->conf->bss_expiration_age = bss_expire_age;
19928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
19948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
19958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
19988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_set_bss_expiration_count - Set BSS entry expiration scan count
19998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
20008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @expire_count: number of scans after which an unseen BSS is reclaimed
20018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 if succeed or -1 if expire_count has an invalid value
20028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
20038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
20048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
20058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					    unsigned int bss_expire_count)
20068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
20078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss_expire_count < 1) {
20088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration count %u",
20098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss_expire_count);
20108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
20118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
20128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration scan count: %u",
20138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss_expire_count);
20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->conf->bss_expiration_scan_count = bss_expire_count;
20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
202104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * wpa_supplicant_set_scan_interval - Set scan interval
202204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
202304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @scan_interval: scan interval in seconds
202404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Returns: 0 if succeed or -1 if scan_interval has an invalid value
202504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt *
202604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */
202704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint wpa_supplicant_set_scan_interval(struct wpa_supplicant *wpa_s,
202804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				     int scan_interval)
202904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
203004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (scan_interval < 0) {
203104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Invalid scan interval %d",
203204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			scan_interval);
203304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
203404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
203504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_msg(wpa_s, MSG_DEBUG, "Setting scan interval: %d sec",
203604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		scan_interval);
20374b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt	wpa_supplicant_update_scan_int(wpa_s, scan_interval);
203804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
203904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return 0;
204004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
204104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
204204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
204304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/**
20448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_set_debug_params - Set global debug params
20458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: wpa_global structure
20468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @debug_level: debug level
20478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @debug_timestamp: determines if show timestamp in debug data
20488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @debug_show_keys: determines if show keys in debug data
20498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 if succeed or -1 if debug_level has wrong value
20508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
20518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
20528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    int debug_timestamp, int debug_show_keys)
20538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
20548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int old_level, old_timestamp, old_show_keys;
20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* check for allowed debuglevels */
20588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (debug_level != MSG_EXCESSIVE &&
20598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    debug_level != MSG_MSGDUMP &&
20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    debug_level != MSG_DEBUG &&
20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    debug_level != MSG_INFO &&
20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    debug_level != MSG_WARNING &&
20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    debug_level != MSG_ERROR)
20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	old_level = wpa_debug_level;
20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	old_timestamp = wpa_debug_timestamp;
20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	old_show_keys = wpa_debug_show_keys;
20698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_debug_level = debug_level;
20718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_debug_timestamp = debug_timestamp ? 1 : 0;
20728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_debug_show_keys = debug_show_keys ? 1 : 0;
20738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_debug_level != old_level)
20758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_debug_level_changed(global);
20768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_debug_timestamp != old_timestamp)
20778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_debug_timestamp_changed(global);
20788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_debug_show_keys != old_show_keys)
20798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_debug_show_keys_changed(global);
20808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
20828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
20868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_get_ssid - Get a pointer to the current network structure
20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
20888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: A pointer to the current network structure or %NULL on failure
20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *entry;
20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 ssid[MAX_SSID_LEN];
20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int res;
20958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t ssid_len;
20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 bssid[ETH_ALEN];
20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wired;
20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	res = wpa_drv_get_ssid(wpa_s, ssid);
21001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (res < 0) {
21011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
21021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			"driver");
21031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return NULL;
21048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
21051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	ssid_len = res;
21068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
21088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_WARNING, "Could not read BSSID from "
21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"driver");
21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wired = wpa_s->conf->ap_scan == 0 &&
21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		(wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
21158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	entry = wpa_s->conf->ssid;
21178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (entry) {
211804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (!wpas_network_disabled(wpa_s, entry) &&
21198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    ((ssid_len == entry->ssid_len &&
21208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		      os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
21218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (!entry->bssid_set ||
21228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
21238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return entry;
21248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
212504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (!wpas_network_disabled(wpa_s, entry) &&
21268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
21278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (entry->ssid == NULL || entry->ssid_len == 0) &&
21288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (!entry->bssid_set ||
21298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
21308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return entry;
21318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
21321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
213304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
21341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    entry->ssid_len == 0 &&
21351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
21361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			return entry;
21371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		entry = entry->next;
21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return NULL;
21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int select_driver(struct wpa_supplicant *wpa_s, int i)
21461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
21471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_global *global = wpa_s->global;
21481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
21491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_drivers[i]->global_init && global->drv_priv[i] == NULL) {
21501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		global->drv_priv[i] = wpa_drivers[i]->global_init();
21511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (global->drv_priv[i] == NULL) {
21521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_printf(MSG_ERROR, "Failed to initialize driver "
21531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				   "'%s'", wpa_drivers[i]->name);
21541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			return -1;
21551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
21561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
21571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
21581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_s->driver = wpa_drivers[i];
21591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_s->global_drv_priv = global->drv_priv[i];
21601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
21611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return 0;
21621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
21631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
21641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
21668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     const char *name)
21678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
21688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
21698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t len;
21708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *pos, *driver = name;
21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s == NULL)
21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
21748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_drivers[0] == NULL) {
21768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "No driver interfaces build into "
21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"wpa_supplicant");
21788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
21808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (name == NULL) {
21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* default to first driver in the list */
21831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return select_driver(wpa_s, 0);
21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	do {
21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = os_strchr(driver, ',');
21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos)
21898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			len = pos - driver;
21908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else
21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			len = os_strlen(driver);
21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (i = 0; wpa_drivers[i]; i++) {
21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (os_strlen(wpa_drivers[i]->name) == len &&
21958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    os_strncmp(driver, wpa_drivers[i]->name, len) ==
2196c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			    0) {
2197c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				/* First driver that succeeds wins */
2198c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				if (select_driver(wpa_s, i) == 0)
2199c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt					return 0;
2200c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			}
22018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
22028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		driver = pos + 1;
22048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} while (pos);
22058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_msg(wpa_s, MSG_ERROR, "Unsupported driver '%s'", name);
22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return -1;
22088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
22138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ctx: Context pointer (wpa_s); this is the ctx variable registered
22148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *	with struct wpa_driver_ops::init()
22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @src_addr: Source address of the EAPOL frame
22168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of the EAPOL data
22188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called for each received EAPOL frame. Most driver
22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * interfaces rely on more generic OS mechanism for receiving frames through
22218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * l2_packet, but if such a mechanism is not available, the driver wrapper may
22228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * take care of received EAPOL frames and deliver them to the core supplicant
22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * code by calling this function.
22248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
22268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     const u8 *buf, size_t len)
22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
22288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
22318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2233a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen	if (wpa_s->wpa_state < WPA_ASSOCIATED ||
2234a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen	    (wpa_s->last_eapol_matches_bssid &&
2235a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen#ifdef CONFIG_AP
2236a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen	     !wpa_s->ap_iface &&
2237a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen#endif /* CONFIG_AP */
2238a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen	     os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) != 0)) {
22398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
22408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * There is possible race condition between receiving the
22418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * association event and the EAPOL frame since they are coming
22428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * through different paths from the driver. In order to avoid
22438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * issues in trying to process the EAPOL frame before receiving
22448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * association information, lets queue it for processing until
2245a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen		 * the association event is received. This may also be needed in
2246a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen		 * driver-based roaming case, so also use src_addr != BSSID as a
2247a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen		 * trigger if we have previously confirmed that the
2248a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen		 * Authenticator uses BSSID as the src_addr (which is not the
2249a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen		 * case with wired IEEE 802.1X).
22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
22518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing "
2252a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen			"of received EAPOL frame (state=%s bssid=" MACSTR ")",
2253a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen			wpa_supplicant_state_txt(wpa_s->wpa_state),
2254a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen			MAC2STR(wpa_s->bssid));
22558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(wpa_s->pending_eapol_rx);
22568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
22578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->pending_eapol_rx) {
22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_get_time(&wpa_s->pending_eapol_rx_time);
22598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
22608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  ETH_ALEN);
22618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
22628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
22638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2265a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen	wpa_s->last_eapol_matches_bssid =
2266a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen		os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) == 0;
2267a05074ca1abe62b3fd8a8c30a5558e044b1356d5Jouni Malinen
22688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
22698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_iface) {
22708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
22718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
22728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
22748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Ignored received EAPOL frame since "
22778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"no key management is configured");
22788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
22798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->eapol_received == 0 &&
22828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
22838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
22848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     wpa_s->wpa_state != WPA_COMPLETED) &&
22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (wpa_s->current_ssid == NULL ||
22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) {
22878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Timeout for completing IEEE 802.1X and WPA authentication */
22888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_req_auth_timeout(
22898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s,
22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			(wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
22918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
22928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) ?
22938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			70 : 10, 0);
22948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->eapol_received++;
22968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->countermeasures) {
22988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "WPA: Countermeasures - dropped "
22998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"EAPOL packet");
23008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
23018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
23028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IBSS_RSN
23048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->current_ssid &&
23058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
23068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
23078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
23088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
23098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IBSS_RSN */
23108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Source address of the incoming EAPOL frame could be compared to the
23128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * current BSSID. However, it is possible that a centralized
23138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * Authenticator could be using another MAC address than the BSSID of
23148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * an AP, so just allow any address to be used for now. The replies are
23158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * still sent to the current BSSID (if available), though. */
23168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
23188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
23198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
23208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
23218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_poll(wpa_s);
23228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
23238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
23248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
23258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
23268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * Set portValid = TRUE here since we are going to skip 4-way
23278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * handshake processing which would normally set portValid. We
23288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * need this to allow the EAPOL state machines to be completed
23298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * without going through EAPOL-Key handshake.
23308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
23318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
23328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
23338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
23348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
23378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
23388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->driver->send_eapol) {
23398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
23408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (addr)
23418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
23428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (!(wpa_s->drv_flags &
23438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
23441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		l2_packet_deinit(wpa_s->l2);
23458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->l2 = l2_packet_init(wpa_s->ifname,
23468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   wpa_drv_get_mac_addr(wpa_s),
23478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   ETH_P_EAPOL,
23488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   wpa_supplicant_rx_eapol, wpa_s, 0);
23498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->l2 == NULL)
23508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
23518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
23528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
23538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (addr)
23548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
23558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
23568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
23588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Failed to get own L2 address");
23598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
23608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
23618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
23638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		MAC2STR(wpa_s->own_addr));
23641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
23651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
23661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return 0;
23671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
23681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
23691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
237004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr,
237104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					   const u8 *buf, size_t len)
237204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
237304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
237404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	const struct l2_ethhdr *eth;
237504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
237604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (len < sizeof(*eth))
237704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return;
237804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	eth = (const struct l2_ethhdr *) buf;
237904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
238004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_memcmp(eth->h_dest, wpa_s->own_addr, ETH_ALEN) != 0 &&
238104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	    !(eth->h_dest[0] & 0x01)) {
238204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
238304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			" (bridge - not for this interface - ignore)",
238404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			MAC2STR(src_addr), MAC2STR(eth->h_dest));
238504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return;
238604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
238704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
238804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
238904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		" (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest));
239004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth),
239104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				len - sizeof(*eth));
239204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
239304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
239404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
23951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/**
23961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * wpa_supplicant_driver_init - Initialize driver interface parameters
23971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
23981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Returns: 0 on success, -1 on failure
23991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *
24001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * This function is called to initialize driver interface parameters.
24011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * wpa_drv_init() must have been called before this function to initialize the
24021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * driver interface.
24031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */
24041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
24051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
24061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	static int interface_count = 0;
24071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
24081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
24091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
24108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->bridge_ifname[0]) {
24128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
24138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"interface '%s'", wpa_s->bridge_ifname);
24148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->l2_br = l2_packet_init(wpa_s->bridge_ifname,
24158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      wpa_s->own_addr,
24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      ETH_P_EAPOL,
241704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					      wpa_supplicant_rx_eapol_bridge,
241804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					      wpa_s, 1);
24198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->l2_br == NULL) {
24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_msg(wpa_s, MSG_ERROR, "Failed to open l2_packet "
24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"connection for the bridge interface '%s'",
24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s->bridge_ifname);
24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
24268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_clear_keys(wpa_s, NULL);
24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Make sure that TKIP countermeasures are not left enabled (could
24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * happen if wpa_supplicant is killed during countermeasures. */
24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_set_countermeasures(wpa_s, 0);
24328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
24348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_flush_pmkid(wpa_s);
24358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
2437c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_s->prev_scan_wildcard = 0;
2438c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
243904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_supplicant_enabled_networks(wpa_s)) {
24401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpa_supplicant_delayed_sched_scan(wpa_s, interface_count,
24411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						      100000))
24421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_supplicant_req_scan(wpa_s, interface_count,
24431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						100000);
24448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		interface_count++;
24458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else
24468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
24478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
24498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
24508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_daemon(const char *pid_file)
24538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
24548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "Daemonize..");
24558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return os_daemonize(pid_file);
24568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
24578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_supplicant * wpa_supplicant_alloc(void)
24608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
24618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s;
24628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s = os_zalloc(sizeof(*wpa_s));
24648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s == NULL)
24658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
2466d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	wpa_s->scan_req = INITIAL_SCAN_REQ;
24678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->scan_interval = 5;
24688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->new_connection = 1;
24698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->parent = wpa_s;
24701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_s->sched_scanning = 0;
24718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpa_s;
24738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
24748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2476c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#ifdef CONFIG_HT_OVERRIDES
2477c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2478c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtstatic int wpa_set_htcap_mcs(struct wpa_supplicant *wpa_s,
2479c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			     struct ieee80211_ht_capabilities *htcaps,
2480c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			     struct ieee80211_ht_capabilities *htcaps_mask,
2481c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			     const char *ht_mcs)
2482c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
2483c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	/* parse ht_mcs into hex array */
2484c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	int i;
2485c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	const char *tmp = ht_mcs;
2486c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	char *end = NULL;
2487c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2488c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	/* If ht_mcs is null, do not set anything */
2489c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (!ht_mcs)
2490c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return 0;
2491c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2492c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	/* This is what we are setting in the kernel */
2493c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	os_memset(&htcaps->supported_mcs_set, 0, IEEE80211_HT_MCS_MASK_LEN);
2494c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2495c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_msg(wpa_s, MSG_DEBUG, "set_htcap, ht_mcs -:%s:-", ht_mcs);
2496c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2497c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
2498c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		errno = 0;
2499c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		long v = strtol(tmp, &end, 16);
2500c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		if (errno == 0) {
2501c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			wpa_msg(wpa_s, MSG_DEBUG,
2502c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				"htcap value[%i]: %ld end: %p  tmp: %p",
2503c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				i, v, end, tmp);
2504c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			if (end == tmp)
2505c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				break;
2506c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2507c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			htcaps->supported_mcs_set[i] = v;
2508c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			tmp = end;
2509c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		} else {
2510c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			wpa_msg(wpa_s, MSG_ERROR,
2511c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				"Failed to parse ht-mcs: %s, error: %s\n",
2512c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				ht_mcs, strerror(errno));
2513c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			return -1;
2514c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		}
2515c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
2516c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2517c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	/*
2518c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	 * If we were able to parse any values, then set mask for the MCS set.
2519c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	 */
2520c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (i) {
2521c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		os_memset(&htcaps_mask->supported_mcs_set, 0xff,
2522c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			  IEEE80211_HT_MCS_MASK_LEN - 1);
2523c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		/* skip the 3 reserved bits */
2524c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		htcaps_mask->supported_mcs_set[IEEE80211_HT_MCS_MASK_LEN - 1] =
2525c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			0x1f;
2526c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
2527c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2528c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	return 0;
2529c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
2530c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2531c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2532c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtstatic int wpa_disable_max_amsdu(struct wpa_supplicant *wpa_s,
2533c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				 struct ieee80211_ht_capabilities *htcaps,
2534c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				 struct ieee80211_ht_capabilities *htcaps_mask,
2535c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				 int disabled)
2536c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
2537c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	u16 msk;
2538c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2539c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
2540c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2541c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (disabled == -1)
2542c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return 0;
2543c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2544c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	msk = host_to_le16(HT_CAP_INFO_MAX_AMSDU_SIZE);
2545c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	htcaps_mask->ht_capabilities_info |= msk;
2546c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (disabled)
2547c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		htcaps->ht_capabilities_info &= msk;
2548c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	else
2549c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		htcaps->ht_capabilities_info |= msk;
2550c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2551c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	return 0;
2552c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
2553c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2554c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2555c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtstatic int wpa_set_ampdu_factor(struct wpa_supplicant *wpa_s,
2556c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				struct ieee80211_ht_capabilities *htcaps,
2557c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				struct ieee80211_ht_capabilities *htcaps_mask,
2558c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				int factor)
2559c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
2560c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
2561c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2562c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (factor == -1)
2563c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return 0;
2564c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2565c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (factor < 0 || factor > 3) {
2566c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "ampdu_factor: %d out of range. "
2567c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			"Must be 0-3 or -1", factor);
2568c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return -EINVAL;
2569c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
2570c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2571c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	htcaps_mask->a_mpdu_params |= 0x3; /* 2 bits for factor */
2572c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	htcaps->a_mpdu_params &= ~0x3;
2573c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	htcaps->a_mpdu_params |= factor & 0x3;
2574c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2575c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	return 0;
2576c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
2577c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2578c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2579c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtstatic int wpa_set_ampdu_density(struct wpa_supplicant *wpa_s,
2580c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				 struct ieee80211_ht_capabilities *htcaps,
2581c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				 struct ieee80211_ht_capabilities *htcaps_mask,
2582c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				 int density)
2583c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
2584c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
2585c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2586c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (density == -1)
2587c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return 0;
2588c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2589c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (density < 0 || density > 7) {
2590c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR,
2591c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			"ampdu_density: %d out of range. Must be 0-7 or -1.",
2592c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			density);
2593c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return -EINVAL;
2594c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
2595c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2596c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	htcaps_mask->a_mpdu_params |= 0x1C;
2597c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	htcaps->a_mpdu_params &= ~(0x1C);
2598c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	htcaps->a_mpdu_params |= (density << 2) & 0x1C;
2599c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2600c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	return 0;
2601c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
2602c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2603c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2604c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtstatic int wpa_set_disable_ht40(struct wpa_supplicant *wpa_s,
2605c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				struct ieee80211_ht_capabilities *htcaps,
2606c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				struct ieee80211_ht_capabilities *htcaps_mask,
2607c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				int disabled)
2608c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
2609c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	/* Masking these out disables HT40 */
2610c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	u16 msk = host_to_le16(HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET |
2611c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			       HT_CAP_INFO_SHORT_GI40MHZ);
2612c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2613c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
2614c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2615c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (disabled)
2616c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		htcaps->ht_capabilities_info &= ~msk;
2617c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	else
2618c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		htcaps->ht_capabilities_info |= msk;
2619c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2620c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	htcaps_mask->ht_capabilities_info |= msk;
2621c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2622c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	return 0;
2623c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
2624c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2625c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2626a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidtstatic int wpa_set_disable_sgi(struct wpa_supplicant *wpa_s,
2627a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			       struct ieee80211_ht_capabilities *htcaps,
2628a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			       struct ieee80211_ht_capabilities *htcaps_mask,
2629a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			       int disabled)
2630a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt{
2631a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	/* Masking these out disables SGI */
2632a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	u16 msk = host_to_le16(HT_CAP_INFO_SHORT_GI20MHZ |
2633a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			       HT_CAP_INFO_SHORT_GI40MHZ);
2634a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
2635a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	wpa_msg(wpa_s, MSG_DEBUG, "set_disable_sgi: %d", disabled);
2636a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
2637a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (disabled)
2638a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		htcaps->ht_capabilities_info &= ~msk;
2639a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	else
2640a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		htcaps->ht_capabilities_info |= msk;
2641a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
2642a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	htcaps_mask->ht_capabilities_info |= msk;
2643a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
2644a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	return 0;
2645a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt}
2646a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
2647a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
2648c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtvoid wpa_supplicant_apply_ht_overrides(
2649c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
2650c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	struct wpa_driver_associate_params *params)
2651c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
2652c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	struct ieee80211_ht_capabilities *htcaps;
2653c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	struct ieee80211_ht_capabilities *htcaps_mask;
2654c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2655c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (!ssid)
2656c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return;
2657c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2658c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	params->disable_ht = ssid->disable_ht;
2659c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (!params->htcaps || !params->htcaps_mask)
2660c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return;
2661c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2662c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	htcaps = (struct ieee80211_ht_capabilities *) params->htcaps;
2663c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	htcaps_mask = (struct ieee80211_ht_capabilities *) params->htcaps_mask;
2664c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_set_htcap_mcs(wpa_s, htcaps, htcaps_mask, ssid->ht_mcs);
2665c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_disable_max_amsdu(wpa_s, htcaps, htcaps_mask,
2666c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			      ssid->disable_max_amsdu);
2667c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_set_ampdu_factor(wpa_s, htcaps, htcaps_mask, ssid->ampdu_factor);
2668c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_set_ampdu_density(wpa_s, htcaps, htcaps_mask, ssid->ampdu_density);
2669c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40);
2670a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	wpa_set_disable_sgi(wpa_s, htcaps, htcaps_mask, ssid->disable_sgi);
2671c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
2672c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2673c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#endif /* CONFIG_HT_OVERRIDES */
2674c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2675c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
26762f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt#ifdef CONFIG_VHT_OVERRIDES
26772f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidtvoid wpa_supplicant_apply_vht_overrides(
26782f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
26792f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	struct wpa_driver_associate_params *params)
26802f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt{
26812f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	struct ieee80211_vht_capabilities *vhtcaps;
26822f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	struct ieee80211_vht_capabilities *vhtcaps_mask;
26832f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt
26842f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	if (!ssid)
26852f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt		return;
26862f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt
26872f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	params->disable_vht = ssid->disable_vht;
26882f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt
26892f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	vhtcaps = (void *) params->vhtcaps;
26902f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	vhtcaps_mask = (void *) params->vhtcaps_mask;
26912f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt
26922f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	if (!vhtcaps || !vhtcaps_mask)
26932f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt		return;
26942f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt
26952f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	vhtcaps->vht_capabilities_info = ssid->vht_capa;
26962f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	vhtcaps_mask->vht_capabilities_info = ssid->vht_capa_mask;
26972f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt
26982f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt#define OVERRIDE_MCS(i)							\
26992f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	if (ssid->vht_tx_mcs_nss_ ##i >= 0) {				\
27002f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt		vhtcaps_mask->vht_supported_mcs_set.tx_map |=		\
27012f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt			3 << 2 * (i - 1);				\
27022f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt		vhtcaps->vht_supported_mcs_set.tx_map |=		\
27032f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt			ssid->vht_tx_mcs_nss_ ##i << 2 * (i - 1);	\
27042f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	}								\
27052f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	if (ssid->vht_rx_mcs_nss_ ##i >= 0) {				\
27062f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt		vhtcaps_mask->vht_supported_mcs_set.rx_map |=		\
27072f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt			3 << 2 * (i - 1);				\
27082f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt		vhtcaps->vht_supported_mcs_set.rx_map |=		\
27092f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt			ssid->vht_rx_mcs_nss_ ##i << 2 * (i - 1);	\
27102f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	}
27112f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt
27122f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	OVERRIDE_MCS(1);
27132f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	OVERRIDE_MCS(2);
27142f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	OVERRIDE_MCS(3);
27152f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	OVERRIDE_MCS(4);
27162f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	OVERRIDE_MCS(5);
27172f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	OVERRIDE_MCS(6);
27182f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	OVERRIDE_MCS(7);
27192f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt	OVERRIDE_MCS(8);
27202f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt}
27212f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt#endif /* CONFIG_VHT_OVERRIDES */
27222f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt
27232f023193a0fd630eb82ce6381b80911ad5a3462fDmitry Shmidt
272404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int pcsc_reader_init(struct wpa_supplicant *wpa_s)
272504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
272604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef PCSC_FUNCS
272704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	size_t len;
272804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
272904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!wpa_s->conf->pcsc_reader)
273004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 0;
273104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
273204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->scard = scard_init(SCARD_TRY_BOTH, wpa_s->conf->pcsc_reader);
273304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!wpa_s->scard)
273404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 1;
273504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
273604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->conf->pcsc_pin &&
273704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	    scard_set_pin(wpa_s->scard, wpa_s->conf->pcsc_pin) < 0) {
273804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		scard_deinit(wpa_s->scard);
273904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->scard = NULL;
274004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "PC/SC PIN validation failed");
274104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
274204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
274304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
274404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	len = sizeof(wpa_s->imsi) - 1;
274504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
274604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		scard_deinit(wpa_s->scard);
274704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->scard = NULL;
274804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
274904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
275004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
275104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->imsi[len] = '\0';
275204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
275304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
275404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
275504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
275604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		   wpa_s->imsi, wpa_s->mnc_len);
275704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
275804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
275904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
276004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* PCSC_FUNCS */
276104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
276204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return 0;
276304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
276404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
276504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
276661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
276761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
276861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	char *val, *pos;
276961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
277061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	ext_password_deinit(wpa_s->ext_pw);
277161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_s->ext_pw = NULL;
277261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	eapol_sm_set_ext_pw_ctx(wpa_s->eapol, NULL);
277361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
277461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (!wpa_s->conf->ext_password_backend)
277561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return 0;
277661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
277761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	val = os_strdup(wpa_s->conf->ext_password_backend);
277861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (val == NULL)
277961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
278061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos = os_strchr(val, ':');
278161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (pos)
278261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		*pos++ = '\0';
278361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
278461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_printf(MSG_DEBUG, "EXT PW: Initialize backend '%s'", val);
278561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
278661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_s->ext_pw = ext_password_init(val, pos);
278761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_free(val);
278861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (wpa_s->ext_pw == NULL) {
278961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_printf(MSG_DEBUG, "EXT PW: Failed to initialize backend");
279061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
279161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
279261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	eapol_sm_set_ext_pw_ctx(wpa_s->eapol, wpa_s->ext_pw);
279361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
279461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return 0;
279561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
279661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
279761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
27988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
27998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     struct wpa_interface *iface)
28008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
28018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *ifname, *driver;
28028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_driver_capa capa;
28038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
28058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
28068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   iface->confname ? iface->confname : "N/A",
28078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   iface->driver ? iface->driver : "default",
28088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   iface->ctrl_interface ? iface->ctrl_interface : "N/A",
28098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   iface->bridge_ifname ? iface->bridge_ifname : "N/A");
28108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (iface->confname) {
28128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_BACKEND_FILE
28138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->confname = os_rel2abs_path(iface->confname);
28148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->confname == NULL) {
28158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Failed to get absolute path "
28168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "for configuration file '%s'.",
28178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   iface->confname);
28188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
28198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
28208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",
28218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   iface->confname, wpa_s->confname);
28228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_BACKEND_FILE */
28238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->confname = os_strdup(iface->confname);
28248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_BACKEND_FILE */
28258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->conf = wpa_config_read(wpa_s->confname);
28268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->conf == NULL) {
28278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Failed to read or parse "
28288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "configuration '%s'.", wpa_s->confname);
28298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
28308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
28318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
28338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * Override ctrl_interface and driver_param if set on command
28348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * line.
28358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
28368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (iface->ctrl_interface) {
28378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(wpa_s->conf->ctrl_interface);
28388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->conf->ctrl_interface =
28398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				os_strdup(iface->ctrl_interface);
28408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
28418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (iface->driver_param) {
28438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(wpa_s->conf->driver_param);
28448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->conf->driver_param =
28458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				os_strdup(iface->driver_param);
28468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
28478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else
28488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
28498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						     iface->driver_param);
28508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf == NULL) {
28528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "\nNo configuration found.");
28538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
28548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
28558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (iface->ifname == NULL) {
28578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "\nInterface name is required.");
28588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
28598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
28608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
28618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "\nToo long interface name '%s'.",
28628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   iface->ifname);
28638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
28648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
28658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
28668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (iface->bridge_ifname) {
28688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strlen(iface->bridge_ifname) >=
28698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    sizeof(wpa_s->bridge_ifname)) {
28708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "\nToo long bridge interface "
28718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "name '%s'.", iface->bridge_ifname);
28728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
28738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
28748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_strlcpy(wpa_s->bridge_ifname, iface->bridge_ifname,
28758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   sizeof(wpa_s->bridge_ifname));
28768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
28778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* RSNA Supplicant Key Management - INITIALIZE */
28798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
28808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
28818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Initialize driver interface and register driver event handler before
28838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * L2 receive handler so that association events are processed before
28848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * EAPOL-Key packets if both become available for the same select()
28858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * call. */
28868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	driver = iface->driver;
28878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtnext_driver:
28888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_supplicant_set_driver(wpa_s, driver) < 0)
28898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
28908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
28928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->drv_priv == NULL) {
28938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		const char *pos;
28948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = driver ? os_strchr(driver, ',') : NULL;
28958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos) {
28968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
28978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"driver interface - try next driver wrapper");
28988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			driver = pos + 1;
28998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto next_driver;
29008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
29018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Failed to initialize driver "
29028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"interface");
29038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
29048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
29058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
29068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected "
29078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"driver_param '%s'", wpa_s->conf->driver_param);
29088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
29098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
29108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ifname = wpa_drv_get_ifname(wpa_s);
29128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
29138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced "
29148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"interface name with '%s'", ifname);
29158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
29168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
29178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_supplicant_init_wpa(wpa_s) < 0)
29198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
29208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
29228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
29238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  NULL);
29248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
29258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
29278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
29288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
29298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
29308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"dot11RSNAConfigPMKLifetime");
29318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
29328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
29338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
29358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
29368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
29378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
29388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"dot11RSNAConfigPMKReauthThreshold");
29398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
29408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
29418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->dot11RSNAConfigSATimeout &&
29438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
29448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     wpa_s->conf->dot11RSNAConfigSATimeout)) {
29458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
29468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"dot11RSNAConfigSATimeout");
29478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
29488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
29498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
29511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						      &wpa_s->hw.num_modes,
29521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						      &wpa_s->hw.flags);
29531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
29548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_drv_get_capa(wpa_s, &capa) == 0) {
29551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_s->drv_capa_known = 1;
29568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->drv_flags = capa.flags;
295704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->drv_enc = capa.enc;
29581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
29598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->max_scan_ssids = capa.max_scan_ssids;
29601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
29611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_s->sched_scan_supported = capa.sched_scan_supported;
29621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_s->max_match_sets = capa.max_match_sets;
29638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
29648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->max_stations = capa.max_stations;
2965444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		wpa_s->extended_capa = capa.extended_capa;
2966444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		wpa_s->extended_capa_mask = capa.extended_capa_mask;
2967444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt		wpa_s->extended_capa_len = capa.extended_capa_len;
29688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
29698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->max_remain_on_chan == 0)
29708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->max_remain_on_chan = 1000;
29718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_supplicant_driver_init(wpa_s) < 0)
29738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
29748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TDLS
29768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_tdls_init(wpa_s->wpa))
29778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
29788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TDLS */
29798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
29818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
29828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Failed to set country");
29838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
29848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
29858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpas_wps_init(wpa_s))
29878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
29888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_supplicant_init_eapol(wpa_s) < 0)
29908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
29918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
29928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
29948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ctrl_iface == NULL) {
29958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR,
29968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "Failed to initialize control interface '%s'.\n"
29978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "You may have another wpa_supplicant process "
29988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "already running or the file was\n"
29998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "left by an unclean termination of wpa_supplicant "
30008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "in which case you will need\n"
30018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "to manually remove this file before starting "
30028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "wpa_supplicant again.\n",
30038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   wpa_s->conf->ctrl_interface);
30048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
30058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
30068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_s->gas = gas_query_init(wpa_s);
30081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->gas == NULL) {
30091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_printf(MSG_ERROR, "Failed to initialize GAS query");
30101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
30111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
30121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
30138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
30148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
30158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
30168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
30178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
30188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
30198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_bss_init(wpa_s) < 0)
30218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
30228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
302304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (pcsc_reader_init(wpa_s) < 0)
302404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
302504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
302661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (wpas_init_ext_pw(wpa_s) < 0)
302761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
302861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
30298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
30308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
30318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
3034e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt					int notify, int terminate)
30358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
30368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->drv_priv) {
30378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_deauthenticate(wpa_s,
30388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      WLAN_REASON_DEAUTH_LEAVING);
30398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_set_countermeasures(wpa_s, 0);
30418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_clear_keys(wpa_s, NULL);
30428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
30438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_cleanup(wpa_s);
30458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
304604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_P2P
304704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s == wpa_s->global->p2p_init_wpa_s && wpa_s->global->p2p) {
304804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Disable P2P since removing "
304904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			"the management interface is being removed");
305004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpas_p2p_deinit_global(wpa_s->global);
305104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
305204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_P2P */
305304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
30548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->drv_priv)
30558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_deinit(wpa_s);
3056622b66d6efd0cccfeb8623184fadf2f76e7e8206Irfan Sheriff
3057e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt	if (notify)
3058e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt		wpas_notify_iface_removed(wpa_s);
3059e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt
3060e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt	if (terminate)
3061e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
3062622b66d6efd0cccfeb8623184fadf2f76e7e8206Irfan Sheriff
3063622b66d6efd0cccfeb8623184fadf2f76e7e8206Irfan Sheriff	if (wpa_s->ctrl_iface) {
3064622b66d6efd0cccfeb8623184fadf2f76e7e8206Irfan Sheriff		wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
3065622b66d6efd0cccfeb8623184fadf2f76e7e8206Irfan Sheriff		wpa_s->ctrl_iface = NULL;
3066622b66d6efd0cccfeb8623184fadf2f76e7e8206Irfan Sheriff	}
3067622b66d6efd0cccfeb8623184fadf2f76e7e8206Irfan Sheriff
3068622b66d6efd0cccfeb8623184fadf2f76e7e8206Irfan Sheriff	if (wpa_s->conf != NULL) {
3069622b66d6efd0cccfeb8623184fadf2f76e7e8206Irfan Sheriff		wpa_config_free(wpa_s->conf);
3070622b66d6efd0cccfeb8623184fadf2f76e7e8206Irfan Sheriff		wpa_s->conf = NULL;
3071622b66d6efd0cccfeb8623184fadf2f76e7e8206Irfan Sheriff	}
30728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
30738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
30768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_add_iface - Add a new network interface
30778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: Pointer to global data from wpa_supplicant_init()
30788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @iface: Interface configuration options
30798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the created interface or %NULL on failure
30808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
30818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to add new network interfaces for %wpa_supplicant.
30828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This can be called before wpa_supplicant_run() to add interfaces before the
30838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * main event loop has been started. In addition, new interfaces can be added
30848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * dynamically while %wpa_supplicant is already running. This could happen,
30858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * e.g., when a hotplug network adapter is inserted.
30868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
30878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
30888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 struct wpa_interface *iface)
30898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
30908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s;
30918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_interface t_iface;
30928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
30938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global == NULL || iface == NULL)
30958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
30968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s = wpa_supplicant_alloc();
30988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s == NULL)
30998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
31008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->global = global;
31028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	t_iface = *iface;
31048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->params.override_driver) {
31058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "Override interface parameter: driver "
31068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "('%s' -> '%s')",
31078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   iface->driver, global->params.override_driver);
31088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		t_iface.driver = global->params.override_driver;
31098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
31108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->params.override_ctrl_interface) {
31118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "Override interface parameter: "
31128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "ctrl_interface ('%s' -> '%s')",
31138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   iface->ctrl_interface,
31148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   global->params.override_ctrl_interface);
31158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		t_iface.ctrl_interface =
31168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			global->params.override_ctrl_interface;
31178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
31188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
31198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "Failed to add interface %s",
31208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   iface->ifname);
3121e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt		wpa_supplicant_deinit_iface(wpa_s, 0, 0);
31228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(wpa_s);
31238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
31248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
31258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Notify the control interfaces about new iface */
31278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpas_notify_iface_added(wpa_s)) {
3128e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt		wpa_supplicant_deinit_iface(wpa_s, 1, 0);
31298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(wpa_s);
31308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
31318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
31328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
31348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_network_added(wpa_s, ssid);
31358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->next = global->ifaces;
31378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	global->ifaces = wpa_s;
31388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
314004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
31418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpa_s;
31438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
31448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
31478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_remove_iface - Remove a network interface
31488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: Pointer to global data from wpa_supplicant_init()
31498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to the network interface to be removed
31508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 if interface was removed, -1 if interface was not found
31518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
31528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to dynamically remove network interfaces from
31538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In
31548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * addition, this function is used to remove all remaining interfaces when
31558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * %wpa_supplicant is terminated.
31568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
31578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_remove_iface(struct wpa_global *global,
3158e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt				struct wpa_supplicant *wpa_s,
3159e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt				int terminate)
31608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
31618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *prev;
31628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Remove interface from the global list of interfaces */
31648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	prev = global->ifaces;
31658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (prev == wpa_s) {
31668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		global->ifaces = wpa_s->next;
31678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
31688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (prev && prev->next != wpa_s)
31698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			prev = prev->next;
31708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (prev == NULL)
31718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
31728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		prev->next = wpa_s->next;
31738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
31748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
31768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->p2p_group_formation == wpa_s)
31788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		global->p2p_group_formation = NULL;
3179700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt	if (global->p2p_invite_group == wpa_s)
3180700a137ab366edc72e371da68ba187b4717ee660Dmitry Shmidt		global->p2p_invite_group = NULL;
3181e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt	wpa_supplicant_deinit_iface(wpa_s, 1, terminate);
31828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(wpa_s);
31838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
31858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
31868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
31898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_get_eap_mode - Get the current EAP mode
31908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to the network interface
31918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the eap mode or the string "UNKNOWN" if not found
31928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
31938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s)
31948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
31958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *eapol_method;
31968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) == 0 &&
31988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
31998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "NO-EAP";
32008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
32018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_method = eapol_sm_get_method_name(wpa_s->eapol);
32038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (eapol_method == NULL)
32048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "UNKNOWN-EAP";
32058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return eapol_method;
32078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
32088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
32118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_get_iface - Get a new network interface
32128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: Pointer to global data from wpa_supplicant_init()
32138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ifname: Interface name
32148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the interface or %NULL if not found
32158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
32168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
32178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 const char *ifname)
32188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
32198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s;
32208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
32228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strcmp(wpa_s->ifname, ifname) == 0)
32238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return wpa_s;
32248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
32258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return NULL;
32268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
32278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_WPA_MSG
32308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * wpa_supplicant_msg_ifname_cb(void *ctx)
32318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
32328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
32338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s == NULL)
32348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
32358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpa_s->ifname;
32368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
32378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_WPA_MSG */
32388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
32418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_init - Initialize %wpa_supplicant
32428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @params: Parameters for %wpa_supplicant
32438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to global %wpa_supplicant data, or %NULL on failure
32448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
32458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to initialize %wpa_supplicant. After successful
32468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * initialization, the returned data pointer can be used to add and remove
32478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * network interfaces, and eventually, to deinitialize %wpa_supplicant.
32488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
32498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_global * wpa_supplicant_init(struct wpa_params *params)
32508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
32518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_global *global;
32528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret, i;
32538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (params == NULL)
32558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
32568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_DRIVER_NDIS
32581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	{
32591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		void driver_ndis_init_ops(void);
32601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		driver_ndis_init_ops();
32611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
32621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_DRIVER_NDIS */
32631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
32648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_WPA_MSG
32658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
32668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_WPA_MSG */
32678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_debug_open_file(params->wpa_debug_file_path);
32698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (params->wpa_debug_syslog)
32708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_debug_open_syslog();
327104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (params->wpa_debug_tracing) {
327204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		ret = wpa_debug_open_linux_tracing();
327304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (ret) {
327404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_printf(MSG_ERROR,
327504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   "Failed to enable trace logging");
327604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return NULL;
327704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
327804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
32798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = eap_register_methods();
32818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret) {
32828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Failed to register EAP methods");
32838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret == -2)
32848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Two or more EAP methods used "
32858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "the same EAP type.");
32868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
32878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
32888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	global = os_zalloc(sizeof(*global));
32908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global == NULL)
32918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
32928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dl_list_init(&global->p2p_srv_bonjour);
32938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dl_list_init(&global->p2p_srv_upnp);
32948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	global->params.daemonize = params->daemonize;
32958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	global->params.wait_for_monitor = params->wait_for_monitor;
32968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
32978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (params->pid_file)
32988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		global->params.pid_file = os_strdup(params->pid_file);
32998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (params->ctrl_interface)
33008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		global->params.ctrl_interface =
33018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_strdup(params->ctrl_interface);
33028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (params->override_driver)
33038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		global->params.override_driver =
33048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_strdup(params->override_driver);
33058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (params->override_ctrl_interface)
33068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		global->params.override_ctrl_interface =
33078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_strdup(params->override_ctrl_interface);
33088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_debug_level = global->params.wpa_debug_level =
33098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params->wpa_debug_level;
33108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_debug_show_keys = global->params.wpa_debug_show_keys =
33118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params->wpa_debug_show_keys;
33128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_debug_timestamp = global->params.wpa_debug_timestamp =
33138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params->wpa_debug_timestamp;
33148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "wpa_supplicant v" VERSION_STR);
33168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (eloop_init()) {
33188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Failed to initialize event loop");
33198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_deinit(global);
33208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
33218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
33228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
332375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	random_init(params->entropy_file);
33248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
33268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->ctrl_iface == NULL) {
33278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_deinit(global);
33288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
33298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
33308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpas_notify_supplicant_initialized(global)) {
33328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_deinit(global);
33338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
33348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
33358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; wpa_drivers[i]; i++)
33378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		global->drv_count++;
33388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->drv_count == 0) {
33398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "No drivers enabled");
33408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_deinit(global);
33418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
33428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
33438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	global->drv_priv = os_zalloc(global->drv_count * sizeof(void *));
33448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->drv_priv == NULL) {
33458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_deinit(global);
33468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
33478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
33488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
334961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY
335061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (wifi_display_init(global) < 0) {
335161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_printf(MSG_ERROR, "Failed to initialize Wi-Fi Display");
335261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_supplicant_deinit(global);
335361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return NULL;
335461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
335561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */
335661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
33578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return global;
33588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
33598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
33628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_run - Run the %wpa_supplicant main event loop
33638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: Pointer to global data from wpa_supplicant_init()
33648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 after successful event loop run, -1 on failure
33658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
33668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function starts the main event loop and continues running as long as
33678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * there are any remaining events. In most cases, this function is running as
33688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * long as the %wpa_supplicant process in still in use.
33698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
33708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_run(struct wpa_global *global)
33718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
33728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s;
33738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->params.daemonize &&
33758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_supplicant_daemon(global->params.pid_file))
33768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
33778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->params.wait_for_monitor) {
33798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
33808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (wpa_s->ctrl_iface)
33818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_supplicant_ctrl_iface_wait(
33828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					wpa_s->ctrl_iface);
33838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
33848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_register_signal_terminate(wpa_supplicant_terminate, global);
33868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
33878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_run();
33898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
33918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
33928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
33958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_deinit - Deinitialize %wpa_supplicant
33968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: Pointer to global data from wpa_supplicant_init()
33978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
33988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called to deinitialize %wpa_supplicant and to free all
33998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * allocated resources. Remaining network interfaces will also be removed.
34008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
34018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_deinit(struct wpa_global *global)
34028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
34038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
34048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global == NULL)
34068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
34071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
340861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY
340961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wifi_display_deinit(global);
341061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */
34118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
34128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_p2p_deinit_global(global);
34138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
34148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (global->ifaces)
3416e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt		wpa_supplicant_remove_iface(global, global->ifaces, 1);
34178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->ctrl_iface)
34198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_global_ctrl_iface_deinit(global->ctrl_iface);
34208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_notify_supplicant_deinitialized(global);
34228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eap_peer_unregister_methods();
34248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
34258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eap_server_unregister_methods();
34268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
34278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
34298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!global->drv_priv[i])
34308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
34318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drivers[i]->global_deinit(global->drv_priv[i]);
34328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
34338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(global->drv_priv);
34348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	random_deinit();
34368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_destroy();
34388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->params.pid_file) {
34408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_daemonize_terminate(global->params.pid_file);
34418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(global->params.pid_file);
34428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
34438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(global->params.ctrl_interface);
34448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(global->params.override_driver);
34458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(global->params.override_ctrl_interface);
34468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
344704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	os_free(global->p2p_disallow_freq);
344804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
34498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(global);
34508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_debug_close_syslog();
34518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_debug_close_file();
345204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_debug_close_linux_tracing();
34538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
34548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
34578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
34588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
34598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
34608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		char country[3];
34618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		country[0] = wpa_s->conf->country[0];
34628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		country[1] = wpa_s->conf->country[1];
34638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		country[2] = '\0';
34648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_drv_set_country(wpa_s, country) < 0) {
34658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Failed to set country code "
34668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "'%s'", country);
34678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
34688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
34698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
347061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (wpa_s->conf->changed_parameters & CFG_CHANGED_EXT_PW_BACKEND)
347161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpas_init_ext_pw(wpa_s);
347261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
34738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
34748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_wps_update_config(wpa_s);
34758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
34768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
34788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_p2p_update_config(wpa_s);
34798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
34808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->conf->changed_parameters = 0;
34828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
34838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void add_freq(int *freqs, int *num_freqs, int freq)
34868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
34878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
34888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < *num_freqs; i++) {
34908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (freqs[i] == freq)
34918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return;
34928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
34938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	freqs[*num_freqs] = freq;
34958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	(*num_freqs)++;
34968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
34978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s)
35008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
35018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_bss *bss, *cbss;
35028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const int max_freqs = 10;
35038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int *freqs;
35048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int num_freqs = 0;
35058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	freqs = os_zalloc(sizeof(int) * (max_freqs + 1));
35078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (freqs == NULL)
35088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
35098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cbss = wpa_s->current_bss;
35118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
35138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (bss == cbss)
35148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
35158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (bss->ssid_len == cbss->ssid_len &&
35168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
35178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    wpa_blacklist_get(wpa_s, bss->bssid) == NULL) {
35188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			add_freq(freqs, &num_freqs, bss->freq);
35198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (num_freqs == max_freqs)
35208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
35218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
35228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
35238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (num_freqs == 0) {
35258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(freqs);
35268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		freqs = NULL;
35278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
35288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return freqs;
35308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
35318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
35348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
35358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int timeout;
35368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int count;
35378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int *freqs = NULL;
35388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
35398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
3540c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	 * Remove possible authentication timeout since the connection failed.
3541c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	 */
3542c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
3543c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
3544c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	/*
35458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * Add the failed BSSID into the blacklist and speed up next scan
35468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * attempt if there could be other APs that could accept association.
35478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * The current blacklist count indicates how many times we have tried
35488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * connecting to this AP and multiple attempts mean that other APs are
35498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * either not available or has already been tried, so that we can start
35508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * increasing the delay here to avoid constant scanning.
35518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
35528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	count = wpa_blacklist_add(wpa_s, bssid);
35538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (count == 1 && wpa_s->current_bss) {
35548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
35558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * This BSS was not in the blacklist before. If there is
35568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * another BSS available for the same ESS, we should try that
35578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * next. Otherwise, we may as well try this one once more
35588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * before allowing other, likely worse, ESSes to be considered.
35598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
35608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		freqs = get_bss_freqs_in_ess(wpa_s);
35618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (freqs) {
35628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
35638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"has been seen; try it next");
35648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_blacklist_add(wpa_s, bssid);
35658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/*
35668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * On the next scan, go through only the known channels
35678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * used in this ESS based on previous scans to speed up
35688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * common load balancing use case.
35698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 */
35708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(wpa_s->next_scan_freqs);
35718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->next_scan_freqs = freqs;
35728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
35738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
35748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3575d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	/*
3576d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	 * Add previous failure count in case the temporary blacklist was
3577d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	 * cleared due to no other BSSes being available.
3578d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	 */
3579d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	count += wpa_s->extra_blacklist_count;
3580d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
35818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (count) {
35828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 1:
35838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		timeout = 100;
35848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
35858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 2:
35868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		timeout = 500;
35878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
35888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 3:
35898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		timeout = 1000;
35908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
3591d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	case 4:
35928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		timeout = 5000;
3593d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		break;
3594d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	default:
3595d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		timeout = 10000;
3596d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		break;
35978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
35988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3599d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Blacklist count %d --> request scan in %d "
3600d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		"ms", count, timeout);
3601d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
36028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
36038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * TODO: if more than one possible AP is available in scan results,
36048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * could try the other ones before requesting a new scan.
36058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
36068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_req_scan(wpa_s, timeout / 1000,
36078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				1000 * (timeout % 1000));
360861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
360937d4d6a4efea4ef4f864347ac8ed8d62a9e19f90Dmitry Shmidt	wpas_p2p_continue_after_scan(wpa_s);
36108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
36111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
36121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
36131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
36141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
36151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return wpa_s->conf->ap_scan == 2 ||
36161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		(wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
36171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
3618c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
361904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
362004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
362104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
362204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					      struct wpa_ssid *ssid,
362304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					      const char *field,
362404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					      const char *value)
362504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
362604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef IEEE8021X_EAPOL
362704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct eap_peer_config *eap = &ssid->eap;
362804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
362904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
363004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
363104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			      (const u8 *) value, os_strlen(value));
363204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
363304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	switch (wpa_supplicant_ctrl_req_from_string(field)) {
363404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case WPA_CTRL_REQ_EAP_IDENTITY:
363504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_free(eap->identity);
363604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->identity = (u8 *) os_strdup(value);
363704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->identity_len = os_strlen(value);
363804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->pending_req_identity = 0;
363904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (ssid == wpa_s->current_ssid)
364004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s->reassociate = 1;
364104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		break;
364204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case WPA_CTRL_REQ_EAP_PASSWORD:
364304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_free(eap->password);
364404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->password = (u8 *) os_strdup(value);
364504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->password_len = os_strlen(value);
364604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->pending_req_password = 0;
364704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (ssid == wpa_s->current_ssid)
364804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s->reassociate = 1;
364904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		break;
365004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
365104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_free(eap->new_password);
365204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->new_password = (u8 *) os_strdup(value);
365304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->new_password_len = os_strlen(value);
365404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->pending_req_new_password = 0;
365504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (ssid == wpa_s->current_ssid)
365604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s->reassociate = 1;
365704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		break;
365804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case WPA_CTRL_REQ_EAP_PIN:
365904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_free(eap->pin);
366004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->pin = os_strdup(value);
366104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->pending_req_pin = 0;
366204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (ssid == wpa_s->current_ssid)
366304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s->reassociate = 1;
366404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		break;
366504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case WPA_CTRL_REQ_EAP_OTP:
366604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_free(eap->otp);
366704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->otp = (u8 *) os_strdup(value);
366804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->otp_len = os_strlen(value);
366904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_free(eap->pending_req_otp);
367004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->pending_req_otp = NULL;
367104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->pending_req_otp_len = 0;
367204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		break;
367304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case WPA_CTRL_REQ_EAP_PASSPHRASE:
367404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_free(eap->private_key_passwd);
367504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->private_key_passwd = (u8 *) os_strdup(value);
367604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->pending_req_passphrase = 0;
367704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (ssid == wpa_s->current_ssid)
367804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s->reassociate = 1;
367904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		break;
368004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	default:
368104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
368204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
368304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
368404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
368504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return 0;
368604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#else /* IEEE8021X_EAPOL */
368704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
368804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return -1;
368904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* IEEE8021X_EAPOL */
369004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
369104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
369204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
369304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
369404949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
369504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
369604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int i;
369704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	unsigned int drv_enc;
369804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
369904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (ssid == NULL)
370004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 1;
370104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
370204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (ssid->disabled)
370304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 1;
370404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
370504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s && wpa_s->drv_capa_known)
370604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		drv_enc = wpa_s->drv_enc;
370704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	else
370804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		drv_enc = (unsigned int) -1;
370904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
371004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	for (i = 0; i < NUM_WEP_KEYS; i++) {
371104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		size_t len = ssid->wep_key_len[i];
371204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (len == 0)
371304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			continue;
371404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (len == 5 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40))
371504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			continue;
371604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (len == 13 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104))
371704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			continue;
371804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (len == 16 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP128))
371904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			continue;
372004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 1; /* invalid WEP key */
372104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
372204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
372361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
372461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	    !ssid->ext_psk)
372561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return 1;
372661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
372704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return 0;
372804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
372904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
373004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
3731687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidtint wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
3732c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
37332fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt	if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
3734c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return 1;
37352fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt	if (wpa_s->global->conc_pref == WPA_CONC_PREF_STA)
3736687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt		return 0;
3737687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt	return -1;
3738c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
373961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
374061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
374161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid wpas_auth_failed(struct wpa_supplicant *wpa_s)
374261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
374361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	struct wpa_ssid *ssid = wpa_s->current_ssid;
374461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	int dur;
374561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	struct os_time now;
374661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
374761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (ssid == NULL) {
374861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_printf(MSG_DEBUG, "Authentication failure but no known "
374961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			   "SSID block");
375061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return;
375161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
375261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
375361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
375461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return;
375561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
375661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	ssid->auth_failures++;
375761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (ssid->auth_failures > 50)
375861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		dur = 300;
375961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	else if (ssid->auth_failures > 20)
376061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		dur = 120;
376161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	else if (ssid->auth_failures > 10)
376261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		dur = 60;
376361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	else if (ssid->auth_failures > 5)
376461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		dur = 30;
376561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	else if (ssid->auth_failures > 1)
376661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		dur = 20;
376761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	else
376861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		dur = 10;
376961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
377061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_get_time(&now);
377161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (now.sec + dur <= ssid->disabled_until.sec)
377261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return;
377361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
377461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	ssid->disabled_until.sec = now.sec + dur;
377561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
377661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TEMP_DISABLED
377761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		"id=%d ssid=\"%s\" auth_failures=%u duration=%d",
377861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
377961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		ssid->auth_failures, dur);
378061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
378161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
378261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
378361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
378461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			      struct wpa_ssid *ssid, int clear_failures)
378561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
378661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (ssid == NULL)
378761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return;
378861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
378961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (ssid->disabled_until.sec) {
379061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REENABLED
379161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			"id=%d ssid=\"%s\"",
379261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
379361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
379461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	ssid->disabled_until.sec = 0;
379561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	ssid->disabled_until.usec = 0;
379661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (clear_failures)
379761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		ssid->auth_failures = 0;
379861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
3799d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
3800d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
3801d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtint disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid)
3802d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{
3803d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	size_t i;
3804d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
3805d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (wpa_s->disallow_aps_bssid == NULL)
3806d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		return 0;
3807d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
3808d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	for (i = 0; i < wpa_s->disallow_aps_bssid_count; i++) {
3809d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		if (os_memcmp(wpa_s->disallow_aps_bssid + i * ETH_ALEN,
3810d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			      bssid, ETH_ALEN) == 0)
3811d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			return 1;
3812d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	}
3813d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
3814d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	return 0;
3815d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt}
3816d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
3817d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
3818d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtint disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
3819d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		    size_t ssid_len)
3820d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{
3821d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	size_t i;
3822d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
3823d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (wpa_s->disallow_aps_ssid == NULL || ssid == NULL)
3824d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		return 0;
3825d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
3826d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	for (i = 0; i < wpa_s->disallow_aps_ssid_count; i++) {
3827d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		struct wpa_ssid_value *s = &wpa_s->disallow_aps_ssid[i];
3828d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		if (ssid_len == s->ssid_len &&
3829d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		    os_memcmp(ssid, s->ssid, ssid_len) == 0)
3830d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			return 1;
3831d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	}
3832d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
3833d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	return 0;
3834d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt}
3835d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
3836d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt
3837d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt/**
3838d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * wpas_request_connection - Request a new connection
3839d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * @wpa_s: Pointer to the network interface
3840d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt *
3841d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * This function is used to request a new connection to be found. It will mark
3842d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * the interface to allow reassociation and request a new scan to find a
3843d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt * suitable network to connect to.
3844d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt */
3845d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidtvoid wpas_request_connection(struct wpa_supplicant *wpa_s)
3846d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt{
3847d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	wpa_s->normal_scans = 0;
3848d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	wpa_supplicant_reinit_autoscan(wpa_s);
3849d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	wpa_s->extra_blacklist_count = 0;
3850d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	wpa_s->disconnected = 0;
3851d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	wpa_s->reassociate = 1;
38522f3b8dec59373945c5feef8a78ced8967a80cc66Dmitry Shmidt
38532f3b8dec59373945c5feef8a78ced8967a80cc66Dmitry Shmidt	if (wpa_supplicant_fast_associate(wpa_s) != 1)
38542f3b8dec59373945c5feef8a78ced8967a80cc66Dmitry Shmidt		wpa_supplicant_req_scan(wpa_s, 0, 0);
3855d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt}
3856