blob: e58899295d2043db1d6a44c0c726d8ff46cbc409 [file] [log] [blame]
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001/*
2 * WPA Supplicant
Dmitry Shmidt807291d2015-01-27 13:40:23 -08003 * Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi>
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004 *
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07007 *
8 * This file implements functions for registering and unregistering
9 * %wpa_supplicant interfaces. In addition, this file contains number of
10 * functions for managing network connections.
11 */
12
13#include "includes.h"
14
15#include "common.h"
16#include "crypto/random.h"
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080017#include "crypto/sha1.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070018#include "eapol_supp/eapol_supp_sm.h"
19#include "eap_peer/eap.h"
Dmitry Shmidt34af3062013-07-11 10:46:32 -070020#include "eap_peer/eap_proxy.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070021#include "eap_server/eap_methods.h"
22#include "rsn_supp/wpa.h"
23#include "eloop.h"
24#include "config.h"
Dmitry Shmidt61d9df32012-08-29 16:22:06 -070025#include "utils/ext_password.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070026#include "l2_packet/l2_packet.h"
27#include "wpa_supplicant_i.h"
28#include "driver_i.h"
29#include "ctrl_iface.h"
30#include "pcsc_funcs.h"
31#include "common/version.h"
32#include "rsn_supp/preauth.h"
33#include "rsn_supp/pmksa_cache.h"
34#include "common/wpa_ctrl.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070035#include "common/ieee802_11_defs.h"
Dmitry Shmidtff787d52015-01-12 13:01:47 -080036#include "common/hw_features_common.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070037#include "p2p/p2p.h"
Dmitry Shmidtd80a4012015-11-05 16:35:40 -080038#include "fst/fst.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070039#include "blacklist.h"
40#include "wpas_glue.h"
41#include "wps_supplicant.h"
42#include "ibss_rsn.h"
43#include "sme.h"
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080044#include "gas_query.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070045#include "ap.h"
46#include "p2p_supplicant.h"
Dmitry Shmidt61d9df32012-08-29 16:22:06 -070047#include "wifi_display.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070048#include "notify.h"
49#include "bgscan.h"
Dmitry Shmidt04949592012-07-19 12:16:46 -070050#include "autoscan.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070051#include "bss.h"
52#include "scan.h"
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080053#include "offchannel.h"
Dmitry Shmidt04949592012-07-19 12:16:46 -070054#include "hs20_supplicant.h"
Dmitry Shmidt44c95782013-05-17 09:51:35 -070055#include "wnm_sta.h"
Dmitry Shmidt5a1480c2014-05-12 09:46:02 -070056#include "wpas_kay.h"
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -080057#include "mesh.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070058
Dmitry Shmidt1d755d02015-04-28 10:34:29 -070059const char *const wpa_supplicant_version =
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070060"wpa_supplicant v" VERSION_STR "\n"
Dmitry Shmidt807291d2015-01-27 13:40:23 -080061"Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi> and contributors";
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070062
Dmitry Shmidt1d755d02015-04-28 10:34:29 -070063const char *const wpa_supplicant_license =
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -080064"This software may be distributed under the terms of the BSD license.\n"
65"See README for more details.\n"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070066#ifdef EAP_TLS_OPENSSL
67"\nThis product includes software developed by the OpenSSL Project\n"
68"for use in the OpenSSL Toolkit (http://www.openssl.org/)\n"
69#endif /* EAP_TLS_OPENSSL */
70;
71
72#ifndef CONFIG_NO_STDOUT_DEBUG
73/* Long text divided into parts in order to fit in C89 strings size limits. */
Dmitry Shmidt1d755d02015-04-28 10:34:29 -070074const char *const wpa_supplicant_full_license1 =
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -080075"";
Dmitry Shmidt1d755d02015-04-28 10:34:29 -070076const char *const wpa_supplicant_full_license2 =
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -080077"This software may be distributed under the terms of the BSD license.\n"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070078"\n"
79"Redistribution and use in source and binary forms, with or without\n"
80"modification, are permitted provided that the following conditions are\n"
81"met:\n"
82"\n";
Dmitry Shmidt1d755d02015-04-28 10:34:29 -070083const char *const wpa_supplicant_full_license3 =
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070084"1. Redistributions of source code must retain the above copyright\n"
85" notice, this list of conditions and the following disclaimer.\n"
86"\n"
87"2. Redistributions in binary form must reproduce the above copyright\n"
88" notice, this list of conditions and the following disclaimer in the\n"
89" documentation and/or other materials provided with the distribution.\n"
90"\n";
Dmitry Shmidt1d755d02015-04-28 10:34:29 -070091const char *const wpa_supplicant_full_license4 =
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070092"3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
93" names of its contributors may be used to endorse or promote products\n"
94" derived from this software without specific prior written permission.\n"
95"\n"
96"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
97"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
98"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
99"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n";
Dmitry Shmidt1d755d02015-04-28 10:34:29 -0700100const char *const wpa_supplicant_full_license5 =
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700101"OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
102"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
103"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
104"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
105"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
106"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
107"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
108"\n";
109#endif /* CONFIG_NO_STDOUT_DEBUG */
110
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700111/* Configure default/group WEP keys for static WEP */
112int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
113{
114 int i, set = 0;
115
116 for (i = 0; i < NUM_WEP_KEYS; i++) {
117 if (ssid->wep_key_len[i] == 0)
118 continue;
119
120 set = 1;
121 wpa_drv_set_key(wpa_s, WPA_ALG_WEP, NULL,
122 i, i == ssid->wep_tx_keyidx, NULL, 0,
123 ssid->wep_key[i], ssid->wep_key_len[i]);
124 }
125
126 return set;
127}
128
129
Dmitry Shmidt51b6ea82013-05-08 10:42:09 -0700130int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s,
131 struct wpa_ssid *ssid)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700132{
133 u8 key[32];
134 size_t keylen;
135 enum wpa_alg alg;
136 u8 seq[6] = { 0 };
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800137 int ret;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700138
139 /* IBSS/WPA-None uses only one key (Group) for both receiving and
140 * sending unicast and multicast packets. */
141
142 if (ssid->mode != WPAS_MODE_IBSS) {
143 wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid mode %d (not "
144 "IBSS/ad-hoc) for WPA-None", ssid->mode);
145 return -1;
146 }
147
148 if (!ssid->psk_set) {
149 wpa_msg(wpa_s, MSG_INFO, "WPA: No PSK configured for "
150 "WPA-None");
151 return -1;
152 }
153
154 switch (wpa_s->group_cipher) {
155 case WPA_CIPHER_CCMP:
156 os_memcpy(key, ssid->psk, 16);
157 keylen = 16;
158 alg = WPA_ALG_CCMP;
159 break;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700160 case WPA_CIPHER_GCMP:
161 os_memcpy(key, ssid->psk, 16);
162 keylen = 16;
163 alg = WPA_ALG_GCMP;
164 break;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700165 case WPA_CIPHER_TKIP:
166 /* WPA-None uses the same Michael MIC key for both TX and RX */
167 os_memcpy(key, ssid->psk, 16 + 8);
168 os_memcpy(key + 16 + 8, ssid->psk + 16, 8);
169 keylen = 32;
170 alg = WPA_ALG_TKIP;
171 break;
172 default:
173 wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid group cipher %d for "
174 "WPA-None", wpa_s->group_cipher);
175 return -1;
176 }
177
178 /* TODO: should actually remember the previously used seq#, both for TX
179 * and RX from each STA.. */
180
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800181 ret = wpa_drv_set_key(wpa_s, alg, NULL, 0, 1, seq, 6, key, keylen);
182 os_memset(key, 0, sizeof(key));
183 return ret;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700184}
185
186
187static void wpa_supplicant_timeout(void *eloop_ctx, void *timeout_ctx)
188{
189 struct wpa_supplicant *wpa_s = eloop_ctx;
190 const u8 *bssid = wpa_s->bssid;
191 if (is_zero_ether_addr(bssid))
192 bssid = wpa_s->pending_bssid;
193 wpa_msg(wpa_s, MSG_INFO, "Authentication with " MACSTR " timed out.",
194 MAC2STR(bssid));
195 wpa_blacklist_add(wpa_s, bssid);
196 wpa_sm_notify_disassoc(wpa_s->wpa);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800197 wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700198 wpa_s->reassociate = 1;
199
200 /*
201 * If we timed out, the AP or the local radio may be busy.
202 * So, wait a second until scanning again.
203 */
204 wpa_supplicant_req_scan(wpa_s, 1, 0);
205}
206
207
208/**
209 * wpa_supplicant_req_auth_timeout - Schedule a timeout for authentication
210 * @wpa_s: Pointer to wpa_supplicant data
211 * @sec: Number of seconds after which to time out authentication
212 * @usec: Number of microseconds after which to time out authentication
213 *
214 * This function is used to schedule a timeout for the current authentication
215 * attempt.
216 */
217void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s,
218 int sec, int usec)
219{
Dmitry Shmidt68d0e3e2013-10-28 17:59:21 -0700220 if (wpa_s->conf->ap_scan == 0 &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700221 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED))
222 return;
223
224 wpa_dbg(wpa_s, MSG_DEBUG, "Setting authentication timeout: %d sec "
225 "%d usec", sec, usec);
226 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
227 eloop_register_timeout(sec, usec, wpa_supplicant_timeout, wpa_s, NULL);
228}
229
230
231/**
232 * wpa_supplicant_cancel_auth_timeout - Cancel authentication timeout
233 * @wpa_s: Pointer to wpa_supplicant data
234 *
235 * This function is used to cancel authentication timeout scheduled with
236 * wpa_supplicant_req_auth_timeout() and it is called when authentication has
237 * been completed.
238 */
239void wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *wpa_s)
240{
241 wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling authentication timeout");
242 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
243 wpa_blacklist_del(wpa_s, wpa_s->bssid);
244}
245
246
247/**
248 * wpa_supplicant_initiate_eapol - Configure EAPOL state machine
249 * @wpa_s: Pointer to wpa_supplicant data
250 *
251 * This function is used to configure EAPOL state machine based on the selected
252 * authentication mode.
253 */
254void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
255{
256#ifdef IEEE8021X_EAPOL
257 struct eapol_config eapol_conf;
258 struct wpa_ssid *ssid = wpa_s->current_ssid;
259
260#ifdef CONFIG_IBSS_RSN
261 if (ssid->mode == WPAS_MODE_IBSS &&
262 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
263 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
264 /*
265 * RSN IBSS authentication is per-STA and we can disable the
266 * per-BSSID EAPOL authentication.
267 */
268 eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
269 eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
270 eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
271 return;
272 }
273#endif /* CONFIG_IBSS_RSN */
274
275 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
276 eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
277
278 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
279 wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
280 eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
281 else
282 eapol_sm_notify_portControl(wpa_s->eapol, Auto);
283
284 os_memset(&eapol_conf, 0, sizeof(eapol_conf));
285 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
286 eapol_conf.accept_802_1x_keys = 1;
287 eapol_conf.required_keys = 0;
288 if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_UNICAST) {
289 eapol_conf.required_keys |= EAPOL_REQUIRE_KEY_UNICAST;
290 }
291 if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_BROADCAST) {
292 eapol_conf.required_keys |=
293 EAPOL_REQUIRE_KEY_BROADCAST;
294 }
295
Dmitry Shmidt68d0e3e2013-10-28 17:59:21 -0700296 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700297 eapol_conf.required_keys = 0;
298 }
Dmitry Shmidt68d0e3e2013-10-28 17:59:21 -0700299 eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700300 eapol_conf.workaround = ssid->eap_workaround;
301 eapol_conf.eap_disabled =
302 !wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) &&
303 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
304 wpa_s->key_mgmt != WPA_KEY_MGMT_WPS;
Dmitry Shmidt051af732013-10-22 13:52:46 -0700305 eapol_conf.external_sim = wpa_s->conf->external_sim;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800306
307#ifdef CONFIG_WPS
308 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) {
309 eapol_conf.wps |= EAPOL_LOCAL_WPS_IN_USE;
310 if (wpa_s->current_bss) {
311 struct wpabuf *ie;
312 ie = wpa_bss_get_vendor_ie_multi(wpa_s->current_bss,
313 WPS_IE_VENDOR_TYPE);
314 if (ie) {
315 if (wps_is_20(ie))
316 eapol_conf.wps |=
317 EAPOL_PEER_IS_WPS20_AP;
318 wpabuf_free(ie);
319 }
320 }
321 }
322#endif /* CONFIG_WPS */
323
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700324 eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
Dmitry Shmidt5a1480c2014-05-12 09:46:02 -0700325
326 ieee802_1x_alloc_kay_sm(wpa_s, ssid);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800327#endif /* IEEE8021X_EAPOL */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700328}
329
330
331/**
332 * wpa_supplicant_set_non_wpa_policy - Set WPA parameters to non-WPA mode
333 * @wpa_s: Pointer to wpa_supplicant data
334 * @ssid: Configuration data for the network
335 *
336 * This function is used to configure WPA state machine and related parameters
337 * to a mode where WPA is not enabled. This is called as part of the
338 * authentication configuration when the selected network does not use WPA.
339 */
340void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
341 struct wpa_ssid *ssid)
342{
343 int i;
344
345 if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
346 wpa_s->key_mgmt = WPA_KEY_MGMT_WPS;
347 else if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)
348 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_NO_WPA;
349 else
350 wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
351 wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
352 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
353 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
354 wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
355 wpa_s->group_cipher = WPA_CIPHER_NONE;
356 wpa_s->mgmt_group_cipher = 0;
357
358 for (i = 0; i < NUM_WEP_KEYS; i++) {
359 if (ssid->wep_key_len[i] > 5) {
360 wpa_s->pairwise_cipher = WPA_CIPHER_WEP104;
361 wpa_s->group_cipher = WPA_CIPHER_WEP104;
362 break;
363 } else if (ssid->wep_key_len[i] > 0) {
364 wpa_s->pairwise_cipher = WPA_CIPHER_WEP40;
365 wpa_s->group_cipher = WPA_CIPHER_WEP40;
366 break;
367 }
368 }
369
370 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED, 0);
371 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
372 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
373 wpa_s->pairwise_cipher);
374 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
375#ifdef CONFIG_IEEE80211W
376 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
377 wpa_s->mgmt_group_cipher);
378#endif /* CONFIG_IEEE80211W */
379
380 pmksa_cache_clear_current(wpa_s->wpa);
381}
382
383
Dmitry Shmidt04949592012-07-19 12:16:46 -0700384void free_hw_features(struct wpa_supplicant *wpa_s)
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800385{
386 int i;
387 if (wpa_s->hw.modes == NULL)
388 return;
389
390 for (i = 0; i < wpa_s->hw.num_modes; i++) {
391 os_free(wpa_s->hw.modes[i].channels);
392 os_free(wpa_s->hw.modes[i].rates);
393 }
394
395 os_free(wpa_s->hw.modes);
396 wpa_s->hw.modes = NULL;
397}
398
399
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700400static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
401{
Dmitry Shmidt2e67f062014-07-16 09:55:28 -0700402 int i;
403
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700404 bgscan_deinit(wpa_s);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700405 autoscan_deinit(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700406 scard_deinit(wpa_s->scard);
407 wpa_s->scard = NULL;
408 wpa_sm_set_scard_ctx(wpa_s->wpa, NULL);
409 eapol_sm_register_scard_ctx(wpa_s->eapol, NULL);
410 l2_packet_deinit(wpa_s->l2);
411 wpa_s->l2 = NULL;
412 if (wpa_s->l2_br) {
413 l2_packet_deinit(wpa_s->l2_br);
414 wpa_s->l2_br = NULL;
415 }
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800416#ifdef CONFIG_TESTING_OPTIONS
417 l2_packet_deinit(wpa_s->l2_test);
418 wpa_s->l2_test = NULL;
419#endif /* CONFIG_TESTING_OPTIONS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700420
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700421 if (wpa_s->conf != NULL) {
422 struct wpa_ssid *ssid;
423 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
424 wpas_notify_network_removed(wpa_s, ssid);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700425 }
426
427 os_free(wpa_s->confname);
428 wpa_s->confname = NULL;
429
Jouni Malinen5d1c8ad2013-04-23 12:34:56 -0700430 os_free(wpa_s->confanother);
431 wpa_s->confanother = NULL;
432
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700433 wpa_sm_set_eapol(wpa_s->wpa, NULL);
434 eapol_sm_deinit(wpa_s->eapol);
435 wpa_s->eapol = NULL;
436
437 rsn_preauth_deinit(wpa_s->wpa);
438
439#ifdef CONFIG_TDLS
440 wpa_tdls_deinit(wpa_s->wpa);
441#endif /* CONFIG_TDLS */
442
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800443 wmm_ac_clear_saved_tspecs(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700444 pmksa_candidate_free(wpa_s->wpa);
445 wpa_sm_deinit(wpa_s->wpa);
446 wpa_s->wpa = NULL;
447 wpa_blacklist_clear(wpa_s);
448
449 wpa_bss_deinit(wpa_s);
450
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -0700451 wpa_supplicant_cancel_delayed_sched_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700452 wpa_supplicant_cancel_scan(wpa_s);
453 wpa_supplicant_cancel_auth_timeout(wpa_s);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800454 eloop_cancel_timeout(wpa_supplicant_stop_countermeasures, wpa_s, NULL);
455#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
456 eloop_cancel_timeout(wpa_supplicant_delayed_mic_error_report,
457 wpa_s, NULL);
458#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700459
Dmitry Shmidtdda10c22015-03-24 16:05:01 -0700460 eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
461
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700462 wpas_wps_deinit(wpa_s);
463
464 wpabuf_free(wpa_s->pending_eapol_rx);
465 wpa_s->pending_eapol_rx = NULL;
466
467#ifdef CONFIG_IBSS_RSN
468 ibss_rsn_deinit(wpa_s->ibss_rsn);
469 wpa_s->ibss_rsn = NULL;
470#endif /* CONFIG_IBSS_RSN */
471
472 sme_deinit(wpa_s);
473
474#ifdef CONFIG_AP
475 wpa_supplicant_ap_deinit(wpa_s);
476#endif /* CONFIG_AP */
477
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700478 wpas_p2p_deinit(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700479
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800480#ifdef CONFIG_OFFCHANNEL
481 offchannel_deinit(wpa_s);
482#endif /* CONFIG_OFFCHANNEL */
483
484 wpa_supplicant_cancel_sched_scan(wpa_s);
485
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700486 os_free(wpa_s->next_scan_freqs);
487 wpa_s->next_scan_freqs = NULL;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800488
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800489 os_free(wpa_s->manual_scan_freqs);
490 wpa_s->manual_scan_freqs = NULL;
491
Dmitry Shmidtd11f0192014-03-24 12:09:47 -0700492 os_free(wpa_s->manual_sched_scan_freqs);
493 wpa_s->manual_sched_scan_freqs = NULL;
494
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800495 wpas_mac_addr_rand_scan_clear(wpa_s, MAC_ADDR_RAND_ALL);
496
Dmitry Shmidt7a53dbb2015-06-11 13:13:53 -0700497 /*
498 * Need to remove any pending gas-query radio work before the
499 * gas_query_deinit() call because gas_query::work has not yet been set
500 * for works that have not been started. gas_query_free() will be unable
501 * to cancel such pending radio works and once the pending gas-query
502 * radio work eventually gets removed, the deinit notification call to
503 * gas_query_start_cb() would result in dereferencing freed memory.
504 */
505 if (wpa_s->radio)
506 radio_remove_works(wpa_s, "gas-query", 0);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800507 gas_query_deinit(wpa_s->gas);
508 wpa_s->gas = NULL;
509
510 free_hw_features(wpa_s);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700511
Dmitry Shmidt5a1480c2014-05-12 09:46:02 -0700512 ieee802_1x_dealloc_kay_sm(wpa_s);
513
Dmitry Shmidt04949592012-07-19 12:16:46 -0700514 os_free(wpa_s->bssid_filter);
515 wpa_s->bssid_filter = NULL;
516
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800517 os_free(wpa_s->disallow_aps_bssid);
518 wpa_s->disallow_aps_bssid = NULL;
519 os_free(wpa_s->disallow_aps_ssid);
520 wpa_s->disallow_aps_ssid = NULL;
521
Dmitry Shmidt04949592012-07-19 12:16:46 -0700522 wnm_bss_keep_alive_deinit(wpa_s);
Dmitry Shmidt44c95782013-05-17 09:51:35 -0700523#ifdef CONFIG_WNM
524 wnm_deallocate_memory(wpa_s);
525#endif /* CONFIG_WNM */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700526
527 ext_password_deinit(wpa_s->ext_pw);
528 wpa_s->ext_pw = NULL;
529
530 wpabuf_free(wpa_s->last_gas_resp);
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800531 wpa_s->last_gas_resp = NULL;
532 wpabuf_free(wpa_s->prev_gas_resp);
533 wpa_s->prev_gas_resp = NULL;
Dmitry Shmidt9bce59c2012-09-11 15:06:38 -0700534
535 os_free(wpa_s->last_scan_res);
536 wpa_s->last_scan_res = NULL;
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800537
538#ifdef CONFIG_HS20
Dmitry Shmidt684785c2014-05-12 13:34:29 -0700539 hs20_deinit(wpa_s);
Dmitry Shmidtf21452a2014-02-26 10:55:25 -0800540#endif /* CONFIG_HS20 */
Dmitry Shmidt2e67f062014-07-16 09:55:28 -0700541
542 for (i = 0; i < NUM_VENDOR_ELEM_FRAMES; i++) {
543 wpabuf_free(wpa_s->vendor_elem[i]);
544 wpa_s->vendor_elem[i] = NULL;
545 }
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800546
547 wmm_ac_notify_disassoc(wpa_s);
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -0800548
549 wpa_s->sched_scan_plans_num = 0;
550 os_free(wpa_s->sched_scan_plans);
551 wpa_s->sched_scan_plans = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700552}
553
554
555/**
556 * wpa_clear_keys - Clear keys configured for the driver
557 * @wpa_s: Pointer to wpa_supplicant data
558 * @addr: Previously used BSSID or %NULL if not available
559 *
560 * This function clears the encryption keys that has been previously configured
561 * for the driver.
562 */
563void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr)
564{
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800565 int i, max;
566
567#ifdef CONFIG_IEEE80211W
568 max = 6;
569#else /* CONFIG_IEEE80211W */
570 max = 4;
571#endif /* CONFIG_IEEE80211W */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700572
573 /* MLME-DELETEKEYS.request */
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800574 for (i = 0; i < max; i++) {
575 if (wpa_s->keys_cleared & BIT(i))
576 continue;
577 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, i, 0, NULL, 0,
578 NULL, 0);
579 }
580 if (!(wpa_s->keys_cleared & BIT(0)) && addr &&
581 !is_zero_ether_addr(addr)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700582 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, addr, 0, 0, NULL, 0, NULL,
583 0);
584 /* MLME-SETPROTECTION.request(None) */
585 wpa_drv_mlme_setprotection(
586 wpa_s, addr,
587 MLME_SETPROTECTION_PROTECT_TYPE_NONE,
588 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
589 }
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800590 wpa_s->keys_cleared = (u32) -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700591}
592
593
594/**
595 * wpa_supplicant_state_txt - Get the connection state name as a text string
596 * @state: State (wpa_state; WPA_*)
597 * Returns: The state name as a printable text string
598 */
599const char * wpa_supplicant_state_txt(enum wpa_states state)
600{
601 switch (state) {
602 case WPA_DISCONNECTED:
603 return "DISCONNECTED";
604 case WPA_INACTIVE:
605 return "INACTIVE";
606 case WPA_INTERFACE_DISABLED:
607 return "INTERFACE_DISABLED";
608 case WPA_SCANNING:
609 return "SCANNING";
610 case WPA_AUTHENTICATING:
611 return "AUTHENTICATING";
612 case WPA_ASSOCIATING:
613 return "ASSOCIATING";
614 case WPA_ASSOCIATED:
615 return "ASSOCIATED";
616 case WPA_4WAY_HANDSHAKE:
617 return "4WAY_HANDSHAKE";
618 case WPA_GROUP_HANDSHAKE:
619 return "GROUP_HANDSHAKE";
620 case WPA_COMPLETED:
621 return "COMPLETED";
622 default:
623 return "UNKNOWN";
624 }
625}
626
627
628#ifdef CONFIG_BGSCAN
629
630static void wpa_supplicant_start_bgscan(struct wpa_supplicant *wpa_s)
631{
Dmitry Shmidtb96dad42013-11-05 10:07:29 -0800632 const char *name;
633
634 if (wpa_s->current_ssid && wpa_s->current_ssid->bgscan)
635 name = wpa_s->current_ssid->bgscan;
636 else
637 name = wpa_s->conf->bgscan;
Dmitry Shmidta38abf92014-03-06 13:38:44 -0800638 if (name == NULL || name[0] == '\0')
Dmitry Shmidtb96dad42013-11-05 10:07:29 -0800639 return;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800640 if (wpas_driver_bss_selection(wpa_s))
641 return;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700642 if (wpa_s->current_ssid == wpa_s->bgscan_ssid)
643 return;
Dmitry Shmidta38abf92014-03-06 13:38:44 -0800644#ifdef CONFIG_P2P
645 if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE)
646 return;
647#endif /* CONFIG_P2P */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700648
649 bgscan_deinit(wpa_s);
Dmitry Shmidtb96dad42013-11-05 10:07:29 -0800650 if (wpa_s->current_ssid) {
651 if (bgscan_init(wpa_s, wpa_s->current_ssid, name)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700652 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
653 "bgscan");
654 /*
655 * Live without bgscan; it is only used as a roaming
656 * optimization, so the initial connection is not
657 * affected.
658 */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700659 } else {
660 struct wpa_scan_results *scan_res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700661 wpa_s->bgscan_ssid = wpa_s->current_ssid;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700662 scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL,
663 0);
664 if (scan_res) {
665 bgscan_notify_scan(wpa_s, scan_res);
666 wpa_scan_results_free(scan_res);
667 }
668 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700669 } else
670 wpa_s->bgscan_ssid = NULL;
671}
672
673
674static void wpa_supplicant_stop_bgscan(struct wpa_supplicant *wpa_s)
675{
676 if (wpa_s->bgscan_ssid != NULL) {
677 bgscan_deinit(wpa_s);
678 wpa_s->bgscan_ssid = NULL;
679 }
680}
681
682#endif /* CONFIG_BGSCAN */
683
684
Dmitry Shmidt04949592012-07-19 12:16:46 -0700685static void wpa_supplicant_start_autoscan(struct wpa_supplicant *wpa_s)
686{
687 if (autoscan_init(wpa_s, 0))
688 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize autoscan");
689}
690
691
692static void wpa_supplicant_stop_autoscan(struct wpa_supplicant *wpa_s)
693{
694 autoscan_deinit(wpa_s);
695}
696
697
698void wpa_supplicant_reinit_autoscan(struct wpa_supplicant *wpa_s)
699{
700 if (wpa_s->wpa_state == WPA_DISCONNECTED ||
701 wpa_s->wpa_state == WPA_SCANNING) {
702 autoscan_deinit(wpa_s);
703 wpa_supplicant_start_autoscan(wpa_s);
704 }
705}
706
707
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700708/**
709 * wpa_supplicant_set_state - Set current connection state
710 * @wpa_s: Pointer to wpa_supplicant data
711 * @state: The new connection state
712 *
713 * This function is called whenever the connection state changes, e.g.,
714 * association is completed for WPA/WPA2 4-Way Handshake is started.
715 */
716void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
717 enum wpa_states state)
718{
719 enum wpa_states old_state = wpa_s->wpa_state;
720
721 wpa_dbg(wpa_s, MSG_DEBUG, "State: %s -> %s",
722 wpa_supplicant_state_txt(wpa_s->wpa_state),
723 wpa_supplicant_state_txt(state));
724
Dmitry Shmidt9e3f8ee2014-01-17 10:52:01 -0800725 if (state == WPA_INTERFACE_DISABLED) {
726 /* Assure normal scan when interface is restored */
727 wpa_s->normal_scans = 0;
728 }
729
Dmitry Shmidtf9bdef92014-04-25 10:46:36 -0700730 if (state == WPA_COMPLETED) {
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800731 wpas_connect_work_done(wpa_s);
Dmitry Shmidtf9bdef92014-04-25 10:46:36 -0700732 /* Reinitialize normal_scan counter */
733 wpa_s->normal_scans = 0;
734 }
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800735
Dmitry Shmidta3dc3092015-06-23 11:21:28 -0700736#ifdef CONFIG_P2P
737 /*
738 * P2PS client has to reply to Probe Request frames received on the
739 * group operating channel. Enable Probe Request frame reporting for
740 * P2P connected client in case p2p_cli_probe configuration property is
741 * set to 1.
742 */
743 if (wpa_s->conf->p2p_cli_probe && wpa_s->current_ssid &&
744 wpa_s->current_ssid->mode == WPAS_MODE_INFRA &&
745 wpa_s->current_ssid->p2p_group) {
746 if (state == WPA_COMPLETED && !wpa_s->p2p_cli_probe) {
747 wpa_dbg(wpa_s, MSG_DEBUG,
748 "P2P: Enable CLI Probe Request RX reporting");
749 wpa_s->p2p_cli_probe =
750 wpa_drv_probe_req_report(wpa_s, 1) >= 0;
751 } else if (state != WPA_COMPLETED && wpa_s->p2p_cli_probe) {
752 wpa_dbg(wpa_s, MSG_DEBUG,
753 "P2P: Disable CLI Probe Request RX reporting");
754 wpa_s->p2p_cli_probe = 0;
755 wpa_drv_probe_req_report(wpa_s, 0);
756 }
757 }
758#endif /* CONFIG_P2P */
759
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700760 if (state != WPA_SCANNING)
761 wpa_supplicant_notify_scanning(wpa_s, 0);
762
763 if (state == WPA_COMPLETED && wpa_s->new_connection) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700764 struct wpa_ssid *ssid = wpa_s->current_ssid;
Dmitry Shmidt700a1372013-03-15 14:14:44 -0700765#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700766 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- Connection to "
Dmitry Shmidt8f0dbf42013-11-08 13:35:41 -0800767 MACSTR " completed [id=%d id_str=%s]",
Dmitry Shmidtf8623282013-02-20 14:34:59 -0800768 MAC2STR(wpa_s->bssid),
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700769 ssid ? ssid->id : -1,
770 ssid && ssid->id_str ? ssid->id_str : "");
771#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700772 wpas_clear_temp_disabled(wpa_s, ssid, 1);
Dmitry Shmidtaf9da312015-04-03 10:03:11 -0700773 wpa_blacklist_clear(wpa_s);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800774 wpa_s->extra_blacklist_count = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700775 wpa_s->new_connection = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700776 wpa_drv_set_operstate(wpa_s, 1);
777#ifndef IEEE8021X_EAPOL
778 wpa_drv_set_supp_port(wpa_s, 1);
779#endif /* IEEE8021X_EAPOL */
780 wpa_s->after_wps = 0;
Dmitry Shmidt68d0e3e2013-10-28 17:59:21 -0700781 wpa_s->known_wps_freq = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700782 wpas_p2p_completed(wpa_s);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700783
784 sme_sched_obss_scan(wpa_s, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700785 } else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING ||
786 state == WPA_ASSOCIATED) {
787 wpa_s->new_connection = 1;
788 wpa_drv_set_operstate(wpa_s, 0);
789#ifndef IEEE8021X_EAPOL
790 wpa_drv_set_supp_port(wpa_s, 0);
791#endif /* IEEE8021X_EAPOL */
Dmitry Shmidt04949592012-07-19 12:16:46 -0700792 sme_sched_obss_scan(wpa_s, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700793 }
794 wpa_s->wpa_state = state;
795
796#ifdef CONFIG_BGSCAN
797 if (state == WPA_COMPLETED)
798 wpa_supplicant_start_bgscan(wpa_s);
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800799 else if (state < WPA_ASSOCIATED)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700800 wpa_supplicant_stop_bgscan(wpa_s);
801#endif /* CONFIG_BGSCAN */
802
Dmitry Shmidt04949592012-07-19 12:16:46 -0700803 if (state == WPA_AUTHENTICATING)
804 wpa_supplicant_stop_autoscan(wpa_s);
805
806 if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
807 wpa_supplicant_start_autoscan(wpa_s);
808
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800809 if (old_state >= WPA_ASSOCIATED && wpa_s->wpa_state < WPA_ASSOCIATED)
810 wmm_ac_notify_disassoc(wpa_s);
811
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700812 if (wpa_s->wpa_state != old_state) {
813 wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
814
Dmitry Shmidt43cb5782014-06-16 16:23:22 -0700815 /*
816 * Notify the P2P Device interface about a state change in one
817 * of the interfaces.
818 */
819 wpas_p2p_indicate_state_change(wpa_s);
820
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700821 if (wpa_s->wpa_state == WPA_COMPLETED ||
822 old_state == WPA_COMPLETED)
823 wpas_notify_auth_changed(wpa_s);
824 }
825}
826
827
828void wpa_supplicant_terminate_proc(struct wpa_global *global)
829{
830 int pending = 0;
831#ifdef CONFIG_WPS
832 struct wpa_supplicant *wpa_s = global->ifaces;
833 while (wpa_s) {
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800834 struct wpa_supplicant *next = wpa_s->next;
Dmitry Shmidt6dc03bd2014-05-16 10:40:13 -0700835 if (wpas_wps_terminate_pending(wpa_s) == 1)
836 pending = 1;
Dmitry Shmidt56052862013-10-04 10:23:25 -0700837#ifdef CONFIG_P2P
838 if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE ||
839 (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group))
840 wpas_p2p_disconnect(wpa_s);
841#endif /* CONFIG_P2P */
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800842 wpa_s = next;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700843 }
844#endif /* CONFIG_WPS */
845 if (pending)
846 return;
847 eloop_terminate();
848}
849
850
851static void wpa_supplicant_terminate(int sig, void *signal_ctx)
852{
853 struct wpa_global *global = signal_ctx;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700854 wpa_supplicant_terminate_proc(global);
855}
856
857
858void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s)
859{
860 enum wpa_states old_state = wpa_s->wpa_state;
861
862 wpa_s->pairwise_cipher = 0;
863 wpa_s->group_cipher = 0;
864 wpa_s->mgmt_group_cipher = 0;
865 wpa_s->key_mgmt = 0;
866 if (wpa_s->wpa_state != WPA_INTERFACE_DISABLED)
Dmitry Shmidt04949592012-07-19 12:16:46 -0700867 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700868
869 if (wpa_s->wpa_state != old_state)
870 wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
871}
872
873
874/**
875 * wpa_supplicant_reload_configuration - Reload configuration data
876 * @wpa_s: Pointer to wpa_supplicant data
877 * Returns: 0 on success or -1 if configuration parsing failed
878 *
879 * This function can be used to request that the configuration data is reloaded
880 * (e.g., after configuration file change). This function is reloading
881 * configuration only for one interface, so this may need to be called multiple
882 * times if %wpa_supplicant is controlling multiple interfaces and all
883 * interfaces need reconfiguration.
884 */
885int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
886{
887 struct wpa_config *conf;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700888 int reconf_ctrl;
889 int old_ap_scan;
890
891 if (wpa_s->confname == NULL)
892 return -1;
Dmitry Shmidt64f47c52013-04-16 10:41:54 -0700893 conf = wpa_config_read(wpa_s->confname, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700894 if (conf == NULL) {
895 wpa_msg(wpa_s, MSG_ERROR, "Failed to parse the configuration "
896 "file '%s' - exiting", wpa_s->confname);
897 return -1;
898 }
Dmitry Shmidt64f47c52013-04-16 10:41:54 -0700899 wpa_config_read(wpa_s->confanother, conf);
900
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700901 conf->changed_parameters = (unsigned int) -1;
902
903 reconf_ctrl = !!conf->ctrl_interface != !!wpa_s->conf->ctrl_interface
904 || (conf->ctrl_interface && wpa_s->conf->ctrl_interface &&
905 os_strcmp(conf->ctrl_interface,
906 wpa_s->conf->ctrl_interface) != 0);
907
908 if (reconf_ctrl && wpa_s->ctrl_iface) {
909 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
910 wpa_s->ctrl_iface = NULL;
911 }
912
913 eapol_sm_invalidate_cached_session(wpa_s->eapol);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800914 if (wpa_s->current_ssid) {
Dmitry Shmidt7a53dbb2015-06-11 13:13:53 -0700915 if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
916 wpa_s->own_disconnect_req = 1;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800917 wpa_supplicant_deauthenticate(wpa_s,
918 WLAN_REASON_DEAUTH_LEAVING);
919 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700920
921 /*
922 * TODO: should notify EAPOL SM about changes in opensc_engine_path,
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800923 * pkcs11_engine_path, pkcs11_module_path, openssl_ciphers.
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700924 */
925 if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
926 /*
927 * Clear forced success to clear EAP state for next
928 * authentication.
929 */
930 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
931 }
932 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
933 wpa_sm_set_config(wpa_s->wpa, NULL);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800934 wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700935 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
936 rsn_preauth_deinit(wpa_s->wpa);
937
938 old_ap_scan = wpa_s->conf->ap_scan;
939 wpa_config_free(wpa_s->conf);
940 wpa_s->conf = conf;
941 if (old_ap_scan != wpa_s->conf->ap_scan)
942 wpas_notify_ap_scan_changed(wpa_s);
943
944 if (reconf_ctrl)
945 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
946
947 wpa_supplicant_update_config(wpa_s);
948
949 wpa_supplicant_clear_status(wpa_s);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700950 if (wpa_supplicant_enabled_networks(wpa_s)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700951 wpa_s->reassociate = 1;
952 wpa_supplicant_req_scan(wpa_s, 0, 0);
953 }
954 wpa_dbg(wpa_s, MSG_DEBUG, "Reconfiguration completed");
955 return 0;
956}
957
958
959static void wpa_supplicant_reconfig(int sig, void *signal_ctx)
960{
961 struct wpa_global *global = signal_ctx;
962 struct wpa_supplicant *wpa_s;
963 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
964 wpa_dbg(wpa_s, MSG_DEBUG, "Signal %d received - reconfiguring",
965 sig);
966 if (wpa_supplicant_reload_configuration(wpa_s) < 0) {
967 wpa_supplicant_terminate_proc(global);
968 }
969 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800970
971 if (wpa_debug_reopen_file() < 0) {
972 /* Ignore errors since we cannot really do much to fix this */
973 wpa_printf(MSG_DEBUG, "Could not reopen debug log file");
974 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700975}
976
977
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700978static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s,
979 struct wpa_ssid *ssid,
980 struct wpa_ie_data *ie)
981{
982 int ret = wpa_sm_parse_own_wpa_ie(wpa_s->wpa, ie);
983 if (ret) {
984 if (ret == -2) {
985 wpa_msg(wpa_s, MSG_INFO, "WPA: Failed to parse WPA IE "
986 "from association info");
987 }
988 return -1;
989 }
990
991 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Using WPA IE from AssocReq to set "
992 "cipher suites");
993 if (!(ie->group_cipher & ssid->group_cipher)) {
994 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled group "
995 "cipher 0x%x (mask 0x%x) - reject",
996 ie->group_cipher, ssid->group_cipher);
997 return -1;
998 }
999 if (!(ie->pairwise_cipher & ssid->pairwise_cipher)) {
1000 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled pairwise "
1001 "cipher 0x%x (mask 0x%x) - reject",
1002 ie->pairwise_cipher, ssid->pairwise_cipher);
1003 return -1;
1004 }
1005 if (!(ie->key_mgmt & ssid->key_mgmt)) {
1006 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled key "
1007 "management 0x%x (mask 0x%x) - reject",
1008 ie->key_mgmt, ssid->key_mgmt);
1009 return -1;
1010 }
1011
1012#ifdef CONFIG_IEEE80211W
1013 if (!(ie->capabilities & WPA_CAPABILITY_MFPC) &&
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001014 wpas_get_ssid_pmf(wpa_s, ssid) == MGMT_FRAME_PROTECTION_REQUIRED) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001015 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP "
1016 "that does not support management frame protection - "
1017 "reject");
1018 return -1;
1019 }
1020#endif /* CONFIG_IEEE80211W */
1021
1022 return 0;
1023}
1024
1025
1026/**
1027 * wpa_supplicant_set_suites - Set authentication and encryption parameters
1028 * @wpa_s: Pointer to wpa_supplicant data
1029 * @bss: Scan results for the selected BSS, or %NULL if not available
1030 * @ssid: Configuration data for the selected network
1031 * @wpa_ie: Buffer for the WPA/RSN IE
1032 * @wpa_ie_len: Maximum wpa_ie buffer size on input. This is changed to be the
1033 * used buffer length in case the functions returns success.
1034 * Returns: 0 on success or -1 on failure
1035 *
1036 * This function is used to configure authentication and encryption parameters
1037 * based on the network configuration and scan result for the selected BSS (if
1038 * available).
1039 */
1040int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
1041 struct wpa_bss *bss, struct wpa_ssid *ssid,
1042 u8 *wpa_ie, size_t *wpa_ie_len)
1043{
1044 struct wpa_ie_data ie;
1045 int sel, proto;
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001046 const u8 *bss_wpa, *bss_rsn, *bss_osen;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001047
1048 if (bss) {
1049 bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
1050 bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001051 bss_osen = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001052 } else
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001053 bss_wpa = bss_rsn = bss_osen = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001054
1055 if (bss_rsn && (ssid->proto & WPA_PROTO_RSN) &&
1056 wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie) == 0 &&
1057 (ie.group_cipher & ssid->group_cipher) &&
1058 (ie.pairwise_cipher & ssid->pairwise_cipher) &&
1059 (ie.key_mgmt & ssid->key_mgmt)) {
1060 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using IEEE 802.11i/D9.0");
1061 proto = WPA_PROTO_RSN;
1062 } else if (bss_wpa && (ssid->proto & WPA_PROTO_WPA) &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001063 wpa_parse_wpa_ie(bss_wpa, 2 + bss_wpa[1], &ie) == 0 &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001064 (ie.group_cipher & ssid->group_cipher) &&
1065 (ie.pairwise_cipher & ssid->pairwise_cipher) &&
1066 (ie.key_mgmt & ssid->key_mgmt)) {
1067 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using IEEE 802.11i/D3.0");
1068 proto = WPA_PROTO_WPA;
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001069#ifdef CONFIG_HS20
1070 } else if (bss_osen && (ssid->proto & WPA_PROTO_OSEN)) {
1071 wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: using OSEN");
1072 /* TODO: parse OSEN element */
Dmitry Shmidt623d63a2014-06-13 11:05:14 -07001073 os_memset(&ie, 0, sizeof(ie));
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001074 ie.group_cipher = WPA_CIPHER_CCMP;
1075 ie.pairwise_cipher = WPA_CIPHER_CCMP;
1076 ie.key_mgmt = WPA_KEY_MGMT_OSEN;
1077 proto = WPA_PROTO_OSEN;
1078#endif /* CONFIG_HS20 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001079 } else if (bss) {
1080 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select WPA/RSN");
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001081 wpa_dbg(wpa_s, MSG_DEBUG,
1082 "WPA: ssid proto=0x%x pairwise_cipher=0x%x group_cipher=0x%x key_mgmt=0x%x",
1083 ssid->proto, ssid->pairwise_cipher, ssid->group_cipher,
1084 ssid->key_mgmt);
1085 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: BSS " MACSTR " ssid='%s'%s%s%s",
1086 MAC2STR(bss->bssid),
1087 wpa_ssid_txt(bss->ssid, bss->ssid_len),
1088 bss_wpa ? " WPA" : "",
1089 bss_rsn ? " RSN" : "",
1090 bss_osen ? " OSEN" : "");
1091 if (bss_rsn) {
1092 wpa_hexdump(MSG_DEBUG, "RSN", bss_rsn, 2 + bss_rsn[1]);
1093 if (wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie)) {
1094 wpa_dbg(wpa_s, MSG_DEBUG,
1095 "Could not parse RSN element");
1096 } else {
1097 wpa_dbg(wpa_s, MSG_DEBUG,
1098 "RSN: pairwise_cipher=0x%x group_cipher=0x%x key_mgmt=0x%x",
1099 ie.pairwise_cipher, ie.group_cipher,
1100 ie.key_mgmt);
1101 }
1102 }
1103 if (bss_wpa) {
1104 wpa_hexdump(MSG_DEBUG, "WPA", bss_wpa, 2 + bss_wpa[1]);
1105 if (wpa_parse_wpa_ie(bss_wpa, 2 + bss_wpa[1], &ie)) {
1106 wpa_dbg(wpa_s, MSG_DEBUG,
1107 "Could not parse WPA element");
1108 } else {
1109 wpa_dbg(wpa_s, MSG_DEBUG,
1110 "WPA: pairwise_cipher=0x%x group_cipher=0x%x key_mgmt=0x%x",
1111 ie.pairwise_cipher, ie.group_cipher,
1112 ie.key_mgmt);
1113 }
1114 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001115 return -1;
1116 } else {
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001117 if (ssid->proto & WPA_PROTO_OSEN)
1118 proto = WPA_PROTO_OSEN;
1119 else if (ssid->proto & WPA_PROTO_RSN)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001120 proto = WPA_PROTO_RSN;
1121 else
1122 proto = WPA_PROTO_WPA;
1123 if (wpa_supplicant_suites_from_ai(wpa_s, ssid, &ie) < 0) {
1124 os_memset(&ie, 0, sizeof(ie));
1125 ie.group_cipher = ssid->group_cipher;
1126 ie.pairwise_cipher = ssid->pairwise_cipher;
1127 ie.key_mgmt = ssid->key_mgmt;
1128#ifdef CONFIG_IEEE80211W
1129 ie.mgmt_group_cipher =
1130 ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION ?
1131 WPA_CIPHER_AES_128_CMAC : 0;
1132#endif /* CONFIG_IEEE80211W */
1133 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Set cipher suites "
1134 "based on configuration");
1135 } else
1136 proto = ie.proto;
1137 }
1138
1139 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected cipher suites: group %d "
1140 "pairwise %d key_mgmt %d proto %d",
1141 ie.group_cipher, ie.pairwise_cipher, ie.key_mgmt, proto);
1142#ifdef CONFIG_IEEE80211W
1143 if (ssid->ieee80211w) {
1144 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected mgmt group cipher %d",
1145 ie.mgmt_group_cipher);
1146 }
1147#endif /* CONFIG_IEEE80211W */
1148
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001149 wpa_s->wpa_proto = proto;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001150 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, proto);
1151 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001152 !!(ssid->proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN)));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001153
1154 if (bss || !wpa_s->ap_ies_from_associnfo) {
1155 if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
1156 bss_wpa ? 2 + bss_wpa[1] : 0) ||
1157 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
1158 bss_rsn ? 2 + bss_rsn[1] : 0))
1159 return -1;
1160 }
1161
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08001162#ifdef CONFIG_NO_WPA
1163 wpa_s->group_cipher = WPA_CIPHER_NONE;
1164 wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
1165#else /* CONFIG_NO_WPA */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001166 sel = ie.group_cipher & ssid->group_cipher;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001167 wpa_s->group_cipher = wpa_pick_group_cipher(sel);
1168 if (wpa_s->group_cipher < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001169 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select group "
1170 "cipher");
1171 return -1;
1172 }
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001173 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s",
1174 wpa_cipher_txt(wpa_s->group_cipher));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001175
1176 sel = ie.pairwise_cipher & ssid->pairwise_cipher;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001177 wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(sel, 1);
1178 if (wpa_s->pairwise_cipher < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001179 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select pairwise "
1180 "cipher");
1181 return -1;
1182 }
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001183 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK %s",
1184 wpa_cipher_txt(wpa_s->pairwise_cipher));
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08001185#endif /* CONFIG_NO_WPA */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001186
1187 sel = ie.key_mgmt & ssid->key_mgmt;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001188#ifdef CONFIG_SAE
1189 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE))
1190 sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE);
1191#endif /* CONFIG_SAE */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001192 if (0) {
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001193#ifdef CONFIG_SUITEB192
1194 } else if (sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
1195 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
1196 wpa_dbg(wpa_s, MSG_DEBUG,
1197 "WPA: using KEY_MGMT 802.1X with Suite B (192-bit)");
1198#endif /* CONFIG_SUITEB192 */
1199#ifdef CONFIG_SUITEB
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001200 } else if (sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
1201 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B;
1202 wpa_dbg(wpa_s, MSG_DEBUG,
1203 "WPA: using KEY_MGMT 802.1X with Suite B");
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001204#endif /* CONFIG_SUITEB */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001205#ifdef CONFIG_IEEE80211R
1206 } else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) {
1207 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
1208 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/802.1X");
1209 } else if (sel & WPA_KEY_MGMT_FT_PSK) {
1210 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_PSK;
1211 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/PSK");
1212#endif /* CONFIG_IEEE80211R */
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001213#ifdef CONFIG_SAE
1214 } else if (sel & WPA_KEY_MGMT_SAE) {
1215 wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
1216 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT SAE");
1217 } else if (sel & WPA_KEY_MGMT_FT_SAE) {
1218 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_SAE;
1219 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT FT/SAE");
1220#endif /* CONFIG_SAE */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001221#ifdef CONFIG_IEEE80211W
1222 } else if (sel & WPA_KEY_MGMT_IEEE8021X_SHA256) {
1223 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
1224 wpa_dbg(wpa_s, MSG_DEBUG,
1225 "WPA: using KEY_MGMT 802.1X with SHA256");
1226 } else if (sel & WPA_KEY_MGMT_PSK_SHA256) {
1227 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
1228 wpa_dbg(wpa_s, MSG_DEBUG,
1229 "WPA: using KEY_MGMT PSK with SHA256");
1230#endif /* CONFIG_IEEE80211W */
1231 } else if (sel & WPA_KEY_MGMT_IEEE8021X) {
1232 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
1233 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT 802.1X");
1234 } else if (sel & WPA_KEY_MGMT_PSK) {
1235 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
1236 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-PSK");
1237 } else if (sel & WPA_KEY_MGMT_WPA_NONE) {
1238 wpa_s->key_mgmt = WPA_KEY_MGMT_WPA_NONE;
1239 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-NONE");
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001240#ifdef CONFIG_HS20
1241 } else if (sel & WPA_KEY_MGMT_OSEN) {
1242 wpa_s->key_mgmt = WPA_KEY_MGMT_OSEN;
1243 wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: using KEY_MGMT OSEN");
1244#endif /* CONFIG_HS20 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001245 } else {
1246 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select "
1247 "authenticated key management type");
1248 return -1;
1249 }
1250
1251 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
1252 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
1253 wpa_s->pairwise_cipher);
1254 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
1255
1256#ifdef CONFIG_IEEE80211W
1257 sel = ie.mgmt_group_cipher;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001258 if (wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION ||
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001259 !(ie.capabilities & WPA_CAPABILITY_MFPC))
1260 sel = 0;
1261 if (sel & WPA_CIPHER_AES_128_CMAC) {
1262 wpa_s->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
1263 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1264 "AES-128-CMAC");
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -07001265 } else if (sel & WPA_CIPHER_BIP_GMAC_128) {
1266 wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_GMAC_128;
1267 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1268 "BIP-GMAC-128");
1269 } else if (sel & WPA_CIPHER_BIP_GMAC_256) {
1270 wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_GMAC_256;
1271 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1272 "BIP-GMAC-256");
1273 } else if (sel & WPA_CIPHER_BIP_CMAC_256) {
1274 wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_CMAC_256;
1275 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1276 "BIP-CMAC-256");
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001277 } else {
1278 wpa_s->mgmt_group_cipher = 0;
1279 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
1280 }
1281 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
1282 wpa_s->mgmt_group_cipher);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08001283 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP,
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001284 wpas_get_ssid_pmf(wpa_s, ssid));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001285#endif /* CONFIG_IEEE80211W */
1286
1287 if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {
1288 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to generate WPA IE");
1289 return -1;
1290 }
1291
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001292 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -07001293 int psk_set = 0;
1294
1295 if (ssid->psk_set) {
1296 wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN, NULL);
1297 psk_set = 1;
1298 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001299#ifndef CONFIG_NO_PBKDF2
1300 if (bss && ssid->bssid_set && ssid->ssid_len == 0 &&
1301 ssid->passphrase) {
1302 u8 psk[PMK_LEN];
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001303 pbkdf2_sha1(ssid->passphrase, bss->ssid, bss->ssid_len,
1304 4096, psk, PMK_LEN);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001305 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
1306 psk, PMK_LEN);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001307 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL);
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -07001308 psk_set = 1;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001309 os_memset(psk, 0, sizeof(psk));
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001310 }
1311#endif /* CONFIG_NO_PBKDF2 */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001312#ifdef CONFIG_EXT_PASSWORD
1313 if (ssid->ext_psk) {
1314 struct wpabuf *pw = ext_password_get(wpa_s->ext_pw,
1315 ssid->ext_psk);
1316 char pw_str[64 + 1];
1317 u8 psk[PMK_LEN];
1318
1319 if (pw == NULL) {
1320 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No PSK "
1321 "found from external storage");
1322 return -1;
1323 }
1324
1325 if (wpabuf_len(pw) < 8 || wpabuf_len(pw) > 64) {
1326 wpa_msg(wpa_s, MSG_INFO, "EXT PW: Unexpected "
1327 "PSK length %d in external storage",
1328 (int) wpabuf_len(pw));
1329 ext_password_free(pw);
1330 return -1;
1331 }
1332
1333 os_memcpy(pw_str, wpabuf_head(pw), wpabuf_len(pw));
1334 pw_str[wpabuf_len(pw)] = '\0';
1335
1336#ifndef CONFIG_NO_PBKDF2
1337 if (wpabuf_len(pw) >= 8 && wpabuf_len(pw) < 64 && bss)
1338 {
1339 pbkdf2_sha1(pw_str, bss->ssid, bss->ssid_len,
1340 4096, psk, PMK_LEN);
1341 os_memset(pw_str, 0, sizeof(pw_str));
1342 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from "
1343 "external passphrase)",
1344 psk, PMK_LEN);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001345 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL);
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -07001346 psk_set = 1;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001347 os_memset(psk, 0, sizeof(psk));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001348 } else
1349#endif /* CONFIG_NO_PBKDF2 */
1350 if (wpabuf_len(pw) == 2 * PMK_LEN) {
1351 if (hexstr2bin(pw_str, psk, PMK_LEN) < 0) {
1352 wpa_msg(wpa_s, MSG_INFO, "EXT PW: "
1353 "Invalid PSK hex string");
1354 os_memset(pw_str, 0, sizeof(pw_str));
1355 ext_password_free(pw);
1356 return -1;
1357 }
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001358 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL);
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -07001359 psk_set = 1;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001360 os_memset(psk, 0, sizeof(psk));
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001361 } else {
1362 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No suitable "
1363 "PSK available");
1364 os_memset(pw_str, 0, sizeof(pw_str));
1365 ext_password_free(pw);
1366 return -1;
1367 }
1368
1369 os_memset(pw_str, 0, sizeof(pw_str));
1370 ext_password_free(pw);
1371 }
1372#endif /* CONFIG_EXT_PASSWORD */
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -07001373
1374 if (!psk_set) {
1375 wpa_msg(wpa_s, MSG_INFO,
1376 "No PSK available for association");
1377 return -1;
1378 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001379 } else
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001380 wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
1381
1382 return 0;
1383}
1384
1385
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001386static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
1387{
1388 *pos = 0x00;
1389
1390 switch (idx) {
1391 case 0: /* Bits 0-7 */
1392 break;
1393 case 1: /* Bits 8-15 */
1394 break;
1395 case 2: /* Bits 16-23 */
1396#ifdef CONFIG_WNM
1397 *pos |= 0x02; /* Bit 17 - WNM-Sleep Mode */
1398 *pos |= 0x08; /* Bit 19 - BSS Transition */
1399#endif /* CONFIG_WNM */
1400 break;
1401 case 3: /* Bits 24-31 */
1402#ifdef CONFIG_WNM
1403 *pos |= 0x02; /* Bit 25 - SSID List */
1404#endif /* CONFIG_WNM */
1405#ifdef CONFIG_INTERWORKING
1406 if (wpa_s->conf->interworking)
1407 *pos |= 0x80; /* Bit 31 - Interworking */
1408#endif /* CONFIG_INTERWORKING */
1409 break;
1410 case 4: /* Bits 32-39 */
Dmitry Shmidt051af732013-10-22 13:52:46 -07001411#ifdef CONFIG_INTERWORKING
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08001412 if (wpa_s->drv_flags / WPA_DRIVER_FLAGS_QOS_MAPPING)
1413 *pos |= 0x01; /* Bit 32 - QoS Map */
Dmitry Shmidt051af732013-10-22 13:52:46 -07001414#endif /* CONFIG_INTERWORKING */
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001415 break;
1416 case 5: /* Bits 40-47 */
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001417#ifdef CONFIG_HS20
1418 if (wpa_s->conf->hs20)
1419 *pos |= 0x40; /* Bit 46 - WNM-Notification */
1420#endif /* CONFIG_HS20 */
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001421 break;
1422 case 6: /* Bits 48-55 */
1423 break;
1424 }
1425}
1426
1427
Dmitry Shmidt09f57ba2014-06-10 16:07:13 -07001428int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf, size_t buflen)
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001429{
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001430 u8 *pos = buf;
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001431 u8 len = 6, i;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001432
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001433 if (len < wpa_s->extended_capa_len)
1434 len = wpa_s->extended_capa_len;
Dmitry Shmidt09f57ba2014-06-10 16:07:13 -07001435 if (buflen < (size_t) len + 2) {
1436 wpa_printf(MSG_INFO,
1437 "Not enough room for building extended capabilities element");
1438 return -1;
1439 }
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001440
1441 *pos++ = WLAN_EID_EXT_CAPAB;
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001442 *pos++ = len;
1443 for (i = 0; i < len; i++, pos++) {
1444 wpas_ext_capab_byte(wpa_s, pos, i);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001445
Dmitry Shmidt444d5672013-04-01 13:08:44 -07001446 if (i < wpa_s->extended_capa_len) {
1447 *pos &= ~wpa_s->extended_capa_mask[i];
1448 *pos |= wpa_s->extended_capa[i];
1449 }
1450 }
1451
1452 while (len > 0 && buf[1 + len] == 0) {
1453 len--;
1454 buf[1] = len;
1455 }
1456 if (len == 0)
1457 return 0;
1458
1459 return 2 + len;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001460}
1461
1462
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08001463static int wpas_valid_bss(struct wpa_supplicant *wpa_s,
1464 struct wpa_bss *test_bss)
1465{
1466 struct wpa_bss *bss;
1467
1468 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
1469 if (bss == test_bss)
1470 return 1;
1471 }
1472
1473 return 0;
1474}
1475
1476
1477static int wpas_valid_ssid(struct wpa_supplicant *wpa_s,
1478 struct wpa_ssid *test_ssid)
1479{
1480 struct wpa_ssid *ssid;
1481
1482 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
1483 if (ssid == test_ssid)
1484 return 1;
1485 }
1486
1487 return 0;
1488}
1489
1490
1491int wpas_valid_bss_ssid(struct wpa_supplicant *wpa_s, struct wpa_bss *test_bss,
1492 struct wpa_ssid *test_ssid)
1493{
1494 if (test_bss && !wpas_valid_bss(wpa_s, test_bss))
1495 return 0;
1496
1497 return test_ssid == NULL || wpas_valid_ssid(wpa_s, test_ssid);
1498}
1499
1500
1501void wpas_connect_work_free(struct wpa_connect_work *cwork)
1502{
1503 if (cwork == NULL)
1504 return;
1505 os_free(cwork);
1506}
1507
1508
1509void wpas_connect_work_done(struct wpa_supplicant *wpa_s)
1510{
1511 struct wpa_connect_work *cwork;
1512 struct wpa_radio_work *work = wpa_s->connect_work;
1513
1514 if (!work)
1515 return;
1516
1517 wpa_s->connect_work = NULL;
1518 cwork = work->ctx;
1519 work->ctx = NULL;
1520 wpas_connect_work_free(cwork);
1521 radio_work_done(work);
1522}
1523
1524
Dmitry Shmidt661b4f72014-09-29 14:58:27 -07001525int wpas_update_random_addr(struct wpa_supplicant *wpa_s, int style)
1526{
1527 struct os_reltime now;
1528 u8 addr[ETH_ALEN];
1529
1530 os_get_reltime(&now);
1531 if (wpa_s->last_mac_addr_style == style &&
1532 wpa_s->last_mac_addr_change.sec != 0 &&
1533 !os_reltime_expired(&now, &wpa_s->last_mac_addr_change,
1534 wpa_s->conf->rand_addr_lifetime)) {
1535 wpa_msg(wpa_s, MSG_DEBUG,
1536 "Previously selected random MAC address has not yet expired");
1537 return 0;
1538 }
1539
1540 switch (style) {
1541 case 1:
1542 if (random_mac_addr(addr) < 0)
1543 return -1;
1544 break;
1545 case 2:
1546 os_memcpy(addr, wpa_s->perm_addr, ETH_ALEN);
1547 if (random_mac_addr_keep_oui(addr) < 0)
1548 return -1;
1549 break;
1550 default:
1551 return -1;
1552 }
1553
1554 if (wpa_drv_set_mac_addr(wpa_s, addr) < 0) {
1555 wpa_msg(wpa_s, MSG_INFO,
1556 "Failed to set random MAC address");
1557 return -1;
1558 }
1559
1560 os_get_reltime(&wpa_s->last_mac_addr_change);
1561 wpa_s->mac_addr_changed = 1;
1562 wpa_s->last_mac_addr_style = style;
1563
1564 if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
1565 wpa_msg(wpa_s, MSG_INFO,
1566 "Could not update MAC address information");
1567 return -1;
1568 }
1569
1570 wpa_msg(wpa_s, MSG_DEBUG, "Using random MAC address " MACSTR,
1571 MAC2STR(addr));
1572
1573 return 0;
1574}
1575
1576
1577int wpas_update_random_addr_disassoc(struct wpa_supplicant *wpa_s)
1578{
1579 if (wpa_s->wpa_state >= WPA_AUTHENTICATING ||
1580 !wpa_s->conf->preassoc_mac_addr)
1581 return 0;
1582
1583 return wpas_update_random_addr(wpa_s, wpa_s->conf->preassoc_mac_addr);
1584}
1585
1586
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08001587static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit);
1588
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001589/**
1590 * wpa_supplicant_associate - Request association
1591 * @wpa_s: Pointer to wpa_supplicant data
1592 * @bss: Scan results for the selected BSS, or %NULL if not available
1593 * @ssid: Configuration data for the selected network
1594 *
1595 * This function is used to request %wpa_supplicant to associate with a BSS.
1596 */
1597void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
1598 struct wpa_bss *bss, struct wpa_ssid *ssid)
1599{
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08001600 struct wpa_connect_work *cwork;
Dmitry Shmidt661b4f72014-09-29 14:58:27 -07001601 int rand_style;
1602
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001603 wpa_s->own_disconnect_req = 0;
1604
Dmitry Shmidt7d56b752015-12-22 10:59:44 -08001605 /*
1606 * If we are starting a new connection, any previously pending EAPOL
1607 * RX cannot be valid anymore.
1608 */
1609 wpabuf_free(wpa_s->pending_eapol_rx);
1610 wpa_s->pending_eapol_rx = NULL;
1611
Dmitry Shmidt661b4f72014-09-29 14:58:27 -07001612 if (ssid->mac_addr == -1)
1613 rand_style = wpa_s->conf->mac_addr;
1614 else
1615 rand_style = ssid->mac_addr;
1616
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001617 wmm_ac_clear_saved_tspecs(wpa_s);
1618 wpa_s->reassoc_same_bss = 0;
1619
Dmitry Shmidt661b4f72014-09-29 14:58:27 -07001620 if (wpa_s->last_ssid == ssid) {
1621 wpa_dbg(wpa_s, MSG_DEBUG, "Re-association to the same ESS");
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001622 if (wpa_s->current_bss && wpa_s->current_bss == bss) {
1623 wmm_ac_save_tspecs(wpa_s);
1624 wpa_s->reassoc_same_bss = 1;
1625 }
Dmitry Shmidt661b4f72014-09-29 14:58:27 -07001626 } else if (rand_style > 0) {
1627 if (wpas_update_random_addr(wpa_s, rand_style) < 0)
1628 return;
1629 wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
1630 } else if (wpa_s->mac_addr_changed) {
1631 if (wpa_drv_set_mac_addr(wpa_s, NULL) < 0) {
1632 wpa_msg(wpa_s, MSG_INFO,
1633 "Could not restore permanent MAC address");
1634 return;
1635 }
1636 wpa_s->mac_addr_changed = 0;
1637 if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
1638 wpa_msg(wpa_s, MSG_INFO,
1639 "Could not update MAC address information");
1640 return;
1641 }
1642 wpa_msg(wpa_s, MSG_DEBUG, "Using permanent MAC address");
1643 }
1644 wpa_s->last_ssid = ssid;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001645
1646#ifdef CONFIG_IBSS_RSN
1647 ibss_rsn_deinit(wpa_s->ibss_rsn);
1648 wpa_s->ibss_rsn = NULL;
1649#endif /* CONFIG_IBSS_RSN */
1650
1651 if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
1652 ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
1653#ifdef CONFIG_AP
1654 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) {
1655 wpa_msg(wpa_s, MSG_INFO, "Driver does not support AP "
1656 "mode");
1657 return;
1658 }
Dmitry Shmidtaa532512012-09-24 10:35:31 -07001659 if (wpa_supplicant_create_ap(wpa_s, ssid) < 0) {
1660 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt391c59f2013-09-03 12:16:28 -07001661 if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
1662 wpas_p2p_ap_setup_failed(wpa_s);
Dmitry Shmidtaa532512012-09-24 10:35:31 -07001663 return;
1664 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001665 wpa_s->current_bss = bss;
1666#else /* CONFIG_AP */
1667 wpa_msg(wpa_s, MSG_ERROR, "AP mode support not included in "
1668 "the build");
1669#endif /* CONFIG_AP */
1670 return;
1671 }
1672
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001673 if (ssid->mode == WPAS_MODE_MESH) {
1674#ifdef CONFIG_MESH
1675 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MESH)) {
1676 wpa_msg(wpa_s, MSG_INFO,
1677 "Driver does not support mesh mode");
1678 return;
1679 }
1680 if (bss)
1681 ssid->frequency = bss->freq;
1682 if (wpa_supplicant_join_mesh(wpa_s, ssid) < 0) {
1683 wpa_msg(wpa_s, MSG_ERROR, "Could not join mesh");
1684 return;
1685 }
1686 wpa_s->current_bss = bss;
1687 wpa_msg_ctrl(wpa_s, MSG_INFO, MESH_GROUP_STARTED
1688 "ssid=\"%s\" id=%d",
1689 wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
1690 ssid->id);
1691#else /* CONFIG_MESH */
1692 wpa_msg(wpa_s, MSG_ERROR,
1693 "mesh mode support not included in the build");
1694#endif /* CONFIG_MESH */
1695 return;
1696 }
1697
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001698#ifdef CONFIG_TDLS
1699 if (bss)
1700 wpa_tdls_ap_ies(wpa_s->wpa, (const u8 *) (bss + 1),
1701 bss->ie_len);
1702#endif /* CONFIG_TDLS */
1703
1704 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
1705 ssid->mode == IEEE80211_MODE_INFRA) {
1706 sme_authenticate(wpa_s, bss, ssid);
1707 return;
1708 }
1709
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08001710 if (wpa_s->connect_work) {
1711 wpa_dbg(wpa_s, MSG_DEBUG, "Reject wpa_supplicant_associate() call since connect_work exist");
1712 return;
1713 }
1714
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08001715 if (radio_work_pending(wpa_s, "connect")) {
1716 wpa_dbg(wpa_s, MSG_DEBUG, "Reject wpa_supplicant_associate() call since pending work exist");
1717 return;
1718 }
1719
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08001720 wpas_abort_ongoing_scan(wpa_s);
1721
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08001722 cwork = os_zalloc(sizeof(*cwork));
1723 if (cwork == NULL)
1724 return;
1725
1726 cwork->bss = bss;
1727 cwork->ssid = ssid;
1728
1729 if (radio_add_work(wpa_s, bss ? bss->freq : 0, "connect", 1,
1730 wpas_start_assoc_cb, cwork) < 0) {
1731 os_free(cwork);
1732 }
1733}
1734
1735
Dmitry Shmidt7f656022015-02-25 14:36:37 -08001736static int bss_is_ibss(struct wpa_bss *bss)
1737{
1738 return (bss->caps & (IEEE80211_CAP_ESS | IEEE80211_CAP_IBSS)) ==
1739 IEEE80211_CAP_IBSS;
1740}
1741
1742
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08001743static int drv_supports_vht(struct wpa_supplicant *wpa_s,
1744 const struct wpa_ssid *ssid)
1745{
1746 enum hostapd_hw_mode hw_mode;
1747 struct hostapd_hw_modes *mode = NULL;
1748 u8 channel;
1749 int i;
1750
1751#ifdef CONFIG_HT_OVERRIDES
1752 if (ssid->disable_ht)
1753 return 0;
1754#endif /* CONFIG_HT_OVERRIDES */
1755
1756 hw_mode = ieee80211_freq_to_chan(ssid->frequency, &channel);
1757 if (hw_mode == NUM_HOSTAPD_MODES)
1758 return 0;
1759 for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
1760 if (wpa_s->hw.modes[i].mode == hw_mode) {
1761 mode = &wpa_s->hw.modes[i];
1762 break;
1763 }
1764 }
1765
1766 if (!mode)
1767 return 0;
1768
1769 return mode->vht_capab != 0;
1770}
1771
1772
Dmitry Shmidtff787d52015-01-12 13:01:47 -08001773void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s,
1774 const struct wpa_ssid *ssid,
1775 struct hostapd_freq_params *freq)
1776{
1777 enum hostapd_hw_mode hw_mode;
1778 struct hostapd_hw_modes *mode = NULL;
1779 int ht40plus[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157,
1780 184, 192 };
Dmitry Shmidt7f656022015-02-25 14:36:37 -08001781 int vht80[] = { 36, 52, 100, 116, 132, 149 };
Dmitry Shmidtff787d52015-01-12 13:01:47 -08001782 struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL;
1783 u8 channel;
Dmitry Shmidt7f656022015-02-25 14:36:37 -08001784 int i, chan_idx, ht40 = -1, res, obss_scan = 1;
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08001785 unsigned int j, k;
Dmitry Shmidt7f656022015-02-25 14:36:37 -08001786 struct hostapd_freq_params vht_freq;
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08001787 int chwidth, seg0, seg1;
1788 u32 vht_caps = 0;
Dmitry Shmidtff787d52015-01-12 13:01:47 -08001789
1790 freq->freq = ssid->frequency;
1791
Dmitry Shmidt7f656022015-02-25 14:36:37 -08001792 for (j = 0; j < wpa_s->last_scan_res_used; j++) {
1793 struct wpa_bss *bss = wpa_s->last_scan_res[j];
1794
1795 if (ssid->mode != WPAS_MODE_IBSS)
1796 break;
1797
1798 /* Don't adjust control freq in case of fixed_freq */
1799 if (ssid->fixed_freq)
1800 break;
1801
1802 if (!bss_is_ibss(bss))
1803 continue;
1804
1805 if (ssid->ssid_len == bss->ssid_len &&
1806 os_memcmp(ssid->ssid, bss->ssid, bss->ssid_len) == 0) {
1807 wpa_printf(MSG_DEBUG,
1808 "IBSS already found in scan results, adjust control freq: %d",
1809 bss->freq);
1810 freq->freq = bss->freq;
1811 obss_scan = 0;
1812 break;
1813 }
1814 }
1815
Dmitry Shmidtff787d52015-01-12 13:01:47 -08001816 /* For IBSS check HT_IBSS flag */
1817 if (ssid->mode == WPAS_MODE_IBSS &&
1818 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_HT_IBSS))
1819 return;
1820
Dmitry Shmidt7f656022015-02-25 14:36:37 -08001821 if (wpa_s->group_cipher == WPA_CIPHER_WEP40 ||
1822 wpa_s->group_cipher == WPA_CIPHER_WEP104 ||
1823 wpa_s->pairwise_cipher == WPA_CIPHER_TKIP) {
1824 wpa_printf(MSG_DEBUG,
1825 "IBSS: WEP/TKIP detected, do not try to enable HT");
1826 return;
1827 }
1828
1829 hw_mode = ieee80211_freq_to_chan(freq->freq, &channel);
Dmitry Shmidtff787d52015-01-12 13:01:47 -08001830 for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
1831 if (wpa_s->hw.modes[i].mode == hw_mode) {
1832 mode = &wpa_s->hw.modes[i];
1833 break;
1834 }
1835 }
1836
1837 if (!mode)
1838 return;
1839
1840 freq->ht_enabled = ht_supported(mode);
1841 if (!freq->ht_enabled)
1842 return;
1843
1844 /* Setup higher BW only for 5 GHz */
1845 if (mode->mode != HOSTAPD_MODE_IEEE80211A)
1846 return;
1847
1848 for (chan_idx = 0; chan_idx < mode->num_channels; chan_idx++) {
1849 pri_chan = &mode->channels[chan_idx];
1850 if (pri_chan->chan == channel)
1851 break;
1852 pri_chan = NULL;
1853 }
1854 if (!pri_chan)
1855 return;
1856
1857 /* Check primary channel flags */
1858 if (pri_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
1859 return;
1860
1861 /* Check/setup HT40+/HT40- */
1862 for (j = 0; j < ARRAY_SIZE(ht40plus); j++) {
1863 if (ht40plus[j] == channel) {
1864 ht40 = 1;
1865 break;
1866 }
1867 }
1868
1869 /* Find secondary channel */
1870 for (i = 0; i < mode->num_channels; i++) {
1871 sec_chan = &mode->channels[i];
1872 if (sec_chan->chan == channel + ht40 * 4)
1873 break;
1874 sec_chan = NULL;
1875 }
1876 if (!sec_chan)
1877 return;
1878
1879 /* Check secondary channel flags */
1880 if (sec_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
1881 return;
1882
1883 freq->channel = pri_chan->chan;
1884
1885 switch (ht40) {
1886 case -1:
1887 if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS))
1888 return;
1889 freq->sec_channel_offset = -1;
1890 break;
1891 case 1:
1892 if (!(pri_chan->flag & HOSTAPD_CHAN_HT40PLUS))
1893 return;
1894 freq->sec_channel_offset = 1;
1895 break;
1896 default:
1897 break;
1898 }
1899
Dmitry Shmidt7f656022015-02-25 14:36:37 -08001900 if (freq->sec_channel_offset && obss_scan) {
Dmitry Shmidtff787d52015-01-12 13:01:47 -08001901 struct wpa_scan_results *scan_res;
1902
1903 scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
1904 if (scan_res == NULL) {
1905 /* Back to HT20 */
1906 freq->sec_channel_offset = 0;
1907 return;
1908 }
1909
1910 res = check_40mhz_5g(mode, scan_res, pri_chan->chan,
1911 sec_chan->chan);
1912 switch (res) {
1913 case 0:
1914 /* Back to HT20 */
1915 freq->sec_channel_offset = 0;
1916 break;
1917 case 1:
1918 /* Configuration allowed */
1919 break;
1920 case 2:
1921 /* Switch pri/sec channels */
1922 freq->freq = hw_get_freq(mode, sec_chan->chan);
1923 freq->sec_channel_offset = -freq->sec_channel_offset;
1924 freq->channel = sec_chan->chan;
1925 break;
1926 default:
1927 freq->sec_channel_offset = 0;
1928 break;
1929 }
1930
1931 wpa_scan_results_free(scan_res);
1932 }
1933
1934 wpa_printf(MSG_DEBUG,
1935 "IBSS/mesh: setup freq channel %d, sec_channel_offset %d",
1936 freq->channel, freq->sec_channel_offset);
Dmitry Shmidt7f656022015-02-25 14:36:37 -08001937
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08001938 if (!drv_supports_vht(wpa_s, ssid))
Dmitry Shmidt7f656022015-02-25 14:36:37 -08001939 return;
1940
1941 /* For IBSS check VHT_IBSS flag */
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08001942 if (ssid->mode == WPAS_MODE_IBSS &&
1943 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_VHT_IBSS))
Dmitry Shmidt7f656022015-02-25 14:36:37 -08001944 return;
1945
1946 vht_freq = *freq;
1947
1948 vht_freq.vht_enabled = vht_supported(mode);
1949 if (!vht_freq.vht_enabled)
1950 return;
1951
1952 /* setup center_freq1, bandwidth */
1953 for (j = 0; j < ARRAY_SIZE(vht80); j++) {
1954 if (freq->channel >= vht80[j] &&
1955 freq->channel < vht80[j] + 16)
1956 break;
1957 }
1958
1959 if (j == ARRAY_SIZE(vht80))
1960 return;
1961
1962 for (i = vht80[j]; i < vht80[j] + 16; i += 4) {
1963 struct hostapd_channel_data *chan;
1964
1965 chan = hw_get_channel_chan(mode, i, NULL);
1966 if (!chan)
1967 return;
1968
1969 /* Back to HT configuration if channel not usable */
1970 if (chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
1971 return;
1972 }
1973
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08001974 chwidth = VHT_CHANWIDTH_80MHZ;
1975 seg0 = vht80[j] + 6;
1976 seg1 = 0;
1977
1978 if (ssid->max_oper_chwidth == VHT_CHANWIDTH_80P80MHZ) {
1979 /* setup center_freq2, bandwidth */
1980 for (k = 0; k < ARRAY_SIZE(vht80); k++) {
1981 /* Only accept 80 MHz segments separated by a gap */
1982 if (j == k || abs(vht80[j] - vht80[k]) == 16)
1983 continue;
1984 for (i = vht80[k]; i < vht80[k] + 16; i += 4) {
1985 struct hostapd_channel_data *chan;
1986
1987 chan = hw_get_channel_chan(mode, i, NULL);
1988 if (!chan)
1989 continue;
1990
1991 if (chan->flag & (HOSTAPD_CHAN_DISABLED |
1992 HOSTAPD_CHAN_NO_IR |
1993 HOSTAPD_CHAN_RADAR))
1994 continue;
1995
1996 /* Found a suitable second segment for 80+80 */
1997 chwidth = VHT_CHANWIDTH_80P80MHZ;
1998 vht_caps |=
1999 VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
2000 seg1 = vht80[k] + 6;
2001 }
2002
2003 if (chwidth == VHT_CHANWIDTH_80P80MHZ)
2004 break;
2005 }
2006 }
2007
Dmitry Shmidt7f656022015-02-25 14:36:37 -08002008 if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq,
2009 freq->channel, freq->ht_enabled,
2010 vht_freq.vht_enabled,
2011 freq->sec_channel_offset,
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08002012 chwidth, seg0, seg1, vht_caps) != 0)
Dmitry Shmidt7f656022015-02-25 14:36:37 -08002013 return;
2014
2015 *freq = vht_freq;
2016
2017 wpa_printf(MSG_DEBUG, "IBSS: VHT setup freq cf1 %d, cf2 %d, bw %d",
2018 freq->center_freq1, freq->center_freq2, freq->bandwidth);
Dmitry Shmidtff787d52015-01-12 13:01:47 -08002019}
2020
2021
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08002022static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
2023{
2024 struct wpa_connect_work *cwork = work->ctx;
2025 struct wpa_bss *bss = cwork->bss;
2026 struct wpa_ssid *ssid = cwork->ssid;
2027 struct wpa_supplicant *wpa_s = work->wpa_s;
2028 u8 wpa_ie[200];
2029 size_t wpa_ie_len;
2030 int use_crypt, ret, i, bssid_changed;
2031 int algs = WPA_AUTH_ALG_OPEN;
2032 unsigned int cipher_pairwise, cipher_group;
2033 struct wpa_driver_associate_params params;
2034 int wep_keys_set = 0;
2035 int assoc_failed = 0;
2036 struct wpa_ssid *old_ssid;
2037#ifdef CONFIG_HT_OVERRIDES
2038 struct ieee80211_ht_capabilities htcaps;
2039 struct ieee80211_ht_capabilities htcaps_mask;
2040#endif /* CONFIG_HT_OVERRIDES */
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -07002041#ifdef CONFIG_VHT_OVERRIDES
2042 struct ieee80211_vht_capabilities vhtcaps;
2043 struct ieee80211_vht_capabilities vhtcaps_mask;
2044#endif /* CONFIG_VHT_OVERRIDES */
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08002045
2046 if (deinit) {
Dmitry Shmidtbd14a572014-02-18 10:33:49 -08002047 if (work->started) {
2048 wpa_s->connect_work = NULL;
2049
2050 /* cancel possible auth. timeout */
2051 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s,
2052 NULL);
2053 }
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08002054 wpas_connect_work_free(cwork);
2055 return;
2056 }
2057
2058 wpa_s->connect_work = work;
2059
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002060 if (cwork->bss_removed || !wpas_valid_bss_ssid(wpa_s, bss, ssid) ||
2061 wpas_network_disabled(wpa_s, ssid)) {
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08002062 wpa_dbg(wpa_s, MSG_DEBUG, "BSS/SSID entry for association not valid anymore - drop connection attempt");
2063 wpas_connect_work_done(wpa_s);
2064 return;
2065 }
2066
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002067 os_memset(&params, 0, sizeof(params));
2068 wpa_s->reassociate = 0;
Dmitry Shmidt344abd32014-01-14 13:17:00 -08002069 wpa_s->eap_expected_failure = 0;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002070 if (bss &&
2071 (!wpas_driver_bss_selection(wpa_s) || wpas_wps_searching(wpa_s))) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002072#ifdef CONFIG_IEEE80211R
2073 const u8 *ie, *md = NULL;
2074#endif /* CONFIG_IEEE80211R */
2075 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
2076 " (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid),
2077 wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq);
2078 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
2079 os_memset(wpa_s->bssid, 0, ETH_ALEN);
2080 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
2081 if (bssid_changed)
2082 wpas_notify_bssid_changed(wpa_s);
2083#ifdef CONFIG_IEEE80211R
2084 ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
2085 if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
2086 md = ie + 2;
2087 wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
2088 if (md) {
2089 /* Prepare for the next transition */
2090 wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
2091 }
2092#endif /* CONFIG_IEEE80211R */
2093#ifdef CONFIG_WPS
2094 } else if ((ssid->ssid == NULL || ssid->ssid_len == 0) &&
2095 wpa_s->conf->ap_scan == 2 &&
2096 (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
2097 /* Use ap_scan==1 style network selection to find the network
2098 */
Dmitry Shmidt2e425d62014-11-10 11:18:27 -08002099 wpas_connect_work_done(wpa_s);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002100 wpa_s->scan_req = MANUAL_SCAN_REQ;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002101 wpa_s->reassociate = 1;
2102 wpa_supplicant_req_scan(wpa_s, 0, 0);
2103 return;
2104#endif /* CONFIG_WPS */
2105 } else {
2106 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
2107 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
2108 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
2109 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002110 if (!wpa_s->pno)
2111 wpa_supplicant_cancel_sched_scan(wpa_s);
2112
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002113 wpa_supplicant_cancel_scan(wpa_s);
2114
2115 /* Starting new association, so clear the possibly used WPA IE from the
2116 * previous association. */
2117 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
2118
2119#ifdef IEEE8021X_EAPOL
2120 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
2121 if (ssid->leap) {
2122 if (ssid->non_leap == 0)
2123 algs = WPA_AUTH_ALG_LEAP;
2124 else
2125 algs |= WPA_AUTH_ALG_LEAP;
2126 }
2127 }
2128#endif /* IEEE8021X_EAPOL */
2129 wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs);
2130 if (ssid->auth_alg) {
2131 algs = ssid->auth_alg;
2132 wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: "
2133 "0x%x", algs);
2134 }
2135
2136 if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
2137 wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002138 wpa_key_mgmt_wpa(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002139 int try_opportunistic;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002140 try_opportunistic = (ssid->proactive_key_caching < 0 ?
2141 wpa_s->conf->okc :
2142 ssid->proactive_key_caching) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002143 (ssid->proto & WPA_PROTO_RSN);
2144 if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
Dmitry Shmidt700a1372013-03-15 14:14:44 -07002145 ssid, try_opportunistic) == 0)
Dmitry Shmidt216983b2015-02-06 10:50:36 -08002146 eapol_sm_notify_pmkid_attempt(wpa_s->eapol);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002147 wpa_ie_len = sizeof(wpa_ie);
2148 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
2149 wpa_ie, &wpa_ie_len)) {
2150 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
2151 "key management and encryption suites");
Dmitry Shmidt2e425d62014-11-10 11:18:27 -08002152 wpas_connect_work_done(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002153 return;
2154 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002155 } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && bss &&
2156 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
2157 /*
2158 * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
2159 * use non-WPA since the scan results did not indicate that the
2160 * AP is using WPA or WPA2.
2161 */
2162 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
2163 wpa_ie_len = 0;
2164 wpa_s->wpa_proto = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002165 } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002166 wpa_ie_len = sizeof(wpa_ie);
2167 if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
2168 wpa_ie, &wpa_ie_len)) {
2169 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
2170 "key management and encryption suites (no "
2171 "scan results)");
Dmitry Shmidt2e425d62014-11-10 11:18:27 -08002172 wpas_connect_work_done(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002173 return;
2174 }
2175#ifdef CONFIG_WPS
2176 } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
2177 struct wpabuf *wps_ie;
2178 wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
2179 if (wps_ie && wpabuf_len(wps_ie) <= sizeof(wpa_ie)) {
2180 wpa_ie_len = wpabuf_len(wps_ie);
2181 os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
2182 } else
2183 wpa_ie_len = 0;
2184 wpabuf_free(wps_ie);
2185 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
2186 if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY))
2187 params.wps = WPS_MODE_PRIVACY;
2188 else
2189 params.wps = WPS_MODE_OPEN;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002190 wpa_s->wpa_proto = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002191#endif /* CONFIG_WPS */
2192 } else {
2193 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
2194 wpa_ie_len = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002195 wpa_s->wpa_proto = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002196 }
2197
2198#ifdef CONFIG_P2P
2199 if (wpa_s->global->p2p) {
2200 u8 *pos;
2201 size_t len;
2202 int res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002203 pos = wpa_ie + wpa_ie_len;
2204 len = sizeof(wpa_ie) - wpa_ie_len;
Dmitry Shmidt04949592012-07-19 12:16:46 -07002205 res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
2206 ssid->p2p_group);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002207 if (res >= 0)
2208 wpa_ie_len += res;
2209 }
2210
2211 wpa_s->cross_connect_disallowed = 0;
2212 if (bss) {
2213 struct wpabuf *p2p;
2214 p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
2215 if (p2p) {
2216 wpa_s->cross_connect_disallowed =
2217 p2p_get_cross_connect_disallowed(p2p);
2218 wpabuf_free(p2p);
2219 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: WLAN AP %s cross "
2220 "connection",
2221 wpa_s->cross_connect_disallowed ?
2222 "disallows" : "allows");
2223 }
2224 }
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08002225
2226 os_memset(wpa_s->p2p_ip_addr_info, 0, sizeof(wpa_s->p2p_ip_addr_info));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002227#endif /* CONFIG_P2P */
2228
Dmitry Shmidt04949592012-07-19 12:16:46 -07002229#ifdef CONFIG_HS20
Dmitry Shmidt51b6ea82013-05-08 10:42:09 -07002230 if (is_hs20_network(wpa_s, ssid, bss)) {
Dmitry Shmidt04949592012-07-19 12:16:46 -07002231 struct wpabuf *hs20;
2232 hs20 = wpabuf_alloc(20);
2233 if (hs20) {
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08002234 int pps_mo_id = hs20_get_pps_mo_id(wpa_s, ssid);
Dmitry Shmidtc2817022014-07-02 10:32:10 -07002235 size_t len;
2236
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08002237 wpas_hs20_add_indication(hs20, pps_mo_id);
Dmitry Shmidtc2817022014-07-02 10:32:10 -07002238 len = sizeof(wpa_ie) - wpa_ie_len;
2239 if (wpabuf_len(hs20) <= len) {
2240 os_memcpy(wpa_ie + wpa_ie_len,
2241 wpabuf_head(hs20), wpabuf_len(hs20));
2242 wpa_ie_len += wpabuf_len(hs20);
2243 }
Dmitry Shmidt04949592012-07-19 12:16:46 -07002244 wpabuf_free(hs20);
2245 }
2246 }
2247#endif /* CONFIG_HS20 */
2248
Dmitry Shmidt56052862013-10-04 10:23:25 -07002249 /*
2250 * Workaround: Add Extended Capabilities element only if the AP
2251 * included this element in Beacon/Probe Response frames. Some older
2252 * APs seem to have interoperability issues if this element is
2253 * included, so while the standard may require us to include the
2254 * element in all cases, it is justifiable to skip it to avoid
2255 * interoperability issues.
2256 */
2257 if (!bss || wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB)) {
Dmitry Shmidt09f57ba2014-06-10 16:07:13 -07002258 u8 ext_capab[18];
Dmitry Shmidt56052862013-10-04 10:23:25 -07002259 int ext_capab_len;
Dmitry Shmidt09f57ba2014-06-10 16:07:13 -07002260 ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
2261 sizeof(ext_capab));
Dmitry Shmidt56052862013-10-04 10:23:25 -07002262 if (ext_capab_len > 0) {
2263 u8 *pos = wpa_ie;
2264 if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)
2265 pos += 2 + pos[1];
2266 os_memmove(pos + ext_capab_len, pos,
2267 wpa_ie_len - (pos - wpa_ie));
2268 wpa_ie_len += ext_capab_len;
2269 os_memcpy(pos, ext_capab, ext_capab_len);
2270 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002271 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002272
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08002273 if (wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ]) {
2274 struct wpabuf *buf = wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ];
2275 size_t len;
2276
2277 len = sizeof(wpa_ie) - wpa_ie_len;
2278 if (wpabuf_len(buf) <= len) {
2279 os_memcpy(wpa_ie + wpa_ie_len,
2280 wpabuf_head(buf), wpabuf_len(buf));
2281 wpa_ie_len += wpabuf_len(buf);
2282 }
2283 }
2284
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002285#ifdef CONFIG_FST
2286 if (wpa_s->fst_ies) {
2287 int fst_ies_len = wpabuf_len(wpa_s->fst_ies);
2288
2289 if (wpa_ie_len + fst_ies_len <= sizeof(wpa_ie)) {
2290 os_memcpy(wpa_ie + wpa_ie_len,
2291 wpabuf_head(wpa_s->fst_ies), fst_ies_len);
2292 wpa_ie_len += fst_ies_len;
2293 }
2294 }
2295#endif /* CONFIG_FST */
2296
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002297 wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
2298 use_crypt = 1;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08002299 cipher_pairwise = wpa_s->pairwise_cipher;
2300 cipher_group = wpa_s->group_cipher;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002301 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
2302 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
2303 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
2304 use_crypt = 0;
2305 if (wpa_set_wep_keys(wpa_s, ssid)) {
2306 use_crypt = 1;
2307 wep_keys_set = 1;
2308 }
2309 }
2310 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
2311 use_crypt = 0;
2312
2313#ifdef IEEE8021X_EAPOL
2314 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
2315 if ((ssid->eapol_flags &
2316 (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
2317 EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 &&
2318 !wep_keys_set) {
2319 use_crypt = 0;
2320 } else {
2321 /* Assume that dynamic WEP-104 keys will be used and
2322 * set cipher suites in order for drivers to expect
2323 * encryption. */
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08002324 cipher_pairwise = cipher_group = WPA_CIPHER_WEP104;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002325 }
2326 }
2327#endif /* IEEE8021X_EAPOL */
2328
2329 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
2330 /* Set the key before (and later after) association */
2331 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
2332 }
2333
2334 wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
2335 if (bss) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002336 params.ssid = bss->ssid;
2337 params.ssid_len = bss->ssid_len;
Dmitry Shmidt04949592012-07-19 12:16:46 -07002338 if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
2339 wpa_printf(MSG_DEBUG, "Limit connection to BSSID "
2340 MACSTR " freq=%u MHz based on scan results "
2341 "(bssid_set=%d)",
2342 MAC2STR(bss->bssid), bss->freq,
2343 ssid->bssid_set);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002344 params.bssid = bss->bssid;
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07002345 params.freq.freq = bss->freq;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002346 }
Dmitry Shmidt96be6222014-02-13 10:16:51 -08002347 params.bssid_hint = bss->bssid;
2348 params.freq_hint = bss->freq;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002349 } else {
2350 params.ssid = ssid->ssid;
2351 params.ssid_len = ssid->ssid_len;
2352 }
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002353
2354 if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&
2355 wpa_s->conf->ap_scan == 2) {
2356 params.bssid = ssid->bssid;
2357 params.fixed_bssid = 1;
2358 }
2359
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002360 /* Initial frequency for IBSS/mesh */
2361 if ((ssid->mode == WPAS_MODE_IBSS || ssid->mode == WPAS_MODE_MESH) &&
Dmitry Shmidtff787d52015-01-12 13:01:47 -08002362 ssid->frequency > 0 && params.freq.freq == 0)
2363 ibss_mesh_setup_freq(wpa_s, ssid, &params.freq);
Dmitry Shmidt2ac5f602014-03-07 10:08:21 -08002364
2365 if (ssid->mode == WPAS_MODE_IBSS) {
Dmitry Shmidt7f656022015-02-25 14:36:37 -08002366 params.fixed_freq = ssid->fixed_freq;
Dmitry Shmidt2ac5f602014-03-07 10:08:21 -08002367 if (ssid->beacon_int)
2368 params.beacon_int = ssid->beacon_int;
2369 else
2370 params.beacon_int = wpa_s->conf->beacon_int;
2371 }
2372
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002373 params.wpa_ie = wpa_ie;
2374 params.wpa_ie_len = wpa_ie_len;
2375 params.pairwise_suite = cipher_pairwise;
2376 params.group_suite = cipher_group;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08002377 params.key_mgmt_suite = wpa_s->key_mgmt;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002378 params.wpa_proto = wpa_s->wpa_proto;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002379 params.auth_alg = algs;
2380 params.mode = ssid->mode;
Dmitry Shmidt04949592012-07-19 12:16:46 -07002381 params.bg_scan_period = ssid->bg_scan_period;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002382 for (i = 0; i < NUM_WEP_KEYS; i++) {
2383 if (ssid->wep_key_len[i])
2384 params.wep_key[i] = ssid->wep_key[i];
2385 params.wep_key_len[i] = ssid->wep_key_len[i];
2386 }
2387 params.wep_tx_keyidx = ssid->wep_tx_keyidx;
2388
2389 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08002390 (params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
2391 params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002392 params.passphrase = ssid->passphrase;
2393 if (ssid->psk_set)
2394 params.psk = ssid->psk;
2395 }
2396
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002397 if (wpa_s->conf->key_mgmt_offload) {
2398 if (params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
2399 params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
Dmitry Shmidt807291d2015-01-27 13:40:23 -08002400 params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B ||
2401 params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002402 params.req_key_mgmt_offload =
2403 ssid->proactive_key_caching < 0 ?
2404 wpa_s->conf->okc : ssid->proactive_key_caching;
2405 else
2406 params.req_key_mgmt_offload = 1;
2407
2408 if ((params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
2409 params.key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 ||
2410 params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK) &&
2411 ssid->psk_set)
2412 params.psk = ssid->psk;
2413 }
2414
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002415 params.drop_unencrypted = use_crypt;
2416
2417#ifdef CONFIG_IEEE80211W
Dmitry Shmidt807291d2015-01-27 13:40:23 -08002418 params.mgmt_frame_protection = wpas_get_ssid_pmf(wpa_s, ssid);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002419 if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002420 const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
2421 struct wpa_ie_data ie;
2422 if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
2423 ie.capabilities &
2424 (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
2425 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected AP supports "
2426 "MFP: require MFP");
2427 params.mgmt_frame_protection =
2428 MGMT_FRAME_PROTECTION_REQUIRED;
2429 }
2430 }
2431#endif /* CONFIG_IEEE80211W */
2432
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002433 params.p2p = ssid->p2p_group;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002434
2435 if (wpa_s->parent->set_sta_uapsd)
2436 params.uapsd = wpa_s->parent->sta_uapsd;
2437 else
2438 params.uapsd = -1;
2439
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002440#ifdef CONFIG_HT_OVERRIDES
2441 os_memset(&htcaps, 0, sizeof(htcaps));
2442 os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
2443 params.htcaps = (u8 *) &htcaps;
2444 params.htcaps_mask = (u8 *) &htcaps_mask;
2445 wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
2446#endif /* CONFIG_HT_OVERRIDES */
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -07002447#ifdef CONFIG_VHT_OVERRIDES
2448 os_memset(&vhtcaps, 0, sizeof(vhtcaps));
2449 os_memset(&vhtcaps_mask, 0, sizeof(vhtcaps_mask));
2450 params.vhtcaps = &vhtcaps;
2451 params.vhtcaps_mask = &vhtcaps_mask;
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08002452 wpa_supplicant_apply_vht_overrides(wpa_s, ssid, &params);
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -07002453#endif /* CONFIG_VHT_OVERRIDES */
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002454
Dmitry Shmidt04f534e2013-12-09 15:50:16 -08002455#ifdef CONFIG_P2P
2456 /*
2457 * If multi-channel concurrency is not supported, check for any
2458 * frequency conflict. In case of any frequency conflict, remove the
2459 * least prioritized connection.
2460 */
2461 if (wpa_s->num_multichan_concurrent < 2) {
Dmitry Shmidtf9bdef92014-04-25 10:46:36 -07002462 int freq, num;
2463 num = get_shared_radio_freqs(wpa_s, &freq, 1);
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07002464 if (num > 0 && freq > 0 && freq != params.freq.freq) {
Dmitry Shmidtf9bdef92014-04-25 10:46:36 -07002465 wpa_printf(MSG_DEBUG,
2466 "Assoc conflicting freq found (%d != %d)",
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -07002467 freq, params.freq.freq);
2468 if (wpas_p2p_handle_frequency_conflicts(
Dmitry Shmidt2e425d62014-11-10 11:18:27 -08002469 wpa_s, params.freq.freq, ssid) < 0) {
2470 wpas_connect_work_done(wpa_s);
Dmitry Shmidt04f534e2013-12-09 15:50:16 -08002471 return;
Dmitry Shmidt2e425d62014-11-10 11:18:27 -08002472 }
Dmitry Shmidt04f534e2013-12-09 15:50:16 -08002473 }
2474 }
2475#endif /* CONFIG_P2P */
2476
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002477 ret = wpa_drv_associate(wpa_s, &params);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002478 if (ret < 0) {
2479 wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
2480 "failed");
2481 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SANE_ERROR_CODES) {
2482 /*
2483 * The driver is known to mean what is saying, so we
2484 * can stop right here; the association will not
2485 * succeed.
2486 */
2487 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002488 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002489 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
2490 return;
2491 }
2492 /* try to continue anyway; new association will be tried again
2493 * after timeout */
2494 assoc_failed = 1;
2495 }
2496
2497 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
2498 /* Set the key after the association just in case association
2499 * cleared the previously configured key. */
2500 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
2501 /* No need to timeout authentication since there is no key
2502 * management. */
2503 wpa_supplicant_cancel_auth_timeout(wpa_s);
2504 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
2505#ifdef CONFIG_IBSS_RSN
2506 } else if (ssid->mode == WPAS_MODE_IBSS &&
2507 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
2508 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
2509 /*
2510 * RSN IBSS authentication is per-STA and we can disable the
2511 * per-BSSID authentication.
2512 */
2513 wpa_supplicant_cancel_auth_timeout(wpa_s);
2514#endif /* CONFIG_IBSS_RSN */
2515 } else {
2516 /* Timeout for IEEE 802.11 authentication and association */
2517 int timeout = 60;
2518
2519 if (assoc_failed) {
2520 /* give IBSS a bit more time */
2521 timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5;
2522 } else if (wpa_s->conf->ap_scan == 1) {
2523 /* give IBSS a bit more time */
2524 timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10;
2525 }
2526 wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
2527 }
2528
Dmitry Shmidt51b6ea82013-05-08 10:42:09 -07002529 if (wep_keys_set &&
2530 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002531 /* Set static WEP keys again */
2532 wpa_set_wep_keys(wpa_s, ssid);
2533 }
2534
2535 if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
2536 /*
2537 * Do not allow EAP session resumption between different
2538 * network configurations.
2539 */
2540 eapol_sm_invalidate_cached_session(wpa_s->eapol);
2541 }
2542 old_ssid = wpa_s->current_ssid;
2543 wpa_s->current_ssid = ssid;
Dmitry Shmidtb1e52102015-05-29 12:36:29 -07002544 if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set)
2545 wpa_s->current_bss = bss;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002546 wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
2547 wpa_supplicant_initiate_eapol(wpa_s);
2548 if (old_ssid != wpa_s->current_ssid)
2549 wpas_notify_network_changed(wpa_s);
2550}
2551
2552
2553static void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s,
2554 const u8 *addr)
2555{
2556 struct wpa_ssid *old_ssid;
2557
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002558 wpas_connect_work_done(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002559 wpa_clear_keys(wpa_s, addr);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002560 old_ssid = wpa_s->current_ssid;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002561 wpa_supplicant_mark_disassoc(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002562 wpa_sm_set_config(wpa_s->wpa, NULL);
2563 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
2564 if (old_ssid != wpa_s->current_ssid)
2565 wpas_notify_network_changed(wpa_s);
2566 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
2567}
2568
2569
2570/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002571 * wpa_supplicant_deauthenticate - Deauthenticate the current connection
2572 * @wpa_s: Pointer to wpa_supplicant data
2573 * @reason_code: IEEE 802.11 reason code for the deauthenticate frame
2574 *
2575 * This function is used to request %wpa_supplicant to deauthenticate from the
2576 * current AP.
2577 */
2578void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
2579 int reason_code)
2580{
2581 u8 *addr = NULL;
Dmitry Shmidt04949592012-07-19 12:16:46 -07002582 union wpa_event_data event;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002583 int zero_addr = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002584
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002585 wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
2586 " pending_bssid=" MACSTR " reason=%d state=%s",
2587 MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
2588 reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state));
2589
2590 if (!is_zero_ether_addr(wpa_s->bssid))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002591 addr = wpa_s->bssid;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002592 else if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
2593 (wpa_s->wpa_state == WPA_AUTHENTICATING ||
2594 wpa_s->wpa_state == WPA_ASSOCIATING))
2595 addr = wpa_s->pending_bssid;
2596 else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
2597 /*
2598 * When using driver-based BSS selection, we may not know the
2599 * BSSID with which we are currently trying to associate. We
2600 * need to notify the driver of this disconnection even in such
2601 * a case, so use the all zeros address here.
2602 */
2603 addr = wpa_s->bssid;
2604 zero_addr = 1;
2605 }
2606
Dmitry Shmidtf8623282013-02-20 14:34:59 -08002607#ifdef CONFIG_TDLS
2608 wpa_tdls_teardown_peers(wpa_s->wpa);
2609#endif /* CONFIG_TDLS */
2610
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002611#ifdef CONFIG_MESH
2612 if (wpa_s->ifmsh) {
2613 wpa_msg_ctrl(wpa_s, MSG_INFO, MESH_GROUP_REMOVED "%s",
2614 wpa_s->ifname);
2615 wpa_supplicant_leave_mesh(wpa_s);
2616 }
2617#endif /* CONFIG_MESH */
2618
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002619 if (addr) {
2620 wpa_drv_deauthenticate(wpa_s, addr, reason_code);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002621 os_memset(&event, 0, sizeof(event));
2622 event.deauth_info.reason_code = (u16) reason_code;
2623 event.deauth_info.locally_generated = 1;
2624 wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002625 if (zero_addr)
2626 addr = NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002627 }
2628
2629 wpa_supplicant_clear_connection(wpa_s, addr);
2630}
2631
Dmitry Shmidt2f023192013-03-12 12:44:17 -07002632static void wpa_supplicant_enable_one_network(struct wpa_supplicant *wpa_s,
2633 struct wpa_ssid *ssid)
2634{
2635 if (!ssid || !ssid->disabled || ssid->disabled == 2)
2636 return;
2637
2638 ssid->disabled = 0;
2639 wpas_clear_temp_disabled(wpa_s, ssid, 1);
2640 wpas_notify_network_enabled_changed(wpa_s, ssid);
2641
2642 /*
2643 * Try to reassociate since there is no current configuration and a new
2644 * network was made available.
2645 */
Dmitry Shmidt4ce9c872013-10-24 11:08:13 -07002646 if (!wpa_s->current_ssid && !wpa_s->disconnected)
Dmitry Shmidt2f023192013-03-12 12:44:17 -07002647 wpa_s->reassociate = 1;
2648}
2649
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002650
2651/**
2652 * wpa_supplicant_enable_network - Mark a configured network as enabled
2653 * @wpa_s: wpa_supplicant structure for a network interface
2654 * @ssid: wpa_ssid structure for a configured network or %NULL
2655 *
2656 * Enables the specified network or all networks if no network specified.
2657 */
2658void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
2659 struct wpa_ssid *ssid)
2660{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002661 if (ssid == NULL) {
Dmitry Shmidt2f023192013-03-12 12:44:17 -07002662 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
2663 wpa_supplicant_enable_one_network(wpa_s, ssid);
2664 } else
2665 wpa_supplicant_enable_one_network(wpa_s, ssid);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002666
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002667 if (wpa_s->reassociate && !wpa_s->disconnected &&
2668 (!wpa_s->current_ssid ||
2669 wpa_s->wpa_state == WPA_DISCONNECTED ||
2670 wpa_s->wpa_state == WPA_SCANNING)) {
Dmitry Shmidt2f023192013-03-12 12:44:17 -07002671 if (wpa_s->sched_scanning) {
2672 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to add "
2673 "new network to scan filters");
2674 wpa_supplicant_cancel_sched_scan(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002675 }
2676
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002677 if (wpa_supplicant_fast_associate(wpa_s) != 1) {
2678 wpa_s->scan_req = NORMAL_SCAN_REQ;
Dmitry Shmidtf7e0a992013-05-23 11:03:10 -07002679 wpa_supplicant_req_scan(wpa_s, 0, 0);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002680 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002681 }
2682}
2683
2684
2685/**
2686 * wpa_supplicant_disable_network - Mark a configured network as disabled
2687 * @wpa_s: wpa_supplicant structure for a network interface
2688 * @ssid: wpa_ssid structure for a configured network or %NULL
2689 *
2690 * Disables the specified network or all networks if no network specified.
2691 */
2692void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
2693 struct wpa_ssid *ssid)
2694{
2695 struct wpa_ssid *other_ssid;
2696 int was_disabled;
2697
2698 if (ssid == NULL) {
Dmitry Shmidt2f023192013-03-12 12:44:17 -07002699 if (wpa_s->sched_scanning)
2700 wpa_supplicant_cancel_sched_scan(wpa_s);
2701
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002702 for (other_ssid = wpa_s->conf->ssid; other_ssid;
2703 other_ssid = other_ssid->next) {
2704 was_disabled = other_ssid->disabled;
2705 if (was_disabled == 2)
2706 continue; /* do not change persistent P2P group
2707 * data */
2708
2709 other_ssid->disabled = 1;
2710
2711 if (was_disabled != other_ssid->disabled)
2712 wpas_notify_network_enabled_changed(
2713 wpa_s, other_ssid);
2714 }
2715 if (wpa_s->current_ssid)
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002716 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002717 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
2718 } else if (ssid->disabled != 2) {
2719 if (ssid == wpa_s->current_ssid)
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002720 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002721 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
2722
2723 was_disabled = ssid->disabled;
2724
2725 ssid->disabled = 1;
2726
Dmitry Shmidt2f023192013-03-12 12:44:17 -07002727 if (was_disabled != ssid->disabled) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002728 wpas_notify_network_enabled_changed(wpa_s, ssid);
Dmitry Shmidt2f023192013-03-12 12:44:17 -07002729 if (wpa_s->sched_scanning) {
2730 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan "
2731 "to remove network from filters");
2732 wpa_supplicant_cancel_sched_scan(wpa_s);
2733 wpa_supplicant_req_scan(wpa_s, 0, 0);
2734 }
2735 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002736 }
2737}
2738
2739
2740/**
2741 * wpa_supplicant_select_network - Attempt association with a network
2742 * @wpa_s: wpa_supplicant structure for a network interface
2743 * @ssid: wpa_ssid structure for a configured network or %NULL for any network
2744 */
2745void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
2746 struct wpa_ssid *ssid)
2747{
2748
2749 struct wpa_ssid *other_ssid;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002750 int disconnected = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002751
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002752 if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
Dmitry Shmidt7a53dbb2015-06-11 13:13:53 -07002753 if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
2754 wpa_s->own_disconnect_req = 1;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08002755 wpa_supplicant_deauthenticate(
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002756 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002757 disconnected = 1;
2758 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002759
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002760 if (ssid)
2761 wpas_clear_temp_disabled(wpa_s, ssid, 1);
2762
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002763 /*
2764 * Mark all other networks disabled or mark all networks enabled if no
2765 * network specified.
2766 */
2767 for (other_ssid = wpa_s->conf->ssid; other_ssid;
2768 other_ssid = other_ssid->next) {
2769 int was_disabled = other_ssid->disabled;
2770 if (was_disabled == 2)
2771 continue; /* do not change persistent P2P group data */
2772
2773 other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07002774 if (was_disabled && !other_ssid->disabled)
2775 wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002776
2777 if (was_disabled != other_ssid->disabled)
2778 wpas_notify_network_enabled_changed(wpa_s, other_ssid);
2779 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002780
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08002781 if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid &&
2782 wpa_s->wpa_state >= WPA_AUTHENTICATING) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002783 /* We are already associated with the selected network */
2784 wpa_printf(MSG_DEBUG, "Already associated with the "
2785 "selected network - do nothing");
2786 return;
2787 }
2788
Dmitry Shmidtb7b4d0e2013-08-26 12:09:05 -07002789 if (ssid) {
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08002790 wpa_s->current_ssid = ssid;
Dmitry Shmidtb7b4d0e2013-08-26 12:09:05 -07002791 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002792 wpa_s->connect_without_scan =
2793 (ssid->mode == WPAS_MODE_MESH) ? ssid : NULL;
Dmitry Shmidtdda10c22015-03-24 16:05:01 -07002794
2795 /*
2796 * Don't optimize next scan freqs since a new ESS has been
2797 * selected.
2798 */
2799 os_free(wpa_s->next_scan_freqs);
2800 wpa_s->next_scan_freqs = NULL;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002801 } else {
2802 wpa_s->connect_without_scan = NULL;
Dmitry Shmidtb7b4d0e2013-08-26 12:09:05 -07002803 }
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002804
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002805 wpa_s->disconnected = 0;
2806 wpa_s->reassociate = 1;
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -08002807
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08002808 if (wpa_s->connect_without_scan ||
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002809 wpa_supplicant_fast_associate(wpa_s) != 1) {
2810 wpa_s->scan_req = NORMAL_SCAN_REQ;
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -08002811 wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002812 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002813
2814 if (ssid)
2815 wpas_notify_network_selected(wpa_s, ssid);
2816}
2817
2818
2819/**
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08002820 * wpas_set_pkcs11_engine_and_module_path - Set PKCS #11 engine and module path
2821 * @wpa_s: wpa_supplicant structure for a network interface
2822 * @pkcs11_engine_path: PKCS #11 engine path or NULL
2823 * @pkcs11_module_path: PKCS #11 module path or NULL
2824 * Returns: 0 on success; -1 on failure
2825 *
2826 * Sets the PKCS #11 engine and module path. Both have to be NULL or a valid
2827 * path. If resetting the EAPOL state machine with the new PKCS #11 engine and
2828 * module path fails the paths will be reset to the default value (NULL).
2829 */
2830int wpas_set_pkcs11_engine_and_module_path(struct wpa_supplicant *wpa_s,
2831 const char *pkcs11_engine_path,
2832 const char *pkcs11_module_path)
2833{
2834 char *pkcs11_engine_path_copy = NULL;
2835 char *pkcs11_module_path_copy = NULL;
2836
2837 if (pkcs11_engine_path != NULL) {
2838 pkcs11_engine_path_copy = os_strdup(pkcs11_engine_path);
2839 if (pkcs11_engine_path_copy == NULL)
2840 return -1;
2841 }
2842 if (pkcs11_module_path != NULL) {
2843 pkcs11_module_path_copy = os_strdup(pkcs11_module_path);
Dmitry Shmidt97672262014-02-03 13:02:54 -08002844 if (pkcs11_module_path_copy == NULL) {
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08002845 os_free(pkcs11_engine_path_copy);
2846 return -1;
2847 }
2848 }
2849
2850 os_free(wpa_s->conf->pkcs11_engine_path);
2851 os_free(wpa_s->conf->pkcs11_module_path);
2852 wpa_s->conf->pkcs11_engine_path = pkcs11_engine_path_copy;
2853 wpa_s->conf->pkcs11_module_path = pkcs11_module_path_copy;
2854
2855 wpa_sm_set_eapol(wpa_s->wpa, NULL);
2856 eapol_sm_deinit(wpa_s->eapol);
2857 wpa_s->eapol = NULL;
2858 if (wpa_supplicant_init_eapol(wpa_s)) {
2859 /* Error -> Reset paths to the default value (NULL) once. */
2860 if (pkcs11_engine_path != NULL && pkcs11_module_path != NULL)
2861 wpas_set_pkcs11_engine_and_module_path(wpa_s, NULL,
2862 NULL);
2863
2864 return -1;
2865 }
2866 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
2867
2868 return 0;
2869}
2870
2871
2872/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002873 * wpa_supplicant_set_ap_scan - Set AP scan mode for interface
2874 * @wpa_s: wpa_supplicant structure for a network interface
2875 * @ap_scan: AP scan mode
2876 * Returns: 0 if succeed or -1 if ap_scan has an invalid value
2877 *
2878 */
2879int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
2880{
2881
2882 int old_ap_scan;
2883
2884 if (ap_scan < 0 || ap_scan > 2)
2885 return -1;
2886
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08002887 if (ap_scan == 2 && os_strcmp(wpa_s->driver->name, "nl80211") == 0) {
2888 wpa_printf(MSG_INFO,
2889 "Note: nl80211 driver interface is not designed to be used with ap_scan=2; this can result in connection failures");
2890 }
2891
Dmitry Shmidt114c3862011-08-16 11:52:06 -07002892#ifdef ANDROID
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002893 if (ap_scan == 2 && ap_scan != wpa_s->conf->ap_scan &&
2894 wpa_s->wpa_state >= WPA_ASSOCIATING &&
2895 wpa_s->wpa_state < WPA_COMPLETED) {
2896 wpa_printf(MSG_ERROR, "ap_scan = %d (%d) rejected while "
2897 "associating", wpa_s->conf->ap_scan, ap_scan);
Dmitry Shmidt114c3862011-08-16 11:52:06 -07002898 return 0;
2899 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08002900#endif /* ANDROID */
Dmitry Shmidt114c3862011-08-16 11:52:06 -07002901
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002902 old_ap_scan = wpa_s->conf->ap_scan;
2903 wpa_s->conf->ap_scan = ap_scan;
2904
2905 if (old_ap_scan != wpa_s->conf->ap_scan)
2906 wpas_notify_ap_scan_changed(wpa_s);
2907
2908 return 0;
2909}
2910
2911
2912/**
2913 * wpa_supplicant_set_bss_expiration_age - Set BSS entry expiration age
2914 * @wpa_s: wpa_supplicant structure for a network interface
2915 * @expire_age: Expiration age in seconds
2916 * Returns: 0 if succeed or -1 if expire_age has an invalid value
2917 *
2918 */
2919int wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
2920 unsigned int bss_expire_age)
2921{
2922 if (bss_expire_age < 10) {
2923 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration age %u",
2924 bss_expire_age);
2925 return -1;
2926 }
2927 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration age: %d sec",
2928 bss_expire_age);
2929 wpa_s->conf->bss_expiration_age = bss_expire_age;
2930
2931 return 0;
2932}
2933
2934
2935/**
2936 * wpa_supplicant_set_bss_expiration_count - Set BSS entry expiration scan count
2937 * @wpa_s: wpa_supplicant structure for a network interface
2938 * @expire_count: number of scans after which an unseen BSS is reclaimed
2939 * Returns: 0 if succeed or -1 if expire_count has an invalid value
2940 *
2941 */
2942int wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
2943 unsigned int bss_expire_count)
2944{
2945 if (bss_expire_count < 1) {
2946 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration count %u",
2947 bss_expire_count);
2948 return -1;
2949 }
2950 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration scan count: %u",
2951 bss_expire_count);
2952 wpa_s->conf->bss_expiration_scan_count = bss_expire_count;
2953
2954 return 0;
2955}
2956
2957
2958/**
Dmitry Shmidt04949592012-07-19 12:16:46 -07002959 * wpa_supplicant_set_scan_interval - Set scan interval
2960 * @wpa_s: wpa_supplicant structure for a network interface
2961 * @scan_interval: scan interval in seconds
2962 * Returns: 0 if succeed or -1 if scan_interval has an invalid value
2963 *
2964 */
2965int wpa_supplicant_set_scan_interval(struct wpa_supplicant *wpa_s,
2966 int scan_interval)
2967{
2968 if (scan_interval < 0) {
2969 wpa_msg(wpa_s, MSG_ERROR, "Invalid scan interval %d",
2970 scan_interval);
2971 return -1;
2972 }
2973 wpa_msg(wpa_s, MSG_DEBUG, "Setting scan interval: %d sec",
2974 scan_interval);
Dmitry Shmidt4b9d52f2013-02-05 17:44:43 -08002975 wpa_supplicant_update_scan_int(wpa_s, scan_interval);
Dmitry Shmidt04949592012-07-19 12:16:46 -07002976
2977 return 0;
2978}
2979
2980
2981/**
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07002982 * wpa_supplicant_set_debug_params - Set global debug params
2983 * @global: wpa_global structure
2984 * @debug_level: debug level
2985 * @debug_timestamp: determines if show timestamp in debug data
2986 * @debug_show_keys: determines if show keys in debug data
2987 * Returns: 0 if succeed or -1 if debug_level has wrong value
2988 */
2989int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
2990 int debug_timestamp, int debug_show_keys)
2991{
2992
2993 int old_level, old_timestamp, old_show_keys;
2994
2995 /* check for allowed debuglevels */
2996 if (debug_level != MSG_EXCESSIVE &&
2997 debug_level != MSG_MSGDUMP &&
2998 debug_level != MSG_DEBUG &&
2999 debug_level != MSG_INFO &&
3000 debug_level != MSG_WARNING &&
3001 debug_level != MSG_ERROR)
3002 return -1;
3003
3004 old_level = wpa_debug_level;
3005 old_timestamp = wpa_debug_timestamp;
3006 old_show_keys = wpa_debug_show_keys;
3007
3008 wpa_debug_level = debug_level;
3009 wpa_debug_timestamp = debug_timestamp ? 1 : 0;
3010 wpa_debug_show_keys = debug_show_keys ? 1 : 0;
3011
3012 if (wpa_debug_level != old_level)
3013 wpas_notify_debug_level_changed(global);
3014 if (wpa_debug_timestamp != old_timestamp)
3015 wpas_notify_debug_timestamp_changed(global);
3016 if (wpa_debug_show_keys != old_show_keys)
3017 wpas_notify_debug_show_keys_changed(global);
3018
3019 return 0;
3020}
3021
3022
3023/**
3024 * wpa_supplicant_get_ssid - Get a pointer to the current network structure
3025 * @wpa_s: Pointer to wpa_supplicant data
3026 * Returns: A pointer to the current network structure or %NULL on failure
3027 */
3028struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
3029{
3030 struct wpa_ssid *entry;
Dmitry Shmidt9d9e6022015-04-23 10:34:55 -07003031 u8 ssid[SSID_MAX_LEN];
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003032 int res;
3033 size_t ssid_len;
3034 u8 bssid[ETH_ALEN];
3035 int wired;
3036
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003037 res = wpa_drv_get_ssid(wpa_s, ssid);
3038 if (res < 0) {
3039 wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
3040 "driver");
3041 return NULL;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003042 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003043 ssid_len = res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003044
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003045 if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003046 wpa_msg(wpa_s, MSG_WARNING, "Could not read BSSID from "
3047 "driver");
3048 return NULL;
3049 }
3050
3051 wired = wpa_s->conf->ap_scan == 0 &&
3052 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
3053
3054 entry = wpa_s->conf->ssid;
3055 while (entry) {
Dmitry Shmidt04949592012-07-19 12:16:46 -07003056 if (!wpas_network_disabled(wpa_s, entry) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003057 ((ssid_len == entry->ssid_len &&
3058 os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
3059 (!entry->bssid_set ||
3060 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
3061 return entry;
3062#ifdef CONFIG_WPS
Dmitry Shmidt04949592012-07-19 12:16:46 -07003063 if (!wpas_network_disabled(wpa_s, entry) &&
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003064 (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
3065 (entry->ssid == NULL || entry->ssid_len == 0) &&
3066 (!entry->bssid_set ||
3067 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
3068 return entry;
3069#endif /* CONFIG_WPS */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003070
Dmitry Shmidt04949592012-07-19 12:16:46 -07003071 if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003072 entry->ssid_len == 0 &&
3073 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
3074 return entry;
3075
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003076 entry = entry->next;
3077 }
3078
3079 return NULL;
3080}
3081
3082
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003083static int select_driver(struct wpa_supplicant *wpa_s, int i)
3084{
3085 struct wpa_global *global = wpa_s->global;
3086
3087 if (wpa_drivers[i]->global_init && global->drv_priv[i] == NULL) {
3088 global->drv_priv[i] = wpa_drivers[i]->global_init();
3089 if (global->drv_priv[i] == NULL) {
3090 wpa_printf(MSG_ERROR, "Failed to initialize driver "
3091 "'%s'", wpa_drivers[i]->name);
3092 return -1;
3093 }
3094 }
3095
3096 wpa_s->driver = wpa_drivers[i];
3097 wpa_s->global_drv_priv = global->drv_priv[i];
3098
3099 return 0;
3100}
3101
3102
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003103static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
3104 const char *name)
3105{
3106 int i;
3107 size_t len;
3108 const char *pos, *driver = name;
3109
3110 if (wpa_s == NULL)
3111 return -1;
3112
3113 if (wpa_drivers[0] == NULL) {
3114 wpa_msg(wpa_s, MSG_ERROR, "No driver interfaces build into "
3115 "wpa_supplicant");
3116 return -1;
3117 }
3118
3119 if (name == NULL) {
3120 /* default to first driver in the list */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003121 return select_driver(wpa_s, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003122 }
3123
3124 do {
3125 pos = os_strchr(driver, ',');
3126 if (pos)
3127 len = pos - driver;
3128 else
3129 len = os_strlen(driver);
3130
3131 for (i = 0; wpa_drivers[i]; i++) {
3132 if (os_strlen(wpa_drivers[i]->name) == len &&
3133 os_strncmp(driver, wpa_drivers[i]->name, len) ==
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003134 0) {
3135 /* First driver that succeeds wins */
3136 if (select_driver(wpa_s, i) == 0)
3137 return 0;
3138 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003139 }
3140
3141 driver = pos + 1;
3142 } while (pos);
3143
3144 wpa_msg(wpa_s, MSG_ERROR, "Unsupported driver '%s'", name);
3145 return -1;
3146}
3147
3148
3149/**
3150 * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
3151 * @ctx: Context pointer (wpa_s); this is the ctx variable registered
3152 * with struct wpa_driver_ops::init()
3153 * @src_addr: Source address of the EAPOL frame
3154 * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
3155 * @len: Length of the EAPOL data
3156 *
3157 * This function is called for each received EAPOL frame. Most driver
3158 * interfaces rely on more generic OS mechanism for receiving frames through
3159 * l2_packet, but if such a mechanism is not available, the driver wrapper may
3160 * take care of received EAPOL frames and deliver them to the core supplicant
3161 * code by calling this function.
3162 */
3163void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
3164 const u8 *buf, size_t len)
3165{
3166 struct wpa_supplicant *wpa_s = ctx;
3167
3168 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
3169 wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
3170
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08003171#ifdef CONFIG_PEERKEY
3172 if (wpa_s->wpa_state > WPA_ASSOCIATED && wpa_s->current_ssid &&
3173 wpa_s->current_ssid->peerkey &&
3174 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
3175 wpa_sm_rx_eapol_peerkey(wpa_s->wpa, src_addr, buf, len) == 1) {
3176 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: Processed PeerKey EAPOL-Key");
3177 return;
3178 }
3179#endif /* CONFIG_PEERKEY */
3180
Jouni Malinena05074c2012-12-21 21:35:35 +02003181 if (wpa_s->wpa_state < WPA_ASSOCIATED ||
3182 (wpa_s->last_eapol_matches_bssid &&
3183#ifdef CONFIG_AP
3184 !wpa_s->ap_iface &&
3185#endif /* CONFIG_AP */
3186 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) != 0)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003187 /*
3188 * There is possible race condition between receiving the
3189 * association event and the EAPOL frame since they are coming
3190 * through different paths from the driver. In order to avoid
3191 * issues in trying to process the EAPOL frame before receiving
3192 * association information, lets queue it for processing until
Jouni Malinena05074c2012-12-21 21:35:35 +02003193 * the association event is received. This may also be needed in
3194 * driver-based roaming case, so also use src_addr != BSSID as a
3195 * trigger if we have previously confirmed that the
3196 * Authenticator uses BSSID as the src_addr (which is not the
3197 * case with wired IEEE 802.1X).
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003198 */
3199 wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing "
Jouni Malinena05074c2012-12-21 21:35:35 +02003200 "of received EAPOL frame (state=%s bssid=" MACSTR ")",
3201 wpa_supplicant_state_txt(wpa_s->wpa_state),
3202 MAC2STR(wpa_s->bssid));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003203 wpabuf_free(wpa_s->pending_eapol_rx);
3204 wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
3205 if (wpa_s->pending_eapol_rx) {
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08003206 os_get_reltime(&wpa_s->pending_eapol_rx_time);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003207 os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
3208 ETH_ALEN);
3209 }
3210 return;
3211 }
3212
Jouni Malinena05074c2012-12-21 21:35:35 +02003213 wpa_s->last_eapol_matches_bssid =
3214 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) == 0;
3215
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003216#ifdef CONFIG_AP
3217 if (wpa_s->ap_iface) {
3218 wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
3219 return;
3220 }
3221#endif /* CONFIG_AP */
3222
3223 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
3224 wpa_dbg(wpa_s, MSG_DEBUG, "Ignored received EAPOL frame since "
3225 "no key management is configured");
3226 return;
3227 }
3228
3229 if (wpa_s->eapol_received == 0 &&
3230 (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
3231 !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
3232 wpa_s->wpa_state != WPA_COMPLETED) &&
3233 (wpa_s->current_ssid == NULL ||
3234 wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) {
3235 /* Timeout for completing IEEE 802.1X and WPA authentication */
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07003236 int timeout = 10;
3237
3238 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
3239 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
3240 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) {
3241 /* Use longer timeout for IEEE 802.1X/EAP */
3242 timeout = 70;
3243 }
3244
Dmitry Shmidt8bd70b72015-05-26 16:02:19 -07003245#ifdef CONFIG_WPS
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07003246 if (wpa_s->current_ssid && wpa_s->current_bss &&
3247 (wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS) &&
3248 eap_is_wps_pin_enrollee(&wpa_s->current_ssid->eap)) {
3249 /*
3250 * Use shorter timeout if going through WPS AP iteration
3251 * for PIN config method with an AP that does not
3252 * advertise Selected Registrar.
3253 */
3254 struct wpabuf *wps_ie;
3255
3256 wps_ie = wpa_bss_get_vendor_ie_multi(
3257 wpa_s->current_bss, WPS_IE_VENDOR_TYPE);
3258 if (wps_ie &&
3259 !wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1))
3260 timeout = 10;
3261 wpabuf_free(wps_ie);
3262 }
Dmitry Shmidt8bd70b72015-05-26 16:02:19 -07003263#endif /* CONFIG_WPS */
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07003264
3265 wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003266 }
3267 wpa_s->eapol_received++;
3268
3269 if (wpa_s->countermeasures) {
3270 wpa_msg(wpa_s, MSG_INFO, "WPA: Countermeasures - dropped "
3271 "EAPOL packet");
3272 return;
3273 }
3274
3275#ifdef CONFIG_IBSS_RSN
3276 if (wpa_s->current_ssid &&
3277 wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
3278 ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
3279 return;
3280 }
3281#endif /* CONFIG_IBSS_RSN */
3282
3283 /* Source address of the incoming EAPOL frame could be compared to the
3284 * current BSSID. However, it is possible that a centralized
3285 * Authenticator could be using another MAC address than the BSSID of
3286 * an AP, so just allow any address to be used for now. The replies are
3287 * still sent to the current BSSID (if available), though. */
3288
3289 os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
3290 if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
3291 eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
3292 return;
3293 wpa_drv_poll(wpa_s);
3294 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
3295 wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
3296 else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
3297 /*
3298 * Set portValid = TRUE here since we are going to skip 4-way
3299 * handshake processing which would normally set portValid. We
3300 * need this to allow the EAPOL state machines to be completed
3301 * without going through EAPOL-Key handshake.
3302 */
3303 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
3304 }
3305}
3306
3307
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003308int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003309{
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003310 if ((!wpa_s->p2p_mgmt ||
3311 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
3312 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003313 l2_packet_deinit(wpa_s->l2);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003314 wpa_s->l2 = l2_packet_init(wpa_s->ifname,
3315 wpa_drv_get_mac_addr(wpa_s),
3316 ETH_P_EAPOL,
3317 wpa_supplicant_rx_eapol, wpa_s, 0);
3318 if (wpa_s->l2 == NULL)
3319 return -1;
3320 } else {
3321 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
3322 if (addr)
3323 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
3324 }
3325
3326 if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
3327 wpa_msg(wpa_s, MSG_ERROR, "Failed to get own L2 address");
3328 return -1;
3329 }
3330
Dmitry Shmidt661b4f72014-09-29 14:58:27 -07003331 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
3332
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003333 return 0;
3334}
3335
3336
Dmitry Shmidt04949592012-07-19 12:16:46 -07003337static void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr,
3338 const u8 *buf, size_t len)
3339{
3340 struct wpa_supplicant *wpa_s = ctx;
3341 const struct l2_ethhdr *eth;
3342
3343 if (len < sizeof(*eth))
3344 return;
3345 eth = (const struct l2_ethhdr *) buf;
3346
3347 if (os_memcmp(eth->h_dest, wpa_s->own_addr, ETH_ALEN) != 0 &&
3348 !(eth->h_dest[0] & 0x01)) {
3349 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
3350 " (bridge - not for this interface - ignore)",
3351 MAC2STR(src_addr), MAC2STR(eth->h_dest));
3352 return;
3353 }
3354
3355 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
3356 " (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest));
3357 wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth),
3358 len - sizeof(*eth));
3359}
3360
3361
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003362/**
3363 * wpa_supplicant_driver_init - Initialize driver interface parameters
3364 * @wpa_s: Pointer to wpa_supplicant data
3365 * Returns: 0 on success, -1 on failure
3366 *
3367 * This function is called to initialize driver interface parameters.
3368 * wpa_drv_init() must have been called before this function to initialize the
3369 * driver interface.
3370 */
3371int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
3372{
3373 static int interface_count = 0;
3374
3375 if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
3376 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003377
Dmitry Shmidt34af3062013-07-11 10:46:32 -07003378 wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
3379 MAC2STR(wpa_s->own_addr));
Dmitry Shmidt661b4f72014-09-29 14:58:27 -07003380 os_memcpy(wpa_s->perm_addr, wpa_s->own_addr, ETH_ALEN);
Dmitry Shmidt34af3062013-07-11 10:46:32 -07003381 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
3382
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003383 if (wpa_s->bridge_ifname[0]) {
3384 wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
3385 "interface '%s'", wpa_s->bridge_ifname);
Dmitry Shmidt216983b2015-02-06 10:50:36 -08003386 wpa_s->l2_br = l2_packet_init_bridge(
3387 wpa_s->bridge_ifname, wpa_s->ifname, wpa_s->own_addr,
3388 ETH_P_EAPOL, wpa_supplicant_rx_eapol_bridge, wpa_s, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003389 if (wpa_s->l2_br == NULL) {
3390 wpa_msg(wpa_s, MSG_ERROR, "Failed to open l2_packet "
3391 "connection for the bridge interface '%s'",
3392 wpa_s->bridge_ifname);
3393 return -1;
3394 }
3395 }
3396
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003397 if (wpa_s->conf->ap_scan == 2 &&
3398 os_strcmp(wpa_s->driver->name, "nl80211") == 0) {
3399 wpa_printf(MSG_INFO,
3400 "Note: nl80211 driver interface is not designed to be used with ap_scan=2; this can result in connection failures");
3401 }
3402
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003403 wpa_clear_keys(wpa_s, NULL);
3404
3405 /* Make sure that TKIP countermeasures are not left enabled (could
3406 * happen if wpa_supplicant is killed during countermeasures. */
3407 wpa_drv_set_countermeasures(wpa_s, 0);
3408
3409 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
3410 wpa_drv_flush_pmkid(wpa_s);
3411
3412 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003413 wpa_s->prev_scan_wildcard = 0;
3414
Dmitry Shmidt04949592012-07-19 12:16:46 -07003415 if (wpa_supplicant_enabled_networks(wpa_s)) {
Dmitry Shmidt9e3f8ee2014-01-17 10:52:01 -08003416 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
3417 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
3418 interface_count = 0;
3419 }
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003420#ifndef ANDROID
Dmitry Shmidta38abf92014-03-06 13:38:44 -08003421 if (!wpa_s->p2p_mgmt &&
Dmitry Shmidt98660862014-03-11 17:26:21 -07003422 wpa_supplicant_delayed_sched_scan(wpa_s,
3423 interface_count % 3,
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003424 100000))
Dmitry Shmidt98660862014-03-11 17:26:21 -07003425 wpa_supplicant_req_scan(wpa_s, interface_count % 3,
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003426 100000);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003427#endif /* ANDROID */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003428 interface_count++;
3429 } else
3430 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
3431
3432 return 0;
3433}
3434
3435
3436static int wpa_supplicant_daemon(const char *pid_file)
3437{
3438 wpa_printf(MSG_DEBUG, "Daemonize..");
3439 return os_daemonize(pid_file);
3440}
3441
3442
Dmitry Shmidt203eadb2015-03-05 14:16:04 -08003443static struct wpa_supplicant *
3444wpa_supplicant_alloc(struct wpa_supplicant *parent)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003445{
3446 struct wpa_supplicant *wpa_s;
3447
3448 wpa_s = os_zalloc(sizeof(*wpa_s));
3449 if (wpa_s == NULL)
3450 return NULL;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08003451 wpa_s->scan_req = INITIAL_SCAN_REQ;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003452 wpa_s->scan_interval = 5;
3453 wpa_s->new_connection = 1;
Dmitry Shmidt203eadb2015-03-05 14:16:04 -08003454 wpa_s->parent = parent ? parent : wpa_s;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003455 wpa_s->sched_scanning = 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07003456
3457 return wpa_s;
3458}
3459
3460
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003461#ifdef CONFIG_HT_OVERRIDES
3462
3463static int wpa_set_htcap_mcs(struct wpa_supplicant *wpa_s,
3464 struct ieee80211_ht_capabilities *htcaps,
3465 struct ieee80211_ht_capabilities *htcaps_mask,
3466 const char *ht_mcs)
3467{
3468 /* parse ht_mcs into hex array */
3469 int i;
3470 const char *tmp = ht_mcs;
3471 char *end = NULL;
3472
3473 /* If ht_mcs is null, do not set anything */
3474 if (!ht_mcs)
3475 return 0;
3476
3477 /* This is what we are setting in the kernel */
3478 os_memset(&htcaps->supported_mcs_set, 0, IEEE80211_HT_MCS_MASK_LEN);
3479
3480 wpa_msg(wpa_s, MSG_DEBUG, "set_htcap, ht_mcs -:%s:-", ht_mcs);
3481
3482 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
3483 errno = 0;
3484 long v = strtol(tmp, &end, 16);
3485 if (errno == 0) {
3486 wpa_msg(wpa_s, MSG_DEBUG,
3487 "htcap value[%i]: %ld end: %p tmp: %p",
3488 i, v, end, tmp);
3489 if (end == tmp)
3490 break;
3491
3492 htcaps->supported_mcs_set[i] = v;
3493 tmp = end;
3494 } else {
3495 wpa_msg(wpa_s, MSG_ERROR,
3496 "Failed to parse ht-mcs: %s, error: %s\n",
3497 ht_mcs, strerror(errno));
3498 return -1;
3499 }
3500 }
3501
3502 /*
3503 * If we were able to parse any values, then set mask for the MCS set.
3504 */
3505 if (i) {
3506 os_memset(&htcaps_mask->supported_mcs_set, 0xff,
3507 IEEE80211_HT_MCS_MASK_LEN - 1);
3508 /* skip the 3 reserved bits */
3509 htcaps_mask->supported_mcs_set[IEEE80211_HT_MCS_MASK_LEN - 1] =
3510 0x1f;
3511 }
3512
3513 return 0;
3514}
3515
3516
3517static int wpa_disable_max_amsdu(struct wpa_supplicant *wpa_s,
3518 struct ieee80211_ht_capabilities *htcaps,
3519 struct ieee80211_ht_capabilities *htcaps_mask,
3520 int disabled)
3521{
Dmitry Shmidtc2817022014-07-02 10:32:10 -07003522 le16 msk;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003523
3524 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
3525
3526 if (disabled == -1)
3527 return 0;
3528
3529 msk = host_to_le16(HT_CAP_INFO_MAX_AMSDU_SIZE);
3530 htcaps_mask->ht_capabilities_info |= msk;
3531 if (disabled)
3532 htcaps->ht_capabilities_info &= msk;
3533 else
3534 htcaps->ht_capabilities_info |= msk;
3535
3536 return 0;
3537}
3538
3539
3540static int wpa_set_ampdu_factor(struct wpa_supplicant *wpa_s,
3541 struct ieee80211_ht_capabilities *htcaps,
3542 struct ieee80211_ht_capabilities *htcaps_mask,
3543 int factor)
3544{
3545 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
3546
3547 if (factor == -1)
3548 return 0;
3549
3550 if (factor < 0 || factor > 3) {
3551 wpa_msg(wpa_s, MSG_ERROR, "ampdu_factor: %d out of range. "
3552 "Must be 0-3 or -1", factor);
3553 return -EINVAL;
3554 }
3555
3556 htcaps_mask->a_mpdu_params |= 0x3; /* 2 bits for factor */
3557 htcaps->a_mpdu_params &= ~0x3;
3558 htcaps->a_mpdu_params |= factor & 0x3;
3559
3560 return 0;
3561}
3562
3563
3564static int wpa_set_ampdu_density(struct wpa_supplicant *wpa_s,
3565 struct ieee80211_ht_capabilities *htcaps,
3566 struct ieee80211_ht_capabilities *htcaps_mask,
3567 int density)
3568{
3569 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
3570
3571 if (density == -1)
3572 return 0;
3573
3574 if (density < 0 || density > 7) {
3575 wpa_msg(wpa_s, MSG_ERROR,
3576 "ampdu_density: %d out of range. Must be 0-7 or -1.",
3577 density);
3578 return -EINVAL;
3579 }
3580
3581 htcaps_mask->a_mpdu_params |= 0x1C;
3582 htcaps->a_mpdu_params &= ~(0x1C);
3583 htcaps->a_mpdu_params |= (density << 2) & 0x1C;
3584
3585 return 0;
3586}
3587
3588
3589static int wpa_set_disable_ht40(struct wpa_supplicant *wpa_s,
3590 struct ieee80211_ht_capabilities *htcaps,
3591 struct ieee80211_ht_capabilities *htcaps_mask,
3592 int disabled)
3593{
3594 /* Masking these out disables HT40 */
Dmitry Shmidtc2817022014-07-02 10:32:10 -07003595 le16 msk = host_to_le16(HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET |
3596 HT_CAP_INFO_SHORT_GI40MHZ);
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003597
3598 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
3599
3600 if (disabled)
3601 htcaps->ht_capabilities_info &= ~msk;
3602 else
3603 htcaps->ht_capabilities_info |= msk;
3604
3605 htcaps_mask->ht_capabilities_info |= msk;
3606
3607 return 0;
3608}
3609
3610
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08003611static int wpa_set_disable_sgi(struct wpa_supplicant *wpa_s,
3612 struct ieee80211_ht_capabilities *htcaps,
3613 struct ieee80211_ht_capabilities *htcaps_mask,
3614 int disabled)
3615{
3616 /* Masking these out disables SGI */
Dmitry Shmidtc2817022014-07-02 10:32:10 -07003617 le16 msk = host_to_le16(HT_CAP_INFO_SHORT_GI20MHZ |
3618 HT_CAP_INFO_SHORT_GI40MHZ);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08003619
3620 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_sgi: %d", disabled);
3621
3622 if (disabled)
3623 htcaps->ht_capabilities_info &= ~msk;
3624 else
3625 htcaps->ht_capabilities_info |= msk;
3626
3627 htcaps_mask->ht_capabilities_info |= msk;
3628
3629 return 0;
3630}
3631
3632
Dmitry Shmidtdf5a7e42014-04-02 12:59:59 -07003633static int wpa_set_disable_ldpc(struct wpa_supplicant *wpa_s,
3634 struct ieee80211_ht_capabilities *htcaps,
3635 struct ieee80211_ht_capabilities *htcaps_mask,
3636 int disabled)
3637{
3638 /* Masking these out disables LDPC */
Dmitry Shmidtc2817022014-07-02 10:32:10 -07003639 le16 msk = host_to_le16(HT_CAP_INFO_LDPC_CODING_CAP);
Dmitry Shmidtdf5a7e42014-04-02 12:59:59 -07003640
3641 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ldpc: %d", disabled);
3642
3643 if (disabled)
3644 htcaps->ht_capabilities_info &= ~msk;
3645 else
3646 htcaps->ht_capabilities_info |= msk;
3647
3648 htcaps_mask->ht_capabilities_info |= msk;
3649
3650 return 0;
3651}
3652
3653
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003654void wpa_supplicant_apply_ht_overrides(
3655 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
3656 struct wpa_driver_associate_params *params)
3657{
3658 struct ieee80211_ht_capabilities *htcaps;
3659 struct ieee80211_ht_capabilities *htcaps_mask;
3660
3661 if (!ssid)
3662 return;
3663
3664 params->disable_ht = ssid->disable_ht;
3665 if (!params->htcaps || !params->htcaps_mask)
3666 return;
3667
3668 htcaps = (struct ieee80211_ht_capabilities *) params->htcaps;
3669 htcaps_mask = (struct ieee80211_ht_capabilities *) params->htcaps_mask;
3670 wpa_set_htcap_mcs(wpa_s, htcaps, htcaps_mask, ssid->ht_mcs);
3671 wpa_disable_max_amsdu(wpa_s, htcaps, htcaps_mask,
3672 ssid->disable_max_amsdu);
3673 wpa_set_ampdu_factor(wpa_s, htcaps, htcaps_mask, ssid->ampdu_factor);
3674 wpa_set_ampdu_density(wpa_s, htcaps, htcaps_mask, ssid->ampdu_density);
3675 wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08003676 wpa_set_disable_sgi(wpa_s, htcaps, htcaps_mask, ssid->disable_sgi);
Dmitry Shmidtdf5a7e42014-04-02 12:59:59 -07003677 wpa_set_disable_ldpc(wpa_s, htcaps, htcaps_mask, ssid->disable_ldpc);
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003678
3679 if (ssid->ht40_intolerant) {
Dmitry Shmidtc2817022014-07-02 10:32:10 -07003680 le16 bit = host_to_le16(HT_CAP_INFO_40MHZ_INTOLERANT);
Dmitry Shmidt61593f02014-04-21 16:27:35 -07003681 htcaps->ht_capabilities_info |= bit;
3682 htcaps_mask->ht_capabilities_info |= bit;
3683 }
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08003684}
3685
3686#endif /* CONFIG_HT_OVERRIDES */
3687
3688
Dmitry Shmidt2f023192013-03-12 12:44:17 -07003689#ifdef CONFIG_VHT_OVERRIDES
3690void wpa_supplicant_apply_vht_overrides(
3691 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
3692 struct wpa_driver_associate_params *params)
3693{
3694 struct ieee80211_vht_capabilities *vhtcaps;
3695 struct ieee80211_vht_capabilities *vhtcaps_mask;
3696
3697 if (!ssid)
3698 return;
3699
3700 params->disable_vht = ssid->disable_vht;
3701
3702 vhtcaps = (void *) params->vhtcaps;
3703 vhtcaps_mask = (void *) params->vhtcaps_mask;
3704
3705 if (!vhtcaps || !vhtcaps_mask)
3706 return;
3707
3708 vhtcaps->vht_capabilities_info = ssid->vht_capa;
3709 vhtcaps_mask->vht_capabilities_info = ssid->vht_capa_mask;
3710
Dmitry Shmidtdf5a7e42014-04-02 12:59:59 -07003711#ifdef CONFIG_HT_OVERRIDES
3712 /* if max ampdu is <= 3, we have to make the HT cap the same */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003713 if (ssid->vht_capa_mask & VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX) {
3714 int max_ampdu;
3715
3716 max_ampdu = (ssid->vht_capa &
3717 VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX) >>
3718 VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX_SHIFT;
Dmitry Shmidtdf5a7e42014-04-02 12:59:59 -07003719
3720 max_ampdu = max_ampdu < 3 ? max_ampdu : 3;
3721 wpa_set_ampdu_factor(wpa_s,
3722 (void *) params->htcaps,
3723 (void *) params->htcaps_mask,
3724 max_ampdu);
3725 }
3726#endif /* CONFIG_HT_OVERRIDES */
3727
Dmitry Shmidt2f023192013-03-12 12:44:17 -07003728#define OVERRIDE_MCS(i) \
3729 if (ssid->vht_tx_mcs_nss_ ##i >= 0) { \
3730 vhtcaps_mask->vht_supported_mcs_set.tx_map |= \
3731 3 << 2 * (i - 1); \
3732 vhtcaps->vht_supported_mcs_set.tx_map |= \
3733 ssid->vht_tx_mcs_nss_ ##i << 2 * (i - 1); \
3734 } \
3735 if (ssid->vht_rx_mcs_nss_ ##i >= 0) { \
3736 vhtcaps_mask->vht_supported_mcs_set.rx_map |= \
3737 3 << 2 * (i - 1); \
3738 vhtcaps->vht_supported_mcs_set.rx_map |= \
3739 ssid->vht_rx_mcs_nss_ ##i << 2 * (i - 1); \
3740 }
3741
3742 OVERRIDE_MCS(1);
3743 OVERRIDE_MCS(2);
3744 OVERRIDE_MCS(3);
3745 OVERRIDE_MCS(4);
3746 OVERRIDE_MCS(5);
3747 OVERRIDE_MCS(6);
3748 OVERRIDE_MCS(7);
3749 OVERRIDE_MCS(8);
3750}
3751#endif /* CONFIG_VHT_OVERRIDES */
3752
3753
Dmitry Shmidt04949592012-07-19 12:16:46 -07003754static int pcsc_reader_init(struct wpa_supplicant *wpa_s)
3755{
3756#ifdef PCSC_FUNCS
3757 size_t len;
3758
3759 if (!wpa_s->conf->pcsc_reader)
3760 return 0;
3761
Dmitry Shmidte0e48dc2013-11-18 12:00:06 -08003762 wpa_s->scard = scard_init(wpa_s->conf->pcsc_reader);
Dmitry Shmidt04949592012-07-19 12:16:46 -07003763 if (!wpa_s->scard)
3764 return 1;
3765
3766 if (wpa_s->conf->pcsc_pin &&
3767 scard_set_pin(wpa_s->scard, wpa_s->conf->pcsc_pin) < 0) {
3768 scard_deinit(wpa_s->scard);
3769 wpa_s->scard = NULL;
3770 wpa_msg(wpa_s, MSG_ERROR, "PC/SC PIN validation failed");
3771 return -1;
3772 }
3773
3774 len = sizeof(wpa_s->imsi) - 1;
3775 if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
3776 scard_deinit(wpa_s->scard);
3777 wpa_s->scard = NULL;
3778 wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
3779 return -1;
3780 }
3781 wpa_s->imsi[len] = '\0';
3782
3783 wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
3784
3785 wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
3786 wpa_s->imsi, wpa_s->mnc_len);
3787
3788 wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
3789 eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
3790#endif /* PCSC_FUNCS */
3791
3792 return 0;
3793}
3794
3795
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07003796int wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
3797{
3798 char *val, *pos;
3799
3800 ext_password_deinit(wpa_s->ext_pw);
3801 wpa_s->ext_pw = NULL;
3802 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, NULL);
3803
3804 if (!wpa_s->conf->ext_password_backend)
3805 return 0;
3806
3807 val = os_strdup(wpa_s->conf->ext_password_backend);
3808 if (val == NULL)
3809 return -1;
3810 pos = os_strchr(val, ':');
3811 if (pos)
3812 *pos++ = '\0';
3813
3814 wpa_printf(MSG_DEBUG, "EXT PW: Initialize backend '%s'", val);
3815
3816 wpa_s->ext_pw = ext_password_init(val, pos);
3817 os_free(val);
3818 if (wpa_s->ext_pw == NULL) {
3819 wpa_printf(MSG_DEBUG, "EXT PW: Failed to initialize backend");
3820 return -1;
3821 }
3822 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, wpa_s->ext_pw);
3823
3824 return 0;
3825}
3826
3827
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003828#ifdef CONFIG_FST
3829
3830static const u8 * wpas_fst_get_bssid_cb(void *ctx)
3831{
3832 struct wpa_supplicant *wpa_s = ctx;
3833
3834 return (is_zero_ether_addr(wpa_s->bssid) ||
3835 wpa_s->wpa_state != WPA_COMPLETED) ? NULL : wpa_s->bssid;
3836}
3837
3838
3839static void wpas_fst_get_channel_info_cb(void *ctx,
3840 enum hostapd_hw_mode *hw_mode,
3841 u8 *channel)
3842{
3843 struct wpa_supplicant *wpa_s = ctx;
3844
3845 if (wpa_s->current_bss) {
3846 *hw_mode = ieee80211_freq_to_chan(wpa_s->current_bss->freq,
3847 channel);
3848 } else if (wpa_s->hw.num_modes) {
3849 *hw_mode = wpa_s->hw.modes[0].mode;
3850 } else {
3851 WPA_ASSERT(0);
3852 *hw_mode = 0;
3853 }
3854}
3855
3856
3857static int wpas_fst_get_hw_modes(void *ctx, struct hostapd_hw_modes **modes)
3858{
3859 struct wpa_supplicant *wpa_s = ctx;
3860
3861 *modes = wpa_s->hw.modes;
3862 return wpa_s->hw.num_modes;
3863}
3864
3865
3866static void wpas_fst_set_ies_cb(void *ctx, const struct wpabuf *fst_ies)
3867{
3868 struct wpa_supplicant *wpa_s = ctx;
3869
3870 wpa_hexdump_buf(MSG_DEBUG, "FST: Set IEs", fst_ies);
3871 wpa_s->fst_ies = fst_ies;
3872}
3873
3874
3875static int wpas_fst_send_action_cb(void *ctx, const u8 *da, struct wpabuf *data)
3876{
3877 struct wpa_supplicant *wpa_s = ctx;
3878
3879 WPA_ASSERT(os_memcmp(wpa_s->bssid, da, ETH_ALEN) == 0);
3880 return wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
3881 wpa_s->own_addr, wpa_s->bssid,
3882 wpabuf_head(data), wpabuf_len(data),
3883 0);
3884}
3885
3886
3887static const struct wpabuf * wpas_fst_get_mb_ie_cb(void *ctx, const u8 *addr)
3888{
3889 struct wpa_supplicant *wpa_s = ctx;
3890
3891 WPA_ASSERT(os_memcmp(wpa_s->bssid, addr, ETH_ALEN) == 0);
3892 return wpa_s->received_mb_ies;
3893}
3894
3895
3896static void wpas_fst_update_mb_ie_cb(void *ctx, const u8 *addr,
3897 const u8 *buf, size_t size)
3898{
3899 struct wpa_supplicant *wpa_s = ctx;
3900 struct mb_ies_info info;
3901
3902 WPA_ASSERT(os_memcmp(wpa_s->bssid, addr, ETH_ALEN) == 0);
3903
3904 if (!mb_ies_info_by_ies(&info, buf, size)) {
3905 wpabuf_free(wpa_s->received_mb_ies);
3906 wpa_s->received_mb_ies = mb_ies_by_info(&info);
3907 }
3908}
3909
3910
3911const u8 * wpas_fst_get_peer_first(void *ctx, struct fst_get_peer_ctx **get_ctx,
3912 Boolean mb_only)
3913{
3914 struct wpa_supplicant *wpa_s = ctx;
3915
3916 *get_ctx = NULL;
3917 if (!is_zero_ether_addr(wpa_s->bssid))
3918 return (wpa_s->received_mb_ies || !mb_only) ?
3919 wpa_s->bssid : NULL;
3920 return NULL;
3921}
3922
3923
3924const u8 * wpas_fst_get_peer_next(void *ctx, struct fst_get_peer_ctx **get_ctx,
3925 Boolean mb_only)
3926{
3927 return NULL;
3928}
3929
3930void fst_wpa_supplicant_fill_iface_obj(struct wpa_supplicant *wpa_s,
3931 struct fst_wpa_obj *iface_obj)
3932{
3933 iface_obj->ctx = wpa_s;
3934 iface_obj->get_bssid = wpas_fst_get_bssid_cb;
3935 iface_obj->get_channel_info = wpas_fst_get_channel_info_cb;
3936 iface_obj->get_hw_modes = wpas_fst_get_hw_modes;
3937 iface_obj->set_ies = wpas_fst_set_ies_cb;
3938 iface_obj->send_action = wpas_fst_send_action_cb;
3939 iface_obj->get_mb_ie = wpas_fst_get_mb_ie_cb;
3940 iface_obj->update_mb_ie = wpas_fst_update_mb_ie_cb;
3941 iface_obj->get_peer_first = wpas_fst_get_peer_first;
3942 iface_obj->get_peer_next = wpas_fst_get_peer_next;
3943}
3944#endif /* CONFIG_FST */
3945
Dmitry Shmidtc2817022014-07-02 10:32:10 -07003946static int wpas_set_wowlan_triggers(struct wpa_supplicant *wpa_s,
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08003947 const struct wpa_driver_capa *capa)
Dmitry Shmidtb58836e2014-04-29 14:35:56 -07003948{
Dmitry Shmidt0207e232014-09-03 14:58:37 -07003949 struct wowlan_triggers *triggers;
3950 int ret = 0;
Dmitry Shmidtb58836e2014-04-29 14:35:56 -07003951
3952 if (!wpa_s->conf->wowlan_triggers)
3953 return 0;
3954
Dmitry Shmidt0207e232014-09-03 14:58:37 -07003955 triggers = wpa_get_wowlan_triggers(wpa_s->conf->wowlan_triggers, capa);
3956 if (triggers) {
3957 ret = wpa_drv_wowlan(wpa_s, triggers);
3958 os_free(triggers);
Dmitry Shmidtb58836e2014-04-29 14:35:56 -07003959 }
Dmitry Shmidtb58836e2014-04-29 14:35:56 -07003960 return ret;
3961}
3962
3963
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08003964static enum wpa_radio_work_band wpas_freq_to_band(int freq)
3965{
3966 if (freq < 3000)
3967 return BAND_2_4_GHZ;
3968 if (freq > 50000)
3969 return BAND_60_GHZ;
3970 return BAND_5_GHZ;
3971}
3972
3973
3974static unsigned int wpas_get_bands(struct wpa_supplicant *wpa_s,
3975 const int *freqs)
3976{
3977 int i;
3978 unsigned int band = 0;
3979
3980 if (freqs) {
3981 /* freqs are specified for the radio work */
3982 for (i = 0; freqs[i]; i++)
3983 band |= wpas_freq_to_band(freqs[i]);
3984 } else {
3985 /*
3986 * freqs are not specified, implies all
3987 * the supported freqs by HW
3988 */
3989 for (i = 0; i < wpa_s->hw.num_modes; i++) {
3990 if (wpa_s->hw.modes[i].num_channels != 0) {
3991 if (wpa_s->hw.modes[i].mode ==
3992 HOSTAPD_MODE_IEEE80211B ||
3993 wpa_s->hw.modes[i].mode ==
3994 HOSTAPD_MODE_IEEE80211G)
3995 band |= BAND_2_4_GHZ;
3996 else if (wpa_s->hw.modes[i].mode ==
3997 HOSTAPD_MODE_IEEE80211A)
3998 band |= BAND_5_GHZ;
3999 else if (wpa_s->hw.modes[i].mode ==
4000 HOSTAPD_MODE_IEEE80211AD)
4001 band |= BAND_60_GHZ;
4002 else if (wpa_s->hw.modes[i].mode ==
4003 HOSTAPD_MODE_IEEE80211ANY)
4004 band = BAND_2_4_GHZ | BAND_5_GHZ |
4005 BAND_60_GHZ;
4006 }
4007 }
4008 }
4009
4010 return band;
4011}
4012
4013
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08004014static struct wpa_radio * radio_add_interface(struct wpa_supplicant *wpa_s,
4015 const char *rn)
4016{
4017 struct wpa_supplicant *iface = wpa_s->global->ifaces;
4018 struct wpa_radio *radio;
4019
4020 while (rn && iface) {
4021 radio = iface->radio;
4022 if (radio && os_strcmp(rn, radio->name) == 0) {
4023 wpa_printf(MSG_DEBUG, "Add interface %s to existing radio %s",
4024 wpa_s->ifname, rn);
4025 dl_list_add(&radio->ifaces, &wpa_s->radio_list);
4026 return radio;
4027 }
Dmitry Shmidt3cf6f792013-12-18 13:12:19 -08004028
4029 iface = iface->next;
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08004030 }
4031
4032 wpa_printf(MSG_DEBUG, "Add interface %s to a new radio %s",
4033 wpa_s->ifname, rn ? rn : "N/A");
4034 radio = os_zalloc(sizeof(*radio));
4035 if (radio == NULL)
4036 return NULL;
4037
4038 if (rn)
4039 os_strlcpy(radio->name, rn, sizeof(radio->name));
4040 dl_list_init(&radio->ifaces);
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004041 dl_list_init(&radio->work);
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08004042 dl_list_add(&radio->ifaces, &wpa_s->radio_list);
4043
4044 return radio;
4045}
4046
4047
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004048static void radio_work_free(struct wpa_radio_work *work)
4049{
4050 if (work->wpa_s->scan_work == work) {
4051 /* This should not really happen. */
4052 wpa_dbg(work->wpa_s, MSG_INFO, "Freeing radio work '%s'@%p (started=%d) that is marked as scan_work",
4053 work->type, work, work->started);
4054 work->wpa_s->scan_work = NULL;
4055 }
4056
4057#ifdef CONFIG_P2P
4058 if (work->wpa_s->p2p_scan_work == work) {
4059 /* This should not really happen. */
4060 wpa_dbg(work->wpa_s, MSG_INFO, "Freeing radio work '%s'@%p (started=%d) that is marked as p2p_scan_work",
4061 work->type, work, work->started);
4062 work->wpa_s->p2p_scan_work = NULL;
4063 }
4064#endif /* CONFIG_P2P */
4065
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004066 if (work->started) {
4067 work->wpa_s->radio->num_active_works--;
4068 wpa_dbg(work->wpa_s, MSG_DEBUG,
4069 "radio_work_free('%s'@%p: num_active_works --> %u",
4070 work->type, work,
4071 work->wpa_s->radio->num_active_works);
4072 }
4073
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004074 dl_list_del(&work->list);
4075 os_free(work);
4076}
4077
4078
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004079static struct wpa_radio_work * radio_work_get_next_work(struct wpa_radio *radio)
4080{
4081 struct wpa_radio_work *active_work = NULL;
4082 struct wpa_radio_work *tmp;
4083
4084 /* Get the active work to know the type and band. */
4085 dl_list_for_each(tmp, &radio->work, struct wpa_radio_work, list) {
4086 if (tmp->started) {
4087 active_work = tmp;
4088 break;
4089 }
4090 }
4091
4092 if (!active_work) {
4093 /* No active work, start one */
4094 radio->num_active_works = 0;
4095 dl_list_for_each(tmp, &radio->work, struct wpa_radio_work,
4096 list) {
4097 if (os_strcmp(tmp->type, "scan") == 0 &&
4098 radio->external_scan_running &&
4099 (((struct wpa_driver_scan_params *)
4100 tmp->ctx)->only_new_results ||
4101 tmp->wpa_s->clear_driver_scan_cache))
4102 continue;
4103 return tmp;
4104 }
4105 return NULL;
4106 }
4107
4108 if (os_strcmp(active_work->type, "sme-connect") == 0 ||
4109 os_strcmp(active_work->type, "connect") == 0) {
4110 /*
4111 * If the active work is either connect or sme-connect,
4112 * do not parallelize them with other radio works.
4113 */
4114 wpa_dbg(active_work->wpa_s, MSG_DEBUG,
4115 "Do not parallelize radio work with %s",
4116 active_work->type);
4117 return NULL;
4118 }
4119
4120 dl_list_for_each(tmp, &radio->work, struct wpa_radio_work, list) {
4121 if (tmp->started)
4122 continue;
4123
4124 /*
4125 * If connect or sme-connect are enqueued, parallelize only
4126 * those operations ahead of them in the queue.
4127 */
4128 if (os_strcmp(tmp->type, "connect") == 0 ||
4129 os_strcmp(tmp->type, "sme-connect") == 0)
4130 break;
4131
4132 /*
4133 * Check that the radio works are distinct and
4134 * on different bands.
4135 */
4136 if (os_strcmp(active_work->type, tmp->type) != 0 &&
4137 (active_work->bands != tmp->bands)) {
4138 /*
4139 * If a scan has to be scheduled through nl80211 scan
4140 * interface and if an external scan is already running,
4141 * do not schedule the scan since it is likely to get
4142 * rejected by kernel.
4143 */
4144 if (os_strcmp(tmp->type, "scan") == 0 &&
4145 radio->external_scan_running &&
4146 (((struct wpa_driver_scan_params *)
4147 tmp->ctx)->only_new_results ||
4148 tmp->wpa_s->clear_driver_scan_cache))
4149 continue;
4150
4151 wpa_dbg(active_work->wpa_s, MSG_DEBUG,
4152 "active_work:%s new_work:%s",
4153 active_work->type, tmp->type);
4154 return tmp;
4155 }
4156 }
4157
4158 /* Did not find a radio work to schedule in parallel. */
4159 return NULL;
4160}
4161
4162
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004163static void radio_start_next_work(void *eloop_ctx, void *timeout_ctx)
4164{
4165 struct wpa_radio *radio = eloop_ctx;
4166 struct wpa_radio_work *work;
4167 struct os_reltime now, diff;
4168 struct wpa_supplicant *wpa_s;
4169
4170 work = dl_list_first(&radio->work, struct wpa_radio_work, list);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004171 if (work == NULL) {
4172 radio->num_active_works = 0;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004173 return;
4174 }
4175
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004176 wpa_s = dl_list_first(&radio->ifaces, struct wpa_supplicant,
4177 radio_list);
4178
4179 if (!(wpa_s &&
4180 wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS)) {
4181 if (work->started)
4182 return; /* already started and still in progress */
4183
4184 if (wpa_s && wpa_s->radio->external_scan_running) {
4185 wpa_printf(MSG_DEBUG, "Delay radio work start until externally triggered scan completes");
4186 return;
4187 }
4188 } else {
4189 work = NULL;
4190 if (radio->num_active_works < MAX_ACTIVE_WORKS) {
4191 /* get the work to schedule next */
4192 work = radio_work_get_next_work(radio);
4193 }
4194 if (!work)
4195 return;
4196 }
4197
4198 wpa_s = work->wpa_s;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004199 os_get_reltime(&now);
4200 os_reltime_sub(&now, &work->time, &diff);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004201 wpa_dbg(wpa_s, MSG_DEBUG,
4202 "Starting radio work '%s'@%p after %ld.%06ld second wait",
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004203 work->type, work, diff.sec, diff.usec);
4204 work->started = 1;
4205 work->time = now;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004206 radio->num_active_works++;
4207
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004208 work->cb(work, 0);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004209
4210 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS) &&
4211 radio->num_active_works < MAX_ACTIVE_WORKS)
4212 radio_work_check_next(wpa_s);
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004213}
4214
4215
Dmitry Shmidtbd14a572014-02-18 10:33:49 -08004216/*
4217 * This function removes both started and pending radio works running on
4218 * the provided interface's radio.
4219 * Prior to the removal of the radio work, its callback (cb) is called with
4220 * deinit set to be 1. Each work's callback is responsible for clearing its
4221 * internal data and restoring to a correct state.
4222 * @wpa_s: wpa_supplicant data
4223 * @type: type of works to be removed
4224 * @remove_all: 1 to remove all the works on this radio, 0 to remove only
4225 * this interface's works.
4226 */
4227void radio_remove_works(struct wpa_supplicant *wpa_s,
4228 const char *type, int remove_all)
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004229{
4230 struct wpa_radio_work *work, *tmp;
4231 struct wpa_radio *radio = wpa_s->radio;
4232
4233 dl_list_for_each_safe(work, tmp, &radio->work, struct wpa_radio_work,
4234 list) {
Dmitry Shmidtbd14a572014-02-18 10:33:49 -08004235 if (type && os_strcmp(type, work->type) != 0)
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004236 continue;
Dmitry Shmidtbd14a572014-02-18 10:33:49 -08004237
4238 /* skip other ifaces' works */
4239 if (!remove_all && work->wpa_s != wpa_s)
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004240 continue;
Dmitry Shmidtbd14a572014-02-18 10:33:49 -08004241
4242 wpa_dbg(wpa_s, MSG_DEBUG, "Remove radio work '%s'@%p%s",
4243 work->type, work, work->started ? " (started)" : "");
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004244 work->cb(work, 1);
4245 radio_work_free(work);
4246 }
Dmitry Shmidtbd14a572014-02-18 10:33:49 -08004247
4248 /* in case we removed the started work */
4249 radio_work_check_next(wpa_s);
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004250}
4251
4252
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08004253static void radio_remove_interface(struct wpa_supplicant *wpa_s)
4254{
4255 struct wpa_radio *radio = wpa_s->radio;
4256
4257 if (!radio)
4258 return;
4259
4260 wpa_printf(MSG_DEBUG, "Remove interface %s from radio %s",
4261 wpa_s->ifname, radio->name);
4262 dl_list_del(&wpa_s->radio_list);
Dmitry Shmidtd11f0192014-03-24 12:09:47 -07004263 radio_remove_works(wpa_s, NULL, 0);
4264 wpa_s->radio = NULL;
4265 if (!dl_list_empty(&radio->ifaces))
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08004266 return; /* Interfaces remain for this radio */
4267
4268 wpa_printf(MSG_DEBUG, "Remove radio %s", radio->name);
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004269 eloop_cancel_timeout(radio_start_next_work, radio, NULL);
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08004270 os_free(radio);
4271}
4272
4273
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004274void radio_work_check_next(struct wpa_supplicant *wpa_s)
4275{
4276 struct wpa_radio *radio = wpa_s->radio;
4277
4278 if (dl_list_empty(&radio->work))
4279 return;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004280 if (wpa_s->ext_work_in_progress) {
4281 wpa_printf(MSG_DEBUG,
4282 "External radio work in progress - delay start of pending item");
4283 return;
4284 }
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004285 eloop_cancel_timeout(radio_start_next_work, radio, NULL);
4286 eloop_register_timeout(0, 0, radio_start_next_work, radio, NULL);
4287}
4288
4289
4290/**
4291 * radio_add_work - Add a radio work item
4292 * @wpa_s: Pointer to wpa_supplicant data
4293 * @freq: Frequency of the offchannel operation in MHz or 0
4294 * @type: Unique identifier for each type of work
4295 * @next: Force as the next work to be executed
4296 * @cb: Callback function for indicating when radio is available
4297 * @ctx: Context pointer for the work (work->ctx in cb())
4298 * Returns: 0 on success, -1 on failure
4299 *
4300 * This function is used to request time for an operation that requires
4301 * exclusive radio control. Once the radio is available, the registered callback
4302 * function will be called. radio_work_done() must be called once the exclusive
4303 * radio operation has been completed, so that the radio is freed for other
4304 * operations. The special case of deinit=1 is used to free the context data
4305 * during interface removal. That does not allow the callback function to start
4306 * the radio operation, i.e., it must free any resources allocated for the radio
4307 * work and return.
4308 *
4309 * The @freq parameter can be used to indicate a single channel on which the
4310 * offchannel operation will occur. This may allow multiple radio work
4311 * operations to be performed in parallel if they apply for the same channel.
4312 * Setting this to 0 indicates that the work item may use multiple channels or
4313 * requires exclusive control of the radio.
4314 */
4315int radio_add_work(struct wpa_supplicant *wpa_s, unsigned int freq,
4316 const char *type, int next,
4317 void (*cb)(struct wpa_radio_work *work, int deinit),
4318 void *ctx)
4319{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004320 struct wpa_radio *radio = wpa_s->radio;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004321 struct wpa_radio_work *work;
4322 int was_empty;
4323
4324 work = os_zalloc(sizeof(*work));
4325 if (work == NULL)
4326 return -1;
4327 wpa_dbg(wpa_s, MSG_DEBUG, "Add radio work '%s'@%p", type, work);
4328 os_get_reltime(&work->time);
4329 work->freq = freq;
4330 work->type = type;
4331 work->wpa_s = wpa_s;
4332 work->cb = cb;
4333 work->ctx = ctx;
4334
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004335 if (freq)
4336 work->bands = wpas_freq_to_band(freq);
4337 else if (os_strcmp(type, "scan") == 0 ||
4338 os_strcmp(type, "p2p-scan") == 0)
4339 work->bands = wpas_get_bands(wpa_s,
4340 ((struct wpa_driver_scan_params *)
4341 ctx)->freqs);
4342 else
4343 work->bands = wpas_get_bands(wpa_s, NULL);
4344
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004345 was_empty = dl_list_empty(&wpa_s->radio->work);
4346 if (next)
4347 dl_list_add(&wpa_s->radio->work, &work->list);
4348 else
4349 dl_list_add_tail(&wpa_s->radio->work, &work->list);
4350 if (was_empty) {
4351 wpa_dbg(wpa_s, MSG_DEBUG, "First radio work item in the queue - schedule start immediately");
4352 radio_work_check_next(wpa_s);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004353 } else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS)
4354 && radio->num_active_works < MAX_ACTIVE_WORKS) {
4355 wpa_dbg(wpa_s, MSG_DEBUG,
4356 "Try to schedule a radio work (num_active_works=%u)",
4357 radio->num_active_works);
4358 radio_work_check_next(wpa_s);
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004359 }
4360
4361 return 0;
4362}
4363
4364
4365/**
4366 * radio_work_done - Indicate that a radio work item has been completed
4367 * @work: Completed work
4368 *
4369 * This function is called once the callback function registered with
4370 * radio_add_work() has completed its work.
4371 */
4372void radio_work_done(struct wpa_radio_work *work)
4373{
4374 struct wpa_supplicant *wpa_s = work->wpa_s;
4375 struct os_reltime now, diff;
4376 unsigned int started = work->started;
4377
4378 os_get_reltime(&now);
4379 os_reltime_sub(&now, &work->time, &diff);
4380 wpa_dbg(wpa_s, MSG_DEBUG, "Radio work '%s'@%p %s in %ld.%06ld seconds",
4381 work->type, work, started ? "done" : "canceled",
4382 diff.sec, diff.usec);
4383 radio_work_free(work);
4384 if (started)
4385 radio_work_check_next(wpa_s);
4386}
4387
4388
Dmitry Shmidt2e425d62014-11-10 11:18:27 -08004389struct wpa_radio_work *
4390radio_work_pending(struct wpa_supplicant *wpa_s, const char *type)
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08004391{
4392 struct wpa_radio_work *work;
4393 struct wpa_radio *radio = wpa_s->radio;
4394
4395 dl_list_for_each(work, &radio->work, struct wpa_radio_work, list) {
4396 if (work->wpa_s == wpa_s && os_strcmp(work->type, type) == 0)
Dmitry Shmidt2e425d62014-11-10 11:18:27 -08004397 return work;
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08004398 }
4399
Dmitry Shmidt2e425d62014-11-10 11:18:27 -08004400 return NULL;
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08004401}
4402
4403
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08004404static int wpas_init_driver(struct wpa_supplicant *wpa_s,
4405 struct wpa_interface *iface)
4406{
4407 const char *ifname, *driver, *rn;
4408
4409 driver = iface->driver;
4410next_driver:
4411 if (wpa_supplicant_set_driver(wpa_s, driver) < 0)
4412 return -1;
4413
4414 wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
4415 if (wpa_s->drv_priv == NULL) {
4416 const char *pos;
4417 pos = driver ? os_strchr(driver, ',') : NULL;
4418 if (pos) {
4419 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
4420 "driver interface - try next driver wrapper");
4421 driver = pos + 1;
4422 goto next_driver;
4423 }
4424 wpa_msg(wpa_s, MSG_ERROR, "Failed to initialize driver "
4425 "interface");
4426 return -1;
4427 }
4428 if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
4429 wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected "
4430 "driver_param '%s'", wpa_s->conf->driver_param);
4431 return -1;
4432 }
4433
4434 ifname = wpa_drv_get_ifname(wpa_s);
4435 if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
4436 wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced "
4437 "interface name with '%s'", ifname);
4438 os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
4439 }
4440
Dmitry Shmidtd11f0192014-03-24 12:09:47 -07004441 rn = wpa_driver_get_radio_name(wpa_s);
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08004442 if (rn && rn[0] == '\0')
4443 rn = NULL;
4444
4445 wpa_s->radio = radio_add_interface(wpa_s, rn);
4446 if (wpa_s->radio == NULL)
4447 return -1;
4448
4449 return 0;
4450}
4451
4452
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004453static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
4454 struct wpa_interface *iface)
4455{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004456 struct wpa_driver_capa capa;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004457 int capa_res;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004458
4459 wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
4460 "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
4461 iface->confname ? iface->confname : "N/A",
4462 iface->driver ? iface->driver : "default",
4463 iface->ctrl_interface ? iface->ctrl_interface : "N/A",
4464 iface->bridge_ifname ? iface->bridge_ifname : "N/A");
4465
4466 if (iface->confname) {
4467#ifdef CONFIG_BACKEND_FILE
4468 wpa_s->confname = os_rel2abs_path(iface->confname);
4469 if (wpa_s->confname == NULL) {
4470 wpa_printf(MSG_ERROR, "Failed to get absolute path "
4471 "for configuration file '%s'.",
4472 iface->confname);
4473 return -1;
4474 }
4475 wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",
4476 iface->confname, wpa_s->confname);
4477#else /* CONFIG_BACKEND_FILE */
4478 wpa_s->confname = os_strdup(iface->confname);
4479#endif /* CONFIG_BACKEND_FILE */
Dmitry Shmidt64f47c52013-04-16 10:41:54 -07004480 wpa_s->conf = wpa_config_read(wpa_s->confname, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004481 if (wpa_s->conf == NULL) {
4482 wpa_printf(MSG_ERROR, "Failed to read or parse "
4483 "configuration '%s'.", wpa_s->confname);
4484 return -1;
4485 }
Dmitry Shmidt64f47c52013-04-16 10:41:54 -07004486 wpa_s->confanother = os_rel2abs_path(iface->confanother);
4487 wpa_config_read(wpa_s->confanother, wpa_s->conf);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004488
4489 /*
4490 * Override ctrl_interface and driver_param if set on command
4491 * line.
4492 */
4493 if (iface->ctrl_interface) {
4494 os_free(wpa_s->conf->ctrl_interface);
4495 wpa_s->conf->ctrl_interface =
4496 os_strdup(iface->ctrl_interface);
4497 }
4498
4499 if (iface->driver_param) {
4500 os_free(wpa_s->conf->driver_param);
4501 wpa_s->conf->driver_param =
4502 os_strdup(iface->driver_param);
4503 }
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004504
4505 if (iface->p2p_mgmt && !iface->ctrl_interface) {
4506 os_free(wpa_s->conf->ctrl_interface);
4507 wpa_s->conf->ctrl_interface = NULL;
4508 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004509 } else
4510 wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
4511 iface->driver_param);
4512
4513 if (wpa_s->conf == NULL) {
4514 wpa_printf(MSG_ERROR, "\nNo configuration found.");
4515 return -1;
4516 }
4517
4518 if (iface->ifname == NULL) {
4519 wpa_printf(MSG_ERROR, "\nInterface name is required.");
4520 return -1;
4521 }
4522 if (os_strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
4523 wpa_printf(MSG_ERROR, "\nToo long interface name '%s'.",
4524 iface->ifname);
4525 return -1;
4526 }
4527 os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
4528
4529 if (iface->bridge_ifname) {
4530 if (os_strlen(iface->bridge_ifname) >=
4531 sizeof(wpa_s->bridge_ifname)) {
4532 wpa_printf(MSG_ERROR, "\nToo long bridge interface "
4533 "name '%s'.", iface->bridge_ifname);
4534 return -1;
4535 }
4536 os_strlcpy(wpa_s->bridge_ifname, iface->bridge_ifname,
4537 sizeof(wpa_s->bridge_ifname));
4538 }
4539
4540 /* RSNA Supplicant Key Management - INITIALIZE */
4541 eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
4542 eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
4543
4544 /* Initialize driver interface and register driver event handler before
4545 * L2 receive handler so that association events are processed before
4546 * EAPOL-Key packets if both become available for the same select()
4547 * call. */
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08004548 if (wpas_init_driver(wpa_s, iface) < 0)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004549 return -1;
4550
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004551 if (wpa_supplicant_init_wpa(wpa_s) < 0)
4552 return -1;
4553
4554 wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
4555 wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
4556 NULL);
4557 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
4558
4559 if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
4560 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
4561 wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
4562 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
4563 "dot11RSNAConfigPMKLifetime");
4564 return -1;
4565 }
4566
4567 if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
4568 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
4569 wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
4570 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
4571 "dot11RSNAConfigPMKReauthThreshold");
4572 return -1;
4573 }
4574
4575 if (wpa_s->conf->dot11RSNAConfigSATimeout &&
4576 wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
4577 wpa_s->conf->dot11RSNAConfigSATimeout)) {
4578 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
4579 "dot11RSNAConfigSATimeout");
4580 return -1;
4581 }
4582
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08004583 wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
4584 &wpa_s->hw.num_modes,
4585 &wpa_s->hw.flags);
Dmitry Shmidt7f656022015-02-25 14:36:37 -08004586 if (wpa_s->hw.modes) {
4587 u16 i;
4588
4589 for (i = 0; i < wpa_s->hw.num_modes; i++) {
4590 if (wpa_s->hw.modes[i].vht_capab) {
4591 wpa_s->hw_capab = CAPAB_VHT;
4592 break;
4593 }
4594
4595 if (wpa_s->hw.modes[i].ht_capab &
4596 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)
4597 wpa_s->hw_capab = CAPAB_HT40;
4598 else if (wpa_s->hw.modes[i].ht_capab &&
4599 wpa_s->hw_capab == CAPAB_NO_HT_VHT)
4600 wpa_s->hw_capab = CAPAB_HT;
4601 }
4602 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08004603
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004604 capa_res = wpa_drv_get_capa(wpa_s, &capa);
4605 if (capa_res == 0) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08004606 wpa_s->drv_capa_known = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004607 wpa_s->drv_flags = capa.flags;
Dmitry Shmidt04949592012-07-19 12:16:46 -07004608 wpa_s->drv_enc = capa.enc;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004609 wpa_s->drv_smps_modes = capa.smps_modes;
4610 wpa_s->drv_rrm_flags = capa.rrm_flags;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08004611 wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004612 wpa_s->max_scan_ssids = capa.max_scan_ssids;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08004613 wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08004614 wpa_s->max_sched_scan_plans = capa.max_sched_scan_plans;
4615 wpa_s->max_sched_scan_plan_interval =
4616 capa.max_sched_scan_plan_interval;
4617 wpa_s->max_sched_scan_plan_iterations =
4618 capa.max_sched_scan_plan_iterations;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08004619 wpa_s->sched_scan_supported = capa.sched_scan_supported;
4620 wpa_s->max_match_sets = capa.max_match_sets;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004621 wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
4622 wpa_s->max_stations = capa.max_stations;
Dmitry Shmidt444d5672013-04-01 13:08:44 -07004623 wpa_s->extended_capa = capa.extended_capa;
4624 wpa_s->extended_capa_mask = capa.extended_capa_mask;
4625 wpa_s->extended_capa_len = capa.extended_capa_len;
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07004626 wpa_s->num_multichan_concurrent =
4627 capa.num_multichan_concurrent;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004628 wpa_s->wmm_ac_supported = capa.wmm_ac_supported;
4629
4630 if (capa.mac_addr_rand_scan_supported)
4631 wpa_s->mac_addr_rand_supported |= MAC_ADDR_RAND_SCAN;
4632 if (wpa_s->sched_scan_supported &&
4633 capa.mac_addr_rand_sched_scan_supported)
4634 wpa_s->mac_addr_rand_supported |=
4635 (MAC_ADDR_RAND_SCHED_SCAN | MAC_ADDR_RAND_PNO);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004636 }
4637 if (wpa_s->max_remain_on_chan == 0)
4638 wpa_s->max_remain_on_chan = 1000;
4639
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004640 /*
4641 * Only take p2p_mgmt parameters when P2P Device is supported.
4642 * Doing it here as it determines whether l2_packet_init() will be done
4643 * during wpa_supplicant_driver_init().
4644 */
4645 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)
4646 wpa_s->p2p_mgmt = iface->p2p_mgmt;
4647 else
4648 iface->p2p_mgmt = 1;
4649
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07004650 if (wpa_s->num_multichan_concurrent == 0)
4651 wpa_s->num_multichan_concurrent = 1;
4652
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004653 if (wpa_supplicant_driver_init(wpa_s) < 0)
4654 return -1;
4655
4656#ifdef CONFIG_TDLS
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004657 if ((!iface->p2p_mgmt ||
4658 !(wpa_s->drv_flags &
4659 WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
4660 wpa_tdls_init(wpa_s->wpa))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004661 return -1;
4662#endif /* CONFIG_TDLS */
4663
4664 if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
4665 wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
4666 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to set country");
4667 return -1;
4668 }
4669
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004670#ifdef CONFIG_FST
4671 if (wpa_s->conf->fst_group_id) {
4672 struct fst_iface_cfg cfg;
4673 struct fst_wpa_obj iface_obj;
4674
4675 fst_wpa_supplicant_fill_iface_obj(wpa_s, &iface_obj);
4676 os_strlcpy(cfg.group_id, wpa_s->conf->fst_group_id,
4677 sizeof(cfg.group_id));
4678 cfg.priority = wpa_s->conf->fst_priority;
4679 cfg.llt = wpa_s->conf->fst_llt;
4680
4681 wpa_s->fst = fst_attach(wpa_s->ifname, wpa_s->own_addr,
4682 &iface_obj, &cfg);
4683 if (!wpa_s->fst) {
4684 wpa_msg(wpa_s, MSG_ERROR,
4685 "FST: Cannot attach iface %s to group %s",
4686 wpa_s->ifname, cfg.group_id);
4687 return -1;
4688 }
4689 }
4690#endif /* CONFIG_FST */
4691
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004692 if (wpas_wps_init(wpa_s))
4693 return -1;
4694
4695 if (wpa_supplicant_init_eapol(wpa_s) < 0)
4696 return -1;
4697 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
4698
4699 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
4700 if (wpa_s->ctrl_iface == NULL) {
4701 wpa_printf(MSG_ERROR,
4702 "Failed to initialize control interface '%s'.\n"
4703 "You may have another wpa_supplicant process "
4704 "already running or the file was\n"
4705 "left by an unclean termination of wpa_supplicant "
4706 "in which case you will need\n"
4707 "to manually remove this file before starting "
4708 "wpa_supplicant again.\n",
4709 wpa_s->conf->ctrl_interface);
4710 return -1;
4711 }
4712
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08004713 wpa_s->gas = gas_query_init(wpa_s);
4714 if (wpa_s->gas == NULL) {
4715 wpa_printf(MSG_ERROR, "Failed to initialize GAS query");
4716 return -1;
4717 }
4718
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004719 if (iface->p2p_mgmt && wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004720 wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
4721 return -1;
4722 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004723
4724 if (wpa_bss_init(wpa_s) < 0)
4725 return -1;
4726
Dmitry Shmidtb58836e2014-04-29 14:35:56 -07004727 /*
4728 * Set Wake-on-WLAN triggers, if configured.
4729 * Note: We don't restore/remove the triggers on shutdown (it doesn't
4730 * have effect anyway when the interface is down).
4731 */
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004732 if (capa_res == 0 && wpas_set_wowlan_triggers(wpa_s, &capa) < 0)
Dmitry Shmidtb58836e2014-04-29 14:35:56 -07004733 return -1;
4734
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004735#ifdef CONFIG_EAP_PROXY
4736{
4737 size_t len;
Dmitry Shmidt4ce9c872013-10-24 11:08:13 -07004738 wpa_s->mnc_len = eapol_sm_get_eap_proxy_imsi(wpa_s->eapol, wpa_s->imsi,
4739 &len);
Dmitry Shmidt34af3062013-07-11 10:46:32 -07004740 if (wpa_s->mnc_len > 0) {
4741 wpa_s->imsi[len] = '\0';
4742 wpa_printf(MSG_DEBUG, "eap_proxy: IMSI %s (MNC length %d)",
4743 wpa_s->imsi, wpa_s->mnc_len);
4744 } else {
4745 wpa_printf(MSG_DEBUG, "eap_proxy: IMSI not available");
4746 }
4747}
4748#endif /* CONFIG_EAP_PROXY */
4749
Dmitry Shmidt04949592012-07-19 12:16:46 -07004750 if (pcsc_reader_init(wpa_s) < 0)
4751 return -1;
4752
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07004753 if (wpas_init_ext_pw(wpa_s) < 0)
4754 return -1;
4755
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004756 wpas_rrm_reset(wpa_s);
4757
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08004758 wpas_sched_scan_plans_set(wpa_s, wpa_s->conf->sched_scan_plans);
4759
Dmitry Shmidt7d56b752015-12-22 10:59:44 -08004760#ifdef CONFIG_HS20
4761 hs20_init(wpa_s);
4762#endif /* CONFIG_HS20 */
4763
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004764 return 0;
4765}
4766
4767
4768static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07004769 int notify, int terminate)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004770{
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004771 struct wpa_global *global = wpa_s->global;
4772 struct wpa_supplicant *iface, *prev;
4773
4774 if (wpa_s == wpa_s->parent)
4775 wpas_p2p_group_remove(wpa_s, "*");
4776
4777 iface = global->ifaces;
4778 while (iface) {
4779 if (iface == wpa_s || iface->parent != wpa_s) {
4780 iface = iface->next;
4781 continue;
4782 }
4783 wpa_printf(MSG_DEBUG,
4784 "Remove remaining child interface %s from parent %s",
4785 iface->ifname, wpa_s->ifname);
4786 prev = iface;
4787 iface = iface->next;
4788 wpa_supplicant_remove_iface(global, prev, terminate);
4789 }
4790
Dmitry Shmidtea69e842013-05-13 14:52:28 -07004791 wpa_s->disconnected = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004792 if (wpa_s->drv_priv) {
4793 wpa_supplicant_deauthenticate(wpa_s,
4794 WLAN_REASON_DEAUTH_LEAVING);
4795
4796 wpa_drv_set_countermeasures(wpa_s, 0);
4797 wpa_clear_keys(wpa_s, NULL);
4798 }
4799
4800 wpa_supplicant_cleanup(wpa_s);
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07004801 wpas_p2p_deinit_iface(wpa_s);
Dmitry Shmidt04949592012-07-19 12:16:46 -07004802
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08004803 wpas_ctrl_radio_work_flush(wpa_s);
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08004804 radio_remove_interface(wpa_s);
4805
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08004806#ifdef CONFIG_FST
4807 if (wpa_s->fst) {
4808 fst_detach(wpa_s->fst);
4809 wpa_s->fst = NULL;
4810 }
4811 if (wpa_s->received_mb_ies) {
4812 wpabuf_free(wpa_s->received_mb_ies);
4813 wpa_s->received_mb_ies = NULL;
4814 }
4815#endif /* CONFIG_FST */
4816
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004817 if (wpa_s->drv_priv)
4818 wpa_drv_deinit(wpa_s);
Irfan Sheriff622b66d2011-08-03 09:11:49 -07004819
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07004820 if (notify)
4821 wpas_notify_iface_removed(wpa_s);
4822
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07004823 if (terminate)
4824 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
Irfan Sheriff622b66d2011-08-03 09:11:49 -07004825
4826 if (wpa_s->ctrl_iface) {
4827 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
4828 wpa_s->ctrl_iface = NULL;
4829 }
4830
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004831#ifdef CONFIG_MESH
4832 if (wpa_s->ifmsh) {
4833 wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh);
4834 wpa_s->ifmsh = NULL;
4835 }
4836#endif /* CONFIG_MESH */
4837
Irfan Sheriff622b66d2011-08-03 09:11:49 -07004838 if (wpa_s->conf != NULL) {
Irfan Sheriff622b66d2011-08-03 09:11:49 -07004839 wpa_config_free(wpa_s->conf);
4840 wpa_s->conf = NULL;
4841 }
Dmitry Shmidt8da800a2013-04-24 12:57:01 -07004842
Dmitry Shmidt7a53dbb2015-06-11 13:13:53 -07004843 os_free(wpa_s->ssids_from_scan_req);
4844
Dmitry Shmidt8da800a2013-04-24 12:57:01 -07004845 os_free(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004846}
4847
4848
4849/**
4850 * wpa_supplicant_add_iface - Add a new network interface
4851 * @global: Pointer to global data from wpa_supplicant_init()
4852 * @iface: Interface configuration options
Dmitry Shmidt203eadb2015-03-05 14:16:04 -08004853 * @parent: Parent interface or %NULL to assign new interface as parent
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004854 * Returns: Pointer to the created interface or %NULL on failure
4855 *
4856 * This function is used to add new network interfaces for %wpa_supplicant.
4857 * This can be called before wpa_supplicant_run() to add interfaces before the
4858 * main event loop has been started. In addition, new interfaces can be added
4859 * dynamically while %wpa_supplicant is already running. This could happen,
4860 * e.g., when a hotplug network adapter is inserted.
4861 */
4862struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
Dmitry Shmidt203eadb2015-03-05 14:16:04 -08004863 struct wpa_interface *iface,
4864 struct wpa_supplicant *parent)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004865{
4866 struct wpa_supplicant *wpa_s;
4867 struct wpa_interface t_iface;
4868 struct wpa_ssid *ssid;
4869
4870 if (global == NULL || iface == NULL)
4871 return NULL;
4872
Dmitry Shmidt203eadb2015-03-05 14:16:04 -08004873 wpa_s = wpa_supplicant_alloc(parent);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004874 if (wpa_s == NULL)
4875 return NULL;
4876
4877 wpa_s->global = global;
4878
4879 t_iface = *iface;
4880 if (global->params.override_driver) {
4881 wpa_printf(MSG_DEBUG, "Override interface parameter: driver "
4882 "('%s' -> '%s')",
4883 iface->driver, global->params.override_driver);
4884 t_iface.driver = global->params.override_driver;
4885 }
4886 if (global->params.override_ctrl_interface) {
4887 wpa_printf(MSG_DEBUG, "Override interface parameter: "
4888 "ctrl_interface ('%s' -> '%s')",
4889 iface->ctrl_interface,
4890 global->params.override_ctrl_interface);
4891 t_iface.ctrl_interface =
4892 global->params.override_ctrl_interface;
4893 }
4894 if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
4895 wpa_printf(MSG_DEBUG, "Failed to add interface %s",
4896 iface->ifname);
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07004897 wpa_supplicant_deinit_iface(wpa_s, 0, 0);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004898 return NULL;
4899 }
4900
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004901 if (iface->p2p_mgmt == 0) {
4902 /* Notify the control interfaces about new iface */
4903 if (wpas_notify_iface_added(wpa_s)) {
4904 wpa_supplicant_deinit_iface(wpa_s, 1, 0);
4905 return NULL;
4906 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004907
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004908 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
4909 wpas_notify_network_added(wpa_s, ssid);
4910 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004911
4912 wpa_s->next = global->ifaces;
4913 global->ifaces = wpa_s;
4914
4915 wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
Dmitry Shmidt04949592012-07-19 12:16:46 -07004916 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004917
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004918#ifdef CONFIG_P2P
4919 if (wpa_s->global->p2p == NULL &&
Dmitry Shmidt1d755d02015-04-28 10:34:29 -07004920 !wpa_s->global->p2p_disabled && !wpa_s->conf->p2p_disabled &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004921 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
Dmitry Shmidta3dc3092015-06-23 11:21:28 -07004922 wpas_p2p_add_p2pdev_interface(
4923 wpa_s, wpa_s->global->params.conf_p2p_dev) < 0) {
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004924 wpa_printf(MSG_INFO,
4925 "P2P: Failed to enable P2P Device interface");
4926 /* Try to continue without. P2P will be disabled. */
4927 }
4928#endif /* CONFIG_P2P */
4929
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004930 return wpa_s;
4931}
4932
4933
4934/**
4935 * wpa_supplicant_remove_iface - Remove a network interface
4936 * @global: Pointer to global data from wpa_supplicant_init()
4937 * @wpa_s: Pointer to the network interface to be removed
4938 * Returns: 0 if interface was removed, -1 if interface was not found
4939 *
4940 * This function can be used to dynamically remove network interfaces from
4941 * %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In
4942 * addition, this function is used to remove all remaining interfaces when
4943 * %wpa_supplicant is terminated.
4944 */
4945int wpa_supplicant_remove_iface(struct wpa_global *global,
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07004946 struct wpa_supplicant *wpa_s,
4947 int terminate)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004948{
4949 struct wpa_supplicant *prev;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004950#ifdef CONFIG_MESH
4951 unsigned int mesh_if_created = wpa_s->mesh_if_created;
4952 char *ifname = NULL;
4953#endif /* CONFIG_MESH */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004954
4955 /* Remove interface from the global list of interfaces */
4956 prev = global->ifaces;
4957 if (prev == wpa_s) {
4958 global->ifaces = wpa_s->next;
4959 } else {
4960 while (prev && prev->next != wpa_s)
4961 prev = prev->next;
4962 if (prev == NULL)
4963 return -1;
4964 prev->next = wpa_s->next;
4965 }
4966
4967 wpa_dbg(wpa_s, MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
4968
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004969#ifdef CONFIG_MESH
4970 if (mesh_if_created) {
4971 ifname = os_strdup(wpa_s->ifname);
4972 if (ifname == NULL) {
4973 wpa_dbg(wpa_s, MSG_ERROR,
4974 "mesh: Failed to malloc ifname");
4975 return -1;
4976 }
4977 }
4978#endif /* CONFIG_MESH */
4979
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004980 if (global->p2p_group_formation == wpa_s)
4981 global->p2p_group_formation = NULL;
Dmitry Shmidt700a1372013-03-15 14:14:44 -07004982 if (global->p2p_invite_group == wpa_s)
4983 global->p2p_invite_group = NULL;
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07004984 wpa_supplicant_deinit_iface(wpa_s, 1, terminate);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004985
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08004986#ifdef CONFIG_MESH
4987 if (mesh_if_created) {
4988 wpa_drv_if_remove(global->ifaces, WPA_IF_MESH, ifname);
4989 os_free(ifname);
4990 }
4991#endif /* CONFIG_MESH */
4992
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004993 return 0;
4994}
4995
4996
4997/**
4998 * wpa_supplicant_get_eap_mode - Get the current EAP mode
4999 * @wpa_s: Pointer to the network interface
5000 * Returns: Pointer to the eap mode or the string "UNKNOWN" if not found
5001 */
5002const char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s)
5003{
5004 const char *eapol_method;
5005
5006 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) == 0 &&
5007 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
5008 return "NO-EAP";
5009 }
5010
5011 eapol_method = eapol_sm_get_method_name(wpa_s->eapol);
5012 if (eapol_method == NULL)
5013 return "UNKNOWN-EAP";
5014
5015 return eapol_method;
5016}
5017
5018
5019/**
5020 * wpa_supplicant_get_iface - Get a new network interface
5021 * @global: Pointer to global data from wpa_supplicant_init()
5022 * @ifname: Interface name
5023 * Returns: Pointer to the interface or %NULL if not found
5024 */
5025struct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
5026 const char *ifname)
5027{
5028 struct wpa_supplicant *wpa_s;
5029
5030 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
5031 if (os_strcmp(wpa_s->ifname, ifname) == 0)
5032 return wpa_s;
5033 }
5034 return NULL;
5035}
5036
5037
5038#ifndef CONFIG_NO_WPA_MSG
5039static const char * wpa_supplicant_msg_ifname_cb(void *ctx)
5040{
5041 struct wpa_supplicant *wpa_s = ctx;
5042 if (wpa_s == NULL)
5043 return NULL;
5044 return wpa_s->ifname;
5045}
5046#endif /* CONFIG_NO_WPA_MSG */
5047
5048
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08005049#ifndef WPA_SUPPLICANT_CLEANUP_INTERVAL
5050#define WPA_SUPPLICANT_CLEANUP_INTERVAL 10
5051#endif /* WPA_SUPPLICANT_CLEANUP_INTERVAL */
5052
5053/* Periodic cleanup tasks */
5054static void wpas_periodic(void *eloop_ctx, void *timeout_ctx)
5055{
5056 struct wpa_global *global = eloop_ctx;
5057 struct wpa_supplicant *wpa_s;
5058
5059 eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0,
5060 wpas_periodic, global, NULL);
5061
5062#ifdef CONFIG_P2P
5063 if (global->p2p)
5064 p2p_expire_peers(global->p2p);
5065#endif /* CONFIG_P2P */
5066
5067 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
5068 wpa_bss_flush_by_age(wpa_s, wpa_s->conf->bss_expiration_age);
5069#ifdef CONFIG_AP
5070 ap_periodic(wpa_s);
5071#endif /* CONFIG_AP */
5072 }
5073}
5074
5075
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005076/**
5077 * wpa_supplicant_init - Initialize %wpa_supplicant
5078 * @params: Parameters for %wpa_supplicant
5079 * Returns: Pointer to global %wpa_supplicant data, or %NULL on failure
5080 *
5081 * This function is used to initialize %wpa_supplicant. After successful
5082 * initialization, the returned data pointer can be used to add and remove
5083 * network interfaces, and eventually, to deinitialize %wpa_supplicant.
5084 */
5085struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
5086{
5087 struct wpa_global *global;
5088 int ret, i;
5089
5090 if (params == NULL)
5091 return NULL;
5092
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08005093#ifdef CONFIG_DRIVER_NDIS
5094 {
5095 void driver_ndis_init_ops(void);
5096 driver_ndis_init_ops();
5097 }
5098#endif /* CONFIG_DRIVER_NDIS */
5099
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005100#ifndef CONFIG_NO_WPA_MSG
5101 wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
5102#endif /* CONFIG_NO_WPA_MSG */
5103
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08005104 if (params->wpa_debug_file_path)
5105 wpa_debug_open_file(params->wpa_debug_file_path);
5106 else
5107 wpa_debug_setup_stdout();
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005108 if (params->wpa_debug_syslog)
5109 wpa_debug_open_syslog();
Dmitry Shmidt04949592012-07-19 12:16:46 -07005110 if (params->wpa_debug_tracing) {
5111 ret = wpa_debug_open_linux_tracing();
5112 if (ret) {
5113 wpa_printf(MSG_ERROR,
5114 "Failed to enable trace logging");
5115 return NULL;
5116 }
5117 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005118
5119 ret = eap_register_methods();
5120 if (ret) {
5121 wpa_printf(MSG_ERROR, "Failed to register EAP methods");
5122 if (ret == -2)
5123 wpa_printf(MSG_ERROR, "Two or more EAP methods used "
5124 "the same EAP type.");
5125 return NULL;
5126 }
5127
5128 global = os_zalloc(sizeof(*global));
5129 if (global == NULL)
5130 return NULL;
5131 dl_list_init(&global->p2p_srv_bonjour);
5132 dl_list_init(&global->p2p_srv_upnp);
5133 global->params.daemonize = params->daemonize;
5134 global->params.wait_for_monitor = params->wait_for_monitor;
5135 global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
5136 if (params->pid_file)
5137 global->params.pid_file = os_strdup(params->pid_file);
5138 if (params->ctrl_interface)
5139 global->params.ctrl_interface =
5140 os_strdup(params->ctrl_interface);
Dmitry Shmidtb6e9aaf2013-05-20 14:49:44 -07005141 if (params->ctrl_interface_group)
5142 global->params.ctrl_interface_group =
5143 os_strdup(params->ctrl_interface_group);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005144 if (params->override_driver)
5145 global->params.override_driver =
5146 os_strdup(params->override_driver);
5147 if (params->override_ctrl_interface)
5148 global->params.override_ctrl_interface =
5149 os_strdup(params->override_ctrl_interface);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08005150#ifdef CONFIG_P2P
Sasha Levitskiydaa60e52015-08-05 13:02:59 -07005151 if (params->conf_p2p_dev)
5152 global->params.conf_p2p_dev =
5153 os_strdup(params->conf_p2p_dev);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08005154#endif /* CONFIG_P2P */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005155 wpa_debug_level = global->params.wpa_debug_level =
5156 params->wpa_debug_level;
5157 wpa_debug_show_keys = global->params.wpa_debug_show_keys =
5158 params->wpa_debug_show_keys;
5159 wpa_debug_timestamp = global->params.wpa_debug_timestamp =
5160 params->wpa_debug_timestamp;
5161
5162 wpa_printf(MSG_DEBUG, "wpa_supplicant v" VERSION_STR);
5163
5164 if (eloop_init()) {
5165 wpa_printf(MSG_ERROR, "Failed to initialize event loop");
5166 wpa_supplicant_deinit(global);
5167 return NULL;
5168 }
5169
Jouni Malinen75ecf522011-06-27 15:19:46 -07005170 random_init(params->entropy_file);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005171
5172 global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
5173 if (global->ctrl_iface == NULL) {
5174 wpa_supplicant_deinit(global);
5175 return NULL;
5176 }
5177
5178 if (wpas_notify_supplicant_initialized(global)) {
5179 wpa_supplicant_deinit(global);
5180 return NULL;
5181 }
5182
5183 for (i = 0; wpa_drivers[i]; i++)
5184 global->drv_count++;
5185 if (global->drv_count == 0) {
5186 wpa_printf(MSG_ERROR, "No drivers enabled");
5187 wpa_supplicant_deinit(global);
5188 return NULL;
5189 }
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08005190 global->drv_priv = os_calloc(global->drv_count, sizeof(void *));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005191 if (global->drv_priv == NULL) {
5192 wpa_supplicant_deinit(global);
5193 return NULL;
5194 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005195
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005196#ifdef CONFIG_WIFI_DISPLAY
5197 if (wifi_display_init(global) < 0) {
5198 wpa_printf(MSG_ERROR, "Failed to initialize Wi-Fi Display");
5199 wpa_supplicant_deinit(global);
5200 return NULL;
5201 }
5202#endif /* CONFIG_WIFI_DISPLAY */
5203
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08005204 eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0,
5205 wpas_periodic, global, NULL);
5206
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005207 return global;
5208}
5209
5210
5211/**
5212 * wpa_supplicant_run - Run the %wpa_supplicant main event loop
5213 * @global: Pointer to global data from wpa_supplicant_init()
5214 * Returns: 0 after successful event loop run, -1 on failure
5215 *
5216 * This function starts the main event loop and continues running as long as
5217 * there are any remaining events. In most cases, this function is running as
5218 * long as the %wpa_supplicant process in still in use.
5219 */
5220int wpa_supplicant_run(struct wpa_global *global)
5221{
5222 struct wpa_supplicant *wpa_s;
5223
5224 if (global->params.daemonize &&
5225 wpa_supplicant_daemon(global->params.pid_file))
5226 return -1;
5227
5228 if (global->params.wait_for_monitor) {
5229 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
Dmitry Shmidt014a3ff2015-12-28 13:27:49 -08005230 if (wpa_s->ctrl_iface && !wpa_s->p2p_mgmt)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005231 wpa_supplicant_ctrl_iface_wait(
5232 wpa_s->ctrl_iface);
5233 }
5234
5235 eloop_register_signal_terminate(wpa_supplicant_terminate, global);
5236 eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
5237
5238 eloop_run();
5239
5240 return 0;
5241}
5242
5243
5244/**
5245 * wpa_supplicant_deinit - Deinitialize %wpa_supplicant
5246 * @global: Pointer to global data from wpa_supplicant_init()
5247 *
5248 * This function is called to deinitialize %wpa_supplicant and to free all
5249 * allocated resources. Remaining network interfaces will also be removed.
5250 */
5251void wpa_supplicant_deinit(struct wpa_global *global)
5252{
5253 int i;
5254
5255 if (global == NULL)
5256 return;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08005257
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08005258 eloop_cancel_timeout(wpas_periodic, global, NULL);
5259
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005260#ifdef CONFIG_WIFI_DISPLAY
5261 wifi_display_deinit(global);
5262#endif /* CONFIG_WIFI_DISPLAY */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005263
5264 while (global->ifaces)
Dmitry Shmidte15c7b52011-08-03 15:04:35 -07005265 wpa_supplicant_remove_iface(global, global->ifaces, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005266
5267 if (global->ctrl_iface)
5268 wpa_supplicant_global_ctrl_iface_deinit(global->ctrl_iface);
5269
5270 wpas_notify_supplicant_deinitialized(global);
5271
5272 eap_peer_unregister_methods();
5273#ifdef CONFIG_AP
5274 eap_server_unregister_methods();
5275#endif /* CONFIG_AP */
5276
5277 for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
5278 if (!global->drv_priv[i])
5279 continue;
5280 wpa_drivers[i]->global_deinit(global->drv_priv[i]);
5281 }
5282 os_free(global->drv_priv);
5283
5284 random_deinit();
5285
5286 eloop_destroy();
5287
5288 if (global->params.pid_file) {
5289 os_daemonize_terminate(global->params.pid_file);
5290 os_free(global->params.pid_file);
5291 }
5292 os_free(global->params.ctrl_interface);
Dmitry Shmidtb6e9aaf2013-05-20 14:49:44 -07005293 os_free(global->params.ctrl_interface_group);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005294 os_free(global->params.override_driver);
5295 os_free(global->params.override_ctrl_interface);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08005296#ifdef CONFIG_P2P
Sasha Levitskiydaa60e52015-08-05 13:02:59 -07005297 os_free(global->params.conf_p2p_dev);
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08005298#endif /* CONFIG_P2P */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005299
Dmitry Shmidt4ce9c872013-10-24 11:08:13 -07005300 os_free(global->p2p_disallow_freq.range);
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08005301 os_free(global->p2p_go_avoid_freq.range);
Dmitry Shmidt391c59f2013-09-03 12:16:28 -07005302 os_free(global->add_psk);
Dmitry Shmidt04949592012-07-19 12:16:46 -07005303
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005304 os_free(global);
5305 wpa_debug_close_syslog();
5306 wpa_debug_close_file();
Dmitry Shmidt04949592012-07-19 12:16:46 -07005307 wpa_debug_close_linux_tracing();
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005308}
5309
5310
5311void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
5312{
5313 if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
5314 wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
5315 char country[3];
5316 country[0] = wpa_s->conf->country[0];
5317 country[1] = wpa_s->conf->country[1];
5318 country[2] = '\0';
5319 if (wpa_drv_set_country(wpa_s, country) < 0) {
5320 wpa_printf(MSG_ERROR, "Failed to set country code "
5321 "'%s'", country);
5322 }
5323 }
5324
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005325 if (wpa_s->conf->changed_parameters & CFG_CHANGED_EXT_PW_BACKEND)
5326 wpas_init_ext_pw(wpa_s);
5327
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -08005328 if (wpa_s->conf->changed_parameters & CFG_CHANGED_SCHED_SCAN_PLANS)
5329 wpas_sched_scan_plans_set(wpa_s, wpa_s->conf->sched_scan_plans);
5330
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005331#ifdef CONFIG_WPS
5332 wpas_wps_update_config(wpa_s);
5333#endif /* CONFIG_WPS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005334 wpas_p2p_update_config(wpa_s);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005335 wpa_s->conf->changed_parameters = 0;
5336}
5337
5338
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08005339void add_freq(int *freqs, int *num_freqs, int freq)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005340{
5341 int i;
5342
5343 for (i = 0; i < *num_freqs; i++) {
5344 if (freqs[i] == freq)
5345 return;
5346 }
5347
5348 freqs[*num_freqs] = freq;
5349 (*num_freqs)++;
5350}
5351
5352
5353static int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s)
5354{
5355 struct wpa_bss *bss, *cbss;
5356 const int max_freqs = 10;
5357 int *freqs;
5358 int num_freqs = 0;
5359
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08005360 freqs = os_calloc(max_freqs + 1, sizeof(int));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005361 if (freqs == NULL)
5362 return NULL;
5363
5364 cbss = wpa_s->current_bss;
5365
5366 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
5367 if (bss == cbss)
5368 continue;
5369 if (bss->ssid_len == cbss->ssid_len &&
5370 os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
5371 wpa_blacklist_get(wpa_s, bss->bssid) == NULL) {
5372 add_freq(freqs, &num_freqs, bss->freq);
5373 if (num_freqs == max_freqs)
5374 break;
5375 }
5376 }
5377
5378 if (num_freqs == 0) {
5379 os_free(freqs);
5380 freqs = NULL;
5381 }
5382
5383 return freqs;
5384}
5385
5386
5387void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
5388{
5389 int timeout;
5390 int count;
5391 int *freqs = NULL;
5392
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08005393 wpas_connect_work_done(wpa_s);
5394
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005395 /*
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005396 * Remove possible authentication timeout since the connection failed.
5397 */
5398 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
5399
Dmitry Shmidt203eadb2015-03-05 14:16:04 -08005400 /*
5401 * There is no point in blacklisting the AP if this event is
5402 * generated based on local request to disconnect.
5403 */
5404 if (wpa_s->own_disconnect_req) {
5405 wpa_s->own_disconnect_req = 0;
5406 wpa_dbg(wpa_s, MSG_DEBUG,
5407 "Ignore connection failure due to local request to disconnect");
5408 return;
5409 }
Dmitry Shmidtea69e842013-05-13 14:52:28 -07005410 if (wpa_s->disconnected) {
Dmitry Shmidtea69e842013-05-13 14:52:28 -07005411 wpa_dbg(wpa_s, MSG_DEBUG, "Ignore connection failure "
5412 "indication since interface has been put into "
5413 "disconnected state");
5414 return;
5415 }
5416
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005417 /*
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005418 * Add the failed BSSID into the blacklist and speed up next scan
5419 * attempt if there could be other APs that could accept association.
5420 * The current blacklist count indicates how many times we have tried
5421 * connecting to this AP and multiple attempts mean that other APs are
5422 * either not available or has already been tried, so that we can start
5423 * increasing the delay here to avoid constant scanning.
5424 */
5425 count = wpa_blacklist_add(wpa_s, bssid);
5426 if (count == 1 && wpa_s->current_bss) {
5427 /*
5428 * This BSS was not in the blacklist before. If there is
5429 * another BSS available for the same ESS, we should try that
5430 * next. Otherwise, we may as well try this one once more
5431 * before allowing other, likely worse, ESSes to be considered.
5432 */
5433 freqs = get_bss_freqs_in_ess(wpa_s);
5434 if (freqs) {
5435 wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
5436 "has been seen; try it next");
5437 wpa_blacklist_add(wpa_s, bssid);
5438 /*
5439 * On the next scan, go through only the known channels
5440 * used in this ESS based on previous scans to speed up
5441 * common load balancing use case.
5442 */
5443 os_free(wpa_s->next_scan_freqs);
5444 wpa_s->next_scan_freqs = freqs;
5445 }
5446 }
5447
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08005448 /*
5449 * Add previous failure count in case the temporary blacklist was
5450 * cleared due to no other BSSes being available.
5451 */
5452 count += wpa_s->extra_blacklist_count;
5453
Dmitry Shmidt4b060592013-04-29 16:42:49 -07005454 if (count > 3 && wpa_s->current_ssid) {
5455 wpa_printf(MSG_DEBUG, "Continuous association failures - "
5456 "consider temporary network disabling");
Dmitry Shmidt6dc03bd2014-05-16 10:40:13 -07005457 wpas_auth_failed(wpa_s, "CONN_FAILED");
Dmitry Shmidt4b060592013-04-29 16:42:49 -07005458 }
5459
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005460 switch (count) {
5461 case 1:
5462 timeout = 100;
5463 break;
5464 case 2:
5465 timeout = 500;
5466 break;
5467 case 3:
5468 timeout = 1000;
5469 break;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08005470 case 4:
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005471 timeout = 5000;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08005472 break;
5473 default:
5474 timeout = 10000;
5475 break;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005476 }
5477
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08005478 wpa_dbg(wpa_s, MSG_DEBUG, "Blacklist count %d --> request scan in %d "
5479 "ms", count, timeout);
5480
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07005481 /*
5482 * TODO: if more than one possible AP is available in scan results,
5483 * could try the other ones before requesting a new scan.
5484 */
5485 wpa_supplicant_req_scan(wpa_s, timeout / 1000,
5486 1000 * (timeout % 1000));
5487}
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08005488
5489
5490int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
5491{
5492 return wpa_s->conf->ap_scan == 2 ||
5493 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
5494}
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005495
Dmitry Shmidt04949592012-07-19 12:16:46 -07005496
5497#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
5498int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
5499 struct wpa_ssid *ssid,
5500 const char *field,
5501 const char *value)
5502{
5503#ifdef IEEE8021X_EAPOL
5504 struct eap_peer_config *eap = &ssid->eap;
5505
5506 wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
5507 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
5508 (const u8 *) value, os_strlen(value));
5509
5510 switch (wpa_supplicant_ctrl_req_from_string(field)) {
5511 case WPA_CTRL_REQ_EAP_IDENTITY:
5512 os_free(eap->identity);
5513 eap->identity = (u8 *) os_strdup(value);
5514 eap->identity_len = os_strlen(value);
5515 eap->pending_req_identity = 0;
5516 if (ssid == wpa_s->current_ssid)
5517 wpa_s->reassociate = 1;
5518 break;
5519 case WPA_CTRL_REQ_EAP_PASSWORD:
Dmitry Shmidtc2817022014-07-02 10:32:10 -07005520 bin_clear_free(eap->password, eap->password_len);
Dmitry Shmidt04949592012-07-19 12:16:46 -07005521 eap->password = (u8 *) os_strdup(value);
5522 eap->password_len = os_strlen(value);
5523 eap->pending_req_password = 0;
5524 if (ssid == wpa_s->current_ssid)
5525 wpa_s->reassociate = 1;
5526 break;
5527 case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
Dmitry Shmidtc2817022014-07-02 10:32:10 -07005528 bin_clear_free(eap->new_password, eap->new_password_len);
Dmitry Shmidt04949592012-07-19 12:16:46 -07005529 eap->new_password = (u8 *) os_strdup(value);
5530 eap->new_password_len = os_strlen(value);
5531 eap->pending_req_new_password = 0;
5532 if (ssid == wpa_s->current_ssid)
5533 wpa_s->reassociate = 1;
5534 break;
5535 case WPA_CTRL_REQ_EAP_PIN:
Dmitry Shmidtc2817022014-07-02 10:32:10 -07005536 str_clear_free(eap->pin);
Dmitry Shmidt04949592012-07-19 12:16:46 -07005537 eap->pin = os_strdup(value);
5538 eap->pending_req_pin = 0;
5539 if (ssid == wpa_s->current_ssid)
5540 wpa_s->reassociate = 1;
5541 break;
5542 case WPA_CTRL_REQ_EAP_OTP:
Dmitry Shmidtc2817022014-07-02 10:32:10 -07005543 bin_clear_free(eap->otp, eap->otp_len);
Dmitry Shmidt04949592012-07-19 12:16:46 -07005544 eap->otp = (u8 *) os_strdup(value);
5545 eap->otp_len = os_strlen(value);
5546 os_free(eap->pending_req_otp);
5547 eap->pending_req_otp = NULL;
5548 eap->pending_req_otp_len = 0;
5549 break;
5550 case WPA_CTRL_REQ_EAP_PASSPHRASE:
Dmitry Shmidtc2817022014-07-02 10:32:10 -07005551 str_clear_free(eap->private_key_passwd);
5552 eap->private_key_passwd = os_strdup(value);
Dmitry Shmidt04949592012-07-19 12:16:46 -07005553 eap->pending_req_passphrase = 0;
5554 if (ssid == wpa_s->current_ssid)
5555 wpa_s->reassociate = 1;
5556 break;
Dmitry Shmidt051af732013-10-22 13:52:46 -07005557 case WPA_CTRL_REQ_SIM:
Dmitry Shmidtc2817022014-07-02 10:32:10 -07005558 str_clear_free(eap->external_sim_resp);
Dmitry Shmidt051af732013-10-22 13:52:46 -07005559 eap->external_sim_resp = os_strdup(value);
5560 break;
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -07005561 case WPA_CTRL_REQ_PSK_PASSPHRASE:
5562 if (wpa_config_set(ssid, "psk", value, 0) < 0)
5563 return -1;
5564 ssid->mem_only_psk = 1;
5565 if (ssid->passphrase)
5566 wpa_config_update_psk(ssid);
5567 if (wpa_s->wpa_state == WPA_SCANNING && !wpa_s->scanning)
5568 wpa_supplicant_req_scan(wpa_s, 0, 0);
5569 break;
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08005570 case WPA_CTRL_REQ_EXT_CERT_CHECK:
5571 if (eap->pending_ext_cert_check != PENDING_CHECK)
5572 return -1;
5573 if (os_strcmp(value, "good") == 0)
5574 eap->pending_ext_cert_check = EXT_CERT_CHECK_GOOD;
5575 else if (os_strcmp(value, "bad") == 0)
5576 eap->pending_ext_cert_check = EXT_CERT_CHECK_BAD;
5577 else
5578 return -1;
5579 break;
Dmitry Shmidt04949592012-07-19 12:16:46 -07005580 default:
5581 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
5582 return -1;
5583 }
5584
5585 return 0;
5586#else /* IEEE8021X_EAPOL */
5587 wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
5588 return -1;
5589#endif /* IEEE8021X_EAPOL */
5590}
5591#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
5592
5593
5594int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
5595{
5596 int i;
5597 unsigned int drv_enc;
5598
Dmitry Shmidt203eadb2015-03-05 14:16:04 -08005599 if (wpa_s->p2p_mgmt)
5600 return 1; /* no normal network profiles on p2p_mgmt interface */
5601
Dmitry Shmidt04949592012-07-19 12:16:46 -07005602 if (ssid == NULL)
5603 return 1;
5604
5605 if (ssid->disabled)
5606 return 1;
5607
Dmitry Shmidt203eadb2015-03-05 14:16:04 -08005608 if (wpa_s->drv_capa_known)
Dmitry Shmidt04949592012-07-19 12:16:46 -07005609 drv_enc = wpa_s->drv_enc;
5610 else
5611 drv_enc = (unsigned int) -1;
5612
5613 for (i = 0; i < NUM_WEP_KEYS; i++) {
5614 size_t len = ssid->wep_key_len[i];
5615 if (len == 0)
5616 continue;
5617 if (len == 5 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40))
5618 continue;
5619 if (len == 13 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104))
5620 continue;
5621 if (len == 16 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP128))
5622 continue;
5623 return 1; /* invalid WEP key */
5624 }
5625
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005626 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -07005627 (!ssid->passphrase || ssid->ssid_len != 0) && !ssid->ext_psk &&
5628 !ssid->mem_only_psk)
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005629 return 1;
5630
Dmitry Shmidt04949592012-07-19 12:16:46 -07005631 return 0;
5632}
5633
5634
Dmitry Shmidt807291d2015-01-27 13:40:23 -08005635int wpas_get_ssid_pmf(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
5636{
5637#ifdef CONFIG_IEEE80211W
5638 if (ssid == NULL || ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT) {
5639 if (wpa_s->conf->pmf == MGMT_FRAME_PROTECTION_OPTIONAL &&
5640 !(wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_BIP)) {
5641 /*
5642 * Driver does not support BIP -- ignore pmf=1 default
5643 * since the connection with PMF would fail and the
5644 * configuration does not require PMF to be enabled.
5645 */
5646 return NO_MGMT_FRAME_PROTECTION;
5647 }
5648
5649 return wpa_s->conf->pmf;
5650 }
5651
5652 return ssid->ieee80211w;
5653#else /* CONFIG_IEEE80211W */
5654 return NO_MGMT_FRAME_PROTECTION;
5655#endif /* CONFIG_IEEE80211W */
5656}
5657
5658
Dmitry Shmidt687922c2012-03-26 14:02:32 -07005659int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005660{
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07005661 if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005662 return 1;
Dmitry Shmidt2fb777c2012-05-02 12:29:53 -07005663 if (wpa_s->global->conc_pref == WPA_CONC_PREF_STA)
Dmitry Shmidt687922c2012-03-26 14:02:32 -07005664 return 0;
Dmitry Shmidt687922c2012-03-26 14:02:32 -07005665 return -1;
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005666}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005667
5668
Dmitry Shmidt6dc03bd2014-05-16 10:40:13 -07005669void wpas_auth_failed(struct wpa_supplicant *wpa_s, char *reason)
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005670{
5671 struct wpa_ssid *ssid = wpa_s->current_ssid;
5672 int dur;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08005673 struct os_reltime now;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005674
5675 if (ssid == NULL) {
5676 wpa_printf(MSG_DEBUG, "Authentication failure but no known "
5677 "SSID block");
5678 return;
5679 }
5680
5681 if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
5682 return;
5683
5684 ssid->auth_failures++;
Dmitry Shmidtd5c075b2013-08-05 14:36:10 -07005685
5686#ifdef CONFIG_P2P
5687 if (ssid->p2p_group &&
5688 (wpa_s->p2p_in_provisioning || wpa_s->show_group_started)) {
5689 /*
5690 * Skip the wait time since there is a short timeout on the
5691 * connection to a P2P group.
5692 */
5693 return;
5694 }
5695#endif /* CONFIG_P2P */
5696
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005697 if (ssid->auth_failures > 50)
5698 dur = 300;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005699 else if (ssid->auth_failures > 10)
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08005700 dur = 120;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005701 else if (ssid->auth_failures > 5)
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08005702 dur = 90;
5703 else if (ssid->auth_failures > 3)
5704 dur = 60;
5705 else if (ssid->auth_failures > 2)
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005706 dur = 30;
5707 else if (ssid->auth_failures > 1)
5708 dur = 20;
5709 else
5710 dur = 10;
5711
Dmitry Shmidtf21452a2014-02-26 10:55:25 -08005712 if (ssid->auth_failures > 1 &&
5713 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt))
5714 dur += os_random() % (ssid->auth_failures * 10);
5715
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -08005716 os_get_reltime(&now);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005717 if (now.sec + dur <= ssid->disabled_until.sec)
5718 return;
5719
5720 ssid->disabled_until.sec = now.sec + dur;
5721
5722 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TEMP_DISABLED
Dmitry Shmidt6dc03bd2014-05-16 10:40:13 -07005723 "id=%d ssid=\"%s\" auth_failures=%u duration=%d reason=%s",
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005724 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
Dmitry Shmidt6dc03bd2014-05-16 10:40:13 -07005725 ssid->auth_failures, dur, reason);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07005726}
5727
5728
5729void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
5730 struct wpa_ssid *ssid, int clear_failures)
5731{
5732 if (ssid == NULL)
5733 return;
5734
5735 if (ssid->disabled_until.sec) {
5736 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REENABLED
5737 "id=%d ssid=\"%s\"",
5738 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
5739 }
5740 ssid->disabled_until.sec = 0;
5741 ssid->disabled_until.usec = 0;
5742 if (clear_failures)
5743 ssid->auth_failures = 0;
5744}
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08005745
5746
5747int disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid)
5748{
5749 size_t i;
5750
5751 if (wpa_s->disallow_aps_bssid == NULL)
5752 return 0;
5753
5754 for (i = 0; i < wpa_s->disallow_aps_bssid_count; i++) {
5755 if (os_memcmp(wpa_s->disallow_aps_bssid + i * ETH_ALEN,
5756 bssid, ETH_ALEN) == 0)
5757 return 1;
5758 }
5759
5760 return 0;
5761}
5762
5763
5764int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
5765 size_t ssid_len)
5766{
5767 size_t i;
5768
5769 if (wpa_s->disallow_aps_ssid == NULL || ssid == NULL)
5770 return 0;
5771
5772 for (i = 0; i < wpa_s->disallow_aps_ssid_count; i++) {
5773 struct wpa_ssid_value *s = &wpa_s->disallow_aps_ssid[i];
5774 if (ssid_len == s->ssid_len &&
5775 os_memcmp(ssid, s->ssid, ssid_len) == 0)
5776 return 1;
5777 }
5778
5779 return 0;
5780}
5781
5782
5783/**
5784 * wpas_request_connection - Request a new connection
5785 * @wpa_s: Pointer to the network interface
5786 *
5787 * This function is used to request a new connection to be found. It will mark
5788 * the interface to allow reassociation and request a new scan to find a
5789 * suitable network to connect to.
5790 */
5791void wpas_request_connection(struct wpa_supplicant *wpa_s)
5792{
5793 wpa_s->normal_scans = 0;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08005794 wpa_s->scan_req = NORMAL_SCAN_REQ;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08005795 wpa_supplicant_reinit_autoscan(wpa_s);
5796 wpa_s->extra_blacklist_count = 0;
5797 wpa_s->disconnected = 0;
5798 wpa_s->reassociate = 1;
Dmitry Shmidt2f3b8de2013-03-01 09:32:50 -08005799
5800 if (wpa_supplicant_fast_associate(wpa_s) != 1)
5801 wpa_supplicant_req_scan(wpa_s, 0, 0);
Dmitry Shmidt2f74e362015-01-21 13:19:05 -08005802 else
5803 wpa_s->reattach = 0;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -08005804}
Dmitry Shmidtea69e842013-05-13 14:52:28 -07005805
5806
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07005807void dump_freq_data(struct wpa_supplicant *wpa_s, const char *title,
5808 struct wpa_used_freq_data *freqs_data,
5809 unsigned int len)
Dmitry Shmidtb96dad42013-11-05 10:07:29 -08005810{
5811 unsigned int i;
5812
5813 wpa_dbg(wpa_s, MSG_DEBUG, "Shared frequencies (len=%u): %s",
5814 len, title);
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07005815 for (i = 0; i < len; i++) {
5816 struct wpa_used_freq_data *cur = &freqs_data[i];
5817 wpa_dbg(wpa_s, MSG_DEBUG, "freq[%u]: %d, flags=0x%X",
5818 i, cur->freq, cur->flags);
5819 }
Dmitry Shmidtb96dad42013-11-05 10:07:29 -08005820}
5821
5822
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07005823/*
5824 * Find the operating frequencies of any of the virtual interfaces that
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07005825 * are using the same radio as the current interface, and in addition, get
5826 * information about the interface types that are using the frequency.
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07005827 */
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07005828int get_shared_radio_freqs_data(struct wpa_supplicant *wpa_s,
5829 struct wpa_used_freq_data *freqs_data,
5830 unsigned int len)
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07005831{
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07005832 struct wpa_supplicant *ifs;
5833 u8 bssid[ETH_ALEN];
5834 int freq;
5835 unsigned int idx = 0, i;
5836
Dmitry Shmidtb96dad42013-11-05 10:07:29 -08005837 wpa_dbg(wpa_s, MSG_DEBUG,
5838 "Determining shared radio frequencies (max len %u)", len);
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07005839 os_memset(freqs_data, 0, sizeof(struct wpa_used_freq_data) * len);
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07005840
Dmitry Shmidt01904cf2013-12-05 11:08:35 -08005841 dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
5842 radio_list) {
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07005843 if (idx == len)
5844 break;
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07005845
5846 if (ifs->current_ssid == NULL || ifs->assoc_freq == 0)
5847 continue;
5848
5849 if (ifs->current_ssid->mode == WPAS_MODE_AP ||
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08005850 ifs->current_ssid->mode == WPAS_MODE_P2P_GO ||
5851 ifs->current_ssid->mode == WPAS_MODE_MESH)
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07005852 freq = ifs->current_ssid->frequency;
5853 else if (wpa_drv_get_bssid(ifs, bssid) == 0)
5854 freq = ifs->assoc_freq;
5855 else
5856 continue;
5857
5858 /* Hold only distinct freqs */
5859 for (i = 0; i < idx; i++)
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07005860 if (freqs_data[i].freq == freq)
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07005861 break;
5862
5863 if (i == idx)
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07005864 freqs_data[idx++].freq = freq;
5865
5866 if (ifs->current_ssid->mode == WPAS_MODE_INFRA) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08005867 freqs_data[i].flags |= ifs->current_ssid->p2p_group ?
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07005868 WPA_FREQ_USED_BY_P2P_CLIENT :
5869 WPA_FREQ_USED_BY_INFRA_STATION;
5870 }
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07005871 }
Dmitry Shmidtb96dad42013-11-05 10:07:29 -08005872
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07005873 dump_freq_data(wpa_s, "completed iteration", freqs_data, idx);
Dmitry Shmidtc2ebb4b2013-07-24 12:57:51 -07005874 return idx;
5875}
Dmitry Shmidt43cb5782014-06-16 16:23:22 -07005876
5877
5878/*
5879 * Find the operating frequencies of any of the virtual interfaces that
5880 * are using the same radio as the current interface.
5881 */
5882int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
5883 int *freq_array, unsigned int len)
5884{
5885 struct wpa_used_freq_data *freqs_data;
5886 int num, i;
5887
5888 os_memset(freq_array, 0, sizeof(int) * len);
5889
5890 freqs_data = os_calloc(len, sizeof(struct wpa_used_freq_data));
5891 if (!freqs_data)
5892 return -1;
5893
5894 num = get_shared_radio_freqs_data(wpa_s, freqs_data, len);
5895 for (i = 0; i < num; i++)
5896 freq_array[i] = freqs_data[i].freq;
5897
5898 os_free(freqs_data);
5899
5900 return num;
5901}
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08005902
5903
5904static void wpas_rrm_neighbor_rep_timeout_handler(void *data, void *user_ctx)
5905{
5906 struct rrm_data *rrm = data;
5907
5908 if (!rrm->notify_neighbor_rep) {
5909 wpa_printf(MSG_ERROR,
5910 "RRM: Unexpected neighbor report timeout");
5911 return;
5912 }
5913
5914 wpa_printf(MSG_DEBUG, "RRM: Notifying neighbor report - NONE");
5915 rrm->notify_neighbor_rep(rrm->neighbor_rep_cb_ctx, NULL);
5916
5917 rrm->notify_neighbor_rep = NULL;
5918 rrm->neighbor_rep_cb_ctx = NULL;
5919}
5920
5921
5922/*
5923 * wpas_rrm_reset - Clear and reset all RRM data in wpa_supplicant
5924 * @wpa_s: Pointer to wpa_supplicant
5925 */
5926void wpas_rrm_reset(struct wpa_supplicant *wpa_s)
5927{
5928 wpa_s->rrm.rrm_used = 0;
5929
5930 eloop_cancel_timeout(wpas_rrm_neighbor_rep_timeout_handler, &wpa_s->rrm,
5931 NULL);
5932 if (wpa_s->rrm.notify_neighbor_rep)
5933 wpas_rrm_neighbor_rep_timeout_handler(&wpa_s->rrm, NULL);
5934 wpa_s->rrm.next_neighbor_rep_token = 1;
5935}
5936
5937
5938/*
5939 * wpas_rrm_process_neighbor_rep - Handle incoming neighbor report
5940 * @wpa_s: Pointer to wpa_supplicant
5941 * @report: Neighbor report buffer, prefixed by a 1-byte dialog token
5942 * @report_len: Length of neighbor report buffer
5943 */
5944void wpas_rrm_process_neighbor_rep(struct wpa_supplicant *wpa_s,
5945 const u8 *report, size_t report_len)
5946{
5947 struct wpabuf *neighbor_rep;
5948
5949 wpa_hexdump(MSG_DEBUG, "RRM: New Neighbor Report", report, report_len);
5950 if (report_len < 1)
5951 return;
5952
5953 if (report[0] != wpa_s->rrm.next_neighbor_rep_token - 1) {
5954 wpa_printf(MSG_DEBUG,
5955 "RRM: Discarding neighbor report with token %d (expected %d)",
5956 report[0], wpa_s->rrm.next_neighbor_rep_token - 1);
5957 return;
5958 }
5959
5960 eloop_cancel_timeout(wpas_rrm_neighbor_rep_timeout_handler, &wpa_s->rrm,
5961 NULL);
5962
5963 if (!wpa_s->rrm.notify_neighbor_rep) {
5964 wpa_printf(MSG_ERROR, "RRM: Unexpected neighbor report");
5965 return;
5966 }
5967
5968 /* skipping the first byte, which is only an id (dialog token) */
5969 neighbor_rep = wpabuf_alloc(report_len - 1);
5970 if (neighbor_rep == NULL)
5971 return;
5972 wpabuf_put_data(neighbor_rep, report + 1, report_len - 1);
5973 wpa_printf(MSG_DEBUG, "RRM: Notifying neighbor report (token = %d)",
5974 report[0]);
5975 wpa_s->rrm.notify_neighbor_rep(wpa_s->rrm.neighbor_rep_cb_ctx,
5976 neighbor_rep);
5977 wpa_s->rrm.notify_neighbor_rep = NULL;
5978 wpa_s->rrm.neighbor_rep_cb_ctx = NULL;
5979}
5980
5981
Dmitry Shmidtff787d52015-01-12 13:01:47 -08005982#if defined(__CYGWIN__) || defined(CONFIG_NATIVE_WINDOWS)
5983/* Workaround different, undefined for Windows, error codes used here */
5984#define ENOTCONN -1
5985#define EOPNOTSUPP -1
5986#define ECANCELED -1
5987#endif
5988
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08005989/**
5990 * wpas_rrm_send_neighbor_rep_request - Request a neighbor report from our AP
5991 * @wpa_s: Pointer to wpa_supplicant
5992 * @ssid: if not null, this is sent in the request. Otherwise, no SSID IE
5993 * is sent in the request.
5994 * @cb: Callback function to be called once the requested report arrives, or
5995 * timed out after RRM_NEIGHBOR_REPORT_TIMEOUT seconds.
5996 * In the former case, 'neighbor_rep' is a newly allocated wpabuf, and it's
5997 * the requester's responsibility to free it.
5998 * In the latter case NULL will be sent in 'neighbor_rep'.
5999 * @cb_ctx: Context value to send the callback function
6000 * Returns: 0 in case of success, negative error code otherwise
6001 *
6002 * In case there is a previous request which has not been answered yet, the
6003 * new request fails. The caller may retry after RRM_NEIGHBOR_REPORT_TIMEOUT.
6004 * Request must contain a callback function.
6005 */
6006int wpas_rrm_send_neighbor_rep_request(struct wpa_supplicant *wpa_s,
6007 const struct wpa_ssid *ssid,
6008 void (*cb)(void *ctx,
6009 struct wpabuf *neighbor_rep),
6010 void *cb_ctx)
6011{
6012 struct wpabuf *buf;
6013 const u8 *rrm_ie;
6014
6015 if (wpa_s->wpa_state != WPA_COMPLETED || wpa_s->current_ssid == NULL) {
6016 wpa_printf(MSG_DEBUG, "RRM: No connection, no RRM.");
6017 return -ENOTCONN;
6018 }
6019
6020 if (!wpa_s->rrm.rrm_used) {
6021 wpa_printf(MSG_DEBUG, "RRM: No RRM in current connection.");
6022 return -EOPNOTSUPP;
6023 }
6024
6025 rrm_ie = wpa_bss_get_ie(wpa_s->current_bss,
6026 WLAN_EID_RRM_ENABLED_CAPABILITIES);
6027 if (!rrm_ie || !(wpa_s->current_bss->caps & IEEE80211_CAP_RRM) ||
6028 !(rrm_ie[2] & WLAN_RRM_CAPS_NEIGHBOR_REPORT)) {
6029 wpa_printf(MSG_DEBUG,
6030 "RRM: No network support for Neighbor Report.");
6031 return -EOPNOTSUPP;
6032 }
6033
6034 if (!cb) {
6035 wpa_printf(MSG_DEBUG,
6036 "RRM: Neighbor Report request must provide a callback.");
6037 return -EINVAL;
6038 }
6039
6040 /* Refuse if there's a live request */
6041 if (wpa_s->rrm.notify_neighbor_rep) {
6042 wpa_printf(MSG_DEBUG,
6043 "RRM: Currently handling previous Neighbor Report.");
6044 return -EBUSY;
6045 }
6046
6047 /* 3 = action category + action code + dialog token */
6048 buf = wpabuf_alloc(3 + (ssid ? 2 + ssid->ssid_len : 0));
6049 if (buf == NULL) {
6050 wpa_printf(MSG_DEBUG,
6051 "RRM: Failed to allocate Neighbor Report Request");
6052 return -ENOMEM;
6053 }
6054
6055 wpa_printf(MSG_DEBUG, "RRM: Neighbor report request (for %s), token=%d",
6056 (ssid ? wpa_ssid_txt(ssid->ssid, ssid->ssid_len) : ""),
6057 wpa_s->rrm.next_neighbor_rep_token);
6058
6059 wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT);
6060 wpabuf_put_u8(buf, WLAN_RRM_NEIGHBOR_REPORT_REQUEST);
6061 wpabuf_put_u8(buf, wpa_s->rrm.next_neighbor_rep_token);
6062 if (ssid) {
6063 wpabuf_put_u8(buf, WLAN_EID_SSID);
6064 wpabuf_put_u8(buf, ssid->ssid_len);
6065 wpabuf_put_data(buf, ssid->ssid, ssid->ssid_len);
6066 }
6067
6068 wpa_s->rrm.next_neighbor_rep_token++;
6069
6070 if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
6071 wpa_s->own_addr, wpa_s->bssid,
6072 wpabuf_head(buf), wpabuf_len(buf), 0) < 0) {
6073 wpa_printf(MSG_DEBUG,
6074 "RRM: Failed to send Neighbor Report Request");
6075 wpabuf_free(buf);
6076 return -ECANCELED;
6077 }
6078
6079 wpa_s->rrm.neighbor_rep_cb_ctx = cb_ctx;
6080 wpa_s->rrm.notify_neighbor_rep = cb;
6081 eloop_register_timeout(RRM_NEIGHBOR_REPORT_TIMEOUT, 0,
6082 wpas_rrm_neighbor_rep_timeout_handler,
6083 &wpa_s->rrm, NULL);
6084
6085 wpabuf_free(buf);
6086 return 0;
6087}
6088
6089
6090void wpas_rrm_handle_link_measurement_request(struct wpa_supplicant *wpa_s,
6091 const u8 *src,
6092 const u8 *frame, size_t len,
6093 int rssi)
6094{
6095 struct wpabuf *buf;
6096 const struct rrm_link_measurement_request *req;
6097 struct rrm_link_measurement_report report;
6098
6099 if (wpa_s->wpa_state != WPA_COMPLETED) {
6100 wpa_printf(MSG_INFO,
6101 "RRM: Ignoring link measurement request. Not associated");
6102 return;
6103 }
6104
6105 if (!wpa_s->rrm.rrm_used) {
6106 wpa_printf(MSG_INFO,
6107 "RRM: Ignoring link measurement request. Not RRM network");
6108 return;
6109 }
6110
6111 if (!(wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_TX_POWER_INSERTION)) {
6112 wpa_printf(MSG_INFO,
6113 "RRM: Measurement report failed. TX power insertion not supported");
6114 return;
6115 }
6116
6117 req = (const struct rrm_link_measurement_request *) frame;
6118 if (len < sizeof(*req)) {
6119 wpa_printf(MSG_INFO,
6120 "RRM: Link measurement report failed. Request too short");
6121 return;
6122 }
6123
6124 os_memset(&report, 0, sizeof(report));
6125 report.tpc.eid = WLAN_EID_TPC_REPORT;
6126 report.tpc.len = 2;
6127 report.rsni = 255; /* 255 indicates that RSNI is not available */
6128 report.dialog_token = req->dialog_token;
6129
6130 /*
6131 * It's possible to estimate RCPI based on RSSI in dBm. This
6132 * calculation will not reflect the correct value for high rates,
6133 * but it's good enough for Action frames which are transmitted
6134 * with up to 24 Mbps rates.
6135 */
6136 if (!rssi)
6137 report.rcpi = 255; /* not available */
6138 else if (rssi < -110)
6139 report.rcpi = 0;
6140 else if (rssi > 0)
6141 report.rcpi = 220;
6142 else
6143 report.rcpi = (rssi + 110) * 2;
6144
6145 /* action_category + action_code */
6146 buf = wpabuf_alloc(2 + sizeof(report));
6147 if (buf == NULL) {
6148 wpa_printf(MSG_ERROR,
6149 "RRM: Link measurement report failed. Buffer allocation failed");
6150 return;
6151 }
6152
6153 wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT);
6154 wpabuf_put_u8(buf, WLAN_RRM_LINK_MEASUREMENT_REPORT);
6155 wpabuf_put_data(buf, &report, sizeof(report));
6156 wpa_hexdump(MSG_DEBUG, "RRM: Link measurement report:",
6157 wpabuf_head(buf), wpabuf_len(buf));
6158
6159 if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, src,
6160 wpa_s->own_addr, wpa_s->bssid,
6161 wpabuf_head(buf), wpabuf_len(buf), 0)) {
6162 wpa_printf(MSG_ERROR,
6163 "RRM: Link measurement report failed. Send action failed");
6164 }
6165 wpabuf_free(buf);
6166}
Dmitry Shmidt55840ad2015-12-14 12:45:46 -08006167
6168
6169struct wpa_supplicant *
6170wpas_vendor_elem(struct wpa_supplicant *wpa_s, enum wpa_vendor_elem_frame frame)
6171{
6172 switch (frame) {
6173#ifdef CONFIG_P2P
6174 case VENDOR_ELEM_PROBE_REQ_P2P:
6175 case VENDOR_ELEM_PROBE_RESP_P2P:
6176 case VENDOR_ELEM_PROBE_RESP_P2P_GO:
6177 case VENDOR_ELEM_BEACON_P2P_GO:
6178 case VENDOR_ELEM_P2P_PD_REQ:
6179 case VENDOR_ELEM_P2P_PD_RESP:
6180 case VENDOR_ELEM_P2P_GO_NEG_REQ:
6181 case VENDOR_ELEM_P2P_GO_NEG_RESP:
6182 case VENDOR_ELEM_P2P_GO_NEG_CONF:
6183 case VENDOR_ELEM_P2P_INV_REQ:
6184 case VENDOR_ELEM_P2P_INV_RESP:
6185 case VENDOR_ELEM_P2P_ASSOC_REQ:
6186 case VENDOR_ELEM_P2P_ASSOC_RESP:
6187 return wpa_s->parent;
6188#endif /* CONFIG_P2P */
6189 default:
6190 return wpa_s;
6191 }
6192}
6193
6194
6195void wpas_vendor_elem_update(struct wpa_supplicant *wpa_s)
6196{
6197 unsigned int i;
6198 char buf[30];
6199
6200 wpa_printf(MSG_DEBUG, "Update vendor elements");
6201
6202 for (i = 0; i < NUM_VENDOR_ELEM_FRAMES; i++) {
6203 if (wpa_s->vendor_elem[i]) {
6204 int res;
6205
6206 res = os_snprintf(buf, sizeof(buf), "frame[%u]", i);
6207 if (!os_snprintf_error(sizeof(buf), res)) {
6208 wpa_hexdump_buf(MSG_DEBUG, buf,
6209 wpa_s->vendor_elem[i]);
6210 }
6211 }
6212 }
6213
6214#ifdef CONFIG_P2P
6215 if (wpa_s->parent == wpa_s &&
6216 wpa_s->global->p2p &&
6217 !wpa_s->global->p2p_disabled)
6218 p2p_set_vendor_elems(wpa_s->global->p2p, wpa_s->vendor_elem);
6219#endif /* CONFIG_P2P */
6220}
6221
6222
6223int wpas_vendor_elem_remove(struct wpa_supplicant *wpa_s, int frame,
6224 const u8 *elem, size_t len)
6225{
6226 u8 *ie, *end;
6227
6228 ie = wpabuf_mhead_u8(wpa_s->vendor_elem[frame]);
6229 end = ie + wpabuf_len(wpa_s->vendor_elem[frame]);
6230
6231 for (; ie + 1 < end; ie += 2 + ie[1]) {
6232 if (ie + len > end)
6233 break;
6234 if (os_memcmp(ie, elem, len) != 0)
6235 continue;
6236
6237 if (wpabuf_len(wpa_s->vendor_elem[frame]) == len) {
6238 wpabuf_free(wpa_s->vendor_elem[frame]);
6239 wpa_s->vendor_elem[frame] = NULL;
6240 } else {
6241 os_memmove(ie, ie + len, end - (ie + len));
6242 wpa_s->vendor_elem[frame]->used -= len;
6243 }
6244 wpas_vendor_elem_update(wpa_s);
6245 return 0;
6246 }
6247
6248 return -1;
6249}