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"
55c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt"Copyright (c) 2003-2012, 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);
1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_disassociate(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
20261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_P2P
203dc7b71324df9788e194745e8ab9386a4619a623aJouni Malinen	if (wpa_s->global->p2p_cb_on_scan_complete && !wpa_s->global->p2p_disabled &&
20461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	    wpa_s->global->p2p != NULL) {
205dc7b71324df9788e194745e8ab9386a4619a623aJouni Malinen		wpa_s->global->p2p_cb_on_scan_complete = 0;
20661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (p2p_other_scan_completed(wpa_s->global->p2p) == 1) {
20761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Pending P2P operation "
20861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				"continued after timed out authentication");
20961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		}
21061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
21161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_P2P */
2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_req_auth_timeout - Schedule a timeout for authentication
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sec: Number of seconds after which to time out authentication
2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @usec: Number of microseconds after which to time out authentication
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to schedule a timeout for the current authentication
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * attempt.
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s,
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     int sec, int usec)
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf && wpa_s->conf->ap_scan == 0 &&
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED))
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Setting authentication timeout: %d sec "
2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"%d usec", sec, usec);
2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_register_timeout(sec, usec, wpa_supplicant_timeout, wpa_s, NULL);
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_cancel_auth_timeout - Cancel authentication timeout
2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to cancel authentication timeout scheduled with
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_req_auth_timeout() and it is called when authentication has
2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * been completed.
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *wpa_s)
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling authentication timeout");
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_blacklist_del(wpa_s, wpa_s->bssid);
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_initiate_eapol - Configure EAPOL state machine
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to configure EAPOL state machine based on the selected
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authentication mode.
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL
2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct eapol_config eapol_conf;
2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid = wpa_s->current_ssid;
2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IBSS_RSN
2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->mode == WPAS_MODE_IBSS &&
2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * RSN IBSS authentication is per-STA and we can disable the
2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * per-BSSID EAPOL authentication.
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IBSS_RSN */
2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_portControl(wpa_s->eapol, Auto);
2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&eapol_conf, 0, sizeof(eapol_conf));
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_conf.accept_802_1x_keys = 1;
2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_conf.required_keys = 0;
2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_UNICAST) {
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eapol_conf.required_keys |= EAPOL_REQUIRE_KEY_UNICAST;
2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_BROADCAST) {
2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eapol_conf.required_keys |=
3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				EAPOL_REQUIRE_KEY_BROADCAST;
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->conf && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED))
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eapol_conf.required_keys = 0;
3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf)
3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_conf.workaround = ssid->eap_workaround;
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_conf.eap_disabled =
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		!wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) &&
3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt != WPA_KEY_MGMT_WPS;
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */
3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_set_non_wpa_policy - Set WPA parameters to non-WPA mode
3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid: Configuration data for the network
3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to configure WPA state machine and related parameters
3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to a mode where WPA is not enabled. This is called as part of the
3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * authentication configuration when the selected network does not use WPA.
3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       struct wpa_ssid *ssid)
3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_WPS;
3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)
3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_NO_WPA;
3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->group_cipher = WPA_CIPHER_NONE;
3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->mgmt_group_cipher = 0;
3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < NUM_WEP_KEYS; i++) {
3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->wep_key_len[i] > 5) {
3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->pairwise_cipher = WPA_CIPHER_WEP104;
3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->group_cipher = WPA_CIPHER_WEP104;
3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (ssid->wep_key_len[i] > 0) {
3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->pairwise_cipher = WPA_CIPHER_WEP40;
3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->group_cipher = WPA_CIPHER_WEP40;
3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			break;
3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED, 0);
3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 wpa_s->pairwise_cipher);
3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 wpa_s->mgmt_group_cipher);
3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pmksa_cache_clear_current(wpa_s->wpa);
3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
37104949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid free_hw_features(struct wpa_supplicant *wpa_s)
3721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
3731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int i;
3741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->hw.modes == NULL)
3751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return;
3761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	for (i = 0; i < wpa_s->hw.num_modes; i++) {
3781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		os_free(wpa_s->hw.modes[i].channels);
3791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		os_free(wpa_s->hw.modes[i].rates);
3801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
3811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	os_free(wpa_s->hw.modes);
3831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_s->hw.modes = NULL;
3841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
3851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bgscan_deinit(wpa_s);
39004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	autoscan_deinit(wpa_s);
3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	scard_deinit(wpa_s->scard);
3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->scard = NULL;
3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_scard_ctx(wpa_s->wpa, NULL);
3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_register_scard_ctx(wpa_s->eapol, NULL);
3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	l2_packet_deinit(wpa_s->l2);
3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->l2 = NULL;
3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->l2_br) {
3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		l2_packet_deinit(wpa_s->l2_br);
3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->l2_br = NULL;
4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf != NULL) {
4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpa_ssid *ssid;
4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_notify_network_removed(wpa_s, ssid);
4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(wpa_s->confname);
4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->confname = NULL;
4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_eapol(wpa_s->wpa, NULL);
4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_deinit(wpa_s->eapol);
4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->eapol = NULL;
4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	rsn_preauth_deinit(wpa_s->wpa);
4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TDLS
4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_tdls_deinit(wpa_s->wpa);
4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TDLS */
4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pmksa_candidate_free(wpa_s->wpa);
4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_deinit(wpa_s->wpa);
4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->wpa = NULL;
4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_blacklist_clear(wpa_s);
4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_bss_deinit(wpa_s);
4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_cancel_scan(wpa_s);
4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_cancel_auth_timeout(wpa_s);
4301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	eloop_cancel_timeout(wpa_supplicant_stop_countermeasures, wpa_s, NULL);
4311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
4321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	eloop_cancel_timeout(wpa_supplicant_delayed_mic_error_report,
4331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			     wpa_s, NULL);
4341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_wps_deinit(wpa_s);
4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpabuf_free(wpa_s->pending_eapol_rx);
4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->pending_eapol_rx = NULL;
4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IBSS_RSN
4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ibss_rsn_deinit(wpa_s->ibss_rsn);
4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->ibss_rsn = NULL;
4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IBSS_RSN */
4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sme_deinit(wpa_s);
4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_ap_deinit(wpa_s);
4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_p2p_deinit(wpa_s);
4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_OFFCHANNEL
4571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	offchannel_deinit(wpa_s);
4581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_OFFCHANNEL */
4591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
4601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_supplicant_cancel_sched_scan(wpa_s);
4611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(wpa_s->next_scan_freqs);
4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->next_scan_freqs = NULL;
4641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
4651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	gas_query_deinit(wpa_s->gas);
4661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_s->gas = NULL;
4671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
4681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	free_hw_features(wpa_s);
46904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
47004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	os_free(wpa_s->bssid_filter);
47104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->bssid_filter = NULL;
47204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
47304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wnm_bss_keep_alive_deinit(wpa_s);
47461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
47561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	ext_password_deinit(wpa_s->ext_pw);
47661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_s->ext_pw = NULL;
47761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
47861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpabuf_free(wpa_s->last_gas_resp);
4799bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt
4809bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	os_free(wpa_s->last_scan_res);
4819bce59c7fef20e34a05f04d1e33a4076083dca0cDmitry Shmidt	wpa_s->last_scan_res = NULL;
4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_clear_keys - Clear keys configured for the driver
4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @addr: Previously used BSSID or %NULL if not available
4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function clears the encryption keys that has been previously configured
4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * for the driver.
4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr)
4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->keys_cleared) {
4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Some drivers (e.g., ndiswrapper & NDIS drivers) seem to have
4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * timing issues with keys being cleared just before new keys
4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * are set or just after association or something similar. This
4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * shows up in group key handshake failing often because of the
5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * client not receiving the first encrypted packets correctly.
5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * Skipping some of the extra key clearing steps seems to help
5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * in completing group key handshake more reliably. */
5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "No keys have been configured - "
5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"skip key clearing");
5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* MLME-DELETEKEYS.request */
5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 0, 0, NULL, 0, NULL, 0);
5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 1, 0, NULL, 0, NULL, 0);
5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 2, 0, NULL, 0, NULL, 0);
5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 3, 0, NULL, 0, NULL, 0);
5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 4, 0, NULL, 0, NULL, 0);
5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, 5, 0, NULL, 0, NULL, 0);
5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (addr) {
5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_set_key(wpa_s, WPA_ALG_NONE, addr, 0, 0, NULL, 0, NULL,
5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				0);
5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* MLME-SETPROTECTION.request(None) */
5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_mlme_setprotection(
5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s, addr,
5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MLME_SETPROTECTION_PROTECT_TYPE_NONE,
5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->keys_cleared = 1;
5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_state_txt - Get the connection state name as a text string
5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @state: State (wpa_state; WPA_*)
5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: The state name as a printable text string
5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char * wpa_supplicant_state_txt(enum wpa_states state)
5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (state) {
5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_DISCONNECTED:
5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "DISCONNECTED";
5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_INACTIVE:
5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "INACTIVE";
5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_INTERFACE_DISABLED:
5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "INTERFACE_DISABLED";
5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_SCANNING:
5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "SCANNING";
5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_AUTHENTICATING:
5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "AUTHENTICATING";
5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_ASSOCIATING:
5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "ASSOCIATING";
5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_ASSOCIATED:
5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "ASSOCIATED";
5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_4WAY_HANDSHAKE:
5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "4WAY_HANDSHAKE";
5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_GROUP_HANDSHAKE:
5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "GROUP_HANDSHAKE";
5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_COMPLETED:
5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "COMPLETED";
5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "UNKNOWN";
5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_BGSCAN
5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_start_bgscan(struct wpa_supplicant *wpa_s)
5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpas_driver_bss_selection(wpa_s))
5691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return;
5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->current_ssid == wpa_s->bgscan_ssid)
5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bgscan_deinit(wpa_s);
5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->current_ssid && wpa_s->current_ssid->bgscan) {
5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (bgscan_init(wpa_s, wpa_s->current_ssid)) {
5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"bgscan");
5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/*
5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * Live without bgscan; it is only used as a roaming
5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * optimization, so the initial connection is not
5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * affected.
5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 */
58361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		} else {
58461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			struct wpa_scan_results *scan_res;
5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->bgscan_ssid = wpa_s->current_ssid;
58661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL,
58761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt								   0);
58861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (scan_res) {
58961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				bgscan_notify_scan(wpa_s, scan_res);
59061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_scan_results_free(scan_res);
59161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
59261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		}
5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else
5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->bgscan_ssid = NULL;
5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_stop_bgscan(struct wpa_supplicant *wpa_s)
5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->bgscan_ssid != NULL) {
6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bgscan_deinit(wpa_s);
6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->bgscan_ssid = NULL;
6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_BGSCAN */
6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
60904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpa_supplicant_start_autoscan(struct wpa_supplicant *wpa_s)
61004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
61104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (autoscan_init(wpa_s, 0))
61204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize autoscan");
61304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
61404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
61504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
61604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpa_supplicant_stop_autoscan(struct wpa_supplicant *wpa_s)
61704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
61804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	autoscan_deinit(wpa_s);
61904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
62004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
62104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
62204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid wpa_supplicant_reinit_autoscan(struct wpa_supplicant *wpa_s)
62304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
62404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->wpa_state == WPA_DISCONNECTED ||
62504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	    wpa_s->wpa_state == WPA_SCANNING) {
62604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		autoscan_deinit(wpa_s);
62704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_supplicant_start_autoscan(wpa_s);
62804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
62904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
63004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
63104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_set_state - Set current connection state
6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @state: The new connection state
6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called whenever the connection state changes, e.g.,
6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * association is completed for WPA/WPA2 4-Way Handshake is started.
6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      enum wpa_states state)
6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum wpa_states old_state = wpa_s->wpa_state;
6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "State: %s -> %s",
6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_state_txt(wpa_s->wpa_state),
6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_state_txt(state));
6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
64998f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt#ifdef ANDROID_P2P
6507db4ef75f0190d98dbc84f8968ede3ac0ae29571Irfan Sheriff	if(state == WPA_ASSOCIATED && wpa_s->current_ssid) {
6517db4ef75f0190d98dbc84f8968ede3ac0ae29571Irfan Sheriff		wpa_s->current_ssid->assoc_retry = 0;
6527db4ef75f0190d98dbc84f8968ede3ac0ae29571Irfan Sheriff	}
65398f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt#endif /* ANDROID_P2P */
65498f9e76624da6bb96edc1982c423e4a119c5170aDmitry Shmidt
6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (state != WPA_SCANNING)
6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_notify_scanning(wpa_s, 0);
6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (state == WPA_COMPLETED && wpa_s->new_connection) {
6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpa_ssid *ssid = wpa_s->current_ssid;
6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- Connection to "
6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MACSTR " completed %s [id=%d id_str=%s]",
6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			MAC2STR(wpa_s->bssid), wpa_s->reassociated_connection ?
6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"(reauth)" : "(auth)",
6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ssid ? ssid->id : -1,
6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ssid && ssid->id_str ? ssid->id_str : "");
6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
66861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpas_clear_temp_disabled(wpa_s, ssid, 1);
6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->new_connection = 0;
6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->reassociated_connection = 1;
6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_set_operstate(wpa_s, 1);
6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef IEEE8021X_EAPOL
6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_set_supp_port(wpa_s, 1);
6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */
6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->after_wps = 0;
6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_p2p_completed(wpa_s);
6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
67904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
68004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		sme_sched_obss_scan(wpa_s, 1);
6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING ||
6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   state == WPA_ASSOCIATED) {
6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->new_connection = 1;
6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_set_operstate(wpa_s, 0);
6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef IEEE8021X_EAPOL
6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_set_supp_port(wpa_s, 0);
6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */
68804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		sme_sched_obss_scan(wpa_s, 0);
6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->wpa_state = state;
6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_BGSCAN
6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (state == WPA_COMPLETED)
6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_start_bgscan(wpa_s);
6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_stop_bgscan(wpa_s);
6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_BGSCAN */
6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
69904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (state == WPA_AUTHENTICATING)
70004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_supplicant_stop_autoscan(wpa_s);
70104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
70204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
70304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_supplicant_start_autoscan(wpa_s);
70404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->wpa_state != old_state) {
7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->wpa_state == WPA_COMPLETED ||
7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    old_state == WPA_COMPLETED)
7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_notify_auth_changed(wpa_s);
7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_terminate_proc(struct wpa_global *global)
7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int pending = 0;
7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = global->ifaces;
7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (wpa_s) {
7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpas_wps_terminate_pending(wpa_s) == 1)
7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			pending = 1;
7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s = wpa_s->next;
7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pending)
7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_terminate();
7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_terminate(int sig, void *signal_ctx)
7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_global *global = signal_ctx;
7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_terminate_proc(global);
7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s)
7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum wpa_states old_state = wpa_s->wpa_state;
7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->pairwise_cipher = 0;
7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->group_cipher = 0;
7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->mgmt_group_cipher = 0;
7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->key_mgmt = 0;
7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->wpa_state != WPA_INTERFACE_DISABLED)
74804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->wpa_state != old_state)
7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_reload_configuration - Reload configuration data
7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success or -1 if configuration parsing failed
7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to request that the configuration data is reloaded
7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (e.g., after configuration file change). This function is reloading
7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * configuration only for one interface, so this may need to be called multiple
7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * times if %wpa_supplicant is controlling multiple interfaces and all
7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * interfaces need reconfiguration.
7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_config *conf;
7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int reconf_ctrl;
7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int old_ap_scan;
7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->confname == NULL)
7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf = wpa_config_read(wpa_s->confname);
7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (conf == NULL) {
7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Failed to parse the configuration "
7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"file '%s' - exiting", wpa_s->confname);
7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->changed_parameters = (unsigned int) -1;
7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reconf_ctrl = !!conf->ctrl_interface != !!wpa_s->conf->ctrl_interface
7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		|| (conf->ctrl_interface && wpa_s->conf->ctrl_interface &&
7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    os_strcmp(conf->ctrl_interface,
7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      wpa_s->conf->ctrl_interface) != 0);
7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (reconf_ctrl && wpa_s->ctrl_iface) {
7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->ctrl_iface = NULL;
7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_invalidate_cached_session(wpa_s->eapol);
7931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->current_ssid) {
7941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_supplicant_deauthenticate(wpa_s,
7951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					      WLAN_REASON_DEAUTH_LEAVING);
7961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * TODO: should notify EAPOL SM about changes in opensc_engine_path,
8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * pkcs11_engine_path, pkcs11_module_path.
8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * Clear forced success to clear EAP state for next
8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * authentication.
8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_config(wpa_s->wpa, NULL);
8111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	rsn_preauth_deinit(wpa_s->wpa);
8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	old_ap_scan = wpa_s->conf->ap_scan;
8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_config_free(wpa_s->conf);
8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->conf = conf;
8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (old_ap_scan != wpa_s->conf->ap_scan)
8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_ap_scan_changed(wpa_s);
8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (reconf_ctrl)
8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_update_config(wpa_s);
8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_clear_status(wpa_s);
82704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_supplicant_enabled_networks(wpa_s)) {
8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->reassociate = 1;
8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_req_scan(wpa_s, 0, 0);
8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Reconfiguration completed");
8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_reconfig(int sig, void *signal_ctx)
8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_global *global = signal_ctx;
8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s;
8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Signal %d received - reconfiguring",
8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			sig);
8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_reload_configuration(wpa_s) < 0) {
8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_terminate_proc(global);
8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtenum wpa_cipher cipher_suite2driver(int cipher)
8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (cipher) {
8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_CIPHER_NONE:
8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return CIPHER_NONE;
8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_CIPHER_WEP40:
8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return CIPHER_WEP40;
8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_CIPHER_WEP104:
8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return CIPHER_WEP104;
8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_CIPHER_CCMP:
8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return CIPHER_CCMP;
86161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	case WPA_CIPHER_GCMP:
86261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return CIPHER_GCMP;
8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_CIPHER_TKIP:
8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return CIPHER_TKIP;
8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtenum wpa_key_mgmt key_mgmt2driver(int key_mgmt)
8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (key_mgmt) {
8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_KEY_MGMT_NONE:
8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return KEY_MGMT_NONE;
8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_KEY_MGMT_IEEE8021X_NO_WPA:
8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return KEY_MGMT_802_1X_NO_WPA;
8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_KEY_MGMT_IEEE8021X:
8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return KEY_MGMT_802_1X;
8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_KEY_MGMT_WPA_NONE:
8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return KEY_MGMT_WPA_NONE;
8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_KEY_MGMT_FT_IEEE8021X:
8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return KEY_MGMT_FT_802_1X;
8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_KEY_MGMT_FT_PSK:
8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return KEY_MGMT_FT_PSK;
8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_KEY_MGMT_IEEE8021X_SHA256:
8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return KEY_MGMT_802_1X_SHA256;
8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_KEY_MGMT_PSK_SHA256:
8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return KEY_MGMT_PSK_SHA256;
8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_KEY_MGMT_WPS:
8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return KEY_MGMT_WPS;
8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPA_KEY_MGMT_PSK:
8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return KEY_MGMT_PSK;
8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s,
8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 struct wpa_ssid *ssid,
9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 struct wpa_ie_data *ie)
9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret = wpa_sm_parse_own_wpa_ie(wpa_s->wpa, ie);
9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret) {
9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret == -2) {
9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_msg(wpa_s, MSG_INFO, "WPA: Failed to parse WPA IE "
9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"from association info");
9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Using WPA IE from AssocReq to set "
9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"cipher suites");
9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!(ie->group_cipher & ssid->group_cipher)) {
9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled group "
9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"cipher 0x%x (mask 0x%x) - reject",
9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ie->group_cipher, ssid->group_cipher);
9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!(ie->pairwise_cipher & ssid->pairwise_cipher)) {
9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled pairwise "
9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"cipher 0x%x (mask 0x%x) - reject",
9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ie->pairwise_cipher, ssid->pairwise_cipher);
9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!(ie->key_mgmt & ssid->key_mgmt)) {
9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled key "
9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"management 0x%x (mask 0x%x) - reject",
9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ie->key_mgmt, ssid->key_mgmt);
9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!(ie->capabilities & WPA_CAPABILITY_MFPC) &&
9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    ssid->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) {
9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP "
9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"that does not support management frame protection - "
9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"reject");
9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_set_suites - Set authentication and encryption parameters
9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @bss: Scan results for the selected BSS, or %NULL if not available
9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid: Configuration data for the selected network
9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_ie: Buffer for the WPA/RSN IE
9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_ie_len: Maximum wpa_ie buffer size on input. This is changed to be the
9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * used buffer length in case the functions returns success.
9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success or -1 on failure
9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to configure authentication and encryption parameters
9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * based on the network configuration and scan result for the selected BSS (if
9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * available).
9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      struct wpa_bss *bss, struct wpa_ssid *ssid,
9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      u8 *wpa_ie, size_t *wpa_ie_len)
9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ie_data ie;
9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int sel, proto;
9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const u8 *bss_wpa, *bss_rsn;
9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss) {
9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else
9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss_wpa = bss_rsn = NULL;
9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss_rsn && (ssid->proto & WPA_PROTO_RSN) &&
9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie) == 0 &&
9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (ie.group_cipher & ssid->group_cipher) &&
9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (ie.pairwise_cipher & ssid->pairwise_cipher) &&
9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (ie.key_mgmt & ssid->key_mgmt)) {
9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using IEEE 802.11i/D9.0");
9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		proto = WPA_PROTO_RSN;
9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (bss_wpa && (ssid->proto & WPA_PROTO_WPA) &&
9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   wpa_parse_wpa_ie(bss_wpa, 2 +bss_wpa[1], &ie) == 0 &&
9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   (ie.group_cipher & ssid->group_cipher) &&
9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   (ie.pairwise_cipher & ssid->pairwise_cipher) &&
9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   (ie.key_mgmt & ssid->key_mgmt)) {
9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using IEEE 802.11i/D3.0");
9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		proto = WPA_PROTO_WPA;
9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (bss) {
9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select WPA/RSN");
9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->proto & WPA_PROTO_RSN)
9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			proto = WPA_PROTO_RSN;
9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else
9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			proto = WPA_PROTO_WPA;
9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_suites_from_ai(wpa_s, ssid, &ie) < 0) {
9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memset(&ie, 0, sizeof(ie));
9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ie.group_cipher = ssid->group_cipher;
9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ie.pairwise_cipher = ssid->pairwise_cipher;
10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ie.key_mgmt = ssid->key_mgmt;
10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ie.mgmt_group_cipher =
10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION ?
10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				WPA_CIPHER_AES_128_CMAC : 0;
10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Set cipher suites "
10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"based on configuration");
10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else
10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			proto = ie.proto;
10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected cipher suites: group %d "
10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		"pairwise %d key_mgmt %d proto %d",
10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ie.group_cipher, ie.pairwise_cipher, ie.key_mgmt, proto);
10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->ieee80211w) {
10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected mgmt group cipher %d",
10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			ie.mgmt_group_cipher);
10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_s->wpa_proto = proto;
10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, proto);
10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 !!(ssid->proto & WPA_PROTO_RSN));
10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss || !wpa_s->ap_ies_from_associnfo) {
10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 bss_wpa ? 2 + bss_wpa[1] : 0) ||
10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 bss_rsn ? 2 + bss_rsn[1] : 0))
10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sel = ie.group_cipher & ssid->group_cipher;
10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (sel & WPA_CIPHER_CCMP) {
10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->group_cipher = WPA_CIPHER_CCMP;
10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK CCMP");
103961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	} else if (sel & WPA_CIPHER_GCMP) {
104061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_s->group_cipher = WPA_CIPHER_GCMP;
104161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK GCMP");
10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (sel & WPA_CIPHER_TKIP) {
10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->group_cipher = WPA_CIPHER_TKIP;
10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK TKIP");
10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (sel & WPA_CIPHER_WEP104) {
10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->group_cipher = WPA_CIPHER_WEP104;
10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK WEP104");
10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (sel & WPA_CIPHER_WEP40) {
10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->group_cipher = WPA_CIPHER_WEP40;
10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK WEP40");
10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select group "
10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"cipher");
10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sel = ie.pairwise_cipher & ssid->pairwise_cipher;
10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (sel & WPA_CIPHER_CCMP) {
10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->pairwise_cipher = WPA_CIPHER_CCMP;
10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK CCMP");
106161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	} else if (sel & WPA_CIPHER_GCMP) {
106261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_s->pairwise_cipher = WPA_CIPHER_GCMP;
106361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK GCMP");
10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (sel & WPA_CIPHER_TKIP) {
10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->pairwise_cipher = WPA_CIPHER_TKIP;
10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK TKIP");
10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (sel & WPA_CIPHER_NONE) {
10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK NONE");
10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select pairwise "
10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"cipher");
10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sel = ie.key_mgmt & ssid->key_mgmt;
10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (0) {
10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) {
10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/802.1X");
10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (sel & WPA_KEY_MGMT_FT_PSK) {
10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_FT_PSK;
10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/PSK");
10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (sel & WPA_KEY_MGMT_IEEE8021X_SHA256) {
10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG,
10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"WPA: using KEY_MGMT 802.1X with SHA256");
10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (sel & WPA_KEY_MGMT_PSK_SHA256) {
10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG,
10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"WPA: using KEY_MGMT PSK with SHA256");
10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (sel & WPA_KEY_MGMT_IEEE8021X) {
10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT 802.1X");
10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (sel & WPA_KEY_MGMT_PSK) {
11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-PSK");
11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (sel & WPA_KEY_MGMT_WPA_NONE) {
11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_WPA_NONE;
11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-NONE");
11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select "
11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"authenticated key management type");
11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 wpa_s->pairwise_cipher);
11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	sel = ie.mgmt_group_cipher;
11188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->ieee80211w == NO_MGMT_FRAME_PROTECTION ||
11198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    !(ie.capabilities & WPA_CAPABILITY_MFPC))
11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		sel = 0;
11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (sel & WPA_CIPHER_AES_128_CMAC) {
11228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
11238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
11248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"AES-128-CMAC");
11258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
11268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->mgmt_group_cipher = 0;
11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 wpa_s->mgmt_group_cipher);
11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP, ssid->ieee80211w);
11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
11338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {
11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to generate WPA IE");
11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN);
11411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifndef CONFIG_NO_PBKDF2
11421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (bss && ssid->bssid_set && ssid->ssid_len == 0 &&
11431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    ssid->passphrase) {
11441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			u8 psk[PMK_LEN];
114561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		        pbkdf2_sha1(ssid->passphrase, bss->ssid, bss->ssid_len,
114661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				    4096, psk, PMK_LEN);
11471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		        wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
11481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt					psk, PMK_LEN);
11491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
11501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
11511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_NO_PBKDF2 */
115261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_EXT_PASSWORD
115361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (ssid->ext_psk) {
115461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			struct wpabuf *pw = ext_password_get(wpa_s->ext_pw,
115561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt							     ssid->ext_psk);
115661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			char pw_str[64 + 1];
115761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			u8 psk[PMK_LEN];
115861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
115961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (pw == NULL) {
116061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_msg(wpa_s, MSG_INFO, "EXT PW: No PSK "
116161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					"found from external storage");
116261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				return -1;
116361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
116461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
116561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (wpabuf_len(pw) < 8 || wpabuf_len(pw) > 64) {
116661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_msg(wpa_s, MSG_INFO, "EXT PW: Unexpected "
116761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					"PSK length %d in external storage",
116861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					(int) wpabuf_len(pw));
116961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				ext_password_free(pw);
117061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				return -1;
117161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
117261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
117361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			os_memcpy(pw_str, wpabuf_head(pw), wpabuf_len(pw));
117461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			pw_str[wpabuf_len(pw)] = '\0';
117561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
117661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifndef CONFIG_NO_PBKDF2
117761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (wpabuf_len(pw) >= 8 && wpabuf_len(pw) < 64 && bss)
117861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			{
117961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				pbkdf2_sha1(pw_str, bss->ssid, bss->ssid_len,
118061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					    4096, psk, PMK_LEN);
118161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				os_memset(pw_str, 0, sizeof(pw_str));
118261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_hexdump_key(MSG_MSGDUMP, "PSK (from "
118361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt						"external passphrase)",
118461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt						psk, PMK_LEN);
118561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
118661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			} else
118761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_NO_PBKDF2 */
118861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (wpabuf_len(pw) == 2 * PMK_LEN) {
118961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				if (hexstr2bin(pw_str, psk, PMK_LEN) < 0) {
119061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					wpa_msg(wpa_s, MSG_INFO, "EXT PW: "
119161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt						"Invalid PSK hex string");
119261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					os_memset(pw_str, 0, sizeof(pw_str));
119361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					ext_password_free(pw);
119461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					return -1;
119561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				}
119661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
119761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			} else {
119861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpa_msg(wpa_s, MSG_INFO, "EXT PW: No suitable "
119961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					"PSK available");
120061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				os_memset(pw_str, 0, sizeof(pw_str));
120161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				ext_password_free(pw);
120261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				return -1;
120361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			}
120461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
120561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			os_memset(pw_str, 0, sizeof(pw_str));
120661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			ext_password_free(pw);
120761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		}
120861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_EXT_PASSWORD */
12091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	} else
12108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
12118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
12138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
12148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
12178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_associate - Request association
12188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
12198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @bss: Scan results for the selected BSS, or %NULL if not available
12208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid: Configuration data for the selected network
12218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
12228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to request %wpa_supplicant to associate with a BSS.
12238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
12248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
12258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      struct wpa_bss *bss, struct wpa_ssid *ssid)
12268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
12278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 wpa_ie[200];
12288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t wpa_ie_len;
12298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int use_crypt, ret, i, bssid_changed;
12308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int algs = WPA_AUTH_ALG_OPEN;
12318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	enum wpa_cipher cipher_pairwise, cipher_group;
12328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_driver_associate_params params;
12338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wep_keys_set = 0;
12348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_driver_capa capa;
12358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int assoc_failed = 0;
12368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *old_ssid;
1237c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#ifdef CONFIG_HT_OVERRIDES
1238c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	struct ieee80211_ht_capabilities htcaps;
1239c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	struct ieee80211_ht_capabilities htcaps_mask;
1240c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#endif /* CONFIG_HT_OVERRIDES */
12418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IBSS_RSN
12438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ibss_rsn_deinit(wpa_s->ibss_rsn);
12448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->ibss_rsn = NULL;
12458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IBSS_RSN */
1246c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#ifdef ANDROID_P2P
1247c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	int freq = 0;
1248c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#endif
12498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
12538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) {
12548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_msg(wpa_s, MSG_INFO, "Driver does not support AP "
12558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"mode");
12568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return;
12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1258aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt		if (wpa_supplicant_create_ap(wpa_s, ssid) < 0) {
1259aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt			wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
1260aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt			return;
1261aa532510a7b8c4da2d7d6e2c11dda5db840894e4Dmitry Shmidt		}
12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->current_bss = bss;
12638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_AP */
12648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "AP mode support not included in "
12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"the build");
12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
12688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TDLS
12718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss)
12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_tdls_ap_ies(wpa_s->wpa, (const u8 *) (bss + 1),
12738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				bss->ie_len);
12748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TDLS */
12758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
12778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    ssid->mode == IEEE80211_MODE_INFRA) {
12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		sme_authenticate(wpa_s, bss, ssid);
12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&params, 0, sizeof(params));
12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->reassociate = 0;
12841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (bss && !wpas_driver_bss_selection(wpa_s)) {
12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		const u8 *ie, *md = NULL;
12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			" (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid),
12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq);
12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memset(wpa_s->bssid, 0, ETH_ALEN);
12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
12948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (bssid_changed)
12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_notify_bssid_changed(wpa_s);
12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211R
12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			md = ie + 2;
13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (md) {
13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* Prepare for the next transition */
13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211R */
13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if ((ssid->ssid == NULL || ssid->ssid_len == 0) &&
13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   wpa_s->conf->ap_scan == 2 &&
13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Use ap_scan==1 style network selection to find the network
13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->scan_req = 2;
13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->reassociate = 1;
13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_req_scan(wpa_s, 0, 0);
13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_supplicant_cancel_sched_scan(wpa_s);
13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_cancel_scan(wpa_s);
13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Starting new association, so clear the possibly used WPA IE from the
13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * previous association. */
13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL
13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->leap) {
13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (ssid->non_leap == 0)
13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				algs = WPA_AUTH_ALG_LEAP;
13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			else
13358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				algs |= WPA_AUTH_ALG_LEAP;
13368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */
13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs);
13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->auth_alg) {
13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		algs = ssid->auth_alg;
13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: "
13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"0x%x", algs);
13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
13478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
13481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    wpa_key_mgmt_wpa(ssid->key_mgmt)) {
13498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int try_opportunistic;
13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		try_opportunistic = ssid->proactive_key_caching &&
13518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			(ssid->proto & WPA_PROTO_RSN);
13528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
13538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					    wpa_s->current_ssid,
13548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					    try_opportunistic) == 0)
13558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1);
13568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_ie_len = sizeof(wpa_ie);
13578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
13588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      wpa_ie, &wpa_ie_len)) {
13598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
13608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"key management and encryption suites");
13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return;
13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
136361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	} else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && bss &&
136461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		   wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
136561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		/*
136661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		 * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
136761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		 * use non-WPA since the scan results did not indicate that the
136861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		 * AP is using WPA or WPA2.
136961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		 */
137061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
137161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_ie_len = 0;
137261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_s->wpa_proto = 0;
13731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	} else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
13748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_ie_len = sizeof(wpa_ie);
13758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
13768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      wpa_ie, &wpa_ie_len)) {
13778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
13788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"key management and encryption suites (no "
13798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"scan results)");
13808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return;
13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
13828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpabuf *wps_ie;
13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wps_ie && wpabuf_len(wps_ie) <= sizeof(wpa_ie)) {
13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_ie_len = wpabuf_len(wps_ie);
13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else
13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_ie_len = 0;
13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(wps_ie);
13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY))
13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.wps = WPS_MODE_PRIVACY;
13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else
13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.wps = WPS_MODE_OPEN;
13971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_s->wpa_proto = 0;
13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_ie_len = 0;
14021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_s->wpa_proto = 0;
14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->global->p2p) {
14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		u8 *pos;
14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		size_t len;
14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int res;
14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = wpa_ie + wpa_ie_len;
14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		len = sizeof(wpa_ie) - wpa_ie_len;
141204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
141304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					    ssid->p2p_group);
14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (res >= 0)
14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_ie_len += res;
14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->cross_connect_disallowed = 0;
14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss) {
14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpabuf *p2p;
14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (p2p) {
14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->cross_connect_disallowed =
14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				p2p_get_cross_connect_disallowed(p2p);
14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpabuf_free(p2p);
14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: WLAN AP %s cross "
14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"connection",
14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s->cross_connect_disallowed ?
14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"disallows" : "allows");
14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
143404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_HS20
143504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->conf->hs20) {
143604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		struct wpabuf *hs20;
143704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		hs20 = wpabuf_alloc(20);
143804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (hs20) {
143904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpas_hs20_add_indication(hs20);
144004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			os_memcpy(wpa_ie + wpa_ie_len, wpabuf_head(hs20),
144104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				  wpabuf_len(hs20));
144204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_ie_len += wpabuf_len(hs20);
144304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpabuf_free(hs20);
144404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
144504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
144604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_HS20 */
144704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
14481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_INTERWORKING
14491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->conf->interworking) {
14501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		u8 *pos = wpa_ie;
14511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)
14521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			pos += 2 + pos[1];
14531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		os_memmove(pos + 6, pos, wpa_ie_len - (pos - wpa_ie));
14541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_ie_len += 6;
14551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		*pos++ = WLAN_EID_EXT_CAPAB;
14561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		*pos++ = 4;
14571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		*pos++ = 0x00;
14581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		*pos++ = 0x00;
14591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		*pos++ = 0x00;
14601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		*pos++ = 0x80; /* Bit 31 - Interworking */
14611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
14621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_INTERWORKING */
14631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	use_crypt = 1;
14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cipher_pairwise = cipher_suite2driver(wpa_s->pairwise_cipher);
14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cipher_group = cipher_suite2driver(wpa_s->group_cipher);
14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			use_crypt = 0;
14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_set_wep_keys(wpa_s, ssid)) {
14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			use_crypt = 1;
14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wep_keys_set = 1;
14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		use_crypt = 0;
14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef IEEE8021X_EAPOL
14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if ((ssid->eapol_flags &
14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		      EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 &&
14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    !wep_keys_set) {
14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			use_crypt = 0;
14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else {
14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* Assume that dynamic WEP-104 keys will be used and
14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * set cipher suites in order for drivers to expect
14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * encryption. */
14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			cipher_pairwise = cipher_group = CIPHER_WEP104;
14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* IEEE8021X_EAPOL */
14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Set the key before (and later after) association */
14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
15028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss) {
15038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.ssid = bss->ssid;
15048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.ssid_len = bss->ssid_len;
150504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
150604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_printf(MSG_DEBUG, "Limit connection to BSSID "
150704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   MACSTR " freq=%u MHz based on scan results "
150804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   "(bssid_set=%d)",
150904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   MAC2STR(bss->bssid), bss->freq,
151004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   ssid->bssid_set);
15111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			params.bssid = bss->bssid;
15121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			params.freq = bss->freq;
15131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.ssid = ssid->ssid;
15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.ssid_len = ssid->ssid_len;
15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1518c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1519c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&
1520c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	    wpa_s->conf->ap_scan == 2) {
1521c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		params.bssid = ssid->bssid;
1522c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		params.fixed_bssid = 1;
1523c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
1524c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->mode == WPAS_MODE_IBSS && ssid->frequency > 0 &&
15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    params.freq == 0)
15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.freq = ssid->frequency; /* Initial channel for IBSS */
15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.wpa_ie = wpa_ie;
15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.wpa_ie_len = wpa_ie_len;
15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.pairwise_suite = cipher_pairwise;
15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.group_suite = cipher_group;
15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.key_mgmt_suite = key_mgmt2driver(wpa_s->key_mgmt);
15331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	params.wpa_proto = wpa_s->wpa_proto;
15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.auth_alg = algs;
15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.mode = ssid->mode;
153604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	params.bg_scan_period = ssid->bg_scan_period;
15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < NUM_WEP_KEYS; i++) {
15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->wep_key_len[i])
15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.wep_key[i] = ssid->wep_key[i];
15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.wep_key_len[i] = ssid->wep_key_len[i];
15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.wep_tx_keyidx = ssid->wep_tx_keyidx;
15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (params.key_mgmt_suite == KEY_MGMT_PSK ||
15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     params.key_mgmt_suite == KEY_MGMT_FT_PSK)) {
15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.passphrase = ssid->passphrase;
15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid->psk_set)
15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.psk = ssid->psk;
15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.drop_unencrypted = use_crypt;
15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.mgmt_frame_protection = ssid->ieee80211w;
15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION && bss) {
15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wpa_ie_data ie;
15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    ie.capabilities &
15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected AP supports "
15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"MFP: require MFP");
15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			params.mgmt_frame_protection =
15658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				MGMT_FRAME_PROTECTION_REQUIRED;
15668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
15678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
15688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
15698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	params.p2p = ssid->p2p_group;
15718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->parent->set_sta_uapsd)
15738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.uapsd = wpa_s->parent->sta_uapsd;
15748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
15758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.uapsd = -1;
15768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1577c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#ifdef CONFIG_HT_OVERRIDES
1578c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	os_memset(&htcaps, 0, sizeof(htcaps));
1579c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
1580c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	params.htcaps = (u8 *) &htcaps;
1581c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	params.htcaps_mask = (u8 *) &htcaps_mask;
1582c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
1583c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#endif /* CONFIG_HT_OVERRIDES */
1584c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
15851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef ANDROID_P2P
15861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	/* If multichannel concurrency is not supported, check for any frequency
15871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 * conflict and take appropriate action.
15881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 */
1589c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) &&
1590c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		((freq = wpa_drv_shared_freq(wpa_s)) > 0) && (freq != params.freq)) {
1591c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		wpa_printf(MSG_DEBUG, "Shared interface with conflicting frequency found (%d != %d)"
15921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt																, freq, params.freq);
1593c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		if (wpas_p2p_handle_frequency_conflicts(wpa_s, params.freq) < 0) {
1594c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			/* Handling conflicts failed. Disable the current connect req and
1595c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			 * notify the userspace to take appropriate action */
1596c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			wpa_printf(MSG_DEBUG, "proiritize is not set. Notifying user space to handle the case");
1597c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			wpa_supplicant_disable_network(wpa_s, ssid);
1598c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_FREQ_CONFLICT
1599c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				" id=%d", ssid->id);
1600c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1601687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt			return;
1602c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		}
16031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
16041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif
16051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	ret = wpa_drv_associate(wpa_s, &params);
16068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret < 0) {
16078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
16088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"failed");
16098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SANE_ERROR_CODES) {
16108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/*
16118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * The driver is known to mean what is saying, so we
16128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * can stop right here; the association will not
16138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * succeed.
16148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 */
16158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
161604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
16178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
16188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return;
16198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
16208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* try to continue anyway; new association will be tried again
16218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * after timeout */
16228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		assoc_failed = 1;
16238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
16268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Set the key after the association just in case association
16278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * cleared the previously configured key. */
16288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
16298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* No need to timeout authentication since there is no key
16308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * management. */
16318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_cancel_auth_timeout(wpa_s);
16328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
16338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IBSS_RSN
16348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (ssid->mode == WPAS_MODE_IBSS &&
16358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
16368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
16378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
16388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * RSN IBSS authentication is per-STA and we can disable the
16398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * per-BSSID authentication.
16408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
16418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_cancel_auth_timeout(wpa_s);
16428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IBSS_RSN */
16438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
16448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Timeout for IEEE 802.11 authentication and association */
16458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int timeout = 60;
16468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (assoc_failed) {
16488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* give IBSS a bit more time */
16498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5;
16508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		} else if (wpa_s->conf->ap_scan == 1) {
16518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/* give IBSS a bit more time */
16528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10;
16538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
16548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
16558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wep_keys_set && wpa_drv_get_capa(wpa_s, &capa) == 0 &&
16588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    capa.flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC) {
16598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Set static WEP keys again */
16608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_set_wep_keys(wpa_s, ssid);
16618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
16648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
16658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * Do not allow EAP session resumption between different
16668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * network configurations.
16678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
16688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_invalidate_cached_session(wpa_s->eapol);
16698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
16708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	old_ssid = wpa_s->current_ssid;
16718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->current_ssid = ssid;
16728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->current_bss = bss;
16738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
16748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_initiate_eapol(wpa_s);
16758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (old_ssid != wpa_s->current_ssid)
16768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_network_changed(wpa_s);
16778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
16788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s,
16818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					    const u8 *addr)
16828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
16838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *old_ssid;
16848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_clear_keys(wpa_s, addr);
16868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	old_ssid = wpa_s->current_ssid;
168761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_supplicant_mark_disassoc(wpa_s);
16888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_config(wpa_s->wpa, NULL);
16898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
16908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (old_ssid != wpa_s->current_ssid)
16918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_network_changed(wpa_s);
16928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
16938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
16948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
16968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
16978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_disassociate - Disassociate the current connection
16988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
16998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @reason_code: IEEE 802.11 reason code for the disassociate frame
17008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
17018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to request %wpa_supplicant to disassociate with the
17028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * current AP.
17038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
17048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_disassociate(struct wpa_supplicant *wpa_s,
17058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				 int reason_code)
17068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
17078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 *addr = NULL;
170804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	union wpa_event_data event;
17098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!is_zero_ether_addr(wpa_s->bssid)) {
17111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_drv_disassociate(wpa_s, wpa_s->bssid, reason_code);
17128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		addr = wpa_s->bssid;
171304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_memset(&event, 0, sizeof(event));
171404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		event.disassoc_info.reason_code = (u16) reason_code;
171504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		event.disassoc_info.locally_generated = 1;
171604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_supplicant_event(wpa_s, EVENT_DISASSOC, &event);
17178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
17188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_clear_connection(wpa_s, addr);
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;
17368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!is_zero_ether_addr(wpa_s->bssid)) {
17381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_drv_deauthenticate(wpa_s, wpa_s->bssid, reason_code);
17398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		addr = wpa_s->bssid;
174004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_memset(&event, 0, sizeof(event));
174104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		event.deauth_info.reason_code = (u16) reason_code;
174204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		event.deauth_info.locally_generated = 1;
174304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
17448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
17458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_clear_connection(wpa_s, addr);
17478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
17488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
17518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_enable_network - Mark a configured network as enabled
17528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
17538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid: wpa_ssid structure for a configured network or %NULL
17548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
17558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Enables the specified network or all networks if no network specified.
17568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
17578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
17588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   struct wpa_ssid *ssid)
17598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
17608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *other_ssid;
17618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int was_disabled;
17628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL) {
17648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (other_ssid = wpa_s->conf->ssid; other_ssid;
17658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     other_ssid = other_ssid->next) {
17668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (other_ssid->disabled == 2)
17678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				continue; /* do not change persistent P2P group
17688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   * data */
17698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (other_ssid == wpa_s->current_ssid &&
17708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    other_ssid->disabled)
17718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s->reassociate = 1;
17728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			was_disabled = other_ssid->disabled;
17748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			other_ssid->disabled = 0;
177661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (was_disabled)
177761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
17788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (was_disabled != other_ssid->disabled)
17808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpas_notify_network_enabled_changed(
17818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					wpa_s, other_ssid);
17828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
17838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->reassociate)
17848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_req_scan(wpa_s, 0, 0);
17858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (ssid->disabled && ssid->disabled != 2) {
17868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->current_ssid == NULL) {
17878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/*
17888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * Try to reassociate since there is no current
17898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * configuration and a new network was made available.
17908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 */
17918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->reassociate = 1;
17928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_req_scan(wpa_s, 0, 0);
17938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
17948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		was_disabled = ssid->disabled;
17968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
17978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid->disabled = 0;
179861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpas_clear_temp_disabled(wpa_s, ssid, 1);
17998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (was_disabled != ssid->disabled)
18018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_notify_network_enabled_changed(wpa_s, ssid);
18028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
18078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_disable_network - Mark a configured network as disabled
18088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
18098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid: wpa_ssid structure for a configured network or %NULL
18108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
18118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Disables the specified network or all networks if no network specified.
18128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
18138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
18148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    struct wpa_ssid *ssid)
18158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
18168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *other_ssid;
18178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int was_disabled;
18188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid == NULL) {
18208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (other_ssid = wpa_s->conf->ssid; other_ssid;
18218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     other_ssid = other_ssid->next) {
18228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			was_disabled = other_ssid->disabled;
18238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (was_disabled == 2)
18248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				continue; /* do not change persistent P2P group
18258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   * data */
18268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			other_ssid->disabled = 1;
18288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (was_disabled != other_ssid->disabled)
18308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpas_notify_network_enabled_changed(
18318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					wpa_s, other_ssid);
18328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
18338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->current_ssid)
18348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_disassociate(
18358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s, WLAN_REASON_DEAUTH_LEAVING);
18368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (ssid->disabled != 2) {
18378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ssid == wpa_s->current_ssid)
18388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_disassociate(
18398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s, WLAN_REASON_DEAUTH_LEAVING);
18408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		was_disabled = ssid->disabled;
18428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ssid->disabled = 1;
18448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (was_disabled != ssid->disabled)
18468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_notify_network_enabled_changed(wpa_s, ssid);
18478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
18498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
18528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_select_network - Attempt association with a network
18538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
18548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ssid: wpa_ssid structure for a configured network or %NULL for any network
18558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
18568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
18578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   struct wpa_ssid *ssid)
18588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
18598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *other_ssid;
1861c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	int disconnected = 0;
18628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1863c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
18648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_disassociate(
18658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s, WLAN_REASON_DEAUTH_LEAVING);
1866c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		disconnected = 1;
1867c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
18688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
186961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (ssid)
187061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpas_clear_temp_disabled(wpa_s, ssid, 1);
187161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
18728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
18738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * Mark all other networks disabled or mark all networks enabled if no
18748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * network specified.
18758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
18768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (other_ssid = wpa_s->conf->ssid; other_ssid;
18778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     other_ssid = other_ssid->next) {
18788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int was_disabled = other_ssid->disabled;
18798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (was_disabled == 2)
18808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue; /* do not change persistent P2P group data */
18818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
188361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (was_disabled && !other_ssid->disabled)
188461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
18858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
18868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (was_disabled != other_ssid->disabled)
18878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpas_notify_network_enabled_changed(wpa_s, other_ssid);
18888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
18891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
18901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid) {
18911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		/* We are already associated with the selected network */
18921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_printf(MSG_DEBUG, "Already associated with the "
18931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			   "selected network - do nothing");
18941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return;
18951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
18961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1897c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (ssid)
1898c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		wpa_s->current_ssid = ssid;
189975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	wpa_s->connect_without_scan = NULL;
19008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->disconnected = 0;
19018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->reassociate = 1;
1902c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
19038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid)
19058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_network_selected(wpa_s, ssid);
19068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
19078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
19108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_set_ap_scan - Set AP scan mode for interface
19118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
19128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ap_scan: AP scan mode
19138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 if succeed or -1 if ap_scan has an invalid value
19148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
19158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
19168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
19178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
19188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int old_ap_scan;
19208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ap_scan < 0 || ap_scan > 2)
19228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
19238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1924114c3866dda61e84385bb5327f0acf727f2156daDmitry Shmidt#ifdef ANDROID
19251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (ap_scan == 2 && ap_scan != wpa_s->conf->ap_scan &&
19261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    wpa_s->wpa_state >= WPA_ASSOCIATING &&
19271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    wpa_s->wpa_state < WPA_COMPLETED) {
19281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_printf(MSG_ERROR, "ap_scan = %d (%d) rejected while "
19291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			   "associating", wpa_s->conf->ap_scan, ap_scan);
1930114c3866dda61e84385bb5327f0acf727f2156daDmitry Shmidt		return 0;
1931114c3866dda61e84385bb5327f0acf727f2156daDmitry Shmidt	}
19321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* ANDROID */
1933114c3866dda61e84385bb5327f0acf727f2156daDmitry Shmidt
19348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	old_ap_scan = wpa_s->conf->ap_scan;
19358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->conf->ap_scan = ap_scan;
19368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (old_ap_scan != wpa_s->conf->ap_scan)
19388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_ap_scan_changed(wpa_s);
19398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
19418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
19428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
19458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_set_bss_expiration_age - Set BSS entry expiration age
19468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
19478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @expire_age: Expiration age in seconds
19488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 if succeed or -1 if expire_age has an invalid value
19498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
19508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
19518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
19528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  unsigned int bss_expire_age)
19538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
19548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss_expire_age < 10) {
19558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration age %u",
19568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss_expire_age);
19578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
19588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
19598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration age: %d sec",
19608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss_expire_age);
19618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->conf->bss_expiration_age = bss_expire_age;
19628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
19648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
19658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
19688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_set_bss_expiration_count - Set BSS entry expiration scan count
19698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
19708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @expire_count: number of scans after which an unseen BSS is reclaimed
19718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 if succeed or -1 if expire_count has an invalid value
19728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
19738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
19748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
19758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					    unsigned int bss_expire_count)
19768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
19778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss_expire_count < 1) {
19788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration count %u",
19798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			bss_expire_count);
19808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
19818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
19828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration scan count: %u",
19838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss_expire_count);
19848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->conf->bss_expiration_scan_count = bss_expire_count;
19858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
19878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
19888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
19908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
199104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * wpa_supplicant_set_scan_interval - Set scan interval
199204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @wpa_s: wpa_supplicant structure for a network interface
199304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * @scan_interval: scan interval in seconds
199404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * Returns: 0 if succeed or -1 if scan_interval has an invalid value
199504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt *
199604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt */
199704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint wpa_supplicant_set_scan_interval(struct wpa_supplicant *wpa_s,
199804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				     int scan_interval)
199904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
200004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (scan_interval < 0) {
200104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Invalid scan interval %d",
200204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			scan_interval);
200304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
200404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
200504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_msg(wpa_s, MSG_DEBUG, "Setting scan interval: %d sec",
200604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		scan_interval);
200704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->scan_interval = scan_interval;
200804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
200904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return 0;
201004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
201104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
201204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
201304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/**
20148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_set_debug_params - Set global debug params
20158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: wpa_global structure
20168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @debug_level: debug level
20178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @debug_timestamp: determines if show timestamp in debug data
20188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @debug_show_keys: determines if show keys in debug data
20198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 if succeed or -1 if debug_level has wrong value
20208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
20218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
20228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    int debug_timestamp, int debug_show_keys)
20238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
20248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int old_level, old_timestamp, old_show_keys;
20268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* check for allowed debuglevels */
20288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (debug_level != MSG_EXCESSIVE &&
20298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    debug_level != MSG_MSGDUMP &&
20308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    debug_level != MSG_DEBUG &&
20318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    debug_level != MSG_INFO &&
20328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    debug_level != MSG_WARNING &&
20338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    debug_level != MSG_ERROR)
20348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
20358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	old_level = wpa_debug_level;
20378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	old_timestamp = wpa_debug_timestamp;
20388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	old_show_keys = wpa_debug_show_keys;
20398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_debug_level = debug_level;
20418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_debug_timestamp = debug_timestamp ? 1 : 0;
20428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_debug_show_keys = debug_show_keys ? 1 : 0;
20438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_debug_level != old_level)
20458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_debug_level_changed(global);
20468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_debug_timestamp != old_timestamp)
20478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_debug_timestamp_changed(global);
20488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_debug_show_keys != old_show_keys)
20498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_debug_show_keys_changed(global);
20508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
20528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
20538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
20568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_get_ssid - Get a pointer to the current network structure
20578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
20588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: A pointer to the current network structure or %NULL on failure
20598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
20608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
20618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
20628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *entry;
20638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 ssid[MAX_SSID_LEN];
20648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int res;
20658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t ssid_len;
20668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 bssid[ETH_ALEN];
20678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int wired;
20688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	res = wpa_drv_get_ssid(wpa_s, ssid);
20701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (res < 0) {
20711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
20721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			"driver");
20731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return NULL;
20748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
20751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	ssid_len = res;
20768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
20788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_WARNING, "Could not read BSSID from "
20798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"driver");
20808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
20818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
20828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wired = wpa_s->conf->ap_scan == 0 &&
20848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		(wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
20858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
20868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	entry = wpa_s->conf->ssid;
20878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (entry) {
208804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (!wpas_network_disabled(wpa_s, entry) &&
20898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    ((ssid_len == entry->ssid_len &&
20908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		      os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
20918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (!entry->bssid_set ||
20928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
20938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return entry;
20948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
209504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (!wpas_network_disabled(wpa_s, entry) &&
20968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
20978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (entry->ssid == NULL || entry->ssid_len == 0) &&
20988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    (!entry->bssid_set ||
20998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
21008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return entry;
21018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
21021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
210304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
21041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    entry->ssid_len == 0 &&
21051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
21061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			return entry;
21071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
21088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		entry = entry->next;
21098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
21108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return NULL;
21128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
21138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int select_driver(struct wpa_supplicant *wpa_s, int i)
21161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
21171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_global *global = wpa_s->global;
21181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
21191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_drivers[i]->global_init && global->drv_priv[i] == NULL) {
21201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		global->drv_priv[i] = wpa_drivers[i]->global_init();
21211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (global->drv_priv[i] == NULL) {
21221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_printf(MSG_ERROR, "Failed to initialize driver "
21231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				   "'%s'", wpa_drivers[i]->name);
21241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			return -1;
21251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
21261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
21271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
21281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_s->driver = wpa_drivers[i];
21291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_s->global_drv_priv = global->drv_priv[i];
21301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
21311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return 0;
21321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
21331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
21341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
21358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
21368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     const char *name)
21378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
21388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
21398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t len;
21408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *pos, *driver = name;
21418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s == NULL)
21438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
21448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_drivers[0] == NULL) {
21468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "No driver interfaces build into "
21478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"wpa_supplicant");
21488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
21498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
21508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (name == NULL) {
21528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* default to first driver in the list */
21531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return select_driver(wpa_s, 0);
21548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
21558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	do {
21578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = os_strchr(driver, ',');
21588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos)
21598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			len = pos - driver;
21608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		else
21618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			len = os_strlen(driver);
21628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (i = 0; wpa_drivers[i]; i++) {
21648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (os_strlen(wpa_drivers[i]->name) == len &&
21658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    os_strncmp(driver, wpa_drivers[i]->name, len) ==
2166c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			    0) {
2167c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				/* First driver that succeeds wins */
2168c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				if (select_driver(wpa_s, i) == 0)
2169c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt					return 0;
2170c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			}
21718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
21728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		driver = pos + 1;
21748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} while (pos);
21758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_msg(wpa_s, MSG_ERROR, "Unsupported driver '%s'", name);
21778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return -1;
21788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
21798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
21828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
21838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ctx: Context pointer (wpa_s); this is the ctx variable registered
21848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *	with struct wpa_driver_ops::init()
21858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @src_addr: Source address of the EAPOL frame
21868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
21878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of the EAPOL data
21888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
21898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called for each received EAPOL frame. Most driver
21908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * interfaces rely on more generic OS mechanism for receiving frames through
21918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * l2_packet, but if such a mechanism is not available, the driver wrapper may
21928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * take care of received EAPOL frames and deliver them to the core supplicant
21938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * code by calling this function.
21948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
21958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
21968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     const u8 *buf, size_t len)
21978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
21988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
21998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
22018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
22028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->wpa_state < WPA_ASSOCIATED) {
22048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
22058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * There is possible race condition between receiving the
22068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * association event and the EAPOL frame since they are coming
22078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * through different paths from the driver. In order to avoid
22088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * issues in trying to process the EAPOL frame before receiving
22098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * association information, lets queue it for processing until
22108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * the association event is received.
22118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
22128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing "
22138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"of received EAPOL frame");
22148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpabuf_free(wpa_s->pending_eapol_rx);
22158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
22168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->pending_eapol_rx) {
22178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_get_time(&wpa_s->pending_eapol_rx_time);
22188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
22198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  ETH_ALEN);
22208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
22218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
22228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
22258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_iface) {
22268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
22278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
22288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
22308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
22328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Ignored received EAPOL frame since "
22338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"no key management is configured");
22348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
22358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->eapol_received == 0 &&
22388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
22398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
22408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     wpa_s->wpa_state != WPA_COMPLETED) &&
22418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    (wpa_s->current_ssid == NULL ||
22428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) {
22438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Timeout for completing IEEE 802.1X and WPA authentication */
22448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_req_auth_timeout(
22458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s,
22468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			(wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
22478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
22488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) ?
22498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			70 : 10, 0);
22508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->eapol_received++;
22528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->countermeasures) {
22548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "WPA: Countermeasures - dropped "
22558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"EAPOL packet");
22568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
22578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IBSS_RSN
22608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->current_ssid &&
22618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
22628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
22638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
22648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IBSS_RSN */
22668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Source address of the incoming EAPOL frame could be compared to the
22688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * current BSSID. However, it is possible that a centralized
22698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * Authenticator could be using another MAC address than the BSSID of
22708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * an AP, so just allow any address to be used for now. The replies are
22718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * still sent to the current BSSID (if available), though. */
22728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
22748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
22758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
22768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
22778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_poll(wpa_s);
22788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
22798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
22808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
22818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
22828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * Set portValid = TRUE here since we are going to skip 4-way
22838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * handshake processing which would normally set portValid. We
22848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * need this to allow the EAPOL state machines to be completed
22858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * without going through EAPOL-Key handshake.
22868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
22878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
22888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
22898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
22908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
22921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
22938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
22948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->driver->send_eapol) {
22958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
22968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (addr)
22978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
22988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else if (!(wpa_s->drv_flags &
22998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		     WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
23001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		l2_packet_deinit(wpa_s->l2);
23018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->l2 = l2_packet_init(wpa_s->ifname,
23028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   wpa_drv_get_mac_addr(wpa_s),
23038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   ETH_P_EAPOL,
23048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   wpa_supplicant_rx_eapol, wpa_s, 0);
23058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->l2 == NULL)
23068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
23078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
23088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
23098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (addr)
23108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
23118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
23128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
23148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Failed to get own L2 address");
23158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
23168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
23178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
23198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		MAC2STR(wpa_s->own_addr));
23201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
23211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
23221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return 0;
23231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
23241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
23251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
232604949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr,
232704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					   const u8 *buf, size_t len)
232804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
232904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
233004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	const struct l2_ethhdr *eth;
233104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
233204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (len < sizeof(*eth))
233304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return;
233404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	eth = (const struct l2_ethhdr *) buf;
233504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
233604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (os_memcmp(eth->h_dest, wpa_s->own_addr, ETH_ALEN) != 0 &&
233704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	    !(eth->h_dest[0] & 0x01)) {
233804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
233904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			" (bridge - not for this interface - ignore)",
234004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			MAC2STR(src_addr), MAC2STR(eth->h_dest));
234104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return;
234204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
234304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
234404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
234504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		" (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest));
234604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth),
234704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				len - sizeof(*eth));
234804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
234904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
235004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
23511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt/**
23521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * wpa_supplicant_driver_init - Initialize driver interface parameters
23531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * @wpa_s: Pointer to wpa_supplicant data
23541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Returns: 0 on success, -1 on failure
23551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt *
23561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * This function is called to initialize driver interface parameters.
23571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * wpa_drv_init() must have been called before this function to initialize the
23581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * driver interface.
23591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */
23601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
23611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
23621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	static int interface_count = 0;
23631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
23641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
23651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
23668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->bridge_ifname[0]) {
23688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
23698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"interface '%s'", wpa_s->bridge_ifname);
23708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->l2_br = l2_packet_init(wpa_s->bridge_ifname,
23718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      wpa_s->own_addr,
23728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      ETH_P_EAPOL,
237304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					      wpa_supplicant_rx_eapol_bridge,
237404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					      wpa_s, 1);
23758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->l2_br == NULL) {
23768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_msg(wpa_s, MSG_ERROR, "Failed to open l2_packet "
23778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"connection for the bridge interface '%s'",
23788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_s->bridge_ifname);
23798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
23808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
23818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
23828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_clear_keys(wpa_s, NULL);
23848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Make sure that TKIP countermeasures are not left enabled (could
23868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * happen if wpa_supplicant is killed during countermeasures. */
23878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_set_countermeasures(wpa_s, 0);
23888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
23908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_flush_pmkid(wpa_s);
23918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
23928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
2393c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_s->prev_scan_wildcard = 0;
2394c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
239504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_supplicant_enabled_networks(wpa_s)) {
23961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpa_supplicant_delayed_sched_scan(wpa_s, interface_count,
23971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						      100000))
23981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpa_supplicant_req_scan(wpa_s, interface_count,
23991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						100000);
24008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		interface_count++;
24018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else
24028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
24038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
24058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
24068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_daemon(const char *pid_file)
24098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
24108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "Daemonize..");
24118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return os_daemonize(pid_file);
24128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
24138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpa_supplicant * wpa_supplicant_alloc(void)
24168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
24178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s;
24188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s = os_zalloc(sizeof(*wpa_s));
24208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s == NULL)
24218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
24228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->scan_req = 1;
24238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->scan_interval = 5;
24248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->new_connection = 1;
24258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->parent = wpa_s;
24261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_s->sched_scanning = 0;
24278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpa_s;
24298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
24308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2432c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#ifdef CONFIG_HT_OVERRIDES
2433c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2434c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtstatic int wpa_set_htcap_mcs(struct wpa_supplicant *wpa_s,
2435c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			     struct ieee80211_ht_capabilities *htcaps,
2436c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			     struct ieee80211_ht_capabilities *htcaps_mask,
2437c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			     const char *ht_mcs)
2438c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
2439c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	/* parse ht_mcs into hex array */
2440c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	int i;
2441c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	const char *tmp = ht_mcs;
2442c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	char *end = NULL;
2443c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2444c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	/* If ht_mcs is null, do not set anything */
2445c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (!ht_mcs)
2446c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return 0;
2447c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2448c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	/* This is what we are setting in the kernel */
2449c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	os_memset(&htcaps->supported_mcs_set, 0, IEEE80211_HT_MCS_MASK_LEN);
2450c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2451c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_msg(wpa_s, MSG_DEBUG, "set_htcap, ht_mcs -:%s:-", ht_mcs);
2452c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2453c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
2454c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		errno = 0;
2455c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		long v = strtol(tmp, &end, 16);
2456c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		if (errno == 0) {
2457c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			wpa_msg(wpa_s, MSG_DEBUG,
2458c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				"htcap value[%i]: %ld end: %p  tmp: %p",
2459c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				i, v, end, tmp);
2460c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			if (end == tmp)
2461c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				break;
2462c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2463c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			htcaps->supported_mcs_set[i] = v;
2464c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			tmp = end;
2465c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		} else {
2466c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			wpa_msg(wpa_s, MSG_ERROR,
2467c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				"Failed to parse ht-mcs: %s, error: %s\n",
2468c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				ht_mcs, strerror(errno));
2469c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			return -1;
2470c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		}
2471c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
2472c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2473c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	/*
2474c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	 * If we were able to parse any values, then set mask for the MCS set.
2475c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	 */
2476c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (i) {
2477c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		os_memset(&htcaps_mask->supported_mcs_set, 0xff,
2478c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			  IEEE80211_HT_MCS_MASK_LEN - 1);
2479c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		/* skip the 3 reserved bits */
2480c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		htcaps_mask->supported_mcs_set[IEEE80211_HT_MCS_MASK_LEN - 1] =
2481c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			0x1f;
2482c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
2483c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2484c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	return 0;
2485c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
2486c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2487c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2488c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtstatic int wpa_disable_max_amsdu(struct wpa_supplicant *wpa_s,
2489c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				 struct ieee80211_ht_capabilities *htcaps,
2490c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				 struct ieee80211_ht_capabilities *htcaps_mask,
2491c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				 int disabled)
2492c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
2493c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	u16 msk;
2494c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2495c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
2496c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2497c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (disabled == -1)
2498c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return 0;
2499c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2500c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	msk = host_to_le16(HT_CAP_INFO_MAX_AMSDU_SIZE);
2501c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	htcaps_mask->ht_capabilities_info |= msk;
2502c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (disabled)
2503c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		htcaps->ht_capabilities_info &= msk;
2504c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	else
2505c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		htcaps->ht_capabilities_info |= msk;
2506c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2507c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	return 0;
2508c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
2509c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2510c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2511c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtstatic int wpa_set_ampdu_factor(struct wpa_supplicant *wpa_s,
2512c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				struct ieee80211_ht_capabilities *htcaps,
2513c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				struct ieee80211_ht_capabilities *htcaps_mask,
2514c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				int factor)
2515c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
2516c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
2517c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2518c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (factor == -1)
2519c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return 0;
2520c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2521c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (factor < 0 || factor > 3) {
2522c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "ampdu_factor: %d out of range. "
2523c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			"Must be 0-3 or -1", factor);
2524c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return -EINVAL;
2525c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
2526c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2527c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	htcaps_mask->a_mpdu_params |= 0x3; /* 2 bits for factor */
2528c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	htcaps->a_mpdu_params &= ~0x3;
2529c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	htcaps->a_mpdu_params |= factor & 0x3;
2530c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2531c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	return 0;
2532c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
2533c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2534c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2535c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtstatic int wpa_set_ampdu_density(struct wpa_supplicant *wpa_s,
2536c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				 struct ieee80211_ht_capabilities *htcaps,
2537c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				 struct ieee80211_ht_capabilities *htcaps_mask,
2538c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				 int density)
2539c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
2540c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
2541c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2542c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (density == -1)
2543c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return 0;
2544c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2545c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (density < 0 || density > 7) {
2546c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR,
2547c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			"ampdu_density: %d out of range. Must be 0-7 or -1.",
2548c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			density);
2549c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return -EINVAL;
2550c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	}
2551c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2552c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	htcaps_mask->a_mpdu_params |= 0x1C;
2553c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	htcaps->a_mpdu_params &= ~(0x1C);
2554c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	htcaps->a_mpdu_params |= (density << 2) & 0x1C;
2555c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2556c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	return 0;
2557c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
2558c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2559c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2560c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtstatic int wpa_set_disable_ht40(struct wpa_supplicant *wpa_s,
2561c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				struct ieee80211_ht_capabilities *htcaps,
2562c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				struct ieee80211_ht_capabilities *htcaps_mask,
2563c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt				int disabled)
2564c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
2565c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	/* Masking these out disables HT40 */
2566c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	u16 msk = host_to_le16(HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET |
2567c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			       HT_CAP_INFO_SHORT_GI40MHZ);
2568c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2569c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
2570c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2571c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (disabled)
2572c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		htcaps->ht_capabilities_info &= ~msk;
2573c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	else
2574c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		htcaps->ht_capabilities_info |= msk;
2575c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2576c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	htcaps_mask->ht_capabilities_info |= msk;
2577c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2578c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	return 0;
2579c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
2580c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2581c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2582c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidtvoid wpa_supplicant_apply_ht_overrides(
2583c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
2584c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	struct wpa_driver_associate_params *params)
2585c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
2586c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	struct ieee80211_ht_capabilities *htcaps;
2587c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	struct ieee80211_ht_capabilities *htcaps_mask;
2588c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2589c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (!ssid)
2590c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return;
2591c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2592c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	params->disable_ht = ssid->disable_ht;
2593c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	if (!params->htcaps || !params->htcaps_mask)
2594c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return;
2595c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2596c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	htcaps = (struct ieee80211_ht_capabilities *) params->htcaps;
2597c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	htcaps_mask = (struct ieee80211_ht_capabilities *) params->htcaps_mask;
2598c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_set_htcap_mcs(wpa_s, htcaps, htcaps_mask, ssid->ht_mcs);
2599c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_disable_max_amsdu(wpa_s, htcaps, htcaps_mask,
2600c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt			      ssid->disable_max_amsdu);
2601c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_set_ampdu_factor(wpa_s, htcaps, htcaps_mask, ssid->ampdu_factor);
2602c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_set_ampdu_density(wpa_s, htcaps, htcaps_mask, ssid->ampdu_density);
2603c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40);
2604c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
2605c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2606c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt#endif /* CONFIG_HT_OVERRIDES */
2607c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
2608c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
260904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtstatic int pcsc_reader_init(struct wpa_supplicant *wpa_s)
261004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
261104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef PCSC_FUNCS
261204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	size_t len;
261304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
261404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!wpa_s->conf->pcsc_reader)
261504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 0;
261604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
261704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->scard = scard_init(SCARD_TRY_BOTH, wpa_s->conf->pcsc_reader);
261804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!wpa_s->scard)
261904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 1;
262004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
262104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->conf->pcsc_pin &&
262204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	    scard_set_pin(wpa_s->scard, wpa_s->conf->pcsc_pin) < 0) {
262304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		scard_deinit(wpa_s->scard);
262404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->scard = NULL;
262504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "PC/SC PIN validation failed");
262604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
262704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
262804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
262904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	len = sizeof(wpa_s->imsi) - 1;
263004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
263104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		scard_deinit(wpa_s->scard);
263204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->scard = NULL;
263304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
263404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
263504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
263604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->imsi[len] = '\0';
263704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
263804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
263904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
264004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
264104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		   wpa_s->imsi, wpa_s->mnc_len);
264204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
264304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
264404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
264504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* PCSC_FUNCS */
264604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
264704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return 0;
264804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
264904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
265004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
265161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
265261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
265361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	char *val, *pos;
265461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
265561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	ext_password_deinit(wpa_s->ext_pw);
265661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_s->ext_pw = NULL;
265761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	eapol_sm_set_ext_pw_ctx(wpa_s->eapol, NULL);
265861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
265961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (!wpa_s->conf->ext_password_backend)
266061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return 0;
266161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
266261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	val = os_strdup(wpa_s->conf->ext_password_backend);
266361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (val == NULL)
266461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
266561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos = os_strchr(val, ':');
266661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (pos)
266761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		*pos++ = '\0';
266861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
266961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_printf(MSG_DEBUG, "EXT PW: Initialize backend '%s'", val);
267061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
267161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_s->ext_pw = ext_password_init(val, pos);
267261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_free(val);
267361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (wpa_s->ext_pw == NULL) {
267461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_printf(MSG_DEBUG, "EXT PW: Failed to initialize backend");
267561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
267661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
267761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	eapol_sm_set_ext_pw_ctx(wpa_s->eapol, wpa_s->ext_pw);
267861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
267961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return 0;
268061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
268161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
268261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
26838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
26848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     struct wpa_interface *iface)
26858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
26868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *ifname, *driver;
26878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_driver_capa capa;
26888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
26908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
26918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   iface->confname ? iface->confname : "N/A",
26928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   iface->driver ? iface->driver : "default",
26938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   iface->ctrl_interface ? iface->ctrl_interface : "N/A",
26948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   iface->bridge_ifname ? iface->bridge_ifname : "N/A");
26958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
26968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (iface->confname) {
26978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_BACKEND_FILE
26988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->confname = os_rel2abs_path(iface->confname);
26998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->confname == NULL) {
27008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Failed to get absolute path "
27018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "for configuration file '%s'.",
27028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   iface->confname);
27038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
27048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
27058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",
27068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   iface->confname, wpa_s->confname);
27078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_BACKEND_FILE */
27088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->confname = os_strdup(iface->confname);
27098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_BACKEND_FILE */
27108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->conf = wpa_config_read(wpa_s->confname);
27118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_s->conf == NULL) {
27128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Failed to read or parse "
27138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "configuration '%s'.", wpa_s->confname);
27148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
27158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
27168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
27188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * Override ctrl_interface and driver_param if set on command
27198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * line.
27208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
27218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (iface->ctrl_interface) {
27228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(wpa_s->conf->ctrl_interface);
27238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->conf->ctrl_interface =
27248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				os_strdup(iface->ctrl_interface);
27258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
27268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (iface->driver_param) {
27288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(wpa_s->conf->driver_param);
27298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->conf->driver_param =
27308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				os_strdup(iface->driver_param);
27318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
27328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else
27338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
27348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						     iface->driver_param);
27358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf == NULL) {
27378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "\nNo configuration found.");
27388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
27398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
27408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (iface->ifname == NULL) {
27428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "\nInterface name is required.");
27438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
27448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
27458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (os_strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
27468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "\nToo long interface name '%s'.",
27478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   iface->ifname);
27488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
27498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
27508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
27518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (iface->bridge_ifname) {
27538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strlen(iface->bridge_ifname) >=
27548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    sizeof(wpa_s->bridge_ifname)) {
27558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "\nToo long bridge interface "
27568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "name '%s'.", iface->bridge_ifname);
27578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
27588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
27598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_strlcpy(wpa_s->bridge_ifname, iface->bridge_ifname,
27608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   sizeof(wpa_s->bridge_ifname));
27618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
27628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* RSNA Supplicant Key Management - INITIALIZE */
27648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
27658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
27668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Initialize driver interface and register driver event handler before
27688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * L2 receive handler so that association events are processed before
27698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * EAPOL-Key packets if both become available for the same select()
27708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * call. */
27718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	driver = iface->driver;
27728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtnext_driver:
27738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_supplicant_set_driver(wpa_s, driver) < 0)
27748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
27758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
27778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->drv_priv == NULL) {
27788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		const char *pos;
27798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pos = driver ? os_strchr(driver, ',') : NULL;
27808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (pos) {
27818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
27828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"driver interface - try next driver wrapper");
27838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			driver = pos + 1;
27848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			goto next_driver;
27858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
27868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Failed to initialize driver "
27878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"interface");
27888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
27898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
27908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
27918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected "
27928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"driver_param '%s'", wpa_s->conf->driver_param);
27938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
27948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
27958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
27968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ifname = wpa_drv_get_ifname(wpa_s);
27978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
27988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced "
27998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"interface name with '%s'", ifname);
28008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
28018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
28028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_supplicant_init_wpa(wpa_s) < 0)
28048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
28058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
28078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
28088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  NULL);
28098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
28108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
28128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
28138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
28148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
28158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"dot11RSNAConfigPMKLifetime");
28168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
28178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
28188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
28208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
28218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
28228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
28238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"dot11RSNAConfigPMKReauthThreshold");
28248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
28258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
28268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->dot11RSNAConfigSATimeout &&
28288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
28298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     wpa_s->conf->dot11RSNAConfigSATimeout)) {
28308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
28318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			"dot11RSNAConfigSATimeout");
28328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
28338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
28348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
28361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						      &wpa_s->hw.num_modes,
28371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt						      &wpa_s->hw.flags);
28381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
28398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_drv_get_capa(wpa_s, &capa) == 0) {
28401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_s->drv_capa_known = 1;
28418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->drv_flags = capa.flags;
284204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_s->drv_enc = capa.enc;
28431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
28448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->max_scan_ssids = capa.max_scan_ssids;
28451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
28461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_s->sched_scan_supported = capa.sched_scan_supported;
28471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_s->max_match_sets = capa.max_match_sets;
28488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
28498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->max_stations = capa.max_stations;
28508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
28518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->max_remain_on_chan == 0)
28528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->max_remain_on_chan = 1000;
28538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_supplicant_driver_init(wpa_s) < 0)
28558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
28568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_TDLS
28588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_tdls_init(wpa_s->wpa))
28598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
28608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_TDLS */
28618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
28638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
28648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "Failed to set country");
28658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
28668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
28678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpas_wps_init(wpa_s))
28698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
28708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_supplicant_init_eapol(wpa_s) < 0)
28728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
28738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
28748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
28768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ctrl_iface == NULL) {
28778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR,
28788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "Failed to initialize control interface '%s'.\n"
28798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "You may have another wpa_supplicant process "
28808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "already running or the file was\n"
28818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "left by an unclean termination of wpa_supplicant "
28828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "in which case you will need\n"
28838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "to manually remove this file before starting "
28848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "wpa_supplicant again.\n",
28858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   wpa_s->conf->ctrl_interface);
28868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
28878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
28888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
28891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpa_s->gas = gas_query_init(wpa_s);
28901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->gas == NULL) {
28911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpa_printf(MSG_ERROR, "Failed to initialize GAS query");
28921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
28931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
28941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
28958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
28968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
28978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
28988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
28998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
29008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
29018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_bss_init(wpa_s) < 0)
29038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
29048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
290504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (pcsc_reader_init(wpa_s) < 0)
290604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
290704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
290861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (wpas_init_ext_pw(wpa_s) < 0)
290961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return -1;
291061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
29118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
29128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
29138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
2916e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt					int notify, int terminate)
29178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
29188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->drv_priv) {
29198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_deauthenticate(wpa_s,
29208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					      WLAN_REASON_DEAUTH_LEAVING);
29218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_set_countermeasures(wpa_s, 0);
29238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_clear_keys(wpa_s, NULL);
29248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
29258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_cleanup(wpa_s);
29278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
292804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_P2P
292904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s == wpa_s->global->p2p_init_wpa_s && wpa_s->global->p2p) {
293004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Disable P2P since removing "
293104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			"the management interface is being removed");
293204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpas_p2p_deinit_global(wpa_s->global);
293304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
293404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_P2P */
293504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
29368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->drv_priv)
29378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drv_deinit(wpa_s);
2938622b66d6efd0cccfeb8623184fadf2f76e7e8206Irfan Sheriff
2939e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt	if (notify)
2940e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt		wpas_notify_iface_removed(wpa_s);
2941e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt
2942e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt	if (terminate)
2943e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
2944622b66d6efd0cccfeb8623184fadf2f76e7e8206Irfan Sheriff
2945622b66d6efd0cccfeb8623184fadf2f76e7e8206Irfan Sheriff	if (wpa_s->ctrl_iface) {
2946622b66d6efd0cccfeb8623184fadf2f76e7e8206Irfan Sheriff		wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
2947622b66d6efd0cccfeb8623184fadf2f76e7e8206Irfan Sheriff		wpa_s->ctrl_iface = NULL;
2948622b66d6efd0cccfeb8623184fadf2f76e7e8206Irfan Sheriff	}
2949622b66d6efd0cccfeb8623184fadf2f76e7e8206Irfan Sheriff
2950622b66d6efd0cccfeb8623184fadf2f76e7e8206Irfan Sheriff	if (wpa_s->conf != NULL) {
2951622b66d6efd0cccfeb8623184fadf2f76e7e8206Irfan Sheriff		wpa_config_free(wpa_s->conf);
2952622b66d6efd0cccfeb8623184fadf2f76e7e8206Irfan Sheriff		wpa_s->conf = NULL;
2953622b66d6efd0cccfeb8623184fadf2f76e7e8206Irfan Sheriff	}
29548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
29558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
29588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_add_iface - Add a new network interface
29598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: Pointer to global data from wpa_supplicant_init()
29608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @iface: Interface configuration options
29618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the created interface or %NULL on failure
29628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
29638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to add new network interfaces for %wpa_supplicant.
29648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This can be called before wpa_supplicant_run() to add interfaces before the
29658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * main event loop has been started. In addition, new interfaces can be added
29668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * dynamically while %wpa_supplicant is already running. This could happen,
29678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * e.g., when a hotplug network adapter is inserted.
29688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
29698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
29708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 struct wpa_interface *iface)
29718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
29728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s;
29738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_interface t_iface;
29748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid;
29758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global == NULL || iface == NULL)
29778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
29788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s = wpa_supplicant_alloc();
29808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s == NULL)
29818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
29828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->global = global;
29848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
29858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	t_iface = *iface;
29868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->params.override_driver) {
29878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "Override interface parameter: driver "
29888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "('%s' -> '%s')",
29898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   iface->driver, global->params.override_driver);
29908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		t_iface.driver = global->params.override_driver;
29918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
29928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->params.override_ctrl_interface) {
29938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "Override interface parameter: "
29948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "ctrl_interface ('%s' -> '%s')",
29958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   iface->ctrl_interface,
29968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   global->params.override_ctrl_interface);
29978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		t_iface.ctrl_interface =
29988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			global->params.override_ctrl_interface;
29998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
30008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
30018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "Failed to add interface %s",
30028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   iface->ifname);
3003e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt		wpa_supplicant_deinit_iface(wpa_s, 0, 0);
30048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(wpa_s);
30058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
30068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
30078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Notify the control interfaces about new iface */
30098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpas_notify_iface_added(wpa_s)) {
3010e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt		wpa_supplicant_deinit_iface(wpa_s, 1, 0);
30118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(wpa_s);
30128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
30138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
30148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
30168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpas_notify_network_added(wpa_s, ssid);
30178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->next = global->ifaces;
30198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	global->ifaces = wpa_s;
30208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
302204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
30238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpa_s;
30258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
30268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
30298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_remove_iface - Remove a network interface
30308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: Pointer to global data from wpa_supplicant_init()
30318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to the network interface to be removed
30328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 if interface was removed, -1 if interface was not found
30338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
30348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to dynamically remove network interfaces from
30358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In
30368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * addition, this function is used to remove all remaining interfaces when
30378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * %wpa_supplicant is terminated.
30388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
30398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_remove_iface(struct wpa_global *global,
3040e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt				struct wpa_supplicant *wpa_s,
3041e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt				int terminate)
30428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
30438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *prev;
30448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/* Remove interface from the global list of interfaces */
30468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	prev = global->ifaces;
30478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (prev == wpa_s) {
30488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		global->ifaces = wpa_s->next;
30498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else {
30508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		while (prev && prev->next != wpa_s)
30518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			prev = prev->next;
30528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (prev == NULL)
30538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
30548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		prev->next = wpa_s->next;
30558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
30568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_dbg(wpa_s, MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
30588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->p2p_group_formation == wpa_s)
30608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		global->p2p_group_formation = NULL;
3061e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt	wpa_supplicant_deinit_iface(wpa_s, 1, terminate);
30628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(wpa_s);
30638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
30658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
30668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
30698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_get_eap_mode - Get the current EAP mode
30708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @wpa_s: Pointer to the network interface
30718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the eap mode or the string "UNKNOWN" if not found
30728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
30738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s)
30748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
30758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *eapol_method;
30768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) == 0 &&
30788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
30798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "NO-EAP";
30808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
30818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eapol_method = eapol_sm_get_method_name(wpa_s->eapol);
30838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (eapol_method == NULL)
30848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return "UNKNOWN-EAP";
30858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return eapol_method;
30878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
30888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
30908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
30918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_get_iface - Get a new network interface
30928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: Pointer to global data from wpa_supplicant_init()
30938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ifname: Interface name
30948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the interface or %NULL if not found
30958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
30968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
30978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 const char *ifname)
30988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
30998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s;
31008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
31028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (os_strcmp(wpa_s->ifname, ifname) == 0)
31038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return wpa_s;
31048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
31058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return NULL;
31068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
31078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_WPA_MSG
31108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const char * wpa_supplicant_msg_ifname_cb(void *ctx)
31118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
31128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
31138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s == NULL)
31148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
31158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return wpa_s->ifname;
31168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
31178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_WPA_MSG */
31188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
31218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_init - Initialize %wpa_supplicant
31228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @params: Parameters for %wpa_supplicant
31238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to global %wpa_supplicant data, or %NULL on failure
31248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
31258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to initialize %wpa_supplicant. After successful
31268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * initialization, the returned data pointer can be used to add and remove
31278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * network interfaces, and eventually, to deinitialize %wpa_supplicant.
31288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
31298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_global * wpa_supplicant_init(struct wpa_params *params)
31308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
31318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_global *global;
31328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret, i;
31338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (params == NULL)
31358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
31368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef CONFIG_DRIVER_NDIS
31381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	{
31391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		void driver_ndis_init_ops(void);
31401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		driver_ndis_init_ops();
31411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
31421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* CONFIG_DRIVER_NDIS */
31431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
31448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef CONFIG_NO_WPA_MSG
31458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
31468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_NO_WPA_MSG */
31478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_debug_open_file(params->wpa_debug_file_path);
31498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (params->wpa_debug_syslog)
31508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_debug_open_syslog();
315104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (params->wpa_debug_tracing) {
315204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		ret = wpa_debug_open_linux_tracing();
315304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (ret) {
315404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_printf(MSG_ERROR,
315504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   "Failed to enable trace logging");
315604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			return NULL;
315704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
315804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
31598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = eap_register_methods();
31618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret) {
31628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Failed to register EAP methods");
31638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (ret == -2)
31648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Two or more EAP methods used "
31658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "the same EAP type.");
31668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
31678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
31688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	global = os_zalloc(sizeof(*global));
31708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global == NULL)
31718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
31728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dl_list_init(&global->p2p_srv_bonjour);
31738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dl_list_init(&global->p2p_srv_upnp);
31748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	global->params.daemonize = params->daemonize;
31758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	global->params.wait_for_monitor = params->wait_for_monitor;
31768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
31778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (params->pid_file)
31788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		global->params.pid_file = os_strdup(params->pid_file);
31798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (params->ctrl_interface)
31808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		global->params.ctrl_interface =
31818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_strdup(params->ctrl_interface);
31828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (params->override_driver)
31838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		global->params.override_driver =
31848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_strdup(params->override_driver);
31858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (params->override_ctrl_interface)
31868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		global->params.override_ctrl_interface =
31878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_strdup(params->override_ctrl_interface);
31888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_debug_level = global->params.wpa_debug_level =
31898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params->wpa_debug_level;
31908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_debug_show_keys = global->params.wpa_debug_show_keys =
31918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params->wpa_debug_show_keys;
31928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_debug_timestamp = global->params.wpa_debug_timestamp =
31938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params->wpa_debug_timestamp;
31948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "wpa_supplicant v" VERSION_STR);
31968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
31978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (eloop_init()) {
31988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Failed to initialize event loop");
31998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_deinit(global);
32008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
32018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
32028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
320375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	random_init(params->entropy_file);
32048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
32068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->ctrl_iface == NULL) {
32078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_deinit(global);
32088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
32098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
32108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpas_notify_supplicant_initialized(global)) {
32128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_deinit(global);
32138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
32148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
32158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; wpa_drivers[i]; i++)
32178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		global->drv_count++;
32188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->drv_count == 0) {
32198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "No drivers enabled");
32208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_deinit(global);
32218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
32228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
32238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	global->drv_priv = os_zalloc(global->drv_count * sizeof(void *));
32248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->drv_priv == NULL) {
32258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_deinit(global);
32268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
32278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
32288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
322961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY
323061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (wifi_display_init(global) < 0) {
323161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_printf(MSG_ERROR, "Failed to initialize Wi-Fi Display");
323261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_supplicant_deinit(global);
323361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return NULL;
323461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
323561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */
323661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
32378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return global;
32388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
32398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
32428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_run - Run the %wpa_supplicant main event loop
32438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: Pointer to global data from wpa_supplicant_init()
32448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 after successful event loop run, -1 on failure
32458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
32468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function starts the main event loop and continues running as long as
32478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * there are any remaining events. In most cases, this function is running as
32488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * long as the %wpa_supplicant process in still in use.
32498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
32508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_run(struct wpa_global *global)
32518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
32528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s;
32538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->params.daemonize &&
32558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_supplicant_daemon(global->params.pid_file))
32568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
32578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->params.wait_for_monitor) {
32598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
32608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (wpa_s->ctrl_iface)
32618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				wpa_supplicant_ctrl_iface_wait(
32628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					wpa_s->ctrl_iface);
32638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
32648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_register_signal_terminate(wpa_supplicant_terminate, global);
32668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
32678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_run();
32698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
32718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
32728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/**
32758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant_deinit - Deinitialize %wpa_supplicant
32768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @global: Pointer to global data from wpa_supplicant_init()
32778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
32788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called to deinitialize %wpa_supplicant and to free all
32798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * allocated resources. Remaining network interfaces will also be removed.
32808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
32818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_deinit(struct wpa_global *global)
32828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
32838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
32848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global == NULL)
32868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
32871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
328861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY
328961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wifi_display_deinit(global);
329061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */
32918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
32928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_p2p_deinit_global(global);
32938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
32948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	while (global->ifaces)
3296e15c7b57cc7a214d5adaa0fc1d7204378eaf62a5Dmitry Shmidt		wpa_supplicant_remove_iface(global, global->ifaces, 1);
32978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
32988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->ctrl_iface)
32998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_global_ctrl_iface_deinit(global->ctrl_iface);
33008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_notify_supplicant_deinitialized(global);
33028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eap_peer_unregister_methods();
33048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_AP
33058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eap_server_unregister_methods();
33068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_AP */
33078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
33098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (!global->drv_priv[i])
33108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
33118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_drivers[i]->global_deinit(global->drv_priv[i]);
33128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
33138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(global->drv_priv);
33148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	random_deinit();
33168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_destroy();
33188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (global->params.pid_file) {
33208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_daemonize_terminate(global->params.pid_file);
33218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(global->params.pid_file);
33228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
33238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(global->params.ctrl_interface);
33248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(global->params.override_driver);
33258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(global->params.override_ctrl_interface);
33268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
332704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	os_free(global->p2p_disallow_freq);
332804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
33298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(global);
33308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_debug_close_syslog();
33318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_debug_close_file();
333204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_debug_close_linux_tracing();
33338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
33348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
33378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
33388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
33398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
33408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		char country[3];
33418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		country[0] = wpa_s->conf->country[0];
33428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		country[1] = wpa_s->conf->country[1];
33438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		country[2] = '\0';
33448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (wpa_drv_set_country(wpa_s, country) < 0) {
33458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_printf(MSG_ERROR, "Failed to set country code "
33468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				   "'%s'", country);
33478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
33488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
33498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
335061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (wpa_s->conf->changed_parameters & CFG_CHANGED_EXT_PW_BACKEND)
335161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpas_init_ext_pw(wpa_s);
335261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
33538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
33548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_wps_update_config(wpa_s);
33558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
33568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
33588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_p2p_update_config(wpa_s);
33598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
33608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->conf->changed_parameters = 0;
33628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
33638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void add_freq(int *freqs, int *num_freqs, int freq)
33668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
33678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int i;
33688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < *num_freqs; i++) {
33708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (freqs[i] == freq)
33718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return;
33728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
33738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	freqs[*num_freqs] = freq;
33758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	(*num_freqs)++;
33768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
33778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s)
33808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
33818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_bss *bss, *cbss;
33828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const int max_freqs = 10;
33838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int *freqs;
33848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int num_freqs = 0;
33858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	freqs = os_zalloc(sizeof(int) * (max_freqs + 1));
33878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (freqs == NULL)
33888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
33898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	cbss = wpa_s->current_bss;
33918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
33928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
33938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (bss == cbss)
33948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			continue;
33958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (bss->ssid_len == cbss->ssid_len &&
33968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
33978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    wpa_blacklist_get(wpa_s, bss->bssid) == NULL) {
33988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			add_freq(freqs, &num_freqs, bss->freq);
33998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			if (num_freqs == max_freqs)
34008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				break;
34018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
34028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
34038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (num_freqs == 0) {
34058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(freqs);
34068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		freqs = NULL;
34078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
34088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return freqs;
34108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
34118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
34148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
34158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int timeout;
34168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int count;
34178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int *freqs = NULL;
34188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
3420c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	 * Remove possible authentication timeout since the connection failed.
3421c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	 */
3422c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
3423c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
3424c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt	/*
34258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * Add the failed BSSID into the blacklist and speed up next scan
34268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * attempt if there could be other APs that could accept association.
34278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * The current blacklist count indicates how many times we have tried
34288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * connecting to this AP and multiple attempts mean that other APs are
34298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * either not available or has already been tried, so that we can start
34308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * increasing the delay here to avoid constant scanning.
34318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
34328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	count = wpa_blacklist_add(wpa_s, bssid);
34338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (count == 1 && wpa_s->current_bss) {
34348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/*
34358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * This BSS was not in the blacklist before. If there is
34368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * another BSS available for the same ESS, we should try that
34378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * next. Otherwise, we may as well try this one once more
34388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 * before allowing other, likely worse, ESSes to be considered.
34398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		 */
34408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		freqs = get_bss_freqs_in_ess(wpa_s);
34418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (freqs) {
34428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
34438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				"has been seen; try it next");
34448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_blacklist_add(wpa_s, bssid);
34458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			/*
34468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * On the next scan, go through only the known channels
34478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * used in this ESS based on previous scans to speed up
34488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 * common load balancing use case.
34498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			 */
34508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			os_free(wpa_s->next_scan_freqs);
34518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_s->next_scan_freqs = freqs;
34528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
34538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
34548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (count) {
34568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 1:
34578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		timeout = 100;
34588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
34598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 2:
34608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		timeout = 500;
34618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
34628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case 3:
34638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		timeout = 1000;
34648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
34658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	default:
34668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		timeout = 5000;
34678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
34688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
34698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
34708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * TODO: if more than one possible AP is available in scan results,
34718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * could try the other ones before requesting a new scan.
34728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
34738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_req_scan(wpa_s, timeout / 1000,
34748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				1000 * (timeout % 1000));
347561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
347661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_P2P
3477dc7b71324df9788e194745e8ab9386a4619a623aJouni Malinen	if (wpa_s->global->p2p_cb_on_scan_complete && !wpa_s->global->p2p_disabled &&
347861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	    wpa_s->global->p2p != NULL) {
3479dc7b71324df9788e194745e8ab9386a4619a623aJouni Malinen		wpa_s->global->p2p_cb_on_scan_complete = 0;
348061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (p2p_other_scan_completed(wpa_s->global->p2p) == 1) {
348161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Pending P2P operation "
348261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				"continued after failed association");
348361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		}
348461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
348561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_P2P */
34868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
34871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
34881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
34891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
34901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
34911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return wpa_s->conf->ap_scan == 2 ||
34921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		(wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
34931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
3494c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
349504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
349604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
349704949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
349804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					      struct wpa_ssid *ssid,
349904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					      const char *field,
350004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					      const char *value)
350104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
350204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef IEEE8021X_EAPOL
350304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	struct eap_peer_config *eap = &ssid->eap;
350404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
350504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
350604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
350704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			      (const u8 *) value, os_strlen(value));
350804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
350904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	switch (wpa_supplicant_ctrl_req_from_string(field)) {
351004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case WPA_CTRL_REQ_EAP_IDENTITY:
351104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_free(eap->identity);
351204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->identity = (u8 *) os_strdup(value);
351304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->identity_len = os_strlen(value);
351404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->pending_req_identity = 0;
351504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (ssid == wpa_s->current_ssid)
351604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s->reassociate = 1;
351704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		break;
351804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case WPA_CTRL_REQ_EAP_PASSWORD:
351904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_free(eap->password);
352004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->password = (u8 *) os_strdup(value);
352104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->password_len = os_strlen(value);
352204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->pending_req_password = 0;
352304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (ssid == wpa_s->current_ssid)
352404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s->reassociate = 1;
352504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		break;
352604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
352704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_free(eap->new_password);
352804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->new_password = (u8 *) os_strdup(value);
352904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->new_password_len = os_strlen(value);
353004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->pending_req_new_password = 0;
353104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (ssid == wpa_s->current_ssid)
353204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s->reassociate = 1;
353304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		break;
353404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case WPA_CTRL_REQ_EAP_PIN:
353504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_free(eap->pin);
353604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->pin = os_strdup(value);
353704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->pending_req_pin = 0;
353804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (ssid == wpa_s->current_ssid)
353904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s->reassociate = 1;
354004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		break;
354104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case WPA_CTRL_REQ_EAP_OTP:
354204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_free(eap->otp);
354304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->otp = (u8 *) os_strdup(value);
354404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->otp_len = os_strlen(value);
354504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_free(eap->pending_req_otp);
354604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->pending_req_otp = NULL;
354704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->pending_req_otp_len = 0;
354804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		break;
354904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	case WPA_CTRL_REQ_EAP_PASSPHRASE:
355004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		os_free(eap->private_key_passwd);
355104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->private_key_passwd = (u8 *) os_strdup(value);
355204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		eap->pending_req_passphrase = 0;
355304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (ssid == wpa_s->current_ssid)
355404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			wpa_s->reassociate = 1;
355504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		break;
355604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	default:
355704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
355804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
355904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
356004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
356104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return 0;
356204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#else /* IEEE8021X_EAPOL */
356304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
356404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return -1;
356504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* IEEE8021X_EAPOL */
356604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
356704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
356804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
356904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
357004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
357104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
357204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	int i;
357304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	unsigned int drv_enc;
357404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
357504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (ssid == NULL)
357604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 1;
357704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
357804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (ssid->disabled)
357904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 1;
358004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
358104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s && wpa_s->drv_capa_known)
358204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		drv_enc = wpa_s->drv_enc;
358304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	else
358404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		drv_enc = (unsigned int) -1;
358504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
358604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	for (i = 0; i < NUM_WEP_KEYS; i++) {
358704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		size_t len = ssid->wep_key_len[i];
358804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (len == 0)
358904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			continue;
359004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (len == 5 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40))
359104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			continue;
359204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (len == 13 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104))
359304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			continue;
359404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (len == 16 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP128))
359504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			continue;
359604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 1; /* invalid WEP key */
359704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	}
359804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
359961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
360061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	    !ssid->ext_psk)
360161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return 1;
360261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
360304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return 0;
360404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
360504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
360604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
3607687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidtint wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
3608c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
36092fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt	if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
3610c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt		return 1;
36112fb777c379ad560c309c54b96c2c13291da23f54Dmitry Shmidt	if (wpa_s->global->conc_pref == WPA_CONC_PREF_STA)
3612687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt		return 0;
3613687922c7347bdc3b4f8c921efe1d1388cb3baac0Dmitry Shmidt	return -1;
3614c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
361561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
361661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
361761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid wpas_auth_failed(struct wpa_supplicant *wpa_s)
361861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
361961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	struct wpa_ssid *ssid = wpa_s->current_ssid;
362061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	int dur;
362161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	struct os_time now;
362261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
362361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (ssid == NULL) {
362461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_printf(MSG_DEBUG, "Authentication failure but no known "
362561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			   "SSID block");
362661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return;
362761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
362861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
362961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
363061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return;
363161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
363261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	ssid->auth_failures++;
363361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (ssid->auth_failures > 50)
363461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		dur = 300;
363561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	else if (ssid->auth_failures > 20)
363661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		dur = 120;
363761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	else if (ssid->auth_failures > 10)
363861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		dur = 60;
363961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	else if (ssid->auth_failures > 5)
364061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		dur = 30;
364161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	else if (ssid->auth_failures > 1)
364261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		dur = 20;
364361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	else
364461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		dur = 10;
364561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
364661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_get_time(&now);
364761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (now.sec + dur <= ssid->disabled_until.sec)
364861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return;
364961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
365061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	ssid->disabled_until.sec = now.sec + dur;
365161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
365261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TEMP_DISABLED
365361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		"id=%d ssid=\"%s\" auth_failures=%u duration=%d",
365461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
365561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		ssid->auth_failures, dur);
365661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
365761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
365861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
365961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtvoid wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
366061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			      struct wpa_ssid *ssid, int clear_failures)
366161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
366261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (ssid == NULL)
366361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return;
366461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
366561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (ssid->disabled_until.sec) {
366661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REENABLED
366761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			"id=%d ssid=\"%s\"",
366861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
366961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
367061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	ssid->disabled_until.sec = 0;
367161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	ssid->disabled_until.usec = 0;
367261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (clear_failures)
367361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		ssid->auth_failures = 0;
367461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
3675