]> git.ipfire.org Git - thirdparty/hostap.git/blame - wpa_supplicant/wpa_supplicant.c
D-Bus: Add GroupMgmt entry into the interface Capabilities dict
[thirdparty/hostap.git] / wpa_supplicant / wpa_supplicant.c
CommitLineData
6fc6879b
JM
1/*
2 * WPA Supplicant
6774c6a9 3 * Copyright (c) 2003-2017, Jouni Malinen <j@w1.fi>
6fc6879b 4 *
0f3d578e
JM
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
6fc6879b
JM
7 *
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"
2e997eec
RM
14#ifdef CONFIG_MATCH_IFACE
15#include <net/if.h>
16#include <fnmatch.h>
17#endif /* CONFIG_MATCH_IFACE */
6fc6879b
JM
18
19#include "common.h"
d47fa330 20#include "crypto/random.h"
7d232e23 21#include "crypto/sha1.h"
6fc6879b
JM
22#include "eapol_supp/eapol_supp_sm.h"
23#include "eap_peer/eap.h"
ec7b97ab 24#include "eap_peer/eap_proxy.h"
3ec97afe 25#include "eap_server/eap_methods.h"
3acb5005 26#include "rsn_supp/wpa.h"
6fc6879b 27#include "eloop.h"
6fc6879b 28#include "config.h"
306ae225 29#include "utils/ext_password.h"
6fc6879b
JM
30#include "l2_packet/l2_packet.h"
31#include "wpa_supplicant_i.h"
2d5b792d 32#include "driver_i.h"
6fc6879b 33#include "ctrl_iface.h"
6fc6879b 34#include "pcsc_funcs.h"
90973fb2 35#include "common/version.h"
3acb5005
JM
36#include "rsn_supp/preauth.h"
37#include "rsn_supp/pmksa_cache.h"
90973fb2 38#include "common/wpa_ctrl.h"
90973fb2 39#include "common/ieee802_11_defs.h"
6b8b0774 40#include "common/hw_features_common.h"
72044390 41#include "p2p/p2p.h"
b36a3a65 42#include "fst/fst.h"
6fc6879b
JM
43#include "blacklist.h"
44#include "wpas_glue.h"
116654ce 45#include "wps_supplicant.h"
11ef8d35 46#include "ibss_rsn.h"
c2a04078 47#include "sme.h"
04ea7b79 48#include "gas_query.h"
1f1b62a0 49#include "ap.h"
b22128ef 50#include "p2p_supplicant.h"
9675ce35 51#include "wifi_display.h"
8bac466b 52#include "notify.h"
60b94c98 53#include "bgscan.h"
7c865c68 54#include "autoscan.h"
83922c2d 55#include "bss.h"
9ba9fa07 56#include "scan.h"
24f6497c 57#include "offchannel.h"
cb418324 58#include "hs20_supplicant.h"
e27d20bb 59#include "wnm_sta.h"
dd10abcc 60#include "wpas_kay.h"
603a3f34 61#include "mesh.h"
6fc6879b 62
8b423edb 63const char *const wpa_supplicant_version =
6fc6879b 64"wpa_supplicant v" VERSION_STR "\n"
6774c6a9 65"Copyright (c) 2003-2017, Jouni Malinen <j@w1.fi> and contributors";
6fc6879b 66
8b423edb 67const char *const wpa_supplicant_license =
331f89ff
JM
68"This software may be distributed under the terms of the BSD license.\n"
69"See README for more details.\n"
6fc6879b
JM
70#ifdef EAP_TLS_OPENSSL
71"\nThis product includes software developed by the OpenSSL Project\n"
72"for use in the OpenSSL Toolkit (http://www.openssl.org/)\n"
73#endif /* EAP_TLS_OPENSSL */
74;
75
76#ifndef CONFIG_NO_STDOUT_DEBUG
77/* Long text divided into parts in order to fit in C89 strings size limits. */
8b423edb 78const char *const wpa_supplicant_full_license1 =
331f89ff 79"";
8b423edb 80const char *const wpa_supplicant_full_license2 =
331f89ff 81"This software may be distributed under the terms of the BSD license.\n"
6fc6879b
JM
82"\n"
83"Redistribution and use in source and binary forms, with or without\n"
84"modification, are permitted provided that the following conditions are\n"
85"met:\n"
86"\n";
8b423edb 87const char *const wpa_supplicant_full_license3 =
6fc6879b
JM
88"1. Redistributions of source code must retain the above copyright\n"
89" notice, this list of conditions and the following disclaimer.\n"
90"\n"
91"2. Redistributions in binary form must reproduce the above copyright\n"
92" notice, this list of conditions and the following disclaimer in the\n"
93" documentation and/or other materials provided with the distribution.\n"
94"\n";
8b423edb 95const char *const wpa_supplicant_full_license4 =
6fc6879b
JM
96"3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
97" names of its contributors may be used to endorse or promote products\n"
98" derived from this software without specific prior written permission.\n"
99"\n"
100"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
101"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
102"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
103"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n";
8b423edb 104const char *const wpa_supplicant_full_license5 =
6fc6879b
JM
105"OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
106"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
107"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
108"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
109"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
110"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
111"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
112"\n";
113#endif /* CONFIG_NO_STDOUT_DEBUG */
114
6fc6879b 115/* Configure default/group WEP keys for static WEP */
0194fedb 116int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
6fc6879b
JM
117{
118 int i, set = 0;
119
120 for (i = 0; i < NUM_WEP_KEYS; i++) {
121 if (ssid->wep_key_len[i] == 0)
122 continue;
123
124 set = 1;
0382097e 125 wpa_drv_set_key(wpa_s, WPA_ALG_WEP, NULL,
da64c266 126 i, i == ssid->wep_tx_keyidx, NULL, 0,
6fc6879b
JM
127 ssid->wep_key[i], ssid->wep_key_len[i]);
128 }
129
130 return set;
131}
132
133
6ea1f413
JM
134int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s,
135 struct wpa_ssid *ssid)
6fc6879b
JM
136{
137 u8 key[32];
138 size_t keylen;
71934751 139 enum wpa_alg alg;
6fc6879b 140 u8 seq[6] = { 0 };
658da804 141 int ret;
6fc6879b
JM
142
143 /* IBSS/WPA-None uses only one key (Group) for both receiving and
144 * sending unicast and multicast packets. */
145
d7dcba70 146 if (ssid->mode != WPAS_MODE_IBSS) {
f049052b
BG
147 wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid mode %d (not "
148 "IBSS/ad-hoc) for WPA-None", ssid->mode);
6fc6879b
JM
149 return -1;
150 }
151
152 if (!ssid->psk_set) {
f049052b
BG
153 wpa_msg(wpa_s, MSG_INFO, "WPA: No PSK configured for "
154 "WPA-None");
6fc6879b
JM
155 return -1;
156 }
157
158 switch (wpa_s->group_cipher) {
159 case WPA_CIPHER_CCMP:
160 os_memcpy(key, ssid->psk, 16);
161 keylen = 16;
162 alg = WPA_ALG_CCMP;
163 break;
eb7719ff
JM
164 case WPA_CIPHER_GCMP:
165 os_memcpy(key, ssid->psk, 16);
166 keylen = 16;
167 alg = WPA_ALG_GCMP;
168 break;
6fc6879b
JM
169 case WPA_CIPHER_TKIP:
170 /* WPA-None uses the same Michael MIC key for both TX and RX */
171 os_memcpy(key, ssid->psk, 16 + 8);
172 os_memcpy(key + 16 + 8, ssid->psk + 16, 8);
173 keylen = 32;
174 alg = WPA_ALG_TKIP;
175 break;
176 default:
f049052b
BG
177 wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid group cipher %d for "
178 "WPA-None", wpa_s->group_cipher);
6fc6879b
JM
179 return -1;
180 }
181
182 /* TODO: should actually remember the previously used seq#, both for TX
183 * and RX from each STA.. */
184
658da804
JM
185 ret = wpa_drv_set_key(wpa_s, alg, NULL, 0, 1, seq, 6, key, keylen);
186 os_memset(key, 0, sizeof(key));
187 return ret;
6fc6879b
JM
188}
189
190
191static void wpa_supplicant_timeout(void *eloop_ctx, void *timeout_ctx)
192{
193 struct wpa_supplicant *wpa_s = eloop_ctx;
194 const u8 *bssid = wpa_s->bssid;
04e3d815
MK
195 if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
196 (wpa_s->wpa_state == WPA_AUTHENTICATING ||
197 wpa_s->wpa_state == WPA_ASSOCIATING))
6fc6879b
JM
198 bssid = wpa_s->pending_bssid;
199 wpa_msg(wpa_s, MSG_INFO, "Authentication with " MACSTR " timed out.",
200 MAC2STR(bssid));
201 wpa_blacklist_add(wpa_s, bssid);
202 wpa_sm_notify_disassoc(wpa_s->wpa);
07783eaa 203 wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
6fc6879b 204 wpa_s->reassociate = 1;
48b84f18
BG
205
206 /*
207 * If we timed out, the AP or the local radio may be busy.
208 * So, wait a second until scanning again.
209 */
210 wpa_supplicant_req_scan(wpa_s, 1, 0);
6fc6879b
JM
211}
212
213
214/**
215 * wpa_supplicant_req_auth_timeout - Schedule a timeout for authentication
216 * @wpa_s: Pointer to wpa_supplicant data
217 * @sec: Number of seconds after which to time out authentication
218 * @usec: Number of microseconds after which to time out authentication
219 *
220 * This function is used to schedule a timeout for the current authentication
221 * attempt.
222 */
223void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s,
224 int sec, int usec)
225{
a2a535f8 226 if (wpa_s->conf->ap_scan == 0 &&
c2a04078 227 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED))
6fc6879b
JM
228 return;
229
f049052b 230 wpa_dbg(wpa_s, MSG_DEBUG, "Setting authentication timeout: %d sec "
6fc6879b
JM
231 "%d usec", sec, usec);
232 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
233 eloop_register_timeout(sec, usec, wpa_supplicant_timeout, wpa_s, NULL);
234}
235
236
237/**
238 * wpa_supplicant_cancel_auth_timeout - Cancel authentication timeout
239 * @wpa_s: Pointer to wpa_supplicant data
240 *
241 * This function is used to cancel authentication timeout scheduled with
242 * wpa_supplicant_req_auth_timeout() and it is called when authentication has
243 * been completed.
244 */
245void wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *wpa_s)
246{
f049052b 247 wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling authentication timeout");
6fc6879b
JM
248 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
249 wpa_blacklist_del(wpa_s, wpa_s->bssid);
250}
251
252
253/**
254 * wpa_supplicant_initiate_eapol - Configure EAPOL state machine
255 * @wpa_s: Pointer to wpa_supplicant data
256 *
257 * This function is used to configure EAPOL state machine based on the selected
258 * authentication mode.
259 */
260void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
261{
262#ifdef IEEE8021X_EAPOL
263 struct eapol_config eapol_conf;
264 struct wpa_ssid *ssid = wpa_s->current_ssid;
265
53895c3b 266#ifdef CONFIG_IBSS_RSN
d7dcba70 267 if (ssid->mode == WPAS_MODE_IBSS &&
53895c3b
JM
268 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
269 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
270 /*
271 * RSN IBSS authentication is per-STA and we can disable the
272 * per-BSSID EAPOL authentication.
273 */
274 eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
275 eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
276 eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
277 return;
278 }
279#endif /* CONFIG_IBSS_RSN */
280
0a40ec6a
JM
281 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
282 eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
283
6fc6879b
JM
284 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
285 wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
286 eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
287 else
288 eapol_sm_notify_portControl(wpa_s->eapol, Auto);
289
290 os_memset(&eapol_conf, 0, sizeof(eapol_conf));
291 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
292 eapol_conf.accept_802_1x_keys = 1;
293 eapol_conf.required_keys = 0;
294 if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_UNICAST) {
295 eapol_conf.required_keys |= EAPOL_REQUIRE_KEY_UNICAST;
296 }
297 if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_BROADCAST) {
298 eapol_conf.required_keys |=
299 EAPOL_REQUIRE_KEY_BROADCAST;
300 }
301
a2a535f8 302 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED)
6fc6879b 303 eapol_conf.required_keys = 0;
6fc6879b 304 }
a2a535f8 305 eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
6fc6879b 306 eapol_conf.workaround = ssid->eap_workaround;
56586197
JM
307 eapol_conf.eap_disabled =
308 !wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) &&
ad08c363
JM
309 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
310 wpa_s->key_mgmt != WPA_KEY_MGMT_WPS;
a5d44ac0 311 eapol_conf.external_sim = wpa_s->conf->external_sim;
3f7ac058
JS
312
313#ifdef CONFIG_WPS
314 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) {
315 eapol_conf.wps |= EAPOL_LOCAL_WPS_IN_USE;
316 if (wpa_s->current_bss) {
317 struct wpabuf *ie;
318 ie = wpa_bss_get_vendor_ie_multi(wpa_s->current_bss,
319 WPS_IE_VENDOR_TYPE);
320 if (ie) {
321 if (wps_is_20(ie))
322 eapol_conf.wps |=
323 EAPOL_PEER_IS_WPS20_AP;
324 wpabuf_free(ie);
325 }
326 }
327 }
328#endif /* CONFIG_WPS */
329
6fc6879b 330 eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
dd10abcc 331
ad51731a
SD
332#ifdef CONFIG_MACSEC
333 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE && ssid->mka_psk_set)
334 ieee802_1x_create_preshared_mka(wpa_s, ssid);
335 else
336 ieee802_1x_alloc_kay_sm(wpa_s, ssid);
337#endif /* CONFIG_MACSEC */
cd3153a9 338#endif /* IEEE8021X_EAPOL */
6fc6879b
JM
339}
340
341
342/**
343 * wpa_supplicant_set_non_wpa_policy - Set WPA parameters to non-WPA mode
344 * @wpa_s: Pointer to wpa_supplicant data
345 * @ssid: Configuration data for the network
346 *
347 * This function is used to configure WPA state machine and related parameters
348 * to a mode where WPA is not enabled. This is called as part of the
349 * authentication configuration when the selected network does not use WPA.
350 */
351void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
352 struct wpa_ssid *ssid)
353{
354 int i;
355
ad08c363
JM
356 if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
357 wpa_s->key_mgmt = WPA_KEY_MGMT_WPS;
358 else if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)
6fc6879b
JM
359 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_NO_WPA;
360 else
361 wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
362 wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
363 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
364 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
365 wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
366 wpa_s->group_cipher = WPA_CIPHER_NONE;
367 wpa_s->mgmt_group_cipher = 0;
368
369 for (i = 0; i < NUM_WEP_KEYS; i++) {
370 if (ssid->wep_key_len[i] > 5) {
371 wpa_s->pairwise_cipher = WPA_CIPHER_WEP104;
372 wpa_s->group_cipher = WPA_CIPHER_WEP104;
373 break;
374 } else if (ssid->wep_key_len[i] > 0) {
375 wpa_s->pairwise_cipher = WPA_CIPHER_WEP40;
376 wpa_s->group_cipher = WPA_CIPHER_WEP40;
377 break;
378 }
379 }
380
381 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED, 0);
382 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
383 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
384 wpa_s->pairwise_cipher);
385 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
386#ifdef CONFIG_IEEE80211W
387 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
388 wpa_s->mgmt_group_cipher);
389#endif /* CONFIG_IEEE80211W */
390
391 pmksa_cache_clear_current(wpa_s->wpa);
392}
393
394
6979582c 395void free_hw_features(struct wpa_supplicant *wpa_s)
6bf731e8
CL
396{
397 int i;
398 if (wpa_s->hw.modes == NULL)
399 return;
400
401 for (i = 0; i < wpa_s->hw.num_modes; i++) {
402 os_free(wpa_s->hw.modes[i].channels);
403 os_free(wpa_s->hw.modes[i].rates);
404 }
405
406 os_free(wpa_s->hw.modes);
407 wpa_s->hw.modes = NULL;
408}
409
410
dd599908
AS
411static void free_bss_tmp_disallowed(struct wpa_supplicant *wpa_s)
412{
413 struct wpa_bss_tmp_disallowed *bss, *prev;
414
415 dl_list_for_each_safe(bss, prev, &wpa_s->bss_tmp_disallowed,
416 struct wpa_bss_tmp_disallowed, list) {
417 dl_list_del(&bss->list);
418 os_free(bss);
419 }
420}
421
422
6fc6879b
JM
423static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
424{
86bd36f0
JM
425 int i;
426
60b94c98 427 bgscan_deinit(wpa_s);
7c865c68 428 autoscan_deinit(wpa_s);
6fc6879b
JM
429 scard_deinit(wpa_s->scard);
430 wpa_s->scard = NULL;
431 wpa_sm_set_scard_ctx(wpa_s->wpa, NULL);
432 eapol_sm_register_scard_ctx(wpa_s->eapol, NULL);
433 l2_packet_deinit(wpa_s->l2);
434 wpa_s->l2 = NULL;
435 if (wpa_s->l2_br) {
436 l2_packet_deinit(wpa_s->l2_br);
437 wpa_s->l2_br = NULL;
438 }
4a6cc862
JM
439#ifdef CONFIG_TESTING_OPTIONS
440 l2_packet_deinit(wpa_s->l2_test);
441 wpa_s->l2_test = NULL;
442#endif /* CONFIG_TESTING_OPTIONS */
6fc6879b 443
6fc6879b 444 if (wpa_s->conf != NULL) {
8e56d189
JM
445 struct wpa_ssid *ssid;
446 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
447 wpas_notify_network_removed(wpa_s, ssid);
6fc6879b
JM
448 }
449
450 os_free(wpa_s->confname);
451 wpa_s->confname = NULL;
452
e6304cad
DS
453 os_free(wpa_s->confanother);
454 wpa_s->confanother = NULL;
455
6fc6879b
JM
456 wpa_sm_set_eapol(wpa_s->wpa, NULL);
457 eapol_sm_deinit(wpa_s->eapol);
458 wpa_s->eapol = NULL;
459
460 rsn_preauth_deinit(wpa_s->wpa);
461
281ff0aa
GP
462#ifdef CONFIG_TDLS
463 wpa_tdls_deinit(wpa_s->wpa);
464#endif /* CONFIG_TDLS */
465
8c42b369 466 wmm_ac_clear_saved_tspecs(wpa_s);
6fc6879b
JM
467 pmksa_candidate_free(wpa_s->wpa);
468 wpa_sm_deinit(wpa_s->wpa);
469 wpa_s->wpa = NULL;
470 wpa_blacklist_clear(wpa_s);
471
83922c2d 472 wpa_bss_deinit(wpa_s);
6fc6879b 473
831770bf 474 wpa_supplicant_cancel_delayed_sched_scan(wpa_s);
6fc6879b
JM
475 wpa_supplicant_cancel_scan(wpa_s);
476 wpa_supplicant_cancel_auth_timeout(wpa_s);
01a17491
JM
477 eloop_cancel_timeout(wpa_supplicant_stop_countermeasures, wpa_s, NULL);
478#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
479 eloop_cancel_timeout(wpa_supplicant_delayed_mic_error_report,
480 wpa_s, NULL);
481#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
6fc6879b 482
9bd566a3
AS
483 eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
484
116654ce 485 wpas_wps_deinit(wpa_s);
11ef8d35 486
1ff73338
JM
487 wpabuf_free(wpa_s->pending_eapol_rx);
488 wpa_s->pending_eapol_rx = NULL;
489
11ef8d35
JM
490#ifdef CONFIG_IBSS_RSN
491 ibss_rsn_deinit(wpa_s->ibss_rsn);
492 wpa_s->ibss_rsn = NULL;
493#endif /* CONFIG_IBSS_RSN */
c2a04078 494
e29853bb 495 sme_deinit(wpa_s);
2d5b792d
JM
496
497#ifdef CONFIG_AP
498 wpa_supplicant_ap_deinit(wpa_s);
499#endif /* CONFIG_AP */
b22128ef 500
b22128ef 501 wpas_p2p_deinit(wpa_s);
f47d639d 502
24f6497c
JM
503#ifdef CONFIG_OFFCHANNEL
504 offchannel_deinit(wpa_s);
505#endif /* CONFIG_OFFCHANNEL */
506
a4cba8f1
LC
507 wpa_supplicant_cancel_sched_scan(wpa_s);
508
f47d639d
JM
509 os_free(wpa_s->next_scan_freqs);
510 wpa_s->next_scan_freqs = NULL;
fee52342
JM
511
512 os_free(wpa_s->manual_scan_freqs);
513 wpa_s->manual_scan_freqs = NULL;
04ea7b79 514
d3c9c35f
DS
515 os_free(wpa_s->manual_sched_scan_freqs);
516 wpa_s->manual_sched_scan_freqs = NULL;
517
56c76fa5
IP
518 wpas_mac_addr_rand_scan_clear(wpa_s, MAC_ADDR_RAND_ALL);
519
57e832de
IP
520 /*
521 * Need to remove any pending gas-query radio work before the
522 * gas_query_deinit() call because gas_query::work has not yet been set
523 * for works that have not been started. gas_query_free() will be unable
524 * to cancel such pending radio works and once the pending gas-query
525 * radio work eventually gets removed, the deinit notification call to
526 * gas_query_start_cb() would result in dereferencing freed memory.
527 */
528 if (wpa_s->radio)
529 radio_remove_works(wpa_s, "gas-query", 0);
04ea7b79
JM
530 gas_query_deinit(wpa_s->gas);
531 wpa_s->gas = NULL;
6bf731e8
CL
532
533 free_hw_features(wpa_s);
d445a5cd 534
dd10abcc
HW
535 ieee802_1x_dealloc_kay_sm(wpa_s);
536
d445a5cd
JM
537 os_free(wpa_s->bssid_filter);
538 wpa_s->bssid_filter = NULL;
b6668734 539
6407f413
JM
540 os_free(wpa_s->disallow_aps_bssid);
541 wpa_s->disallow_aps_bssid = NULL;
542 os_free(wpa_s->disallow_aps_ssid);
543 wpa_s->disallow_aps_ssid = NULL;
544
b6668734 545 wnm_bss_keep_alive_deinit(wpa_s);
e27d20bb
VK
546#ifdef CONFIG_WNM
547 wnm_deallocate_memory(wpa_s);
548#endif /* CONFIG_WNM */
306ae225
JM
549
550 ext_password_deinit(wpa_s->ext_pw);
551 wpa_s->ext_pw = NULL;
b1f12296
JM
552
553 wpabuf_free(wpa_s->last_gas_resp);
b6a9590b
JM
554 wpa_s->last_gas_resp = NULL;
555 wpabuf_free(wpa_s->prev_gas_resp);
556 wpa_s->prev_gas_resp = NULL;
a297201d
JM
557
558 os_free(wpa_s->last_scan_res);
559 wpa_s->last_scan_res = NULL;
b572df86
JM
560
561#ifdef CONFIG_HS20
ece4ac5f
MG
562 if (wpa_s->drv_priv)
563 wpa_drv_configure_frame_filters(wpa_s, 0);
fb2ac53d 564 hs20_deinit(wpa_s);
b572df86 565#endif /* CONFIG_HS20 */
86bd36f0
JM
566
567 for (i = 0; i < NUM_VENDOR_ELEM_FRAMES; i++) {
568 wpabuf_free(wpa_s->vendor_elem[i]);
569 wpa_s->vendor_elem[i] = NULL;
570 }
3882a708
JM
571
572 wmm_ac_notify_disassoc(wpa_s);
32c02261
AS
573
574 wpa_s->sched_scan_plans_num = 0;
575 os_free(wpa_s->sched_scan_plans);
576 wpa_s->sched_scan_plans = NULL;
92c6e2e3
DS
577
578#ifdef CONFIG_MBO
579 wpa_s->non_pref_chan_num = 0;
580 os_free(wpa_s->non_pref_chan);
581 wpa_s->non_pref_chan = NULL;
582#endif /* CONFIG_MBO */
dd599908
AS
583
584 free_bss_tmp_disallowed(wpa_s);
4a742011
DS
585
586 wpabuf_free(wpa_s->lci);
587 wpa_s->lci = NULL;
76196ddb 588 wpas_clear_beacon_rep_data(wpa_s);
6fc6879b
JM
589}
590
591
592/**
593 * wpa_clear_keys - Clear keys configured for the driver
594 * @wpa_s: Pointer to wpa_supplicant data
595 * @addr: Previously used BSSID or %NULL if not available
596 *
597 * This function clears the encryption keys that has been previously configured
598 * for the driver.
599 */
600void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr)
601{
2f30cac3 602 int i, max;
6fc6879b 603
0e27f655 604#ifdef CONFIG_IEEE80211W
2f30cac3
JM
605 max = 6;
606#else /* CONFIG_IEEE80211W */
607 max = 4;
0e27f655 608#endif /* CONFIG_IEEE80211W */
2f30cac3
JM
609
610 /* MLME-DELETEKEYS.request */
611 for (i = 0; i < max; i++) {
612 if (wpa_s->keys_cleared & BIT(i))
613 continue;
614 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, i, 0, NULL, 0,
615 NULL, 0);
616 }
617 if (!(wpa_s->keys_cleared & BIT(0)) && addr &&
618 !is_zero_ether_addr(addr)) {
6fc6879b
JM
619 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, addr, 0, 0, NULL, 0, NULL,
620 0);
621 /* MLME-SETPROTECTION.request(None) */
622 wpa_drv_mlme_setprotection(
623 wpa_s, addr,
624 MLME_SETPROTECTION_PROTECT_TYPE_NONE,
625 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
626 }
2f30cac3 627 wpa_s->keys_cleared = (u32) -1;
6fc6879b
JM
628}
629
630
631/**
632 * wpa_supplicant_state_txt - Get the connection state name as a text string
633 * @state: State (wpa_state; WPA_*)
634 * Returns: The state name as a printable text string
635 */
71934751 636const char * wpa_supplicant_state_txt(enum wpa_states state)
6fc6879b
JM
637{
638 switch (state) {
639 case WPA_DISCONNECTED:
640 return "DISCONNECTED";
641 case WPA_INACTIVE:
642 return "INACTIVE";
8401a6b0
JM
643 case WPA_INTERFACE_DISABLED:
644 return "INTERFACE_DISABLED";
6fc6879b
JM
645 case WPA_SCANNING:
646 return "SCANNING";
c2a04078
JM
647 case WPA_AUTHENTICATING:
648 return "AUTHENTICATING";
6fc6879b
JM
649 case WPA_ASSOCIATING:
650 return "ASSOCIATING";
651 case WPA_ASSOCIATED:
652 return "ASSOCIATED";
653 case WPA_4WAY_HANDSHAKE:
654 return "4WAY_HANDSHAKE";
655 case WPA_GROUP_HANDSHAKE:
656 return "GROUP_HANDSHAKE";
657 case WPA_COMPLETED:
658 return "COMPLETED";
659 default:
660 return "UNKNOWN";
661 }
662}
663
664
cfe53c9a
PS
665#ifdef CONFIG_BGSCAN
666
667static void wpa_supplicant_start_bgscan(struct wpa_supplicant *wpa_s)
668{
31392709
HD
669 const char *name;
670
671 if (wpa_s->current_ssid && wpa_s->current_ssid->bgscan)
672 name = wpa_s->current_ssid->bgscan;
673 else
674 name = wpa_s->conf->bgscan;
268043d5 675 if (name == NULL || name[0] == '\0')
31392709 676 return;
0096c427
JM
677 if (wpas_driver_bss_selection(wpa_s))
678 return;
cfe53c9a
PS
679 if (wpa_s->current_ssid == wpa_s->bgscan_ssid)
680 return;
aa109830
DS
681#ifdef CONFIG_P2P
682 if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE)
683 return;
684#endif /* CONFIG_P2P */
cfe53c9a
PS
685
686 bgscan_deinit(wpa_s);
31392709
HD
687 if (wpa_s->current_ssid) {
688 if (bgscan_init(wpa_s, wpa_s->current_ssid, name)) {
cfe53c9a
PS
689 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
690 "bgscan");
691 /*
692 * Live without bgscan; it is only used as a roaming
693 * optimization, so the initial connection is not
694 * affected.
695 */
6409b7a7
YD
696 } else {
697 struct wpa_scan_results *scan_res;
cfe53c9a 698 wpa_s->bgscan_ssid = wpa_s->current_ssid;
6409b7a7
YD
699 scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL,
700 0);
701 if (scan_res) {
702 bgscan_notify_scan(wpa_s, scan_res);
703 wpa_scan_results_free(scan_res);
704 }
705 }
cfe53c9a
PS
706 } else
707 wpa_s->bgscan_ssid = NULL;
708}
709
710
711static void wpa_supplicant_stop_bgscan(struct wpa_supplicant *wpa_s)
712{
713 if (wpa_s->bgscan_ssid != NULL) {
714 bgscan_deinit(wpa_s);
715 wpa_s->bgscan_ssid = NULL;
716 }
717}
718
719#endif /* CONFIG_BGSCAN */
720
721
7c865c68
TB
722static void wpa_supplicant_start_autoscan(struct wpa_supplicant *wpa_s)
723{
99218999 724 if (autoscan_init(wpa_s, 0))
7c865c68
TB
725 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize autoscan");
726}
727
728
729static void wpa_supplicant_stop_autoscan(struct wpa_supplicant *wpa_s)
730{
731 autoscan_deinit(wpa_s);
732}
733
734
c3d12238
JM
735void wpa_supplicant_reinit_autoscan(struct wpa_supplicant *wpa_s)
736{
737 if (wpa_s->wpa_state == WPA_DISCONNECTED ||
738 wpa_s->wpa_state == WPA_SCANNING) {
739 autoscan_deinit(wpa_s);
740 wpa_supplicant_start_autoscan(wpa_s);
741 }
742}
743
744
6fc6879b
JM
745/**
746 * wpa_supplicant_set_state - Set current connection state
747 * @wpa_s: Pointer to wpa_supplicant data
748 * @state: The new connection state
749 *
750 * This function is called whenever the connection state changes, e.g.,
751 * association is completed for WPA/WPA2 4-Way Handshake is started.
752 */
71934751
JM
753void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
754 enum wpa_states state)
6fc6879b 755{
27f43d8d
MH
756 enum wpa_states old_state = wpa_s->wpa_state;
757
f049052b
BG
758 wpa_dbg(wpa_s, MSG_DEBUG, "State: %s -> %s",
759 wpa_supplicant_state_txt(wpa_s->wpa_state),
760 wpa_supplicant_state_txt(state));
6fc6879b 761
5ddd07cb
AS
762 if (state == WPA_INTERFACE_DISABLED) {
763 /* Assure normal scan when interface is restored */
764 wpa_s->normal_scans = 0;
765 }
766
0cf24fda 767 if (state == WPA_COMPLETED) {
6ac4b15e 768 wpas_connect_work_done(wpa_s);
0cf24fda
LC
769 /* Reinitialize normal_scan counter */
770 wpa_s->normal_scans = 0;
771 }
6ac4b15e 772
07c1e987
MS
773#ifdef CONFIG_P2P
774 /*
775 * P2PS client has to reply to Probe Request frames received on the
776 * group operating channel. Enable Probe Request frame reporting for
777 * P2P connected client in case p2p_cli_probe configuration property is
778 * set to 1.
779 */
780 if (wpa_s->conf->p2p_cli_probe && wpa_s->current_ssid &&
781 wpa_s->current_ssid->mode == WPAS_MODE_INFRA &&
782 wpa_s->current_ssid->p2p_group) {
783 if (state == WPA_COMPLETED && !wpa_s->p2p_cli_probe) {
784 wpa_dbg(wpa_s, MSG_DEBUG,
785 "P2P: Enable CLI Probe Request RX reporting");
786 wpa_s->p2p_cli_probe =
787 wpa_drv_probe_req_report(wpa_s, 1) >= 0;
788 } else if (state != WPA_COMPLETED && wpa_s->p2p_cli_probe) {
789 wpa_dbg(wpa_s, MSG_DEBUG,
790 "P2P: Disable CLI Probe Request RX reporting");
791 wpa_s->p2p_cli_probe = 0;
792 wpa_drv_probe_req_report(wpa_s, 0);
793 }
794 }
795#endif /* CONFIG_P2P */
796
cb8564b1
DW
797 if (state != WPA_SCANNING)
798 wpa_supplicant_notify_scanning(wpa_s, 0);
799
6fc6879b 800 if (state == WPA_COMPLETED && wpa_s->new_connection) {
6fc6879b 801 struct wpa_ssid *ssid = wpa_s->current_ssid;
7d37a357 802#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
6fc6879b 803 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- Connection to "
1cfc6787
JM
804 MACSTR " completed [id=%d id_str=%s]",
805 MAC2STR(wpa_s->bssid),
6fc6879b
JM
806 ssid ? ssid->id : -1,
807 ssid && ssid->id_str ? ssid->id_str : "");
808#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
00e5e3d5 809 wpas_clear_temp_disabled(wpa_s, ssid, 1);
a20a3616 810 wpa_blacklist_clear(wpa_s);
f1a52633 811 wpa_s->extra_blacklist_count = 0;
6fc6879b 812 wpa_s->new_connection = 0;
6fc6879b 813 wpa_drv_set_operstate(wpa_s, 1);
99ac2913
FF
814#ifndef IEEE8021X_EAPOL
815 wpa_drv_set_supp_port(wpa_s, 1);
816#endif /* IEEE8021X_EAPOL */
17a4734d 817 wpa_s->after_wps = 0;
4d9fb08d 818 wpa_s->known_wps_freq = 0;
b22128ef 819 wpas_p2p_completed(wpa_s);
c3701c66
RM
820
821 sme_sched_obss_scan(wpa_s, 1);
6fc6879b
JM
822 } else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING ||
823 state == WPA_ASSOCIATED) {
824 wpa_s->new_connection = 1;
825 wpa_drv_set_operstate(wpa_s, 0);
99ac2913
FF
826#ifndef IEEE8021X_EAPOL
827 wpa_drv_set_supp_port(wpa_s, 0);
828#endif /* IEEE8021X_EAPOL */
c3701c66 829 sme_sched_obss_scan(wpa_s, 0);
6fc6879b
JM
830 }
831 wpa_s->wpa_state = state;
27f43d8d 832
cfe53c9a
PS
833#ifdef CONFIG_BGSCAN
834 if (state == WPA_COMPLETED)
835 wpa_supplicant_start_bgscan(wpa_s);
37271232 836 else if (state < WPA_ASSOCIATED)
cfe53c9a
PS
837 wpa_supplicant_stop_bgscan(wpa_s);
838#endif /* CONFIG_BGSCAN */
839
7c865c68
TB
840 if (state == WPA_AUTHENTICATING)
841 wpa_supplicant_stop_autoscan(wpa_s);
842
843 if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
844 wpa_supplicant_start_autoscan(wpa_s);
845
fecc2bb5
EP
846 if (old_state >= WPA_ASSOCIATED && wpa_s->wpa_state < WPA_ASSOCIATED)
847 wmm_ac_notify_disassoc(wpa_s);
848
5bbf9f10 849 if (wpa_s->wpa_state != old_state) {
27f43d8d 850 wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
5bbf9f10 851
e3bd6e9d
IP
852 /*
853 * Notify the P2P Device interface about a state change in one
854 * of the interfaces.
855 */
856 wpas_p2p_indicate_state_change(wpa_s);
e3bd6e9d 857
5bbf9f10
PS
858 if (wpa_s->wpa_state == WPA_COMPLETED ||
859 old_state == WPA_COMPLETED)
860 wpas_notify_auth_changed(wpa_s);
861 }
6fc6879b
JM
862}
863
864
1a1bf008
JM
865void wpa_supplicant_terminate_proc(struct wpa_global *global)
866{
867 int pending = 0;
868#ifdef CONFIG_WPS
869 struct wpa_supplicant *wpa_s = global->ifaces;
870 while (wpa_s) {
ab41595f 871 struct wpa_supplicant *next = wpa_s->next;
5516ed32
EA
872 if (wpas_wps_terminate_pending(wpa_s) == 1)
873 pending = 1;
20625e97
JM
874#ifdef CONFIG_P2P
875 if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE ||
876 (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group))
877 wpas_p2p_disconnect(wpa_s);
878#endif /* CONFIG_P2P */
ab41595f 879 wpa_s = next;
1a1bf008
JM
880 }
881#endif /* CONFIG_WPS */
882 if (pending)
883 return;
884 eloop_terminate();
885}
886
887
0456ea16 888static void wpa_supplicant_terminate(int sig, void *signal_ctx)
6fc6879b 889{
0456ea16 890 struct wpa_global *global = signal_ctx;
1a1bf008 891 wpa_supplicant_terminate_proc(global);
6fc6879b
JM
892}
893
894
b22128ef 895void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s)
6fc6879b 896{
71934751 897 enum wpa_states old_state = wpa_s->wpa_state;
27f43d8d 898
6fc6879b
JM
899 wpa_s->pairwise_cipher = 0;
900 wpa_s->group_cipher = 0;
901 wpa_s->mgmt_group_cipher = 0;
902 wpa_s->key_mgmt = 0;
8401a6b0 903 if (wpa_s->wpa_state != WPA_INTERFACE_DISABLED)
99218999 904 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
27f43d8d
MH
905
906 if (wpa_s->wpa_state != old_state)
907 wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
6fc6879b
JM
908}
909
910
911/**
912 * wpa_supplicant_reload_configuration - Reload configuration data
913 * @wpa_s: Pointer to wpa_supplicant data
914 * Returns: 0 on success or -1 if configuration parsing failed
915 *
916 * This function can be used to request that the configuration data is reloaded
917 * (e.g., after configuration file change). This function is reloading
918 * configuration only for one interface, so this may need to be called multiple
919 * times if %wpa_supplicant is controlling multiple interfaces and all
920 * interfaces need reconfiguration.
921 */
922int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
923{
924 struct wpa_config *conf;
925 int reconf_ctrl;
8bac466b
JM
926 int old_ap_scan;
927
6fc6879b
JM
928 if (wpa_s->confname == NULL)
929 return -1;
e6304cad 930 conf = wpa_config_read(wpa_s->confname, NULL);
6fc6879b
JM
931 if (conf == NULL) {
932 wpa_msg(wpa_s, MSG_ERROR, "Failed to parse the configuration "
933 "file '%s' - exiting", wpa_s->confname);
934 return -1;
935 }
e6304cad
DS
936 wpa_config_read(wpa_s->confanother, conf);
937
611aea7d 938 conf->changed_parameters = (unsigned int) -1;
6fc6879b
JM
939
940 reconf_ctrl = !!conf->ctrl_interface != !!wpa_s->conf->ctrl_interface
941 || (conf->ctrl_interface && wpa_s->conf->ctrl_interface &&
942 os_strcmp(conf->ctrl_interface,
943 wpa_s->conf->ctrl_interface) != 0);
944
945 if (reconf_ctrl && wpa_s->ctrl_iface) {
946 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
947 wpa_s->ctrl_iface = NULL;
948 }
949
950 eapol_sm_invalidate_cached_session(wpa_s->eapol);
7b7ce8aa 951 if (wpa_s->current_ssid) {
e66bcedd
JM
952 if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
953 wpa_s->own_disconnect_req = 1;
7b7ce8aa
JM
954 wpa_supplicant_deauthenticate(wpa_s,
955 WLAN_REASON_DEAUTH_LEAVING);
956 }
8bac466b 957
6fc6879b
JM
958 /*
959 * TODO: should notify EAPOL SM about changes in opensc_engine_path,
07e2de31 960 * pkcs11_engine_path, pkcs11_module_path, openssl_ciphers.
6fc6879b 961 */
56586197 962 if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
6fc6879b
JM
963 /*
964 * Clear forced success to clear EAP state for next
965 * authentication.
966 */
967 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
968 }
969 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
970 wpa_sm_set_config(wpa_s->wpa, NULL);
d8a790b9 971 wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
6fc6879b
JM
972 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
973 rsn_preauth_deinit(wpa_s->wpa);
8bac466b
JM
974
975 old_ap_scan = wpa_s->conf->ap_scan;
6fc6879b
JM
976 wpa_config_free(wpa_s->conf);
977 wpa_s->conf = conf;
8bac466b
JM
978 if (old_ap_scan != wpa_s->conf->ap_scan)
979 wpas_notify_ap_scan_changed(wpa_s);
980
6fc6879b
JM
981 if (reconf_ctrl)
982 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
983
611aea7d
JM
984 wpa_supplicant_update_config(wpa_s);
985
6fc6879b 986 wpa_supplicant_clear_status(wpa_s);
349493bd 987 if (wpa_supplicant_enabled_networks(wpa_s)) {
43a38635
JM
988 wpa_s->reassociate = 1;
989 wpa_supplicant_req_scan(wpa_s, 0, 0);
990 }
f049052b 991 wpa_dbg(wpa_s, MSG_DEBUG, "Reconfiguration completed");
6fc6879b
JM
992 return 0;
993}
994
995
0456ea16 996static void wpa_supplicant_reconfig(int sig, void *signal_ctx)
6fc6879b 997{
0456ea16 998 struct wpa_global *global = signal_ctx;
6fc6879b 999 struct wpa_supplicant *wpa_s;
6fc6879b 1000 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
f049052b
BG
1001 wpa_dbg(wpa_s, MSG_DEBUG, "Signal %d received - reconfiguring",
1002 sig);
6fc6879b 1003 if (wpa_supplicant_reload_configuration(wpa_s) < 0) {
1a1bf008 1004 wpa_supplicant_terminate_proc(global);
6fc6879b
JM
1005 }
1006 }
1248e584
LR
1007
1008 if (wpa_debug_reopen_file() < 0) {
1009 /* Ignore errors since we cannot really do much to fix this */
1010 wpa_printf(MSG_DEBUG, "Could not reopen debug log file");
1011 }
6fc6879b
JM
1012}
1013
1014
6fc6879b
JM
1015static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s,
1016 struct wpa_ssid *ssid,
1017 struct wpa_ie_data *ie)
1018{
1019 int ret = wpa_sm_parse_own_wpa_ie(wpa_s->wpa, ie);
1020 if (ret) {
1021 if (ret == -2) {
1022 wpa_msg(wpa_s, MSG_INFO, "WPA: Failed to parse WPA IE "
1023 "from association info");
1024 }
1025 return -1;
1026 }
1027
f049052b
BG
1028 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Using WPA IE from AssocReq to set "
1029 "cipher suites");
6fc6879b
JM
1030 if (!(ie->group_cipher & ssid->group_cipher)) {
1031 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled group "
1032 "cipher 0x%x (mask 0x%x) - reject",
1033 ie->group_cipher, ssid->group_cipher);
1034 return -1;
1035 }
1036 if (!(ie->pairwise_cipher & ssid->pairwise_cipher)) {
1037 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled pairwise "
1038 "cipher 0x%x (mask 0x%x) - reject",
1039 ie->pairwise_cipher, ssid->pairwise_cipher);
1040 return -1;
1041 }
1042 if (!(ie->key_mgmt & ssid->key_mgmt)) {
1043 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled key "
1044 "management 0x%x (mask 0x%x) - reject",
1045 ie->key_mgmt, ssid->key_mgmt);
1046 return -1;
1047 }
1048
1049#ifdef CONFIG_IEEE80211W
0b60b0aa 1050 if (!(ie->capabilities & WPA_CAPABILITY_MFPC) &&
3f56a2b7 1051 wpas_get_ssid_pmf(wpa_s, ssid) == MGMT_FRAME_PROTECTION_REQUIRED) {
6fc6879b
JM
1052 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP "
1053 "that does not support management frame protection - "
1054 "reject");
1055 return -1;
1056 }
1057#endif /* CONFIG_IEEE80211W */
1058
1059 return 0;
1060}
1061
1062
1063/**
1064 * wpa_supplicant_set_suites - Set authentication and encryption parameters
1065 * @wpa_s: Pointer to wpa_supplicant data
1066 * @bss: Scan results for the selected BSS, or %NULL if not available
1067 * @ssid: Configuration data for the selected network
1068 * @wpa_ie: Buffer for the WPA/RSN IE
1069 * @wpa_ie_len: Maximum wpa_ie buffer size on input. This is changed to be the
1070 * used buffer length in case the functions returns success.
1071 * Returns: 0 on success or -1 on failure
1072 *
1073 * This function is used to configure authentication and encryption parameters
1074 * based on the network configuration and scan result for the selected BSS (if
1075 * available).
1076 */
1077int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
6fa81a3b 1078 struct wpa_bss *bss, struct wpa_ssid *ssid,
6fc6879b
JM
1079 u8 *wpa_ie, size_t *wpa_ie_len)
1080{
1081 struct wpa_ie_data ie;
1082 int sel, proto;
df0f01d9 1083 const u8 *bss_wpa, *bss_rsn, *bss_osen;
6fc6879b
JM
1084
1085 if (bss) {
6fa81a3b
JM
1086 bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
1087 bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
df0f01d9 1088 bss_osen = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
6fc6879b 1089 } else
df0f01d9 1090 bss_wpa = bss_rsn = bss_osen = NULL;
6fc6879b
JM
1091
1092 if (bss_rsn && (ssid->proto & WPA_PROTO_RSN) &&
1093 wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie) == 0 &&
1094 (ie.group_cipher & ssid->group_cipher) &&
1095 (ie.pairwise_cipher & ssid->pairwise_cipher) &&
1096 (ie.key_mgmt & ssid->key_mgmt)) {
f049052b 1097 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using IEEE 802.11i/D9.0");
6fc6879b
JM
1098 proto = WPA_PROTO_RSN;
1099 } else if (bss_wpa && (ssid->proto & WPA_PROTO_WPA) &&
267ac3bc 1100 wpa_parse_wpa_ie(bss_wpa, 2 + bss_wpa[1], &ie) == 0 &&
6fc6879b
JM
1101 (ie.group_cipher & ssid->group_cipher) &&
1102 (ie.pairwise_cipher & ssid->pairwise_cipher) &&
1103 (ie.key_mgmt & ssid->key_mgmt)) {
f049052b 1104 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using IEEE 802.11i/D3.0");
6fc6879b 1105 proto = WPA_PROTO_WPA;
df0f01d9
JM
1106#ifdef CONFIG_HS20
1107 } else if (bss_osen && (ssid->proto & WPA_PROTO_OSEN)) {
1108 wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: using OSEN");
1109 /* TODO: parse OSEN element */
137ff332 1110 os_memset(&ie, 0, sizeof(ie));
df0f01d9
JM
1111 ie.group_cipher = WPA_CIPHER_CCMP;
1112 ie.pairwise_cipher = WPA_CIPHER_CCMP;
1113 ie.key_mgmt = WPA_KEY_MGMT_OSEN;
1114 proto = WPA_PROTO_OSEN;
1115#endif /* CONFIG_HS20 */
6fc6879b
JM
1116 } else if (bss) {
1117 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select WPA/RSN");
267ac3bc
JM
1118 wpa_dbg(wpa_s, MSG_DEBUG,
1119 "WPA: ssid proto=0x%x pairwise_cipher=0x%x group_cipher=0x%x key_mgmt=0x%x",
1120 ssid->proto, ssid->pairwise_cipher, ssid->group_cipher,
1121 ssid->key_mgmt);
1122 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: BSS " MACSTR " ssid='%s'%s%s%s",
1123 MAC2STR(bss->bssid),
1124 wpa_ssid_txt(bss->ssid, bss->ssid_len),
1125 bss_wpa ? " WPA" : "",
1126 bss_rsn ? " RSN" : "",
1127 bss_osen ? " OSEN" : "");
1128 if (bss_rsn) {
1129 wpa_hexdump(MSG_DEBUG, "RSN", bss_rsn, 2 + bss_rsn[1]);
1130 if (wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie)) {
1131 wpa_dbg(wpa_s, MSG_DEBUG,
1132 "Could not parse RSN element");
1133 } else {
1134 wpa_dbg(wpa_s, MSG_DEBUG,
1135 "RSN: pairwise_cipher=0x%x group_cipher=0x%x key_mgmt=0x%x",
1136 ie.pairwise_cipher, ie.group_cipher,
1137 ie.key_mgmt);
1138 }
1139 }
1140 if (bss_wpa) {
1141 wpa_hexdump(MSG_DEBUG, "WPA", bss_wpa, 2 + bss_wpa[1]);
1142 if (wpa_parse_wpa_ie(bss_wpa, 2 + bss_wpa[1], &ie)) {
1143 wpa_dbg(wpa_s, MSG_DEBUG,
1144 "Could not parse WPA element");
1145 } else {
1146 wpa_dbg(wpa_s, MSG_DEBUG,
1147 "WPA: pairwise_cipher=0x%x group_cipher=0x%x key_mgmt=0x%x",
1148 ie.pairwise_cipher, ie.group_cipher,
1149 ie.key_mgmt);
1150 }
1151 }
6fc6879b
JM
1152 return -1;
1153 } else {
df0f01d9
JM
1154 if (ssid->proto & WPA_PROTO_OSEN)
1155 proto = WPA_PROTO_OSEN;
1156 else if (ssid->proto & WPA_PROTO_RSN)
6fc6879b
JM
1157 proto = WPA_PROTO_RSN;
1158 else
1159 proto = WPA_PROTO_WPA;
1160 if (wpa_supplicant_suites_from_ai(wpa_s, ssid, &ie) < 0) {
1161 os_memset(&ie, 0, sizeof(ie));
1162 ie.group_cipher = ssid->group_cipher;
1163 ie.pairwise_cipher = ssid->pairwise_cipher;
1164 ie.key_mgmt = ssid->key_mgmt;
1165#ifdef CONFIG_IEEE80211W
1166 ie.mgmt_group_cipher =
70f8cc8e 1167 ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION ?
6fc6879b
JM
1168 WPA_CIPHER_AES_128_CMAC : 0;
1169#endif /* CONFIG_IEEE80211W */
f049052b
BG
1170 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Set cipher suites "
1171 "based on configuration");
6fc6879b
JM
1172 } else
1173 proto = ie.proto;
1174 }
1175
f049052b
BG
1176 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected cipher suites: group %d "
1177 "pairwise %d key_mgmt %d proto %d",
1178 ie.group_cipher, ie.pairwise_cipher, ie.key_mgmt, proto);
6fc6879b
JM
1179#ifdef CONFIG_IEEE80211W
1180 if (ssid->ieee80211w) {
f049052b
BG
1181 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected mgmt group cipher %d",
1182 ie.mgmt_group_cipher);
6fc6879b
JM
1183 }
1184#endif /* CONFIG_IEEE80211W */
1185
64fa840a 1186 wpa_s->wpa_proto = proto;
6fc6879b
JM
1187 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, proto);
1188 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
df0f01d9 1189 !!(ssid->proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN)));
6fc6879b
JM
1190
1191 if (bss || !wpa_s->ap_ies_from_associnfo) {
1192 if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
1193 bss_wpa ? 2 + bss_wpa[1] : 0) ||
1194 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
1195 bss_rsn ? 2 + bss_rsn[1] : 0))
1196 return -1;
1197 }
1198
9e68742e
JM
1199#ifdef CONFIG_NO_WPA
1200 wpa_s->group_cipher = WPA_CIPHER_NONE;
1201 wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
1202#else /* CONFIG_NO_WPA */
6fc6879b 1203 sel = ie.group_cipher & ssid->group_cipher;
edbd2a19
JM
1204 wpa_s->group_cipher = wpa_pick_group_cipher(sel);
1205 if (wpa_s->group_cipher < 0) {
f049052b
BG
1206 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select group "
1207 "cipher");
6fc6879b
JM
1208 return -1;
1209 }
edbd2a19
JM
1210 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s",
1211 wpa_cipher_txt(wpa_s->group_cipher));
6fc6879b
JM
1212
1213 sel = ie.pairwise_cipher & ssid->pairwise_cipher;
edbd2a19
JM
1214 wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(sel, 1);
1215 if (wpa_s->pairwise_cipher < 0) {
f049052b
BG
1216 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select pairwise "
1217 "cipher");
6fc6879b
JM
1218 return -1;
1219 }
edbd2a19
JM
1220 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK %s",
1221 wpa_cipher_txt(wpa_s->pairwise_cipher));
9e68742e 1222#endif /* CONFIG_NO_WPA */
6fc6879b
JM
1223
1224 sel = ie.key_mgmt & ssid->key_mgmt;
c10347f2
JM
1225#ifdef CONFIG_SAE
1226 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE))
1227 sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE);
1228#endif /* CONFIG_SAE */
6fc6879b 1229 if (0) {
5e3b5197
JM
1230#ifdef CONFIG_SUITEB192
1231 } else if (sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192) {
1232 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
1233 wpa_dbg(wpa_s, MSG_DEBUG,
1234 "WPA: using KEY_MGMT 802.1X with Suite B (192-bit)");
1235#endif /* CONFIG_SUITEB192 */
1236#ifdef CONFIG_SUITEB
666497c8
JM
1237 } else if (sel & WPA_KEY_MGMT_IEEE8021X_SUITE_B) {
1238 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SUITE_B;
1239 wpa_dbg(wpa_s, MSG_DEBUG,
1240 "WPA: using KEY_MGMT 802.1X with Suite B");
5e3b5197 1241#endif /* CONFIG_SUITEB */
b8ae56e4
JM
1242#ifdef CONFIG_FILS
1243#ifdef CONFIG_IEEE80211R
1244 } else if (sel & WPA_KEY_MGMT_FT_FILS_SHA384) {
1245 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_FILS_SHA384;
1246 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT-FILS-SHA384");
1247 } else if (sel & WPA_KEY_MGMT_FT_FILS_SHA256) {
1248 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_FILS_SHA256;
1249 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT-FILS-SHA256");
1250#endif /* CONFIG_IEEE80211R */
1251 } else if (sel & WPA_KEY_MGMT_FILS_SHA384) {
1252 wpa_s->key_mgmt = WPA_KEY_MGMT_FILS_SHA384;
1253 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FILS-SHA384");
1254 } else if (sel & WPA_KEY_MGMT_FILS_SHA256) {
1255 wpa_s->key_mgmt = WPA_KEY_MGMT_FILS_SHA256;
1256 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FILS-SHA256");
1257#endif /* CONFIG_FILS */
6fc6879b
JM
1258#ifdef CONFIG_IEEE80211R
1259 } else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) {
1260 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
f049052b 1261 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/802.1X");
6fc6879b
JM
1262 } else if (sel & WPA_KEY_MGMT_FT_PSK) {
1263 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_PSK;
f049052b 1264 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/PSK");
6fc6879b 1265#endif /* CONFIG_IEEE80211R */
c10347f2
JM
1266#ifdef CONFIG_SAE
1267 } else if (sel & WPA_KEY_MGMT_SAE) {
1268 wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
1269 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT SAE");
1270 } else if (sel & WPA_KEY_MGMT_FT_SAE) {
1271 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_SAE;
1272 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT FT/SAE");
1273#endif /* CONFIG_SAE */
56586197
JM
1274#ifdef CONFIG_IEEE80211W
1275 } else if (sel & WPA_KEY_MGMT_IEEE8021X_SHA256) {
1276 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
f049052b 1277 wpa_dbg(wpa_s, MSG_DEBUG,
56586197
JM
1278 "WPA: using KEY_MGMT 802.1X with SHA256");
1279 } else if (sel & WPA_KEY_MGMT_PSK_SHA256) {
1280 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
f049052b 1281 wpa_dbg(wpa_s, MSG_DEBUG,
56586197
JM
1282 "WPA: using KEY_MGMT PSK with SHA256");
1283#endif /* CONFIG_IEEE80211W */
6fc6879b
JM
1284 } else if (sel & WPA_KEY_MGMT_IEEE8021X) {
1285 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
f049052b 1286 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT 802.1X");
6fc6879b
JM
1287 } else if (sel & WPA_KEY_MGMT_PSK) {
1288 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
f049052b 1289 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-PSK");
6fc6879b
JM
1290 } else if (sel & WPA_KEY_MGMT_WPA_NONE) {
1291 wpa_s->key_mgmt = WPA_KEY_MGMT_WPA_NONE;
f049052b 1292 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-NONE");
df0f01d9
JM
1293#ifdef CONFIG_HS20
1294 } else if (sel & WPA_KEY_MGMT_OSEN) {
1295 wpa_s->key_mgmt = WPA_KEY_MGMT_OSEN;
1296 wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: using KEY_MGMT OSEN");
1297#endif /* CONFIG_HS20 */
6fc6879b 1298 } else {
f049052b
BG
1299 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select "
1300 "authenticated key management type");
6fc6879b
JM
1301 return -1;
1302 }
1303
1304 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
1305 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
1306 wpa_s->pairwise_cipher);
1307 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
1308
1309#ifdef CONFIG_IEEE80211W
1310 sel = ie.mgmt_group_cipher;
3f56a2b7 1311 if (wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION ||
0b60b0aa 1312 !(ie.capabilities & WPA_CAPABILITY_MFPC))
6fc6879b
JM
1313 sel = 0;
1314 if (sel & WPA_CIPHER_AES_128_CMAC) {
1315 wpa_s->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
f049052b 1316 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
6fc6879b 1317 "AES-128-CMAC");
8dd9f9cd
JM
1318 } else if (sel & WPA_CIPHER_BIP_GMAC_128) {
1319 wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_GMAC_128;
1320 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1321 "BIP-GMAC-128");
1322 } else if (sel & WPA_CIPHER_BIP_GMAC_256) {
1323 wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_GMAC_256;
1324 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1325 "BIP-GMAC-256");
1326 } else if (sel & WPA_CIPHER_BIP_CMAC_256) {
1327 wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_CMAC_256;
1328 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1329 "BIP-CMAC-256");
6fc6879b
JM
1330 } else {
1331 wpa_s->mgmt_group_cipher = 0;
f049052b 1332 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
6fc6879b
JM
1333 }
1334 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
1335 wpa_s->mgmt_group_cipher);
62d49803 1336 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP,
3f56a2b7 1337 wpas_get_ssid_pmf(wpa_s, ssid));
6fc6879b
JM
1338#endif /* CONFIG_IEEE80211W */
1339
1340 if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {
f049052b 1341 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to generate WPA IE");
6fc6879b
JM
1342 return -1;
1343 }
1344
0bf927a0 1345 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
a52410c2
JM
1346 int psk_set = 0;
1347
1348 if (ssid->psk_set) {
70c93963
MH
1349 wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN, NULL,
1350 NULL);
a52410c2
JM
1351 psk_set = 1;
1352 }
7d232e23
ZC
1353#ifndef CONFIG_NO_PBKDF2
1354 if (bss && ssid->bssid_set && ssid->ssid_len == 0 &&
1355 ssid->passphrase) {
1356 u8 psk[PMK_LEN];
986de33d
JM
1357 pbkdf2_sha1(ssid->passphrase, bss->ssid, bss->ssid_len,
1358 4096, psk, PMK_LEN);
7d232e23
ZC
1359 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
1360 psk, PMK_LEN);
70c93963 1361 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL, NULL);
a52410c2 1362 psk_set = 1;
e886c88e 1363 os_memset(psk, 0, sizeof(psk));
7d232e23
ZC
1364 }
1365#endif /* CONFIG_NO_PBKDF2 */
9173b16f
JM
1366#ifdef CONFIG_EXT_PASSWORD
1367 if (ssid->ext_psk) {
1368 struct wpabuf *pw = ext_password_get(wpa_s->ext_pw,
1369 ssid->ext_psk);
1370 char pw_str[64 + 1];
1371 u8 psk[PMK_LEN];
1372
1373 if (pw == NULL) {
1374 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No PSK "
1375 "found from external storage");
1376 return -1;
1377 }
1378
1379 if (wpabuf_len(pw) < 8 || wpabuf_len(pw) > 64) {
1380 wpa_msg(wpa_s, MSG_INFO, "EXT PW: Unexpected "
1381 "PSK length %d in external storage",
1382 (int) wpabuf_len(pw));
1383 ext_password_free(pw);
1384 return -1;
1385 }
1386
1387 os_memcpy(pw_str, wpabuf_head(pw), wpabuf_len(pw));
1388 pw_str[wpabuf_len(pw)] = '\0';
1389
1390#ifndef CONFIG_NO_PBKDF2
1391 if (wpabuf_len(pw) >= 8 && wpabuf_len(pw) < 64 && bss)
1392 {
986de33d
JM
1393 pbkdf2_sha1(pw_str, bss->ssid, bss->ssid_len,
1394 4096, psk, PMK_LEN);
9173b16f
JM
1395 os_memset(pw_str, 0, sizeof(pw_str));
1396 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from "
1397 "external passphrase)",
1398 psk, PMK_LEN);
70c93963
MH
1399 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL,
1400 NULL);
a52410c2 1401 psk_set = 1;
e886c88e 1402 os_memset(psk, 0, sizeof(psk));
9173b16f
JM
1403 } else
1404#endif /* CONFIG_NO_PBKDF2 */
1405 if (wpabuf_len(pw) == 2 * PMK_LEN) {
1406 if (hexstr2bin(pw_str, psk, PMK_LEN) < 0) {
1407 wpa_msg(wpa_s, MSG_INFO, "EXT PW: "
1408 "Invalid PSK hex string");
1409 os_memset(pw_str, 0, sizeof(pw_str));
1410 ext_password_free(pw);
1411 return -1;
1412 }
70c93963
MH
1413 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN, NULL,
1414 NULL);
a52410c2 1415 psk_set = 1;
e886c88e 1416 os_memset(psk, 0, sizeof(psk));
9173b16f
JM
1417 } else {
1418 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No suitable "
1419 "PSK available");
1420 os_memset(pw_str, 0, sizeof(pw_str));
1421 ext_password_free(pw);
1422 return -1;
1423 }
1424
1425 os_memset(pw_str, 0, sizeof(pw_str));
1426 ext_password_free(pw);
1427 }
1428#endif /* CONFIG_EXT_PASSWORD */
a52410c2
JM
1429
1430 if (!psk_set) {
1431 wpa_msg(wpa_s, MSG_INFO,
1432 "No PSK available for association");
1433 return -1;
1434 }
7d232e23 1435 } else
6fc6879b
JM
1436 wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
1437
1438 return 0;
1439}
1440
1441
8cd6b7bc 1442static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
03e47c9c 1443{
8cd6b7bc 1444 *pos = 0x00;
03e47c9c 1445
8cd6b7bc
JB
1446 switch (idx) {
1447 case 0: /* Bits 0-7 */
1448 break;
1449 case 1: /* Bits 8-15 */
1450 break;
1451 case 2: /* Bits 16-23 */
1452#ifdef CONFIG_WNM
1453 *pos |= 0x02; /* Bit 17 - WNM-Sleep Mode */
1454 *pos |= 0x08; /* Bit 19 - BSS Transition */
1455#endif /* CONFIG_WNM */
1456 break;
1457 case 3: /* Bits 24-31 */
1458#ifdef CONFIG_WNM
1459 *pos |= 0x02; /* Bit 25 - SSID List */
1460#endif /* CONFIG_WNM */
03e47c9c 1461#ifdef CONFIG_INTERWORKING
8cd6b7bc
JB
1462 if (wpa_s->conf->interworking)
1463 *pos |= 0x80; /* Bit 31 - Interworking */
03e47c9c 1464#endif /* CONFIG_INTERWORKING */
8cd6b7bc
JB
1465 break;
1466 case 4: /* Bits 32-39 */
56f5af48 1467#ifdef CONFIG_INTERWORKING
429dd9af
JM
1468 if (wpa_s->drv_flags / WPA_DRIVER_FLAGS_QOS_MAPPING)
1469 *pos |= 0x01; /* Bit 32 - QoS Map */
56f5af48 1470#endif /* CONFIG_INTERWORKING */
8cd6b7bc
JB
1471 break;
1472 case 5: /* Bits 40-47 */
95a3ea94
JM
1473#ifdef CONFIG_HS20
1474 if (wpa_s->conf->hs20)
1475 *pos |= 0x40; /* Bit 46 - WNM-Notification */
1476#endif /* CONFIG_HS20 */
92c6e2e3
DS
1477#ifdef CONFIG_MBO
1478 *pos |= 0x40; /* Bit 46 - WNM-Notification */
1479#endif /* CONFIG_MBO */
8cd6b7bc
JB
1480 break;
1481 case 6: /* Bits 48-55 */
1482 break;
d1723c55
LD
1483 case 7: /* Bits 56-63 */
1484 break;
1485 case 8: /* Bits 64-71 */
1486 if (wpa_s->conf->ftm_responder)
1487 *pos |= 0x40; /* Bit 70 - FTM responder */
1488 if (wpa_s->conf->ftm_initiator)
1489 *pos |= 0x80; /* Bit 71 - FTM initiator */
1490 break;
e4d2ce1b
JM
1491 case 9: /* Bits 72-79 */
1492#ifdef CONFIG_FILS
1493 *pos |= 0x01;
1494#endif /* CONFIG_FILS */
1495 break;
8cd6b7bc
JB
1496 }
1497}
03e47c9c 1498
03e47c9c 1499
0bbaa9b9 1500int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf, size_t buflen)
8cd6b7bc
JB
1501{
1502 u8 *pos = buf;
e4d2ce1b 1503 u8 len = 10, i;
8cd6b7bc
JB
1504
1505 if (len < wpa_s->extended_capa_len)
1506 len = wpa_s->extended_capa_len;
0bbaa9b9
JM
1507 if (buflen < (size_t) len + 2) {
1508 wpa_printf(MSG_INFO,
1509 "Not enough room for building extended capabilities element");
1510 return -1;
1511 }
03e47c9c
JM
1512
1513 *pos++ = WLAN_EID_EXT_CAPAB;
8cd6b7bc
JB
1514 *pos++ = len;
1515 for (i = 0; i < len; i++, pos++) {
1516 wpas_ext_capab_byte(wpa_s, pos, i);
1517
1518 if (i < wpa_s->extended_capa_len) {
1519 *pos &= ~wpa_s->extended_capa_mask[i];
1520 *pos |= wpa_s->extended_capa[i];
1521 }
1522 }
03e47c9c 1523
3db5439a
JM
1524 while (len > 0 && buf[1 + len] == 0) {
1525 len--;
1526 buf[1] = len;
1527 }
1528 if (len == 0)
1529 return 0;
1530
1531 return 2 + len;
03e47c9c
JM
1532}
1533
1534
6ac4b15e
JM
1535static int wpas_valid_bss(struct wpa_supplicant *wpa_s,
1536 struct wpa_bss *test_bss)
1537{
1538 struct wpa_bss *bss;
1539
1540 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
1541 if (bss == test_bss)
1542 return 1;
1543 }
1544
1545 return 0;
1546}
1547
1548
1549static int wpas_valid_ssid(struct wpa_supplicant *wpa_s,
1550 struct wpa_ssid *test_ssid)
1551{
1552 struct wpa_ssid *ssid;
1553
1554 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
1555 if (ssid == test_ssid)
1556 return 1;
1557 }
1558
1559 return 0;
1560}
1561
1562
1563int wpas_valid_bss_ssid(struct wpa_supplicant *wpa_s, struct wpa_bss *test_bss,
1564 struct wpa_ssid *test_ssid)
1565{
1566 if (test_bss && !wpas_valid_bss(wpa_s, test_bss))
1567 return 0;
1568
1569 return test_ssid == NULL || wpas_valid_ssid(wpa_s, test_ssid);
1570}
1571
1572
1573void wpas_connect_work_free(struct wpa_connect_work *cwork)
1574{
1575 if (cwork == NULL)
1576 return;
1577 os_free(cwork);
1578}
1579
1580
1581void wpas_connect_work_done(struct wpa_supplicant *wpa_s)
1582{
1583 struct wpa_connect_work *cwork;
1584 struct wpa_radio_work *work = wpa_s->connect_work;
1585
1586 if (!work)
1587 return;
1588
1589 wpa_s->connect_work = NULL;
1590 cwork = work->ctx;
1591 work->ctx = NULL;
1592 wpas_connect_work_free(cwork);
1593 radio_work_done(work);
1594}
1595
1596
a313d17d 1597int wpas_update_random_addr(struct wpa_supplicant *wpa_s, int style)
c267753b
JM
1598{
1599 struct os_reltime now;
1600 u8 addr[ETH_ALEN];
1601
1602 os_get_reltime(&now);
a313d17d
JM
1603 if (wpa_s->last_mac_addr_style == style &&
1604 wpa_s->last_mac_addr_change.sec != 0 &&
c267753b
JM
1605 !os_reltime_expired(&now, &wpa_s->last_mac_addr_change,
1606 wpa_s->conf->rand_addr_lifetime)) {
1607 wpa_msg(wpa_s, MSG_DEBUG,
1608 "Previously selected random MAC address has not yet expired");
1609 return 0;
1610 }
1611
a313d17d
JM
1612 switch (style) {
1613 case 1:
1614 if (random_mac_addr(addr) < 0)
1615 return -1;
1616 break;
1617 case 2:
1618 os_memcpy(addr, wpa_s->perm_addr, ETH_ALEN);
1619 if (random_mac_addr_keep_oui(addr) < 0)
1620 return -1;
1621 break;
1622 default:
c267753b 1623 return -1;
a313d17d 1624 }
c267753b
JM
1625
1626 if (wpa_drv_set_mac_addr(wpa_s, addr) < 0) {
1627 wpa_msg(wpa_s, MSG_INFO,
1628 "Failed to set random MAC address");
1629 return -1;
1630 }
1631
1632 os_get_reltime(&wpa_s->last_mac_addr_change);
1633 wpa_s->mac_addr_changed = 1;
a313d17d 1634 wpa_s->last_mac_addr_style = style;
c267753b
JM
1635
1636 if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
1637 wpa_msg(wpa_s, MSG_INFO,
1638 "Could not update MAC address information");
1639 return -1;
1640 }
1641
1642 wpa_msg(wpa_s, MSG_DEBUG, "Using random MAC address " MACSTR,
1643 MAC2STR(addr));
1644
1645 return 0;
1646}
1647
1648
1649int wpas_update_random_addr_disassoc(struct wpa_supplicant *wpa_s)
1650{
1651 if (wpa_s->wpa_state >= WPA_AUTHENTICATING ||
1652 !wpa_s->conf->preassoc_mac_addr)
1653 return 0;
1654
a313d17d 1655 return wpas_update_random_addr(wpa_s, wpa_s->conf->preassoc_mac_addr);
c267753b
JM
1656}
1657
1658
6ac4b15e
JM
1659static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit);
1660
6fc6879b
JM
1661/**
1662 * wpa_supplicant_associate - Request association
1663 * @wpa_s: Pointer to wpa_supplicant data
1664 * @bss: Scan results for the selected BSS, or %NULL if not available
1665 * @ssid: Configuration data for the selected network
1666 *
1667 * This function is used to request %wpa_supplicant to associate with a BSS.
1668 */
1669void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
6fa81a3b 1670 struct wpa_bss *bss, struct wpa_ssid *ssid)
6fc6879b 1671{
6ac4b15e 1672 struct wpa_connect_work *cwork;
a313d17d
JM
1673 int rand_style;
1674
a8412ec9
JM
1675 wpa_s->own_disconnect_req = 0;
1676
e7160bd8
JM
1677 /*
1678 * If we are starting a new connection, any previously pending EAPOL
1679 * RX cannot be valid anymore.
1680 */
1681 wpabuf_free(wpa_s->pending_eapol_rx);
1682 wpa_s->pending_eapol_rx = NULL;
1683
a313d17d
JM
1684 if (ssid->mac_addr == -1)
1685 rand_style = wpa_s->conf->mac_addr;
1686 else
1687 rand_style = ssid->mac_addr;
6fc6879b 1688
8c42b369
EP
1689 wmm_ac_clear_saved_tspecs(wpa_s);
1690 wpa_s->reassoc_same_bss = 0;
6a5ee810 1691 wpa_s->reassoc_same_ess = 0;
8c42b369 1692
c267753b
JM
1693 if (wpa_s->last_ssid == ssid) {
1694 wpa_dbg(wpa_s, MSG_DEBUG, "Re-association to the same ESS");
6a5ee810 1695 wpa_s->reassoc_same_ess = 1;
8c42b369
EP
1696 if (wpa_s->current_bss && wpa_s->current_bss == bss) {
1697 wmm_ac_save_tspecs(wpa_s);
1698 wpa_s->reassoc_same_bss = 1;
1699 }
5d30f927
BR
1700 }
1701
1702 if (rand_style > 0 && !wpa_s->reassoc_same_ess) {
a313d17d 1703 if (wpas_update_random_addr(wpa_s, rand_style) < 0)
c267753b
JM
1704 return;
1705 wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
5d30f927 1706 } else if (rand_style == 0 && wpa_s->mac_addr_changed) {
c267753b
JM
1707 if (wpa_drv_set_mac_addr(wpa_s, NULL) < 0) {
1708 wpa_msg(wpa_s, MSG_INFO,
1709 "Could not restore permanent MAC address");
1710 return;
1711 }
1712 wpa_s->mac_addr_changed = 0;
1713 if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
1714 wpa_msg(wpa_s, MSG_INFO,
1715 "Could not update MAC address information");
1716 return;
1717 }
1718 wpa_msg(wpa_s, MSG_DEBUG, "Using permanent MAC address");
1719 }
1720 wpa_s->last_ssid = ssid;
1721
78177a00
JM
1722#ifdef CONFIG_IBSS_RSN
1723 ibss_rsn_deinit(wpa_s->ibss_rsn);
1724 wpa_s->ibss_rsn = NULL;
81a10a94
JM
1725#else /* CONFIG_IBSS_RSN */
1726 if (ssid->mode == WPAS_MODE_IBSS &&
1727 !(ssid->key_mgmt & (WPA_KEY_MGMT_NONE | WPA_KEY_MGMT_WPA_NONE))) {
1728 wpa_msg(wpa_s, MSG_INFO,
1729 "IBSS RSN not supported in the build");
1730 return;
1731 }
78177a00
JM
1732#endif /* CONFIG_IBSS_RSN */
1733
2c5d725c
JM
1734 if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
1735 ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
1581b38b
JM
1736#ifdef CONFIG_AP
1737 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) {
f049052b
BG
1738 wpa_msg(wpa_s, MSG_INFO, "Driver does not support AP "
1739 "mode");
1581b38b
JM
1740 return;
1741 }
8c981d17
DW
1742 if (wpa_supplicant_create_ap(wpa_s, ssid) < 0) {
1743 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
b2b688d1
VKE
1744 if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
1745 wpas_p2p_ap_setup_failed(wpa_s);
8c981d17
DW
1746 return;
1747 }
8f770587 1748 wpa_s->current_bss = bss;
1581b38b 1749#else /* CONFIG_AP */
f049052b
BG
1750 wpa_msg(wpa_s, MSG_ERROR, "AP mode support not included in "
1751 "the build");
1581b38b
JM
1752#endif /* CONFIG_AP */
1753 return;
1754 }
1755
603a3f34
JL
1756 if (ssid->mode == WPAS_MODE_MESH) {
1757#ifdef CONFIG_MESH
1758 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MESH)) {
1759 wpa_msg(wpa_s, MSG_INFO,
1760 "Driver does not support mesh mode");
1761 return;
1762 }
1763 if (bss)
1764 ssid->frequency = bss->freq;
1765 if (wpa_supplicant_join_mesh(wpa_s, ssid) < 0) {
1766 wpa_msg(wpa_s, MSG_ERROR, "Could not join mesh");
1767 return;
1768 }
1769 wpa_s->current_bss = bss;
6174de66
JM
1770 wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_STARTED "ssid=\"%s\" id=%d",
1771 wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
1772 ssid->id);
603a3f34
JL
1773#else /* CONFIG_MESH */
1774 wpa_msg(wpa_s, MSG_ERROR,
1775 "mesh mode support not included in the build");
1776#endif /* CONFIG_MESH */
1777 return;
1778 }
1779
52c9e6f3 1780#ifdef CONFIG_TDLS
95cb2d88
JM
1781 if (bss)
1782 wpa_tdls_ap_ies(wpa_s->wpa, (const u8 *) (bss + 1),
1783 bss->ie_len);
52c9e6f3
JM
1784#endif /* CONFIG_TDLS */
1785
5cc4d64b
JM
1786 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
1787 ssid->mode == IEEE80211_MODE_INFRA) {
c2a04078
JM
1788 sme_authenticate(wpa_s, bss, ssid);
1789 return;
1790 }
1791
6ac4b15e
JM
1792 if (wpa_s->connect_work) {
1793 wpa_dbg(wpa_s, MSG_DEBUG, "Reject wpa_supplicant_associate() call since connect_work exist");
1794 return;
1795 }
1796
f0e30c84
JM
1797 if (radio_work_pending(wpa_s, "connect")) {
1798 wpa_dbg(wpa_s, MSG_DEBUG, "Reject wpa_supplicant_associate() call since pending work exist");
1799 return;
1800 }
1801
a1836de6
JM
1802#ifdef CONFIG_SME
1803 if (ssid->mode == WPAS_MODE_IBSS || ssid->mode == WPAS_MODE_MESH) {
1804 /* Clear possibly set auth_alg, if any, from last attempt. */
1805 wpa_s->sme.auth_alg = WPA_AUTH_ALG_OPEN;
1806 }
1807#endif /* CONFIG_SME */
1808
4ead7cfd
KV
1809 wpas_abort_ongoing_scan(wpa_s);
1810
6ac4b15e
JM
1811 cwork = os_zalloc(sizeof(*cwork));
1812 if (cwork == NULL)
1813 return;
1814
1815 cwork->bss = bss;
1816 cwork->ssid = ssid;
1817
1818 if (radio_add_work(wpa_s, bss ? bss->freq : 0, "connect", 1,
1819 wpas_start_assoc_cb, cwork) < 0) {
1820 os_free(cwork);
1821 }
1822}
1823
1824
98479dc9
JD
1825static int bss_is_ibss(struct wpa_bss *bss)
1826{
1827 return (bss->caps & (IEEE80211_CAP_ESS | IEEE80211_CAP_IBSS)) ==
1828 IEEE80211_CAP_IBSS;
1829}
1830
1831
a65efbfb
PO
1832static int drv_supports_vht(struct wpa_supplicant *wpa_s,
1833 const struct wpa_ssid *ssid)
1834{
1835 enum hostapd_hw_mode hw_mode;
1836 struct hostapd_hw_modes *mode = NULL;
1837 u8 channel;
1838 int i;
1839
1840#ifdef CONFIG_HT_OVERRIDES
1841 if (ssid->disable_ht)
1842 return 0;
1843#endif /* CONFIG_HT_OVERRIDES */
1844
1845 hw_mode = ieee80211_freq_to_chan(ssid->frequency, &channel);
1846 if (hw_mode == NUM_HOSTAPD_MODES)
1847 return 0;
1848 for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
1849 if (wpa_s->hw.modes[i].mode == hw_mode) {
1850 mode = &wpa_s->hw.modes[i];
1851 break;
1852 }
1853 }
1854
1855 if (!mode)
1856 return 0;
1857
1858 return mode->vht_capab != 0;
1859}
1860
1861
54fe48b9
JM
1862void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s,
1863 const struct wpa_ssid *ssid,
1864 struct hostapd_freq_params *freq)
1830817e
JD
1865{
1866 enum hostapd_hw_mode hw_mode;
1867 struct hostapd_hw_modes *mode = NULL;
6b8b0774
JD
1868 int ht40plus[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157,
1869 184, 192 };
563ee183 1870 int vht80[] = { 36, 52, 100, 116, 132, 149 };
6b8b0774 1871 struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL;
1830817e 1872 u8 channel;
98479dc9 1873 int i, chan_idx, ht40 = -1, res, obss_scan = 1;
0f29bc68 1874 unsigned int j, k;
563ee183 1875 struct hostapd_freq_params vht_freq;
0f29bc68
AK
1876 int chwidth, seg0, seg1;
1877 u32 vht_caps = 0;
1830817e
JD
1878
1879 freq->freq = ssid->frequency;
1880
98479dc9
JD
1881 for (j = 0; j < wpa_s->last_scan_res_used; j++) {
1882 struct wpa_bss *bss = wpa_s->last_scan_res[j];
1883
1884 if (ssid->mode != WPAS_MODE_IBSS)
1885 break;
1886
1887 /* Don't adjust control freq in case of fixed_freq */
1888 if (ssid->fixed_freq)
1889 break;
1890
1891 if (!bss_is_ibss(bss))
1892 continue;
1893
1894 if (ssid->ssid_len == bss->ssid_len &&
1895 os_memcmp(ssid->ssid, bss->ssid, bss->ssid_len) == 0) {
1896 wpa_printf(MSG_DEBUG,
1897 "IBSS already found in scan results, adjust control freq: %d",
1898 bss->freq);
1899 freq->freq = bss->freq;
1900 obss_scan = 0;
1901 break;
1902 }
1903 }
1904
1830817e
JD
1905 /* For IBSS check HT_IBSS flag */
1906 if (ssid->mode == WPAS_MODE_IBSS &&
1907 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_HT_IBSS))
1908 return;
1909
d9a9bc04
JD
1910 if (wpa_s->group_cipher == WPA_CIPHER_WEP40 ||
1911 wpa_s->group_cipher == WPA_CIPHER_WEP104 ||
1912 wpa_s->pairwise_cipher == WPA_CIPHER_TKIP) {
1913 wpa_printf(MSG_DEBUG,
1914 "IBSS: WEP/TKIP detected, do not try to enable HT");
1915 return;
1916 }
1917
98479dc9 1918 hw_mode = ieee80211_freq_to_chan(freq->freq, &channel);
1830817e
JD
1919 for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
1920 if (wpa_s->hw.modes[i].mode == hw_mode) {
1921 mode = &wpa_s->hw.modes[i];
1922 break;
1923 }
1924 }
1925
1926 if (!mode)
1927 return;
1928
3388e7b9
MH
1929#ifdef CONFIG_HT_OVERRIDES
1930 if (ssid->disable_ht) {
1931 freq->ht_enabled = 0;
1932 return;
1933 }
1934#endif /* CONFIG_HT_OVERRIDES */
1935
1830817e 1936 freq->ht_enabled = ht_supported(mode);
6b8b0774
JD
1937 if (!freq->ht_enabled)
1938 return;
1939
1940 /* Setup higher BW only for 5 GHz */
1941 if (mode->mode != HOSTAPD_MODE_IEEE80211A)
1942 return;
1943
1944 for (chan_idx = 0; chan_idx < mode->num_channels; chan_idx++) {
1945 pri_chan = &mode->channels[chan_idx];
1946 if (pri_chan->chan == channel)
1947 break;
1948 pri_chan = NULL;
1949 }
1950 if (!pri_chan)
1951 return;
1952
1953 /* Check primary channel flags */
1954 if (pri_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
1955 return;
1956
05aed438
MH
1957#ifdef CONFIG_HT_OVERRIDES
1958 if (ssid->disable_ht40)
1959 return;
1960#endif /* CONFIG_HT_OVERRIDES */
1961
6b8b0774
JD
1962 /* Check/setup HT40+/HT40- */
1963 for (j = 0; j < ARRAY_SIZE(ht40plus); j++) {
1964 if (ht40plus[j] == channel) {
1965 ht40 = 1;
1966 break;
1967 }
1968 }
1969
1970 /* Find secondary channel */
1971 for (i = 0; i < mode->num_channels; i++) {
1972 sec_chan = &mode->channels[i];
1973 if (sec_chan->chan == channel + ht40 * 4)
1974 break;
1975 sec_chan = NULL;
1976 }
1977 if (!sec_chan)
1978 return;
1979
1980 /* Check secondary channel flags */
1981 if (sec_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
1982 return;
1983
1984 freq->channel = pri_chan->chan;
1985
ecba4509 1986 if (ht40 == -1) {
6b8b0774
JD
1987 if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS))
1988 return;
ecba4509 1989 } else {
6b8b0774
JD
1990 if (!(pri_chan->flag & HOSTAPD_CHAN_HT40PLUS))
1991 return;
6b8b0774 1992 }
ecba4509 1993 freq->sec_channel_offset = ht40;
6b8b0774 1994
ecba4509 1995 if (obss_scan) {
6b8b0774
JD
1996 struct wpa_scan_results *scan_res;
1997
1998 scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
1999 if (scan_res == NULL) {
2000 /* Back to HT20 */
2001 freq->sec_channel_offset = 0;
2002 return;
2003 }
2004
2005 res = check_40mhz_5g(mode, scan_res, pri_chan->chan,
2006 sec_chan->chan);
2007 switch (res) {
2008 case 0:
2009 /* Back to HT20 */
2010 freq->sec_channel_offset = 0;
2011 break;
2012 case 1:
2013 /* Configuration allowed */
2014 break;
2015 case 2:
2016 /* Switch pri/sec channels */
2017 freq->freq = hw_get_freq(mode, sec_chan->chan);
2018 freq->sec_channel_offset = -freq->sec_channel_offset;
2019 freq->channel = sec_chan->chan;
2020 break;
2021 default:
2022 freq->sec_channel_offset = 0;
2023 break;
2024 }
2025
2026 wpa_scan_results_free(scan_res);
2027 }
2028
2029 wpa_printf(MSG_DEBUG,
2030 "IBSS/mesh: setup freq channel %d, sec_channel_offset %d",
2031 freq->channel, freq->sec_channel_offset);
563ee183 2032
a65efbfb 2033 if (!drv_supports_vht(wpa_s, ssid))
563ee183
JD
2034 return;
2035
2036 /* For IBSS check VHT_IBSS flag */
a65efbfb
PO
2037 if (ssid->mode == WPAS_MODE_IBSS &&
2038 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_VHT_IBSS))
563ee183
JD
2039 return;
2040
2041 vht_freq = *freq;
2042
2043 vht_freq.vht_enabled = vht_supported(mode);
2044 if (!vht_freq.vht_enabled)
2045 return;
2046
2047 /* setup center_freq1, bandwidth */
2048 for (j = 0; j < ARRAY_SIZE(vht80); j++) {
2049 if (freq->channel >= vht80[j] &&
2050 freq->channel < vht80[j] + 16)
2051 break;
2052 }
2053
2054 if (j == ARRAY_SIZE(vht80))
2055 return;
2056
2057 for (i = vht80[j]; i < vht80[j] + 16; i += 4) {
2058 struct hostapd_channel_data *chan;
2059
2060 chan = hw_get_channel_chan(mode, i, NULL);
2061 if (!chan)
2062 return;
2063
2064 /* Back to HT configuration if channel not usable */
2065 if (chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
2066 return;
2067 }
2068
0f29bc68
AK
2069 chwidth = VHT_CHANWIDTH_80MHZ;
2070 seg0 = vht80[j] + 6;
2071 seg1 = 0;
2072
2073 if (ssid->max_oper_chwidth == VHT_CHANWIDTH_80P80MHZ) {
2074 /* setup center_freq2, bandwidth */
2075 for (k = 0; k < ARRAY_SIZE(vht80); k++) {
2076 /* Only accept 80 MHz segments separated by a gap */
2077 if (j == k || abs(vht80[j] - vht80[k]) == 16)
2078 continue;
2079 for (i = vht80[k]; i < vht80[k] + 16; i += 4) {
2080 struct hostapd_channel_data *chan;
2081
2082 chan = hw_get_channel_chan(mode, i, NULL);
2083 if (!chan)
2084 continue;
2085
2086 if (chan->flag & (HOSTAPD_CHAN_DISABLED |
2087 HOSTAPD_CHAN_NO_IR |
2088 HOSTAPD_CHAN_RADAR))
2089 continue;
2090
2091 /* Found a suitable second segment for 80+80 */
2092 chwidth = VHT_CHANWIDTH_80P80MHZ;
2093 vht_caps |=
2094 VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
2095 seg1 = vht80[k] + 6;
2096 }
2097
2098 if (chwidth == VHT_CHANWIDTH_80P80MHZ)
2099 break;
2100 }
331f0774
JM
2101 } else if (ssid->max_oper_chwidth == VHT_CHANWIDTH_160MHZ) {
2102 if (freq->freq == 5180) {
2103 chwidth = VHT_CHANWIDTH_160MHZ;
2104 vht_caps |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
2105 seg0 = 50;
2106 } else if (freq->freq == 5520) {
2107 chwidth = VHT_CHANWIDTH_160MHZ;
2108 vht_caps |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
2109 seg0 = 114;
2110 }
0f29bc68
AK
2111 }
2112
563ee183
JD
2113 if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq,
2114 freq->channel, freq->ht_enabled,
2115 vht_freq.vht_enabled,
2116 freq->sec_channel_offset,
0f29bc68 2117 chwidth, seg0, seg1, vht_caps) != 0)
563ee183
JD
2118 return;
2119
2120 *freq = vht_freq;
2121
2122 wpa_printf(MSG_DEBUG, "IBSS: VHT setup freq cf1 %d, cf2 %d, bw %d",
2123 freq->center_freq1, freq->center_freq2, freq->bandwidth);
1830817e
JD
2124}
2125
2126
6ac4b15e
JM
2127static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
2128{
2129 struct wpa_connect_work *cwork = work->ctx;
2130 struct wpa_bss *bss = cwork->bss;
2131 struct wpa_ssid *ssid = cwork->ssid;
2132 struct wpa_supplicant *wpa_s = work->wpa_s;
2133 u8 wpa_ie[200];
2134 size_t wpa_ie_len;
2135 int use_crypt, ret, i, bssid_changed;
2136 int algs = WPA_AUTH_ALG_OPEN;
2137 unsigned int cipher_pairwise, cipher_group;
2138 struct wpa_driver_associate_params params;
2139 int wep_keys_set = 0;
2140 int assoc_failed = 0;
2141 struct wpa_ssid *old_ssid;
6a5ee810 2142 u8 prev_bssid[ETH_ALEN];
6ac4b15e
JM
2143#ifdef CONFIG_HT_OVERRIDES
2144 struct ieee80211_ht_capabilities htcaps;
2145 struct ieee80211_ht_capabilities htcaps_mask;
2146#endif /* CONFIG_HT_OVERRIDES */
6aa1cd4e
PS
2147#ifdef CONFIG_VHT_OVERRIDES
2148 struct ieee80211_vht_capabilities vhtcaps;
2149 struct ieee80211_vht_capabilities vhtcaps_mask;
2150#endif /* CONFIG_VHT_OVERRIDES */
6ac4b15e
JM
2151
2152 if (deinit) {
b3253ebb
AO
2153 if (work->started) {
2154 wpa_s->connect_work = NULL;
2155
2156 /* cancel possible auth. timeout */
2157 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s,
2158 NULL);
2159 }
6ac4b15e
JM
2160 wpas_connect_work_free(cwork);
2161 return;
2162 }
2163
2164 wpa_s->connect_work = work;
2165
6108536d
HW
2166 if (cwork->bss_removed || !wpas_valid_bss_ssid(wpa_s, bss, ssid) ||
2167 wpas_network_disabled(wpa_s, ssid)) {
6ac4b15e
JM
2168 wpa_dbg(wpa_s, MSG_DEBUG, "BSS/SSID entry for association not valid anymore - drop connection attempt");
2169 wpas_connect_work_done(wpa_s);
2170 return;
2171 }
2172
6a5ee810 2173 os_memcpy(prev_bssid, wpa_s->bssid, ETH_ALEN);
0c80427d 2174 os_memset(&params, 0, sizeof(params));
6fc6879b 2175 wpa_s->reassociate = 0;
c60ba9f7 2176 wpa_s->eap_expected_failure = 0;
76d81b32
JM
2177 if (bss &&
2178 (!wpas_driver_bss_selection(wpa_s) || wpas_wps_searching(wpa_s))) {
6fc6879b 2179#ifdef CONFIG_IEEE80211R
6fa81a3b 2180 const u8 *ie, *md = NULL;
6fc6879b 2181#endif /* CONFIG_IEEE80211R */
6fc6879b
JM
2182 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
2183 " (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid),
6fa81a3b 2184 wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq);
8bac466b 2185 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
6fc6879b
JM
2186 os_memset(wpa_s->bssid, 0, ETH_ALEN);
2187 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
8bac466b
JM
2188 if (bssid_changed)
2189 wpas_notify_bssid_changed(wpa_s);
6fc6879b 2190#ifdef CONFIG_IEEE80211R
6fa81a3b 2191 ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
6fc6879b
JM
2192 if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
2193 md = ie + 2;
e7846b68 2194 wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
91a05482
JM
2195 if (md) {
2196 /* Prepare for the next transition */
76b7981d 2197 wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
91a05482 2198 }
6fc6879b 2199#endif /* CONFIG_IEEE80211R */
24c23d1b
JM
2200#ifdef CONFIG_WPS
2201 } else if ((ssid->ssid == NULL || ssid->ssid_len == 0) &&
2202 wpa_s->conf->ap_scan == 2 &&
2203 (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
2204 /* Use ap_scan==1 style network selection to find the network
2205 */
74656400 2206 wpas_connect_work_done(wpa_s);
4115303b 2207 wpa_s->scan_req = MANUAL_SCAN_REQ;
24c23d1b
JM
2208 wpa_s->reassociate = 1;
2209 wpa_supplicant_req_scan(wpa_s, 0, 0);
2210 return;
2211#endif /* CONFIG_WPS */
6fc6879b
JM
2212 } else {
2213 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
2214 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
04e3d815
MK
2215 if (bss)
2216 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
2217 else
2218 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
6fc6879b 2219 }
0d0f7ecb
MS
2220 if (!wpa_s->pno)
2221 wpa_supplicant_cancel_sched_scan(wpa_s);
2222
6fc6879b
JM
2223 wpa_supplicant_cancel_scan(wpa_s);
2224
2225 /* Starting new association, so clear the possibly used WPA IE from the
2226 * previous association. */
2227 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
2228
2229#ifdef IEEE8021X_EAPOL
2230 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
2231 if (ssid->leap) {
2232 if (ssid->non_leap == 0)
abd9fafa 2233 algs = WPA_AUTH_ALG_LEAP;
6fc6879b 2234 else
abd9fafa 2235 algs |= WPA_AUTH_ALG_LEAP;
6fc6879b
JM
2236 }
2237 }
2238#endif /* IEEE8021X_EAPOL */
f049052b 2239 wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs);
6fc6879b 2240 if (ssid->auth_alg) {
abd9fafa 2241 algs = ssid->auth_alg;
f049052b
BG
2242 wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: "
2243 "0x%x", algs);
6fc6879b 2244 }
6fc6879b 2245
6fa81a3b
JM
2246 if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
2247 wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
0bf927a0 2248 wpa_key_mgmt_wpa(ssid->key_mgmt)) {
6fc6879b 2249 int try_opportunistic;
6e202021
JM
2250 try_opportunistic = (ssid->proactive_key_caching < 0 ?
2251 wpa_s->conf->okc :
2252 ssid->proactive_key_caching) &&
6fc6879b
JM
2253 (ssid->proto & WPA_PROTO_RSN);
2254 if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
b2a12c4f 2255 ssid, try_opportunistic) == 0)
ba422613 2256 eapol_sm_notify_pmkid_attempt(wpa_s->eapol);
6fc6879b
JM
2257 wpa_ie_len = sizeof(wpa_ie);
2258 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
2259 wpa_ie, &wpa_ie_len)) {
f049052b
BG
2260 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
2261 "key management and encryption suites");
74656400 2262 wpas_connect_work_done(wpa_s);
6fc6879b
JM
2263 return;
2264 }
a3f7e518
JM
2265 } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && bss &&
2266 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
2267 /*
2268 * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
2269 * use non-WPA since the scan results did not indicate that the
2270 * AP is using WPA or WPA2.
2271 */
2272 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
2273 wpa_ie_len = 0;
2274 wpa_s->wpa_proto = 0;
0bf927a0 2275 } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
6fc6879b
JM
2276 wpa_ie_len = sizeof(wpa_ie);
2277 if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
2278 wpa_ie, &wpa_ie_len)) {
f049052b
BG
2279 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
2280 "key management and encryption suites (no "
2281 "scan results)");
74656400 2282 wpas_connect_work_done(wpa_s);
6fc6879b
JM
2283 return;
2284 }
ad08c363
JM
2285#ifdef CONFIG_WPS
2286 } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
b01c18a8
JM
2287 struct wpabuf *wps_ie;
2288 wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
ad08c363
JM
2289 if (wps_ie && wpabuf_len(wps_ie) <= sizeof(wpa_ie)) {
2290 wpa_ie_len = wpabuf_len(wps_ie);
2291 os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
24386985
JM
2292 } else
2293 wpa_ie_len = 0;
ad08c363
JM
2294 wpabuf_free(wps_ie);
2295 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
0c80427d
JM
2296 if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY))
2297 params.wps = WPS_MODE_PRIVACY;
2298 else
2299 params.wps = WPS_MODE_OPEN;
cf546f1a 2300 wpa_s->wpa_proto = 0;
ad08c363 2301#endif /* CONFIG_WPS */
6fc6879b
JM
2302 } else {
2303 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
2304 wpa_ie_len = 0;
cf546f1a 2305 wpa_s->wpa_proto = 0;
6fc6879b
JM
2306 }
2307
5f3a6aa0
JM
2308#ifdef CONFIG_P2P
2309 if (wpa_s->global->p2p) {
2310 u8 *pos;
2311 size_t len;
2312 int res;
5f3a6aa0
JM
2313 pos = wpa_ie + wpa_ie_len;
2314 len = sizeof(wpa_ie) - wpa_ie_len;
b8a8d677
JM
2315 res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
2316 ssid->p2p_group);
5f3a6aa0
JM
2317 if (res >= 0)
2318 wpa_ie_len += res;
2319 }
72044390
JM
2320
2321 wpa_s->cross_connect_disallowed = 0;
2322 if (bss) {
2323 struct wpabuf *p2p;
2324 p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
2325 if (p2p) {
2326 wpa_s->cross_connect_disallowed =
2327 p2p_get_cross_connect_disallowed(p2p);
2328 wpabuf_free(p2p);
f049052b
BG
2329 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: WLAN AP %s cross "
2330 "connection",
2331 wpa_s->cross_connect_disallowed ?
2332 "disallows" : "allows");
72044390
JM
2333 }
2334 }
25ef8529
JM
2335
2336 os_memset(wpa_s->p2p_ip_addr_info, 0, sizeof(wpa_s->p2p_ip_addr_info));
5f3a6aa0
JM
2337#endif /* CONFIG_P2P */
2338
5e57ba25 2339 if (bss) {
065c029a 2340 wpa_ie_len += wpas_supp_op_class_ie(wpa_s, bss->freq,
2341 wpa_ie + wpa_ie_len,
2342 sizeof(wpa_ie) -
2343 wpa_ie_len);
5e57ba25 2344 }
5e57ba25 2345
8b3b803a
AH
2346 /*
2347 * Workaround: Add Extended Capabilities element only if the AP
2348 * included this element in Beacon/Probe Response frames. Some older
2349 * APs seem to have interoperability issues if this element is
2350 * included, so while the standard may require us to include the
2351 * element in all cases, it is justifiable to skip it to avoid
2352 * interoperability issues.
2353 */
cc9a2575
KV
2354 if (ssid->p2p_group)
2355 wpa_drv_get_ext_capa(wpa_s, WPA_IF_P2P_CLIENT);
2356 else
2357 wpa_drv_get_ext_capa(wpa_s, WPA_IF_STATION);
2358
8b3b803a 2359 if (!bss || wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB)) {
0bbaa9b9 2360 u8 ext_capab[18];
8b3b803a 2361 int ext_capab_len;
0bbaa9b9
JM
2362 ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
2363 sizeof(ext_capab));
8b3b803a
AH
2364 if (ext_capab_len > 0) {
2365 u8 *pos = wpa_ie;
2366 if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)
2367 pos += 2 + pos[1];
2368 os_memmove(pos + ext_capab_len, pos,
2369 wpa_ie_len - (pos - wpa_ie));
2370 wpa_ie_len += ext_capab_len;
2371 os_memcpy(pos, ext_capab, ext_capab_len);
2372 }
92cbcf91 2373 }
92cbcf91 2374
c484b198
AS
2375#ifdef CONFIG_HS20
2376 if (is_hs20_network(wpa_s, ssid, bss)) {
2377 struct wpabuf *hs20;
2378
2379 hs20 = wpabuf_alloc(20);
2380 if (hs20) {
2381 int pps_mo_id = hs20_get_pps_mo_id(wpa_s, ssid);
2382 size_t len;
2383
2384 wpas_hs20_add_indication(hs20, pps_mo_id);
2385 len = sizeof(wpa_ie) - wpa_ie_len;
2386 if (wpabuf_len(hs20) <= len) {
2387 os_memcpy(wpa_ie + wpa_ie_len,
2388 wpabuf_head(hs20), wpabuf_len(hs20));
2389 wpa_ie_len += wpabuf_len(hs20);
2390 }
2391 wpabuf_free(hs20);
ece4ac5f
MG
2392
2393 hs20_configure_frame_filters(wpa_s);
c484b198
AS
2394 }
2395 }
2396#endif /* CONFIG_HS20 */
2397
d29fa3a7
JM
2398 if (wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ]) {
2399 struct wpabuf *buf = wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ];
2400 size_t len;
2401
2402 len = sizeof(wpa_ie) - wpa_ie_len;
2403 if (wpabuf_len(buf) <= len) {
2404 os_memcpy(wpa_ie + wpa_ie_len,
2405 wpabuf_head(buf), wpabuf_len(buf));
2406 wpa_ie_len += wpabuf_len(buf);
2407 }
2408 }
2409
b36a3a65
AN
2410#ifdef CONFIG_FST
2411 if (wpa_s->fst_ies) {
2412 int fst_ies_len = wpabuf_len(wpa_s->fst_ies);
2413
2414 if (wpa_ie_len + fst_ies_len <= sizeof(wpa_ie)) {
2415 os_memcpy(wpa_ie + wpa_ie_len,
2416 wpabuf_head(wpa_s->fst_ies), fst_ies_len);
2417 wpa_ie_len += fst_ies_len;
2418 }
2419 }
2420#endif /* CONFIG_FST */
2421
92c6e2e3 2422#ifdef CONFIG_MBO
065c029a 2423 if (bss && wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE)) {
5e57ba25 2424 int len;
92c6e2e3 2425
5e57ba25
AS
2426 len = wpas_mbo_ie(wpa_s, wpa_ie + wpa_ie_len,
2427 sizeof(wpa_ie) - wpa_ie_len);
2428 if (len >= 0)
2429 wpa_ie_len += len;
92c6e2e3
DS
2430 }
2431#endif /* CONFIG_MBO */
2432
6fc6879b
JM
2433 wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
2434 use_crypt = 1;
4848a38d
JM
2435 cipher_pairwise = wpa_s->pairwise_cipher;
2436 cipher_group = wpa_s->group_cipher;
6fc6879b
JM
2437 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
2438 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
2439 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
2440 use_crypt = 0;
2441 if (wpa_set_wep_keys(wpa_s, ssid)) {
2442 use_crypt = 1;
2443 wep_keys_set = 1;
2444 }
2445 }
ad08c363
JM
2446 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
2447 use_crypt = 0;
6fc6879b
JM
2448
2449#ifdef IEEE8021X_EAPOL
2450 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
2451 if ((ssid->eapol_flags &
2452 (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
2453 EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 &&
2454 !wep_keys_set) {
2455 use_crypt = 0;
2456 } else {
2457 /* Assume that dynamic WEP-104 keys will be used and
2458 * set cipher suites in order for drivers to expect
2459 * encryption. */
4848a38d 2460 cipher_pairwise = cipher_group = WPA_CIPHER_WEP104;
6fc6879b
JM
2461 }
2462 }
2463#endif /* IEEE8021X_EAPOL */
2464
2465 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
2466 /* Set the key before (and later after) association */
2467 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
2468 }
2469
6fc6879b 2470 wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
6fc6879b 2471 if (bss) {
6fa81a3b
JM
2472 params.ssid = bss->ssid;
2473 params.ssid_len = bss->ssid_len;
4b5b8a53
JM
2474 if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set ||
2475 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) {
f15854d1
JM
2476 wpa_printf(MSG_DEBUG, "Limit connection to BSSID "
2477 MACSTR " freq=%u MHz based on scan results "
4b5b8a53 2478 "(bssid_set=%d wps=%d)",
f15854d1 2479 MAC2STR(bss->bssid), bss->freq,
4b5b8a53
JM
2480 ssid->bssid_set,
2481 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS);
22628eca 2482 params.bssid = bss->bssid;
4ec68377 2483 params.freq.freq = bss->freq;
22628eca 2484 }
7ac7fd43
DS
2485 params.bssid_hint = bss->bssid;
2486 params.freq_hint = bss->freq;
b9074912 2487 params.pbss = bss_is_pbss(bss);
6fc6879b
JM
2488 } else {
2489 params.ssid = ssid->ssid;
2490 params.ssid_len = ssid->ssid_len;
90f14962 2491 params.pbss = (ssid->pbss != 2) ? ssid->pbss : 0;
6fc6879b 2492 }
9e2af29f
NC
2493
2494 if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&
2495 wpa_s->conf->ap_scan == 2) {
2496 params.bssid = ssid->bssid;
2497 params.fixed_bssid = 1;
2498 }
2499
603a3f34
JL
2500 /* Initial frequency for IBSS/mesh */
2501 if ((ssid->mode == WPAS_MODE_IBSS || ssid->mode == WPAS_MODE_MESH) &&
1830817e
JD
2502 ssid->frequency > 0 && params.freq.freq == 0)
2503 ibss_mesh_setup_freq(wpa_s, ssid, &params.freq);
dc152f32 2504
8f05577d 2505 if (ssid->mode == WPAS_MODE_IBSS) {
4d9e6fba 2506 params.fixed_freq = ssid->fixed_freq;
8f05577d
JM
2507 if (ssid->beacon_int)
2508 params.beacon_int = ssid->beacon_int;
2509 else
2510 params.beacon_int = wpa_s->conf->beacon_int;
2511 }
2512
6fc6879b
JM
2513 params.wpa_ie = wpa_ie;
2514 params.wpa_ie_len = wpa_ie_len;
2515 params.pairwise_suite = cipher_pairwise;
2516 params.group_suite = cipher_group;
4848a38d 2517 params.key_mgmt_suite = wpa_s->key_mgmt;
64fa840a 2518 params.wpa_proto = wpa_s->wpa_proto;
6fc6879b
JM
2519 params.auth_alg = algs;
2520 params.mode = ssid->mode;
1f6c0ab8 2521 params.bg_scan_period = ssid->bg_scan_period;
6fc6879b
JM
2522 for (i = 0; i < NUM_WEP_KEYS; i++) {
2523 if (ssid->wep_key_len[i])
2524 params.wep_key[i] = ssid->wep_key[i];
2525 params.wep_key_len[i] = ssid->wep_key_len[i];
2526 }
2527 params.wep_tx_keyidx = ssid->wep_tx_keyidx;
2528
c2a04078 2529 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
4848a38d
JM
2530 (params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
2531 params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK)) {
6fc6879b
JM
2532 params.passphrase = ssid->passphrase;
2533 if (ssid->psk_set)
2534 params.psk = ssid->psk;
b41f2684
CL
2535 }
2536
2537 if (wpa_s->conf->key_mgmt_offload) {
2538 if (params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
666497c8 2539 params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
5e3b5197
JM
2540 params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B ||
2541 params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
b41f2684
CL
2542 params.req_key_mgmt_offload =
2543 ssid->proactive_key_caching < 0 ?
2544 wpa_s->conf->okc : ssid->proactive_key_caching;
2545 else
2546 params.req_key_mgmt_offload = 1;
2547
2548 if ((params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
2549 params.key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 ||
2550 params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK) &&
2551 ssid->psk_set)
2552 params.psk = ssid->psk;
6fc6879b
JM
2553 }
2554
36b15723
JM
2555 params.drop_unencrypted = use_crypt;
2556
6fc6879b 2557#ifdef CONFIG_IEEE80211W
3f56a2b7 2558 params.mgmt_frame_protection = wpas_get_ssid_pmf(wpa_s, ssid);
62d49803 2559 if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
6fa81a3b 2560 const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
97d3497e
JM
2561 struct wpa_ie_data ie;
2562 if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
2563 ie.capabilities &
2564 (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
f049052b
BG
2565 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected AP supports "
2566 "MFP: require MFP");
97d3497e
JM
2567 params.mgmt_frame_protection =
2568 MGMT_FRAME_PROTECTION_REQUIRED;
2569 }
2570 }
6fc6879b
JM
2571#endif /* CONFIG_IEEE80211W */
2572
ffad8858 2573 params.p2p = ssid->p2p_group;
6e3f4b89 2574
ba307f85
LD
2575 if (wpa_s->p2pdev->set_sta_uapsd)
2576 params.uapsd = wpa_s->p2pdev->sta_uapsd;
eea2fd9e
JM
2577 else
2578 params.uapsd = -1;
2579
80e8a5ee
BG
2580#ifdef CONFIG_HT_OVERRIDES
2581 os_memset(&htcaps, 0, sizeof(htcaps));
2582 os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
2583 params.htcaps = (u8 *) &htcaps;
2584 params.htcaps_mask = (u8 *) &htcaps_mask;
2585 wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
2586#endif /* CONFIG_HT_OVERRIDES */
6aa1cd4e
PS
2587#ifdef CONFIG_VHT_OVERRIDES
2588 os_memset(&vhtcaps, 0, sizeof(vhtcaps));
2589 os_memset(&vhtcaps_mask, 0, sizeof(vhtcaps_mask));
2590 params.vhtcaps = &vhtcaps;
2591 params.vhtcaps_mask = &vhtcaps_mask;
95ff3069 2592 wpa_supplicant_apply_vht_overrides(wpa_s, ssid, &params);
6aa1cd4e 2593#endif /* CONFIG_VHT_OVERRIDES */
80e8a5ee 2594
8567866d
JJ
2595#ifdef CONFIG_P2P
2596 /*
2597 * If multi-channel concurrency is not supported, check for any
2598 * frequency conflict. In case of any frequency conflict, remove the
2599 * least prioritized connection.
2600 */
2601 if (wpa_s->num_multichan_concurrent < 2) {
d0df6437
IP
2602 int freq, num;
2603 num = get_shared_radio_freqs(wpa_s, &freq, 1);
4ec68377 2604 if (num > 0 && freq > 0 && freq != params.freq.freq) {
d0df6437
IP
2605 wpa_printf(MSG_DEBUG,
2606 "Assoc conflicting freq found (%d != %d)",
4ec68377
JD
2607 freq, params.freq.freq);
2608 if (wpas_p2p_handle_frequency_conflicts(
74656400
SD
2609 wpa_s, params.freq.freq, ssid) < 0) {
2610 wpas_connect_work_done(wpa_s);
8567866d 2611 return;
74656400 2612 }
8567866d
JJ
2613 }
2614 }
2615#endif /* CONFIG_P2P */
2616
6a5ee810
JM
2617 if (wpa_s->reassoc_same_ess && !is_zero_ether_addr(prev_bssid) &&
2618 wpa_s->current_ssid)
2619 params.prev_bssid = prev_bssid;
2620
17fbb751 2621 ret = wpa_drv_associate(wpa_s, &params);
6fc6879b
JM
2622 if (ret < 0) {
2623 wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
2624 "failed");
871f4dd0
JM
2625 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SANE_ERROR_CODES) {
2626 /*
2627 * The driver is known to mean what is saying, so we
2628 * can stop right here; the association will not
2629 * succeed.
2630 */
2631 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
c1c02342 2632 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
871f4dd0
JM
2633 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
2634 return;
2635 }
6fc6879b
JM
2636 /* try to continue anyway; new association will be tried again
2637 * after timeout */
2638 assoc_failed = 1;
2639 }
2640
2641 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
2642 /* Set the key after the association just in case association
2643 * cleared the previously configured key. */
2644 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
2645 /* No need to timeout authentication since there is no key
2646 * management. */
2647 wpa_supplicant_cancel_auth_timeout(wpa_s);
2648 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
53895c3b 2649#ifdef CONFIG_IBSS_RSN
d7dcba70 2650 } else if (ssid->mode == WPAS_MODE_IBSS &&
53895c3b
JM
2651 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
2652 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
2653 /*
2654 * RSN IBSS authentication is per-STA and we can disable the
2655 * per-BSSID authentication.
2656 */
2657 wpa_supplicant_cancel_auth_timeout(wpa_s);
53895c3b 2658#endif /* CONFIG_IBSS_RSN */
6fc6879b
JM
2659 } else {
2660 /* Timeout for IEEE 802.11 authentication and association */
1d3c75b3
DW
2661 int timeout = 60;
2662
2663 if (assoc_failed) {
2664 /* give IBSS a bit more time */
d7dcba70 2665 timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5;
1d3c75b3
DW
2666 } else if (wpa_s->conf->ap_scan == 1) {
2667 /* give IBSS a bit more time */
d7dcba70 2668 timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10;
1d3c75b3 2669 }
6fc6879b
JM
2670 wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
2671 }
2672
66562e9c
JM
2673 if (wep_keys_set &&
2674 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC)) {
6fc6879b
JM
2675 /* Set static WEP keys again */
2676 wpa_set_wep_keys(wpa_s, ssid);
2677 }
2678
2679 if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
2680 /*
2681 * Do not allow EAP session resumption between different
2682 * network configurations.
2683 */
2684 eapol_sm_invalidate_cached_session(wpa_s->eapol);
2685 }
8bac466b 2686 old_ssid = wpa_s->current_ssid;
6fc6879b 2687 wpa_s->current_ssid = ssid;
ece4ac5f
MG
2688
2689 if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
4d3be9cd 2690 wpa_s->current_bss = bss;
ece4ac5f
MG
2691#ifdef CONFIG_HS20
2692 hs20_configure_frame_filters(wpa_s);
2693#endif /* CONFIG_HS20 */
2694 }
2695
6fc6879b
JM
2696 wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
2697 wpa_supplicant_initiate_eapol(wpa_s);
8bac466b
JM
2698 if (old_ssid != wpa_s->current_ssid)
2699 wpas_notify_network_changed(wpa_s);
6fc6879b
JM
2700}
2701
2702
09f58c09
JM
2703static void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s,
2704 const u8 *addr)
2705{
2706 struct wpa_ssid *old_ssid;
2707
c155305f 2708 wpas_connect_work_done(wpa_s);
09f58c09 2709 wpa_clear_keys(wpa_s, addr);
09f58c09 2710 old_ssid = wpa_s->current_ssid;
0d30cc24 2711 wpa_supplicant_mark_disassoc(wpa_s);
09f58c09
JM
2712 wpa_sm_set_config(wpa_s->wpa, NULL);
2713 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
2714 if (old_ssid != wpa_s->current_ssid)
2715 wpas_notify_network_changed(wpa_s);
2716 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
2717}
2718
2719
6fc6879b
JM
2720/**
2721 * wpa_supplicant_deauthenticate - Deauthenticate the current connection
2722 * @wpa_s: Pointer to wpa_supplicant data
2723 * @reason_code: IEEE 802.11 reason code for the deauthenticate frame
2724 *
073ab58f 2725 * This function is used to request %wpa_supplicant to deauthenticate from the
6fc6879b
JM
2726 * current AP.
2727 */
2728void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
2729 int reason_code)
2730{
2731 u8 *addr = NULL;
ef48ff94 2732 union wpa_event_data event;
42d23547 2733 int zero_addr = 0;
8bac466b 2734
42d23547
JM
2735 wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
2736 " pending_bssid=" MACSTR " reason=%d state=%s",
2737 MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
2738 reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state));
2739
04e3d815
MK
2740 if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
2741 (wpa_s->wpa_state == WPA_AUTHENTICATING ||
2742 wpa_s->wpa_state == WPA_ASSOCIATING))
42d23547 2743 addr = wpa_s->pending_bssid;
04e3d815
MK
2744 else if (!is_zero_ether_addr(wpa_s->bssid))
2745 addr = wpa_s->bssid;
42d23547
JM
2746 else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
2747 /*
2748 * When using driver-based BSS selection, we may not know the
2749 * BSSID with which we are currently trying to associate. We
2750 * need to notify the driver of this disconnection even in such
2751 * a case, so use the all zeros address here.
2752 */
6fc6879b 2753 addr = wpa_s->bssid;
42d23547
JM
2754 zero_addr = 1;
2755 }
2756
7b44ff2c
SD
2757#ifdef CONFIG_TDLS
2758 wpa_tdls_teardown_peers(wpa_s->wpa);
2759#endif /* CONFIG_TDLS */
2760
603a3f34
JL
2761#ifdef CONFIG_MESH
2762 if (wpa_s->ifmsh) {
6174de66
JM
2763 wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_REMOVED "%s",
2764 wpa_s->ifname);
603a3f34
JL
2765 wpa_supplicant_leave_mesh(wpa_s);
2766 }
2767#endif /* CONFIG_MESH */
2768
42d23547
JM
2769 if (addr) {
2770 wpa_drv_deauthenticate(wpa_s, addr, reason_code);
ef48ff94
JM
2771 os_memset(&event, 0, sizeof(event));
2772 event.deauth_info.reason_code = (u16) reason_code;
2773 event.deauth_info.locally_generated = 1;
2774 wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
42d23547
JM
2775 if (zero_addr)
2776 addr = NULL;
6fc6879b 2777 }
09f58c09
JM
2778
2779 wpa_supplicant_clear_connection(wpa_s, addr);
6fc6879b
JM
2780}
2781
dca1a511
DS
2782static void wpa_supplicant_enable_one_network(struct wpa_supplicant *wpa_s,
2783 struct wpa_ssid *ssid)
2784{
2785 if (!ssid || !ssid->disabled || ssid->disabled == 2)
2786 return;
2787
2788 ssid->disabled = 0;
2789 wpas_clear_temp_disabled(wpa_s, ssid, 1);
2790 wpas_notify_network_enabled_changed(wpa_s, ssid);
2791
2792 /*
2793 * Try to reassociate since there is no current configuration and a new
2794 * network was made available.
2795 */
d2592497 2796 if (!wpa_s->current_ssid && !wpa_s->disconnected)
dca1a511
DS
2797 wpa_s->reassociate = 1;
2798}
2799
6fc6879b 2800
d015bb05
RP
2801/**
2802 * wpa_supplicant_add_network - Add a new network
2803 * @wpa_s: wpa_supplicant structure for a network interface
2804 * Returns: The new network configuration or %NULL if operation failed
2805 *
2806 * This function performs the following operations:
2807 * 1. Adds a new network.
2808 * 2. Send network addition notification.
2809 * 3. Marks the network disabled.
2810 * 4. Set network default parameters.
2811 */
2812struct wpa_ssid * wpa_supplicant_add_network(struct wpa_supplicant *wpa_s)
2813{
2814 struct wpa_ssid *ssid;
2815
2816 ssid = wpa_config_add_network(wpa_s->conf);
2817 if (!ssid)
2818 return NULL;
2819 wpas_notify_network_added(wpa_s, ssid);
2820 ssid->disabled = 1;
2821 wpa_config_set_network_defaults(ssid);
2822
2823 return ssid;
2824}
2825
2826
2827/**
2828 * wpa_supplicant_remove_network - Remove a configured network based on id
2829 * @wpa_s: wpa_supplicant structure for a network interface
2830 * @id: Unique network id to search for
2831 * Returns: 0 on success, or -1 if the network was not found, -2 if the network
2832 * could not be removed
2833 *
2834 * This function performs the following operations:
2835 * 1. Removes the network.
2836 * 2. Send network removal notification.
2837 * 3. Update internal state machines.
2838 * 4. Stop any running sched scans.
2839 */
2840int wpa_supplicant_remove_network(struct wpa_supplicant *wpa_s, int id)
2841{
2842 struct wpa_ssid *ssid;
2843 int was_disabled;
2844
2845 ssid = wpa_config_get_network(wpa_s->conf, id);
2846 if (!ssid)
2847 return -1;
2848 wpas_notify_network_removed(wpa_s, ssid);
2849
2850 if (wpa_s->last_ssid == ssid)
2851 wpa_s->last_ssid = NULL;
2852
2853 if (ssid == wpa_s->current_ssid || !wpa_s->current_ssid) {
2854#ifdef CONFIG_SME
2855 wpa_s->sme.prev_bssid_set = 0;
2856#endif /* CONFIG_SME */
2857 /*
2858 * Invalidate the EAP session cache if the current or
2859 * previously used network is removed.
2860 */
2861 eapol_sm_invalidate_cached_session(wpa_s->eapol);
2862 }
2863
2864 if (ssid == wpa_s->current_ssid) {
2865 wpa_sm_set_config(wpa_s->wpa, NULL);
2866 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
2867
2868 if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
2869 wpa_s->own_disconnect_req = 1;
2870 wpa_supplicant_deauthenticate(wpa_s,
2871 WLAN_REASON_DEAUTH_LEAVING);
2872 }
2873
2874 was_disabled = ssid->disabled;
2875
2876 if (wpa_config_remove_network(wpa_s->conf, id) < 0)
2877 return -2;
2878
2879 if (!was_disabled && wpa_s->sched_scanning) {
2880 wpa_printf(MSG_DEBUG,
2881 "Stop ongoing sched_scan to remove network from filters");
2882 wpa_supplicant_cancel_sched_scan(wpa_s);
2883 wpa_supplicant_req_scan(wpa_s, 0, 0);
2884 }
2885
2886 return 0;
2887}
2888
2889
86b89452
WS
2890/**
2891 * wpa_supplicant_enable_network - Mark a configured network as enabled
2892 * @wpa_s: wpa_supplicant structure for a network interface
2893 * @ssid: wpa_ssid structure for a configured network or %NULL
2894 *
2895 * Enables the specified network or all networks if no network specified.
2896 */
2897void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
2898 struct wpa_ssid *ssid)
2899{
86b89452 2900 if (ssid == NULL) {
14f79078
JM
2901 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
2902 wpa_supplicant_enable_one_network(wpa_s, ssid);
dca1a511
DS
2903 } else
2904 wpa_supplicant_enable_one_network(wpa_s, ssid);
86b89452 2905
5a1d9d1a
JM
2906 if (wpa_s->reassociate && !wpa_s->disconnected &&
2907 (!wpa_s->current_ssid ||
2908 wpa_s->wpa_state == WPA_DISCONNECTED ||
2909 wpa_s->wpa_state == WPA_SCANNING)) {
dca1a511
DS
2910 if (wpa_s->sched_scanning) {
2911 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to add "
2912 "new network to scan filters");
2913 wpa_supplicant_cancel_sched_scan(wpa_s);
2914 }
86b89452 2915
35d40309
JM
2916 if (wpa_supplicant_fast_associate(wpa_s) != 1) {
2917 wpa_s->scan_req = NORMAL_SCAN_REQ;
dad153d1 2918 wpa_supplicant_req_scan(wpa_s, 0, 0);
35d40309 2919 }
86b89452
WS
2920 }
2921}
2922
2923
2924/**
2925 * wpa_supplicant_disable_network - Mark a configured network as disabled
2926 * @wpa_s: wpa_supplicant structure for a network interface
2927 * @ssid: wpa_ssid structure for a configured network or %NULL
2928 *
2929 * Disables the specified network or all networks if no network specified.
2930 */
2931void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
2932 struct wpa_ssid *ssid)
2933{
2934 struct wpa_ssid *other_ssid;
2935 int was_disabled;
2936
2937 if (ssid == NULL) {
725fc39e
DS
2938 if (wpa_s->sched_scanning)
2939 wpa_supplicant_cancel_sched_scan(wpa_s);
2940
4dac0245
JM
2941 for (other_ssid = wpa_s->conf->ssid; other_ssid;
2942 other_ssid = other_ssid->next) {
86b89452 2943 was_disabled = other_ssid->disabled;
4dac0245
JM
2944 if (was_disabled == 2)
2945 continue; /* do not change persistent P2P group
2946 * data */
86b89452
WS
2947
2948 other_ssid->disabled = 1;
2949
2950 if (was_disabled != other_ssid->disabled)
2951 wpas_notify_network_enabled_changed(
2952 wpa_s, other_ssid);
86b89452
WS
2953 }
2954 if (wpa_s->current_ssid)
07783eaa 2955 wpa_supplicant_deauthenticate(
86b89452 2956 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
4dac0245 2957 } else if (ssid->disabled != 2) {
86b89452 2958 if (ssid == wpa_s->current_ssid)
07783eaa 2959 wpa_supplicant_deauthenticate(
86b89452
WS
2960 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
2961
2962 was_disabled = ssid->disabled;
2963
2964 ssid->disabled = 1;
2965
725fc39e 2966 if (was_disabled != ssid->disabled) {
86b89452 2967 wpas_notify_network_enabled_changed(wpa_s, ssid);
725fc39e
DS
2968 if (wpa_s->sched_scanning) {
2969 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan "
2970 "to remove network from filters");
2971 wpa_supplicant_cancel_sched_scan(wpa_s);
2972 wpa_supplicant_req_scan(wpa_s, 0, 0);
2973 }
2974 }
86b89452
WS
2975 }
2976}
2977
2978
2979/**
2980 * wpa_supplicant_select_network - Attempt association with a network
2981 * @wpa_s: wpa_supplicant structure for a network interface
2982 * @ssid: wpa_ssid structure for a configured network or %NULL for any network
2983 */
2984void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
2985 struct wpa_ssid *ssid)
2986{
2987
2988 struct wpa_ssid *other_ssid;
d93dfbd5 2989 int disconnected = 0;
86b89452 2990
d93dfbd5 2991 if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
e66bcedd
JM
2992 if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
2993 wpa_s->own_disconnect_req = 1;
07783eaa 2994 wpa_supplicant_deauthenticate(
86b89452 2995 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
d93dfbd5
JM
2996 disconnected = 1;
2997 }
86b89452 2998
00e5e3d5
JM
2999 if (ssid)
3000 wpas_clear_temp_disabled(wpa_s, ssid, 1);
3001
86b89452
WS
3002 /*
3003 * Mark all other networks disabled or mark all networks enabled if no
3004 * network specified.
3005 */
4dac0245
JM
3006 for (other_ssid = wpa_s->conf->ssid; other_ssid;
3007 other_ssid = other_ssid->next) {
86b89452 3008 int was_disabled = other_ssid->disabled;
4dac0245
JM
3009 if (was_disabled == 2)
3010 continue; /* do not change persistent P2P group data */
86b89452
WS
3011
3012 other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
00e5e3d5
JM
3013 if (was_disabled && !other_ssid->disabled)
3014 wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
86b89452
WS
3015
3016 if (was_disabled != other_ssid->disabled)
3017 wpas_notify_network_enabled_changed(wpa_s, other_ssid);
86b89452 3018 }
2a6f78fb 3019
d38c7be0
JM
3020 if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid &&
3021 wpa_s->wpa_state >= WPA_AUTHENTICATING) {
2a6f78fb
JJ
3022 /* We are already associated with the selected network */
3023 wpa_printf(MSG_DEBUG, "Already associated with the "
3024 "selected network - do nothing");
3025 return;
3026 }
3027
25a8f9e3 3028 if (ssid) {
96efeeb6 3029 wpa_s->current_ssid = ssid;
25a8f9e3 3030 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
603a3f34
JL
3031 wpa_s->connect_without_scan =
3032 (ssid->mode == WPAS_MODE_MESH) ? ssid : NULL;
701f3961
AS
3033
3034 /*
3035 * Don't optimize next scan freqs since a new ESS has been
3036 * selected.
3037 */
3038 os_free(wpa_s->next_scan_freqs);
3039 wpa_s->next_scan_freqs = NULL;
603a3f34
JL
3040 } else {
3041 wpa_s->connect_without_scan = NULL;
25a8f9e3 3042 }
603a3f34 3043
86b89452
WS
3044 wpa_s->disconnected = 0;
3045 wpa_s->reassociate = 1;
cecdddc1 3046
e4a35f07 3047 if (wpa_s->connect_without_scan ||
35d40309
JM
3048 wpa_supplicant_fast_associate(wpa_s) != 1) {
3049 wpa_s->scan_req = NORMAL_SCAN_REQ;
be7ebd89 3050 wpas_scan_reset_sched_scan(wpa_s);
cecdddc1 3051 wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
35d40309 3052 }
86b89452 3053
a1641d26
JM
3054 if (ssid)
3055 wpas_notify_network_selected(wpa_s, ssid);
86b89452
WS
3056}
3057
3058
bdec7ee5
MS
3059/**
3060 * wpas_set_pkcs11_engine_and_module_path - Set PKCS #11 engine and module path
3061 * @wpa_s: wpa_supplicant structure for a network interface
3062 * @pkcs11_engine_path: PKCS #11 engine path or NULL
3063 * @pkcs11_module_path: PKCS #11 module path or NULL
3064 * Returns: 0 on success; -1 on failure
3065 *
3066 * Sets the PKCS #11 engine and module path. Both have to be NULL or a valid
3067 * path. If resetting the EAPOL state machine with the new PKCS #11 engine and
3068 * module path fails the paths will be reset to the default value (NULL).
3069 */
3070int wpas_set_pkcs11_engine_and_module_path(struct wpa_supplicant *wpa_s,
3071 const char *pkcs11_engine_path,
3072 const char *pkcs11_module_path)
3073{
3074 char *pkcs11_engine_path_copy = NULL;
3075 char *pkcs11_module_path_copy = NULL;
3076
3077 if (pkcs11_engine_path != NULL) {
3078 pkcs11_engine_path_copy = os_strdup(pkcs11_engine_path);
3079 if (pkcs11_engine_path_copy == NULL)
3080 return -1;
3081 }
3082 if (pkcs11_module_path != NULL) {
3083 pkcs11_module_path_copy = os_strdup(pkcs11_module_path);
04c366cb 3084 if (pkcs11_module_path_copy == NULL) {
bdec7ee5
MS
3085 os_free(pkcs11_engine_path_copy);
3086 return -1;
3087 }
3088 }
3089
3090 os_free(wpa_s->conf->pkcs11_engine_path);
3091 os_free(wpa_s->conf->pkcs11_module_path);
3092 wpa_s->conf->pkcs11_engine_path = pkcs11_engine_path_copy;
3093 wpa_s->conf->pkcs11_module_path = pkcs11_module_path_copy;
3094
3095 wpa_sm_set_eapol(wpa_s->wpa, NULL);
3096 eapol_sm_deinit(wpa_s->eapol);
3097 wpa_s->eapol = NULL;
3098 if (wpa_supplicant_init_eapol(wpa_s)) {
3099 /* Error -> Reset paths to the default value (NULL) once. */
3100 if (pkcs11_engine_path != NULL && pkcs11_module_path != NULL)
3101 wpas_set_pkcs11_engine_and_module_path(wpa_s, NULL,
3102 NULL);
3103
3104 return -1;
3105 }
3106 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
3107
3108 return 0;
3109}
3110
3111
86b89452
WS
3112/**
3113 * wpa_supplicant_set_ap_scan - Set AP scan mode for interface
3114 * @wpa_s: wpa_supplicant structure for a network interface
3115 * @ap_scan: AP scan mode
3116 * Returns: 0 if succeed or -1 if ap_scan has an invalid value
3117 *
3118 */
3119int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
3120{
3121
3122 int old_ap_scan;
3123
3124 if (ap_scan < 0 || ap_scan > 2)
3125 return -1;
3126
8406cd35
JM
3127 if (ap_scan == 2 && os_strcmp(wpa_s->driver->name, "nl80211") == 0) {
3128 wpa_printf(MSG_INFO,
3129 "Note: nl80211 driver interface is not designed to be used with ap_scan=2; this can result in connection failures");
3130 }
3131
48f8e036
DS
3132#ifdef ANDROID
3133 if (ap_scan == 2 && ap_scan != wpa_s->conf->ap_scan &&
3134 wpa_s->wpa_state >= WPA_ASSOCIATING &&
3135 wpa_s->wpa_state < WPA_COMPLETED) {
3136 wpa_printf(MSG_ERROR, "ap_scan = %d (%d) rejected while "
3137 "associating", wpa_s->conf->ap_scan, ap_scan);
3138 return 0;
3139 }
3140#endif /* ANDROID */
3141
86b89452
WS
3142 old_ap_scan = wpa_s->conf->ap_scan;
3143 wpa_s->conf->ap_scan = ap_scan;
3144
3145 if (old_ap_scan != wpa_s->conf->ap_scan)
3146 wpas_notify_ap_scan_changed(wpa_s);
3147
3148 return 0;
3149}
3150
3151
78633c37
SL
3152/**
3153 * wpa_supplicant_set_bss_expiration_age - Set BSS entry expiration age
3154 * @wpa_s: wpa_supplicant structure for a network interface
3155 * @expire_age: Expiration age in seconds
3156 * Returns: 0 if succeed or -1 if expire_age has an invalid value
3157 *
3158 */
3159int wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
3160 unsigned int bss_expire_age)
3161{
3162 if (bss_expire_age < 10) {
3163 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration age %u",
3164 bss_expire_age);
3165 return -1;
3166 }
3167 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration age: %d sec",
3168 bss_expire_age);
3169 wpa_s->conf->bss_expiration_age = bss_expire_age;
3170
3171 return 0;
3172}
3173
3174
3175/**
3176 * wpa_supplicant_set_bss_expiration_count - Set BSS entry expiration scan count
3177 * @wpa_s: wpa_supplicant structure for a network interface
3178 * @expire_count: number of scans after which an unseen BSS is reclaimed
3179 * Returns: 0 if succeed or -1 if expire_count has an invalid value
3180 *
3181 */
3182int wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
3183 unsigned int bss_expire_count)
3184{
3185 if (bss_expire_count < 1) {
3186 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration count %u",
3187 bss_expire_count);
3188 return -1;
3189 }
3190 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration scan count: %u",
3191 bss_expire_count);
3192 wpa_s->conf->bss_expiration_scan_count = bss_expire_count;
3193
3194 return 0;
3195}
3196
3197
c6e86b63
MA
3198/**
3199 * wpa_supplicant_set_scan_interval - Set scan interval
3200 * @wpa_s: wpa_supplicant structure for a network interface
3201 * @scan_interval: scan interval in seconds
3202 * Returns: 0 if succeed or -1 if scan_interval has an invalid value
3203 *
3204 */
3205int wpa_supplicant_set_scan_interval(struct wpa_supplicant *wpa_s,
3206 int scan_interval)
3207{
3208 if (scan_interval < 0) {
3209 wpa_msg(wpa_s, MSG_ERROR, "Invalid scan interval %d",
3210 scan_interval);
3211 return -1;
3212 }
3213 wpa_msg(wpa_s, MSG_DEBUG, "Setting scan interval: %d sec",
3214 scan_interval);
9e737f08 3215 wpa_supplicant_update_scan_int(wpa_s, scan_interval);
c6e86b63
MA
3216
3217 return 0;
3218}
3219
3220
86b89452
WS
3221/**
3222 * wpa_supplicant_set_debug_params - Set global debug params
3223 * @global: wpa_global structure
3224 * @debug_level: debug level
3225 * @debug_timestamp: determines if show timestamp in debug data
3226 * @debug_show_keys: determines if show keys in debug data
3227 * Returns: 0 if succeed or -1 if debug_level has wrong value
3228 */
3229int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
3230 int debug_timestamp, int debug_show_keys)
3231{
3232
3233 int old_level, old_timestamp, old_show_keys;
3234
3235 /* check for allowed debuglevels */
14dc0011
PS
3236 if (debug_level != MSG_EXCESSIVE &&
3237 debug_level != MSG_MSGDUMP &&
86b89452
WS
3238 debug_level != MSG_DEBUG &&
3239 debug_level != MSG_INFO &&
3240 debug_level != MSG_WARNING &&
3241 debug_level != MSG_ERROR)
3242 return -1;
3243
3244 old_level = wpa_debug_level;
3245 old_timestamp = wpa_debug_timestamp;
3246 old_show_keys = wpa_debug_show_keys;
3247
3248 wpa_debug_level = debug_level;
3249 wpa_debug_timestamp = debug_timestamp ? 1 : 0;
3250 wpa_debug_show_keys = debug_show_keys ? 1 : 0;
3251
db9133ac
WS
3252 if (wpa_debug_level != old_level)
3253 wpas_notify_debug_level_changed(global);
3254 if (wpa_debug_timestamp != old_timestamp)
3255 wpas_notify_debug_timestamp_changed(global);
3256 if (wpa_debug_show_keys != old_show_keys)
3257 wpas_notify_debug_show_keys_changed(global);
86b89452
WS
3258
3259 return 0;
3260}
3261
3262
6fc6879b
JM
3263/**
3264 * wpa_supplicant_get_ssid - Get a pointer to the current network structure
3265 * @wpa_s: Pointer to wpa_supplicant data
3266 * Returns: A pointer to the current network structure or %NULL on failure
3267 */
3268struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
3269{
3270 struct wpa_ssid *entry;
eaa8eefe 3271 u8 ssid[SSID_MAX_LEN];
6fc6879b
JM
3272 int res;
3273 size_t ssid_len;
3274 u8 bssid[ETH_ALEN];
3275 int wired;
3276
17fbb751
JM
3277 res = wpa_drv_get_ssid(wpa_s, ssid);
3278 if (res < 0) {
3279 wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
3280 "driver");
3281 return NULL;
6fc6879b 3282 }
17fbb751 3283 ssid_len = res;
6fc6879b 3284
17fbb751 3285 if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
f049052b
BG
3286 wpa_msg(wpa_s, MSG_WARNING, "Could not read BSSID from "
3287 "driver");
6fc6879b
JM
3288 return NULL;
3289 }
3290
c2a04078
JM
3291 wired = wpa_s->conf->ap_scan == 0 &&
3292 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
6fc6879b
JM
3293
3294 entry = wpa_s->conf->ssid;
3295 while (entry) {
349493bd 3296 if (!wpas_network_disabled(wpa_s, entry) &&
6fc6879b
JM
3297 ((ssid_len == entry->ssid_len &&
3298 os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
3299 (!entry->bssid_set ||
3300 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
3301 return entry;
24c23d1b 3302#ifdef CONFIG_WPS
349493bd 3303 if (!wpas_network_disabled(wpa_s, entry) &&
24c23d1b
JM
3304 (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
3305 (entry->ssid == NULL || entry->ssid_len == 0) &&
3306 (!entry->bssid_set ||
3307 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
3308 return entry;
3309#endif /* CONFIG_WPS */
7d232e23 3310
349493bd 3311 if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
7d232e23
ZC
3312 entry->ssid_len == 0 &&
3313 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
3314 return entry;
3315
6fc6879b
JM
3316 entry = entry->next;
3317 }
3318
3319 return NULL;
3320}
3321
3322
7756114f
JM
3323static int select_driver(struct wpa_supplicant *wpa_s, int i)
3324{
3325 struct wpa_global *global = wpa_s->global;
3326
3327 if (wpa_drivers[i]->global_init && global->drv_priv[i] == NULL) {
45e3fc72 3328 global->drv_priv[i] = wpa_drivers[i]->global_init(global);
7756114f
JM
3329 if (global->drv_priv[i] == NULL) {
3330 wpa_printf(MSG_ERROR, "Failed to initialize driver "
3331 "'%s'", wpa_drivers[i]->name);
3332 return -1;
3333 }
3334 }
3335
3336 wpa_s->driver = wpa_drivers[i];
3337 wpa_s->global_drv_priv = global->drv_priv[i];
3338
3339 return 0;
3340}
3341
3342
6fc6879b
JM
3343static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
3344 const char *name)
3345{
3346 int i;
362f781e 3347 size_t len;
74b1c84a 3348 const char *pos, *driver = name;
6fc6879b
JM
3349
3350 if (wpa_s == NULL)
3351 return -1;
3352
c5121837 3353 if (wpa_drivers[0] == NULL) {
f049052b
BG
3354 wpa_msg(wpa_s, MSG_ERROR, "No driver interfaces build into "
3355 "wpa_supplicant");
6fc6879b
JM
3356 return -1;
3357 }
3358
3359 if (name == NULL) {
3360 /* default to first driver in the list */
7756114f 3361 return select_driver(wpa_s, 0);
6fc6879b
JM
3362 }
3363
74b1c84a
SO
3364 do {
3365 pos = os_strchr(driver, ',');
3366 if (pos)
3367 len = pos - driver;
3368 else
3369 len = os_strlen(driver);
3370
3371 for (i = 0; wpa_drivers[i]; i++) {
3372 if (os_strlen(wpa_drivers[i]->name) == len &&
3373 os_strncmp(driver, wpa_drivers[i]->name, len) ==
0f4668ce
DW
3374 0) {
3375 /* First driver that succeeds wins */
3376 if (select_driver(wpa_s, i) == 0)
3377 return 0;
3378 }
6fc6879b 3379 }
74b1c84a
SO
3380
3381 driver = pos + 1;
3382 } while (pos);
6fc6879b 3383
f049052b 3384 wpa_msg(wpa_s, MSG_ERROR, "Unsupported driver '%s'", name);
6fc6879b
JM
3385 return -1;
3386}
3387
3388
a8e0505b
JM
3389/**
3390 * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
3391 * @ctx: Context pointer (wpa_s); this is the ctx variable registered
3392 * with struct wpa_driver_ops::init()
3393 * @src_addr: Source address of the EAPOL frame
3394 * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
3395 * @len: Length of the EAPOL data
3396 *
3397 * This function is called for each received EAPOL frame. Most driver
3398 * interfaces rely on more generic OS mechanism for receiving frames through
3399 * l2_packet, but if such a mechanism is not available, the driver wrapper may
3400 * take care of received EAPOL frames and deliver them to the core supplicant
3401 * code by calling this function.
3402 */
6fc6879b
JM
3403void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
3404 const u8 *buf, size_t len)
3405{
3406 struct wpa_supplicant *wpa_s = ctx;
3407
f049052b 3408 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
6fc6879b
JM
3409 wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
3410
02adead5
MK
3411#ifdef CONFIG_TESTING_OPTIONS
3412 if (wpa_s->ignore_auth_resp) {
3413 wpa_printf(MSG_INFO, "RX EAPOL - ignore_auth_resp active!");
3414 return;
3415 }
3416#endif /* CONFIG_TESTING_OPTIONS */
3417
db76aa64
JM
3418#ifdef CONFIG_PEERKEY
3419 if (wpa_s->wpa_state > WPA_ASSOCIATED && wpa_s->current_ssid &&
3420 wpa_s->current_ssid->peerkey &&
3421 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
3422 wpa_sm_rx_eapol_peerkey(wpa_s->wpa, src_addr, buf, len) == 1) {
3423 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: Processed PeerKey EAPOL-Key");
3424 return;
3425 }
3426#endif /* CONFIG_PEERKEY */
3427
3ab35a66
JM
3428 if (wpa_s->wpa_state < WPA_ASSOCIATED ||
3429 (wpa_s->last_eapol_matches_bssid &&
3430#ifdef CONFIG_AP
3431 !wpa_s->ap_iface &&
3432#endif /* CONFIG_AP */
3433 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) != 0)) {
1ff73338
JM
3434 /*
3435 * There is possible race condition between receiving the
3436 * association event and the EAPOL frame since they are coming
3437 * through different paths from the driver. In order to avoid
3438 * issues in trying to process the EAPOL frame before receiving
3439 * association information, lets queue it for processing until
3ab35a66
JM
3440 * the association event is received. This may also be needed in
3441 * driver-based roaming case, so also use src_addr != BSSID as a
3442 * trigger if we have previously confirmed that the
3443 * Authenticator uses BSSID as the src_addr (which is not the
3444 * case with wired IEEE 802.1X).
1ff73338 3445 */
f049052b 3446 wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing "
3ab35a66
JM
3447 "of received EAPOL frame (state=%s bssid=" MACSTR ")",
3448 wpa_supplicant_state_txt(wpa_s->wpa_state),
3449 MAC2STR(wpa_s->bssid));
1ff73338
JM
3450 wpabuf_free(wpa_s->pending_eapol_rx);
3451 wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
3452 if (wpa_s->pending_eapol_rx) {
c2be937c 3453 os_get_reltime(&wpa_s->pending_eapol_rx_time);
1ff73338
JM
3454 os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
3455 ETH_ALEN);
3456 }
3457 return;
3458 }
3459
3ab35a66
JM
3460 wpa_s->last_eapol_matches_bssid =
3461 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) == 0;
3462
db149ac9
JM
3463#ifdef CONFIG_AP
3464 if (wpa_s->ap_iface) {
3465 wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
3466 return;
3467 }
3468#endif /* CONFIG_AP */
3469
6fc6879b 3470 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
f049052b
BG
3471 wpa_dbg(wpa_s, MSG_DEBUG, "Ignored received EAPOL frame since "
3472 "no key management is configured");
6fc6879b
JM
3473 return;
3474 }
3475
3476 if (wpa_s->eapol_received == 0 &&
c2a04078 3477 (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
56586197 3478 !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
9c972abb
JM
3479 wpa_s->wpa_state != WPA_COMPLETED) &&
3480 (wpa_s->current_ssid == NULL ||
3481 wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) {
6fc6879b 3482 /* Timeout for completing IEEE 802.1X and WPA authentication */
5add4101
JM
3483 int timeout = 10;
3484
3485 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
3486 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
3487 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) {
3488 /* Use longer timeout for IEEE 802.1X/EAP */
3489 timeout = 70;
3490 }
3491
c7dafdf9 3492#ifdef CONFIG_WPS
5add4101
JM
3493 if (wpa_s->current_ssid && wpa_s->current_bss &&
3494 (wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS) &&
3495 eap_is_wps_pin_enrollee(&wpa_s->current_ssid->eap)) {
3496 /*
3497 * Use shorter timeout if going through WPS AP iteration
3498 * for PIN config method with an AP that does not
3499 * advertise Selected Registrar.
3500 */
3501 struct wpabuf *wps_ie;
3502
3503 wps_ie = wpa_bss_get_vendor_ie_multi(
3504 wpa_s->current_bss, WPS_IE_VENDOR_TYPE);
0ef1e290
JM
3505 if (wps_ie &&
3506 !wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1))
5add4101
JM
3507 timeout = 10;
3508 wpabuf_free(wps_ie);
3509 }
c7dafdf9 3510#endif /* CONFIG_WPS */
5add4101
JM
3511
3512 wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
6fc6879b
JM
3513 }
3514 wpa_s->eapol_received++;
3515
3516 if (wpa_s->countermeasures) {
f049052b
BG
3517 wpa_msg(wpa_s, MSG_INFO, "WPA: Countermeasures - dropped "
3518 "EAPOL packet");
6fc6879b
JM
3519 return;
3520 }
3521
8be18440
JM
3522#ifdef CONFIG_IBSS_RSN
3523 if (wpa_s->current_ssid &&
d7dcba70 3524 wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
8be18440
JM
3525 ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
3526 return;
3527 }
3528#endif /* CONFIG_IBSS_RSN */
3529
6fc6879b
JM
3530 /* Source address of the incoming EAPOL frame could be compared to the
3531 * current BSSID. However, it is possible that a centralized
3532 * Authenticator could be using another MAC address than the BSSID of
3533 * an AP, so just allow any address to be used for now. The replies are
3534 * still sent to the current BSSID (if available), though. */
3535
3536 os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
56586197 3537 if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
6fc6879b
JM
3538 eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
3539 return;
3540 wpa_drv_poll(wpa_s);
c2a04078 3541 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
6fc6879b 3542 wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
56586197 3543 else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
6fc6879b
JM
3544 /*
3545 * Set portValid = TRUE here since we are going to skip 4-way
3546 * handshake processing which would normally set portValid. We
3547 * need this to allow the EAPOL state machines to be completed
3548 * without going through EAPOL-Key handshake.
3549 */
3550 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
3551 }
3552}
3553
3554
bfba8deb 3555int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
6fc6879b 3556{
2961bfa8
JM
3557 if ((!wpa_s->p2p_mgmt ||
3558 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
3559 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
bfba8deb 3560 l2_packet_deinit(wpa_s->l2);
6fc6879b
JM
3561 wpa_s->l2 = l2_packet_init(wpa_s->ifname,
3562 wpa_drv_get_mac_addr(wpa_s),
3563 ETH_P_EAPOL,
3564 wpa_supplicant_rx_eapol, wpa_s, 0);
3565 if (wpa_s->l2 == NULL)
3566 return -1;
fdadd5fe
JM
3567 } else {
3568 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
3569 if (addr)
3570 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
6fc6879b
JM
3571 }
3572
3573 if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
f049052b 3574 wpa_msg(wpa_s, MSG_ERROR, "Failed to get own L2 address");
6fc6879b
JM
3575 return -1;
3576 }
3577
c267753b
JM
3578 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
3579
bfba8deb
JM
3580 return 0;
3581}
3582
3583
25f839c6
JM
3584static void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr,
3585 const u8 *buf, size_t len)
3586{
3587 struct wpa_supplicant *wpa_s = ctx;
3588 const struct l2_ethhdr *eth;
3589
3590 if (len < sizeof(*eth))
3591 return;
3592 eth = (const struct l2_ethhdr *) buf;
3593
3594 if (os_memcmp(eth->h_dest, wpa_s->own_addr, ETH_ALEN) != 0 &&
3595 !(eth->h_dest[0] & 0x01)) {
3596 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
3597 " (bridge - not for this interface - ignore)",
3598 MAC2STR(src_addr), MAC2STR(eth->h_dest));
3599 return;
3600 }
3601
3602 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
3603 " (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest));
3604 wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth),
3605 len - sizeof(*eth));
3606}
3607
3608
bfba8deb
JM
3609/**
3610 * wpa_supplicant_driver_init - Initialize driver interface parameters
3611 * @wpa_s: Pointer to wpa_supplicant data
3612 * Returns: 0 on success, -1 on failure
3613 *
3614 * This function is called to initialize driver interface parameters.
3615 * wpa_drv_init() must have been called before this function to initialize the
3616 * driver interface.
3617 */
3618int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
3619{
3620 static int interface_count = 0;
3621
3622 if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
3623 return -1;
3624
c68f6200
AS
3625 wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
3626 MAC2STR(wpa_s->own_addr));
a313d17d 3627 os_memcpy(wpa_s->perm_addr, wpa_s->own_addr, ETH_ALEN);
c68f6200
AS
3628 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
3629
6fc6879b 3630 if (wpa_s->bridge_ifname[0]) {
f049052b
BG
3631 wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
3632 "interface '%s'", wpa_s->bridge_ifname);
e6dd8196
JM
3633 wpa_s->l2_br = l2_packet_init_bridge(
3634 wpa_s->bridge_ifname, wpa_s->ifname, wpa_s->own_addr,
3635 ETH_P_EAPOL, wpa_supplicant_rx_eapol_bridge, wpa_s, 1);
6fc6879b 3636 if (wpa_s->l2_br == NULL) {
f049052b
BG
3637 wpa_msg(wpa_s, MSG_ERROR, "Failed to open l2_packet "
3638 "connection for the bridge interface '%s'",
3639 wpa_s->bridge_ifname);
6fc6879b
JM
3640 return -1;
3641 }
3642 }
3643
8406cd35
JM
3644 if (wpa_s->conf->ap_scan == 2 &&
3645 os_strcmp(wpa_s->driver->name, "nl80211") == 0) {
3646 wpa_printf(MSG_INFO,
3647 "Note: nl80211 driver interface is not designed to be used with ap_scan=2; this can result in connection failures");
3648 }
3649
6fc6879b
JM
3650 wpa_clear_keys(wpa_s, NULL);
3651
3652 /* Make sure that TKIP countermeasures are not left enabled (could
3653 * happen if wpa_supplicant is killed during countermeasures. */
3654 wpa_drv_set_countermeasures(wpa_s, 0);
3655
f049052b 3656 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
6fc6879b
JM
3657 wpa_drv_flush_pmkid(wpa_s);
3658
ba2a573c 3659 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
b3aa456b
ES
3660 wpa_s->prev_scan_wildcard = 0;
3661
349493bd 3662 if (wpa_supplicant_enabled_networks(wpa_s)) {
a0e9d892
AS
3663 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
3664 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
3665 interface_count = 0;
3666 }
ee82e33d 3667#ifndef ANDROID
3a94adbf 3668 if (!wpa_s->p2p_mgmt &&
5d0d72a3
BG
3669 wpa_supplicant_delayed_sched_scan(wpa_s,
3670 interface_count % 3,
6a90053c 3671 100000))
5d0d72a3 3672 wpa_supplicant_req_scan(wpa_s, interface_count % 3,
a4cba8f1 3673 100000);
ee82e33d 3674#endif /* ANDROID */
74e259ec
JM
3675 interface_count++;
3676 } else
3677 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
6fc6879b
JM
3678
3679 return 0;
3680}
3681
3682
3683static int wpa_supplicant_daemon(const char *pid_file)
3684{
3685 wpa_printf(MSG_DEBUG, "Daemonize..");
3686 return os_daemonize(pid_file);
3687}
3688
3689
1772d348
JM
3690static struct wpa_supplicant *
3691wpa_supplicant_alloc(struct wpa_supplicant *parent)
6fc6879b
JM
3692{
3693 struct wpa_supplicant *wpa_s;
3694
3695 wpa_s = os_zalloc(sizeof(*wpa_s));
3696 if (wpa_s == NULL)
3697 return NULL;
4115303b 3698 wpa_s->scan_req = INITIAL_SCAN_REQ;
67b9bd08 3699 wpa_s->scan_interval = 5;
c302f207 3700 wpa_s->new_connection = 1;
1772d348 3701 wpa_s->parent = parent ? parent : wpa_s;
ba307f85 3702 wpa_s->p2pdev = wpa_s->parent;
cbdf3507 3703 wpa_s->sched_scanning = 0;
6fc6879b 3704
dd599908
AS
3705 dl_list_init(&wpa_s->bss_tmp_disallowed);
3706
6fc6879b
JM
3707 return wpa_s;
3708}
3709
3710
80e8a5ee
BG
3711#ifdef CONFIG_HT_OVERRIDES
3712
3713static int wpa_set_htcap_mcs(struct wpa_supplicant *wpa_s,
3714 struct ieee80211_ht_capabilities *htcaps,
3715 struct ieee80211_ht_capabilities *htcaps_mask,
3716 const char *ht_mcs)
3717{
3718 /* parse ht_mcs into hex array */
3719 int i;
3720 const char *tmp = ht_mcs;
3721 char *end = NULL;
3722
3723 /* If ht_mcs is null, do not set anything */
3724 if (!ht_mcs)
3725 return 0;
3726
3727 /* This is what we are setting in the kernel */
3728 os_memset(&htcaps->supported_mcs_set, 0, IEEE80211_HT_MCS_MASK_LEN);
3729
3730 wpa_msg(wpa_s, MSG_DEBUG, "set_htcap, ht_mcs -:%s:-", ht_mcs);
3731
3732 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
3733 errno = 0;
3734 long v = strtol(tmp, &end, 16);
3735 if (errno == 0) {
3736 wpa_msg(wpa_s, MSG_DEBUG,
3737 "htcap value[%i]: %ld end: %p tmp: %p",
3738 i, v, end, tmp);
3739 if (end == tmp)
3740 break;
3741
3742 htcaps->supported_mcs_set[i] = v;
3743 tmp = end;
3744 } else {
3745 wpa_msg(wpa_s, MSG_ERROR,
3746 "Failed to parse ht-mcs: %s, error: %s\n",
3747 ht_mcs, strerror(errno));
3748 return -1;
3749 }
3750 }
3751
3752 /*
3753 * If we were able to parse any values, then set mask for the MCS set.
3754 */
3755 if (i) {
3756 os_memset(&htcaps_mask->supported_mcs_set, 0xff,
3757 IEEE80211_HT_MCS_MASK_LEN - 1);
3758 /* skip the 3 reserved bits */
3759 htcaps_mask->supported_mcs_set[IEEE80211_HT_MCS_MASK_LEN - 1] =
3760 0x1f;
3761 }
3762
3763 return 0;
3764}
3765
3766
3767static int wpa_disable_max_amsdu(struct wpa_supplicant *wpa_s,
3768 struct ieee80211_ht_capabilities *htcaps,
3769 struct ieee80211_ht_capabilities *htcaps_mask,
3770 int disabled)
3771{
5bc28571 3772 le16 msk;
80e8a5ee
BG
3773
3774 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
3775
3776 if (disabled == -1)
3777 return 0;
3778
3779 msk = host_to_le16(HT_CAP_INFO_MAX_AMSDU_SIZE);
3780 htcaps_mask->ht_capabilities_info |= msk;
3781 if (disabled)
3782 htcaps->ht_capabilities_info &= msk;
3783 else
3784 htcaps->ht_capabilities_info |= msk;
3785
3786 return 0;
3787}
3788
3789
3790static int wpa_set_ampdu_factor(struct wpa_supplicant *wpa_s,
3791 struct ieee80211_ht_capabilities *htcaps,
3792 struct ieee80211_ht_capabilities *htcaps_mask,
3793 int factor)
3794{
3795 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
3796
3797 if (factor == -1)
3798 return 0;
3799
3800 if (factor < 0 || factor > 3) {
3801 wpa_msg(wpa_s, MSG_ERROR, "ampdu_factor: %d out of range. "
3802 "Must be 0-3 or -1", factor);
3803 return -EINVAL;
3804 }
3805
3806 htcaps_mask->a_mpdu_params |= 0x3; /* 2 bits for factor */
3807 htcaps->a_mpdu_params &= ~0x3;
3808 htcaps->a_mpdu_params |= factor & 0x3;
3809
3810 return 0;
3811}
3812
3813
3814static int wpa_set_ampdu_density(struct wpa_supplicant *wpa_s,
3815 struct ieee80211_ht_capabilities *htcaps,
3816 struct ieee80211_ht_capabilities *htcaps_mask,
3817 int density)
3818{
3819 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
3820
3821 if (density == -1)
3822 return 0;
3823
3824 if (density < 0 || density > 7) {
3825 wpa_msg(wpa_s, MSG_ERROR,
3826 "ampdu_density: %d out of range. Must be 0-7 or -1.",
3827 density);
3828 return -EINVAL;
3829 }
3830
3831 htcaps_mask->a_mpdu_params |= 0x1C;
3832 htcaps->a_mpdu_params &= ~(0x1C);
3833 htcaps->a_mpdu_params |= (density << 2) & 0x1C;
3834
3835 return 0;
3836}
3837
3838
3839static int wpa_set_disable_ht40(struct wpa_supplicant *wpa_s,
3840 struct ieee80211_ht_capabilities *htcaps,
3841 struct ieee80211_ht_capabilities *htcaps_mask,
3842 int disabled)
3843{
3844 /* Masking these out disables HT40 */
5bc28571
JM
3845 le16 msk = host_to_le16(HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET |
3846 HT_CAP_INFO_SHORT_GI40MHZ);
80e8a5ee
BG
3847
3848 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
3849
3850 if (disabled)
3851 htcaps->ht_capabilities_info &= ~msk;
3852 else
3853 htcaps->ht_capabilities_info |= msk;
3854
3855 htcaps_mask->ht_capabilities_info |= msk;
3856
3857 return 0;
3858}
3859
3860
a90497f8
BG
3861static int wpa_set_disable_sgi(struct wpa_supplicant *wpa_s,
3862 struct ieee80211_ht_capabilities *htcaps,
3863 struct ieee80211_ht_capabilities *htcaps_mask,
3864 int disabled)
3865{
3866 /* Masking these out disables SGI */
5bc28571
JM
3867 le16 msk = host_to_le16(HT_CAP_INFO_SHORT_GI20MHZ |
3868 HT_CAP_INFO_SHORT_GI40MHZ);
a90497f8
BG
3869
3870 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_sgi: %d", disabled);
3871
3872 if (disabled)
3873 htcaps->ht_capabilities_info &= ~msk;
3874 else
3875 htcaps->ht_capabilities_info |= msk;
3876
3877 htcaps_mask->ht_capabilities_info |= msk;
3878
3879 return 0;
3880}
3881
3882
39a5800f
PK
3883static int wpa_set_disable_ldpc(struct wpa_supplicant *wpa_s,
3884 struct ieee80211_ht_capabilities *htcaps,
3885 struct ieee80211_ht_capabilities *htcaps_mask,
3886 int disabled)
3887{
3888 /* Masking these out disables LDPC */
5bc28571 3889 le16 msk = host_to_le16(HT_CAP_INFO_LDPC_CODING_CAP);
39a5800f
PK
3890
3891 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ldpc: %d", disabled);
3892
3893 if (disabled)
3894 htcaps->ht_capabilities_info &= ~msk;
3895 else
3896 htcaps->ht_capabilities_info |= msk;
3897
3898 htcaps_mask->ht_capabilities_info |= msk;
3899
3900 return 0;
3901}
3902
3903
80e8a5ee
BG
3904void wpa_supplicant_apply_ht_overrides(
3905 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
3906 struct wpa_driver_associate_params *params)
3907{
3908 struct ieee80211_ht_capabilities *htcaps;
3909 struct ieee80211_ht_capabilities *htcaps_mask;
3910
3911 if (!ssid)
3912 return;
3913
3914 params->disable_ht = ssid->disable_ht;
3915 if (!params->htcaps || !params->htcaps_mask)
3916 return;
3917
3918 htcaps = (struct ieee80211_ht_capabilities *) params->htcaps;
3919 htcaps_mask = (struct ieee80211_ht_capabilities *) params->htcaps_mask;
3920 wpa_set_htcap_mcs(wpa_s, htcaps, htcaps_mask, ssid->ht_mcs);
3921 wpa_disable_max_amsdu(wpa_s, htcaps, htcaps_mask,
3922 ssid->disable_max_amsdu);
3923 wpa_set_ampdu_factor(wpa_s, htcaps, htcaps_mask, ssid->ampdu_factor);
3924 wpa_set_ampdu_density(wpa_s, htcaps, htcaps_mask, ssid->ampdu_density);
3925 wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40);
a90497f8 3926 wpa_set_disable_sgi(wpa_s, htcaps, htcaps_mask, ssid->disable_sgi);
39a5800f 3927 wpa_set_disable_ldpc(wpa_s, htcaps, htcaps_mask, ssid->disable_ldpc);
d41cc8cc
JM
3928
3929 if (ssid->ht40_intolerant) {
5bc28571 3930 le16 bit = host_to_le16(HT_CAP_INFO_40MHZ_INTOLERANT);
d41cc8cc
JM
3931 htcaps->ht_capabilities_info |= bit;
3932 htcaps_mask->ht_capabilities_info |= bit;
3933 }
80e8a5ee
BG
3934}
3935
3936#endif /* CONFIG_HT_OVERRIDES */
3937
3938
e9ee8dc3
JB
3939#ifdef CONFIG_VHT_OVERRIDES
3940void wpa_supplicant_apply_vht_overrides(
3941 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
3942 struct wpa_driver_associate_params *params)
3943{
3944 struct ieee80211_vht_capabilities *vhtcaps;
3945 struct ieee80211_vht_capabilities *vhtcaps_mask;
3946
3947 if (!ssid)
3948 return;
3949
3950 params->disable_vht = ssid->disable_vht;
3951
3952 vhtcaps = (void *) params->vhtcaps;
3953 vhtcaps_mask = (void *) params->vhtcaps_mask;
3954
3955 if (!vhtcaps || !vhtcaps_mask)
3956 return;
3957
4d8d710f
JM
3958 vhtcaps->vht_capabilities_info = host_to_le32(ssid->vht_capa);
3959 vhtcaps_mask->vht_capabilities_info = host_to_le32(ssid->vht_capa_mask);
e9ee8dc3 3960
4f560cde
EP
3961#ifdef CONFIG_HT_OVERRIDES
3962 /* if max ampdu is <= 3, we have to make the HT cap the same */
b0f33467
JM
3963 if (ssid->vht_capa_mask & VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX) {
3964 int max_ampdu;
3965
3966 max_ampdu = (ssid->vht_capa &
3967 VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX) >>
3968 VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX_SHIFT;
4f560cde
EP
3969
3970 max_ampdu = max_ampdu < 3 ? max_ampdu : 3;
3971 wpa_set_ampdu_factor(wpa_s,
3972 (void *) params->htcaps,
3973 (void *) params->htcaps_mask,
3974 max_ampdu);
3975 }
3976#endif /* CONFIG_HT_OVERRIDES */
3977
e9ee8dc3
JB
3978#define OVERRIDE_MCS(i) \
3979 if (ssid->vht_tx_mcs_nss_ ##i >= 0) { \
3980 vhtcaps_mask->vht_supported_mcs_set.tx_map |= \
4d8d710f 3981 host_to_le16(3 << 2 * (i - 1)); \
e9ee8dc3 3982 vhtcaps->vht_supported_mcs_set.tx_map |= \
4d8d710f
JM
3983 host_to_le16(ssid->vht_tx_mcs_nss_ ##i << \
3984 2 * (i - 1)); \
e9ee8dc3
JB
3985 } \
3986 if (ssid->vht_rx_mcs_nss_ ##i >= 0) { \
3987 vhtcaps_mask->vht_supported_mcs_set.rx_map |= \
4d8d710f 3988 host_to_le16(3 << 2 * (i - 1)); \
e9ee8dc3 3989 vhtcaps->vht_supported_mcs_set.rx_map |= \
4d8d710f
JM
3990 host_to_le16(ssid->vht_rx_mcs_nss_ ##i << \
3991 2 * (i - 1)); \
e9ee8dc3
JB
3992 }
3993
3994 OVERRIDE_MCS(1);
3995 OVERRIDE_MCS(2);
3996 OVERRIDE_MCS(3);
3997 OVERRIDE_MCS(4);
3998 OVERRIDE_MCS(5);
3999 OVERRIDE_MCS(6);
4000 OVERRIDE_MCS(7);
4001 OVERRIDE_MCS(8);
4002}
4003#endif /* CONFIG_VHT_OVERRIDES */
4004
4005
f64adcd7
JM
4006static int pcsc_reader_init(struct wpa_supplicant *wpa_s)
4007{
4008#ifdef PCSC_FUNCS
4009 size_t len;
4010
4011 if (!wpa_s->conf->pcsc_reader)
4012 return 0;
4013
22cf7d73 4014 wpa_s->scard = scard_init(wpa_s->conf->pcsc_reader);
f64adcd7
JM
4015 if (!wpa_s->scard)
4016 return 1;
4017
4018 if (wpa_s->conf->pcsc_pin &&
4019 scard_set_pin(wpa_s->scard, wpa_s->conf->pcsc_pin) < 0) {
4020 scard_deinit(wpa_s->scard);
4021 wpa_s->scard = NULL;
4022 wpa_msg(wpa_s, MSG_ERROR, "PC/SC PIN validation failed");
4023 return -1;
4024 }
4025
4026 len = sizeof(wpa_s->imsi) - 1;
4027 if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
4028 scard_deinit(wpa_s->scard);
4029 wpa_s->scard = NULL;
4030 wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
4031 return -1;
4032 }
4033 wpa_s->imsi[len] = '\0';
4034
4035 wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
4036
4037 wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
4038 wpa_s->imsi, wpa_s->mnc_len);
4039
4040 wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
4041 eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
4042#endif /* PCSC_FUNCS */
4043
4044 return 0;
4045}
4046
4047
306ae225
JM
4048int wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
4049{
4050 char *val, *pos;
4051
4052 ext_password_deinit(wpa_s->ext_pw);
4053 wpa_s->ext_pw = NULL;
4054 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, NULL);
4055
4056 if (!wpa_s->conf->ext_password_backend)
4057 return 0;
4058
4059 val = os_strdup(wpa_s->conf->ext_password_backend);
4060 if (val == NULL)
4061 return -1;
4062 pos = os_strchr(val, ':');
4063 if (pos)
4064 *pos++ = '\0';
4065
4066 wpa_printf(MSG_DEBUG, "EXT PW: Initialize backend '%s'", val);
4067
4068 wpa_s->ext_pw = ext_password_init(val, pos);
4069 os_free(val);
4070 if (wpa_s->ext_pw == NULL) {
4071 wpa_printf(MSG_DEBUG, "EXT PW: Failed to initialize backend");
4072 return -1;
4073 }
4074 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, wpa_s->ext_pw);
4075
4076 return 0;
4077}
4078
4079
b36a3a65
AN
4080#ifdef CONFIG_FST
4081
4082static const u8 * wpas_fst_get_bssid_cb(void *ctx)
4083{
4084 struct wpa_supplicant *wpa_s = ctx;
4085
4086 return (is_zero_ether_addr(wpa_s->bssid) ||
4087 wpa_s->wpa_state != WPA_COMPLETED) ? NULL : wpa_s->bssid;
4088}
4089
4090
4091static void wpas_fst_get_channel_info_cb(void *ctx,
4092 enum hostapd_hw_mode *hw_mode,
4093 u8 *channel)
4094{
4095 struct wpa_supplicant *wpa_s = ctx;
4096
4097 if (wpa_s->current_bss) {
4098 *hw_mode = ieee80211_freq_to_chan(wpa_s->current_bss->freq,
4099 channel);
4100 } else if (wpa_s->hw.num_modes) {
4101 *hw_mode = wpa_s->hw.modes[0].mode;
4102 } else {
4103 WPA_ASSERT(0);
4104 *hw_mode = 0;
4105 }
4106}
4107
4108
4109static int wpas_fst_get_hw_modes(void *ctx, struct hostapd_hw_modes **modes)
4110{
4111 struct wpa_supplicant *wpa_s = ctx;
4112
4113 *modes = wpa_s->hw.modes;
4114 return wpa_s->hw.num_modes;
4115}
4116
4117
84bcb4e7 4118static void wpas_fst_set_ies_cb(void *ctx, const struct wpabuf *fst_ies)
b36a3a65
AN
4119{
4120 struct wpa_supplicant *wpa_s = ctx;
4121
b7a07937 4122 wpa_hexdump_buf(MSG_DEBUG, "FST: Set IEs", fst_ies);
b36a3a65
AN
4123 wpa_s->fst_ies = fst_ies;
4124}
4125
4126
4127static int wpas_fst_send_action_cb(void *ctx, const u8 *da, struct wpabuf *data)
4128{
4129 struct wpa_supplicant *wpa_s = ctx;
4130
4131 WPA_ASSERT(os_memcmp(wpa_s->bssid, da, ETH_ALEN) == 0);
4132 return wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
4133 wpa_s->own_addr, wpa_s->bssid,
4134 wpabuf_head(data), wpabuf_len(data),
4135 0);
4136}
4137
4138
a0f04da5 4139static const struct wpabuf * wpas_fst_get_mb_ie_cb(void *ctx, const u8 *addr)
b36a3a65
AN
4140{
4141 struct wpa_supplicant *wpa_s = ctx;
4142
4143 WPA_ASSERT(os_memcmp(wpa_s->bssid, addr, ETH_ALEN) == 0);
4144 return wpa_s->received_mb_ies;
4145}
4146
4147
4148static void wpas_fst_update_mb_ie_cb(void *ctx, const u8 *addr,
4149 const u8 *buf, size_t size)
4150{
4151 struct wpa_supplicant *wpa_s = ctx;
4152 struct mb_ies_info info;
4153
4154 WPA_ASSERT(os_memcmp(wpa_s->bssid, addr, ETH_ALEN) == 0);
4155
4156 if (!mb_ies_info_by_ies(&info, buf, size)) {
4157 wpabuf_free(wpa_s->received_mb_ies);
4158 wpa_s->received_mb_ies = mb_ies_by_info(&info);
4159 }
4160}
4161
4162
39cdd3a0
JM
4163static const u8 * wpas_fst_get_peer_first(void *ctx,
4164 struct fst_get_peer_ctx **get_ctx,
4165 Boolean mb_only)
b36a3a65
AN
4166{
4167 struct wpa_supplicant *wpa_s = ctx;
4168
4169 *get_ctx = NULL;
4170 if (!is_zero_ether_addr(wpa_s->bssid))
4171 return (wpa_s->received_mb_ies || !mb_only) ?
4172 wpa_s->bssid : NULL;
4173 return NULL;
4174}
4175
4176
39cdd3a0
JM
4177static const u8 * wpas_fst_get_peer_next(void *ctx,
4178 struct fst_get_peer_ctx **get_ctx,
4179 Boolean mb_only)
b36a3a65
AN
4180{
4181 return NULL;
4182}
4183
4184void fst_wpa_supplicant_fill_iface_obj(struct wpa_supplicant *wpa_s,
4185 struct fst_wpa_obj *iface_obj)
4186{
4187 iface_obj->ctx = wpa_s;
4188 iface_obj->get_bssid = wpas_fst_get_bssid_cb;
4189 iface_obj->get_channel_info = wpas_fst_get_channel_info_cb;
4190 iface_obj->get_hw_modes = wpas_fst_get_hw_modes;
4191 iface_obj->set_ies = wpas_fst_set_ies_cb;
4192 iface_obj->send_action = wpas_fst_send_action_cb;
4193 iface_obj->get_mb_ie = wpas_fst_get_mb_ie_cb;
4194 iface_obj->update_mb_ie = wpas_fst_update_mb_ie_cb;
4195 iface_obj->get_peer_first = wpas_fst_get_peer_first;
4196 iface_obj->get_peer_next = wpas_fst_get_peer_next;
4197}
4198#endif /* CONFIG_FST */
4199
a520bf4a 4200static int wpas_set_wowlan_triggers(struct wpa_supplicant *wpa_s,
6cbdb0c5 4201 const struct wpa_driver_capa *capa)
e4fa8b12 4202{
88cb27c7
DS
4203 struct wowlan_triggers *triggers;
4204 int ret = 0;
e4fa8b12
EP
4205
4206 if (!wpa_s->conf->wowlan_triggers)
4207 return 0;
4208
88cb27c7
DS
4209 triggers = wpa_get_wowlan_triggers(wpa_s->conf->wowlan_triggers, capa);
4210 if (triggers) {
4211 ret = wpa_drv_wowlan(wpa_s, triggers);
4212 os_free(triggers);
e4fa8b12 4213 }
e4fa8b12
EP
4214 return ret;
4215}
4216
4217
2b6e9f91 4218enum wpa_radio_work_band wpas_freq_to_band(int freq)
e903d32d
KV
4219{
4220 if (freq < 3000)
4221 return BAND_2_4_GHZ;
4222 if (freq > 50000)
4223 return BAND_60_GHZ;
4224 return BAND_5_GHZ;
4225}
4226
4227
2b6e9f91 4228unsigned int wpas_get_bands(struct wpa_supplicant *wpa_s, const int *freqs)
e903d32d
KV
4229{
4230 int i;
4231 unsigned int band = 0;
4232
4233 if (freqs) {
4234 /* freqs are specified for the radio work */
4235 for (i = 0; freqs[i]; i++)
4236 band |= wpas_freq_to_band(freqs[i]);
4237 } else {
4238 /*
4239 * freqs are not specified, implies all
4240 * the supported freqs by HW
4241 */
4242 for (i = 0; i < wpa_s->hw.num_modes; i++) {
4243 if (wpa_s->hw.modes[i].num_channels != 0) {
4244 if (wpa_s->hw.modes[i].mode ==
4245 HOSTAPD_MODE_IEEE80211B ||
4246 wpa_s->hw.modes[i].mode ==
4247 HOSTAPD_MODE_IEEE80211G)
4248 band |= BAND_2_4_GHZ;
4249 else if (wpa_s->hw.modes[i].mode ==
4250 HOSTAPD_MODE_IEEE80211A)
4251 band |= BAND_5_GHZ;
4252 else if (wpa_s->hw.modes[i].mode ==
4253 HOSTAPD_MODE_IEEE80211AD)
4254 band |= BAND_60_GHZ;
4255 else if (wpa_s->hw.modes[i].mode ==
4256 HOSTAPD_MODE_IEEE80211ANY)
4257 band = BAND_2_4_GHZ | BAND_5_GHZ |
4258 BAND_60_GHZ;
4259 }
4260 }
4261 }
4262
4263 return band;
4264}
4265
4266
202dec2a
JM
4267static struct wpa_radio * radio_add_interface(struct wpa_supplicant *wpa_s,
4268 const char *rn)
4269{
4270 struct wpa_supplicant *iface = wpa_s->global->ifaces;
4271 struct wpa_radio *radio;
4272
4273 while (rn && iface) {
4274 radio = iface->radio;
4275 if (radio && os_strcmp(rn, radio->name) == 0) {
4276 wpa_printf(MSG_DEBUG, "Add interface %s to existing radio %s",
4277 wpa_s->ifname, rn);
4278 dl_list_add(&radio->ifaces, &wpa_s->radio_list);
4279 return radio;
4280 }
b154a24e
TB
4281
4282 iface = iface->next;
202dec2a
JM
4283 }
4284
4285 wpa_printf(MSG_DEBUG, "Add interface %s to a new radio %s",
4286 wpa_s->ifname, rn ? rn : "N/A");
4287 radio = os_zalloc(sizeof(*radio));
4288 if (radio == NULL)
4289 return NULL;
4290
4291 if (rn)
4292 os_strlcpy(radio->name, rn, sizeof(radio->name));
4293 dl_list_init(&radio->ifaces);
b1ae396f 4294 dl_list_init(&radio->work);
202dec2a
JM
4295 dl_list_add(&radio->ifaces, &wpa_s->radio_list);
4296
4297 return radio;
4298}
4299
4300
b1ae396f
JM
4301static void radio_work_free(struct wpa_radio_work *work)
4302{
d12a51b5
JM
4303 if (work->wpa_s->scan_work == work) {
4304 /* This should not really happen. */
4305 wpa_dbg(work->wpa_s, MSG_INFO, "Freeing radio work '%s'@%p (started=%d) that is marked as scan_work",
4306 work->type, work, work->started);
4307 work->wpa_s->scan_work = NULL;
4308 }
4309
1b5d4714
JM
4310#ifdef CONFIG_P2P
4311 if (work->wpa_s->p2p_scan_work == work) {
4312 /* This should not really happen. */
4313 wpa_dbg(work->wpa_s, MSG_INFO, "Freeing radio work '%s'@%p (started=%d) that is marked as p2p_scan_work",
4314 work->type, work, work->started);
4315 work->wpa_s->p2p_scan_work = NULL;
4316 }
4317#endif /* CONFIG_P2P */
4318
e903d32d
KV
4319 if (work->started) {
4320 work->wpa_s->radio->num_active_works--;
4321 wpa_dbg(work->wpa_s, MSG_DEBUG,
4322 "radio_work_free('%s'@%p: num_active_works --> %u",
4323 work->type, work,
4324 work->wpa_s->radio->num_active_works);
4325 }
4326
b1ae396f
JM
4327 dl_list_del(&work->list);
4328 os_free(work);
4329}
4330
4331
e903d32d
KV
4332static struct wpa_radio_work * radio_work_get_next_work(struct wpa_radio *radio)
4333{
4334 struct wpa_radio_work *active_work = NULL;
4335 struct wpa_radio_work *tmp;
4336
4337 /* Get the active work to know the type and band. */
4338 dl_list_for_each(tmp, &radio->work, struct wpa_radio_work, list) {
4339 if (tmp->started) {
4340 active_work = tmp;
4341 break;
4342 }
4343 }
4344
4345 if (!active_work) {
4346 /* No active work, start one */
4347 radio->num_active_works = 0;
4348 dl_list_for_each(tmp, &radio->work, struct wpa_radio_work,
4349 list) {
4350 if (os_strcmp(tmp->type, "scan") == 0 &&
4351 radio->external_scan_running &&
4352 (((struct wpa_driver_scan_params *)
4353 tmp->ctx)->only_new_results ||
4354 tmp->wpa_s->clear_driver_scan_cache))
4355 continue;
4356 return tmp;
4357 }
4358 return NULL;
4359 }
4360
4361 if (os_strcmp(active_work->type, "sme-connect") == 0 ||
4362 os_strcmp(active_work->type, "connect") == 0) {
4363 /*
4364 * If the active work is either connect or sme-connect,
4365 * do not parallelize them with other radio works.
4366 */
4367 wpa_dbg(active_work->wpa_s, MSG_DEBUG,
4368 "Do not parallelize radio work with %s",
4369 active_work->type);
4370 return NULL;
4371 }
4372
4373 dl_list_for_each(tmp, &radio->work, struct wpa_radio_work, list) {
4374 if (tmp->started)
4375 continue;
4376
4377 /*
4378 * If connect or sme-connect are enqueued, parallelize only
4379 * those operations ahead of them in the queue.
4380 */
4381 if (os_strcmp(tmp->type, "connect") == 0 ||
4382 os_strcmp(tmp->type, "sme-connect") == 0)
4383 break;
4384
4385 /*
4386 * Check that the radio works are distinct and
4387 * on different bands.
4388 */
4389 if (os_strcmp(active_work->type, tmp->type) != 0 &&
4390 (active_work->bands != tmp->bands)) {
4391 /*
4392 * If a scan has to be scheduled through nl80211 scan
4393 * interface and if an external scan is already running,
4394 * do not schedule the scan since it is likely to get
4395 * rejected by kernel.
4396 */
4397 if (os_strcmp(tmp->type, "scan") == 0 &&
4398 radio->external_scan_running &&
4399 (((struct wpa_driver_scan_params *)
4400 tmp->ctx)->only_new_results ||
4401 tmp->wpa_s->clear_driver_scan_cache))
4402 continue;
4403
4404 wpa_dbg(active_work->wpa_s, MSG_DEBUG,
4405 "active_work:%s new_work:%s",
4406 active_work->type, tmp->type);
4407 return tmp;
4408 }
4409 }
4410
4411 /* Did not find a radio work to schedule in parallel. */
4412 return NULL;
4413}
4414
4415
b1ae396f
JM
4416static void radio_start_next_work(void *eloop_ctx, void *timeout_ctx)
4417{
4418 struct wpa_radio *radio = eloop_ctx;
4419 struct wpa_radio_work *work;
4420 struct os_reltime now, diff;
6428d0a7 4421 struct wpa_supplicant *wpa_s;
b1ae396f
JM
4422
4423 work = dl_list_first(&radio->work, struct wpa_radio_work, list);
e903d32d
KV
4424 if (work == NULL) {
4425 radio->num_active_works = 0;
b1ae396f 4426 return;
e903d32d 4427 }
b1ae396f 4428
6428d0a7
JM
4429 wpa_s = dl_list_first(&radio->ifaces, struct wpa_supplicant,
4430 radio_list);
e903d32d
KV
4431
4432 if (!(wpa_s &&
4433 wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS)) {
4434 if (work->started)
4435 return; /* already started and still in progress */
4436
4437 if (wpa_s && wpa_s->radio->external_scan_running) {
4438 wpa_printf(MSG_DEBUG, "Delay radio work start until externally triggered scan completes");
4439 return;
4440 }
4441 } else {
4442 work = NULL;
4443 if (radio->num_active_works < MAX_ACTIVE_WORKS) {
4444 /* get the work to schedule next */
4445 work = radio_work_get_next_work(radio);
4446 }
4447 if (!work)
4448 return;
6428d0a7
JM
4449 }
4450
e903d32d 4451 wpa_s = work->wpa_s;
b1ae396f
JM
4452 os_get_reltime(&now);
4453 os_reltime_sub(&now, &work->time, &diff);
e903d32d
KV
4454 wpa_dbg(wpa_s, MSG_DEBUG,
4455 "Starting radio work '%s'@%p after %ld.%06ld second wait",
b1ae396f
JM
4456 work->type, work, diff.sec, diff.usec);
4457 work->started = 1;
4458 work->time = now;
e903d32d
KV
4459 radio->num_active_works++;
4460
b1ae396f 4461 work->cb(work, 0);
e903d32d
KV
4462
4463 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS) &&
4464 radio->num_active_works < MAX_ACTIVE_WORKS)
4465 radio_work_check_next(wpa_s);
b1ae396f
JM
4466}
4467
4468
b3253ebb
AO
4469/*
4470 * This function removes both started and pending radio works running on
4471 * the provided interface's radio.
4472 * Prior to the removal of the radio work, its callback (cb) is called with
4473 * deinit set to be 1. Each work's callback is responsible for clearing its
4474 * internal data and restoring to a correct state.
4475 * @wpa_s: wpa_supplicant data
4476 * @type: type of works to be removed
4477 * @remove_all: 1 to remove all the works on this radio, 0 to remove only
4478 * this interface's works.
4479 */
4480void radio_remove_works(struct wpa_supplicant *wpa_s,
4481 const char *type, int remove_all)
b1ae396f
JM
4482{
4483 struct wpa_radio_work *work, *tmp;
4484 struct wpa_radio *radio = wpa_s->radio;
4485
4486 dl_list_for_each_safe(work, tmp, &radio->work, struct wpa_radio_work,
4487 list) {
b3253ebb 4488 if (type && os_strcmp(type, work->type) != 0)
b1ae396f 4489 continue;
b3253ebb
AO
4490
4491 /* skip other ifaces' works */
4492 if (!remove_all && work->wpa_s != wpa_s)
b1ae396f 4493 continue;
b3253ebb
AO
4494
4495 wpa_dbg(wpa_s, MSG_DEBUG, "Remove radio work '%s'@%p%s",
4496 work->type, work, work->started ? " (started)" : "");
b1ae396f
JM
4497 work->cb(work, 1);
4498 radio_work_free(work);
4499 }
b3253ebb
AO
4500
4501 /* in case we removed the started work */
4502 radio_work_check_next(wpa_s);
b1ae396f
JM
4503}
4504
4505
202dec2a
JM
4506static void radio_remove_interface(struct wpa_supplicant *wpa_s)
4507{
4508 struct wpa_radio *radio = wpa_s->radio;
4509
4510 if (!radio)
4511 return;
4512
4513 wpa_printf(MSG_DEBUG, "Remove interface %s from radio %s",
4514 wpa_s->ifname, radio->name);
4515 dl_list_del(&wpa_s->radio_list);
c46235aa
AO
4516 radio_remove_works(wpa_s, NULL, 0);
4517 wpa_s->radio = NULL;
4518 if (!dl_list_empty(&radio->ifaces))
202dec2a
JM
4519 return; /* Interfaces remain for this radio */
4520
4521 wpa_printf(MSG_DEBUG, "Remove radio %s", radio->name);
b1ae396f 4522 eloop_cancel_timeout(radio_start_next_work, radio, NULL);
202dec2a
JM
4523 os_free(radio);
4524}
4525
4526
6428d0a7 4527void radio_work_check_next(struct wpa_supplicant *wpa_s)
b1ae396f
JM
4528{
4529 struct wpa_radio *radio = wpa_s->radio;
4530
4531 if (dl_list_empty(&radio->work))
4532 return;
e3745228
JM
4533 if (wpa_s->ext_work_in_progress) {
4534 wpa_printf(MSG_DEBUG,
4535 "External radio work in progress - delay start of pending item");
4536 return;
4537 }
b1ae396f
JM
4538 eloop_cancel_timeout(radio_start_next_work, radio, NULL);
4539 eloop_register_timeout(0, 0, radio_start_next_work, radio, NULL);
4540}
4541
4542
4543/**
4544 * radio_add_work - Add a radio work item
4545 * @wpa_s: Pointer to wpa_supplicant data
4546 * @freq: Frequency of the offchannel operation in MHz or 0
4547 * @type: Unique identifier for each type of work
4548 * @next: Force as the next work to be executed
4549 * @cb: Callback function for indicating when radio is available
4550 * @ctx: Context pointer for the work (work->ctx in cb())
4551 * Returns: 0 on success, -1 on failure
4552 *
4553 * This function is used to request time for an operation that requires
4554 * exclusive radio control. Once the radio is available, the registered callback
4555 * function will be called. radio_work_done() must be called once the exclusive
4556 * radio operation has been completed, so that the radio is freed for other
4557 * operations. The special case of deinit=1 is used to free the context data
4558 * during interface removal. That does not allow the callback function to start
4559 * the radio operation, i.e., it must free any resources allocated for the radio
4560 * work and return.
4561 *
4562 * The @freq parameter can be used to indicate a single channel on which the
4563 * offchannel operation will occur. This may allow multiple radio work
4564 * operations to be performed in parallel if they apply for the same channel.
4565 * Setting this to 0 indicates that the work item may use multiple channels or
4566 * requires exclusive control of the radio.
4567 */
4568int radio_add_work(struct wpa_supplicant *wpa_s, unsigned int freq,
4569 const char *type, int next,
4570 void (*cb)(struct wpa_radio_work *work, int deinit),
4571 void *ctx)
4572{
e903d32d 4573 struct wpa_radio *radio = wpa_s->radio;
b1ae396f
JM
4574 struct wpa_radio_work *work;
4575 int was_empty;
4576
4577 work = os_zalloc(sizeof(*work));
4578 if (work == NULL)
4579 return -1;
4580 wpa_dbg(wpa_s, MSG_DEBUG, "Add radio work '%s'@%p", type, work);
4581 os_get_reltime(&work->time);
4582 work->freq = freq;
4583 work->type = type;
4584 work->wpa_s = wpa_s;
4585 work->cb = cb;
4586 work->ctx = ctx;
4587
e903d32d
KV
4588 if (freq)
4589 work->bands = wpas_freq_to_band(freq);
4590 else if (os_strcmp(type, "scan") == 0 ||
4591 os_strcmp(type, "p2p-scan") == 0)
4592 work->bands = wpas_get_bands(wpa_s,
4593 ((struct wpa_driver_scan_params *)
4594 ctx)->freqs);
4595 else
4596 work->bands = wpas_get_bands(wpa_s, NULL);
4597
b1ae396f
JM
4598 was_empty = dl_list_empty(&wpa_s->radio->work);
4599 if (next)
4600 dl_list_add(&wpa_s->radio->work, &work->list);
4601 else
4602 dl_list_add_tail(&wpa_s->radio->work, &work->list);
4603 if (was_empty) {
4604 wpa_dbg(wpa_s, MSG_DEBUG, "First radio work item in the queue - schedule start immediately");
4605 radio_work_check_next(wpa_s);
e903d32d
KV
4606 } else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS)
4607 && radio->num_active_works < MAX_ACTIVE_WORKS) {
4608 wpa_dbg(wpa_s, MSG_DEBUG,
4609 "Try to schedule a radio work (num_active_works=%u)",
4610 radio->num_active_works);
4611 radio_work_check_next(wpa_s);
b1ae396f
JM
4612 }
4613
4614 return 0;
4615}
4616
4617
4618/**
4619 * radio_work_done - Indicate that a radio work item has been completed
4620 * @work: Completed work
4621 *
4622 * This function is called once the callback function registered with
4623 * radio_add_work() has completed its work.
4624 */
4625void radio_work_done(struct wpa_radio_work *work)
4626{
4627 struct wpa_supplicant *wpa_s = work->wpa_s;
4628 struct os_reltime now, diff;
1f965e62 4629 unsigned int started = work->started;
b1ae396f
JM
4630
4631 os_get_reltime(&now);
4632 os_reltime_sub(&now, &work->time, &diff);
1f965e62
JM
4633 wpa_dbg(wpa_s, MSG_DEBUG, "Radio work '%s'@%p %s in %ld.%06ld seconds",
4634 work->type, work, started ? "done" : "canceled",
4635 diff.sec, diff.usec);
b1ae396f 4636 radio_work_free(work);
1f965e62
JM
4637 if (started)
4638 radio_work_check_next(wpa_s);
b1ae396f
JM
4639}
4640
4641
a7f5271d
JM
4642struct wpa_radio_work *
4643radio_work_pending(struct wpa_supplicant *wpa_s, const char *type)
f0e30c84
JM
4644{
4645 struct wpa_radio_work *work;
4646 struct wpa_radio *radio = wpa_s->radio;
4647
4648 dl_list_for_each(work, &radio->work, struct wpa_radio_work, list) {
4649 if (work->wpa_s == wpa_s && os_strcmp(work->type, type) == 0)
a7f5271d 4650 return work;
f0e30c84
JM
4651 }
4652
a7f5271d 4653 return NULL;
f0e30c84
JM
4654}
4655
4656
73c00fd7
JM
4657static int wpas_init_driver(struct wpa_supplicant *wpa_s,
4658 struct wpa_interface *iface)
4659{
202dec2a 4660 const char *ifname, *driver, *rn;
73c00fd7
JM
4661
4662 driver = iface->driver;
4663next_driver:
4664 if (wpa_supplicant_set_driver(wpa_s, driver) < 0)
4665 return -1;
4666
4667 wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
4668 if (wpa_s->drv_priv == NULL) {
4669 const char *pos;
4670 pos = driver ? os_strchr(driver, ',') : NULL;
4671 if (pos) {
4672 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
4673 "driver interface - try next driver wrapper");
4674 driver = pos + 1;
4675 goto next_driver;
4676 }
4677 wpa_msg(wpa_s, MSG_ERROR, "Failed to initialize driver "
4678 "interface");
4679 return -1;
4680 }
4681 if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
4682 wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected "
4683 "driver_param '%s'", wpa_s->conf->driver_param);
4684 return -1;
4685 }
4686
4687 ifname = wpa_drv_get_ifname(wpa_s);
4688 if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
4689 wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced "
4690 "interface name with '%s'", ifname);
4691 os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
4692 }
4693
95bf699f 4694 rn = wpa_driver_get_radio_name(wpa_s);
202dec2a
JM
4695 if (rn && rn[0] == '\0')
4696 rn = NULL;
4697
4698 wpa_s->radio = radio_add_interface(wpa_s, rn);
4699 if (wpa_s->radio == NULL)
4700 return -1;
4701
73c00fd7
JM
4702 return 0;
4703}
4704
4705
6fc6879b
JM
4706static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
4707 struct wpa_interface *iface)
4708{
362f781e 4709 struct wpa_driver_capa capa;
6cbdb0c5 4710 int capa_res;
362f781e 4711
6fc6879b
JM
4712 wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
4713 "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
4714 iface->confname ? iface->confname : "N/A",
4715 iface->driver ? iface->driver : "default",
4716 iface->ctrl_interface ? iface->ctrl_interface : "N/A",
4717 iface->bridge_ifname ? iface->bridge_ifname : "N/A");
4718
6fc6879b
JM
4719 if (iface->confname) {
4720#ifdef CONFIG_BACKEND_FILE
4721 wpa_s->confname = os_rel2abs_path(iface->confname);
4722 if (wpa_s->confname == NULL) {
4723 wpa_printf(MSG_ERROR, "Failed to get absolute path "
4724 "for configuration file '%s'.",
4725 iface->confname);
4726 return -1;
4727 }
4728 wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",
4729 iface->confname, wpa_s->confname);
4730#else /* CONFIG_BACKEND_FILE */
4731 wpa_s->confname = os_strdup(iface->confname);
4732#endif /* CONFIG_BACKEND_FILE */
e6304cad 4733 wpa_s->conf = wpa_config_read(wpa_s->confname, NULL);
6fc6879b
JM
4734 if (wpa_s->conf == NULL) {
4735 wpa_printf(MSG_ERROR, "Failed to read or parse "
4736 "configuration '%s'.", wpa_s->confname);
4737 return -1;
4738 }
e6304cad
DS
4739 wpa_s->confanother = os_rel2abs_path(iface->confanother);
4740 wpa_config_read(wpa_s->confanother, wpa_s->conf);
6fc6879b
JM
4741
4742 /*
4743 * Override ctrl_interface and driver_param if set on command
4744 * line.
4745 */
4746 if (iface->ctrl_interface) {
4747 os_free(wpa_s->conf->ctrl_interface);
4748 wpa_s->conf->ctrl_interface =
4749 os_strdup(iface->ctrl_interface);
4750 }
4751
4752 if (iface->driver_param) {
4753 os_free(wpa_s->conf->driver_param);
4754 wpa_s->conf->driver_param =
4755 os_strdup(iface->driver_param);
4756 }
78f79fe5
JM
4757
4758 if (iface->p2p_mgmt && !iface->ctrl_interface) {
4759 os_free(wpa_s->conf->ctrl_interface);
4760 wpa_s->conf->ctrl_interface = NULL;
4761 }
6fc6879b
JM
4762 } else
4763 wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
4764 iface->driver_param);
4765
4766 if (wpa_s->conf == NULL) {
4767 wpa_printf(MSG_ERROR, "\nNo configuration found.");
4768 return -1;
4769 }
4770
4771 if (iface->ifname == NULL) {
4772 wpa_printf(MSG_ERROR, "\nInterface name is required.");
4773 return -1;
4774 }
4775 if (os_strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
4776 wpa_printf(MSG_ERROR, "\nToo long interface name '%s'.",
4777 iface->ifname);
4778 return -1;
4779 }
4780 os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
4781
4782 if (iface->bridge_ifname) {
4783 if (os_strlen(iface->bridge_ifname) >=
4784 sizeof(wpa_s->bridge_ifname)) {
4785 wpa_printf(MSG_ERROR, "\nToo long bridge interface "
4786 "name '%s'.", iface->bridge_ifname);
4787 return -1;
4788 }
4789 os_strlcpy(wpa_s->bridge_ifname, iface->bridge_ifname,
4790 sizeof(wpa_s->bridge_ifname));
4791 }
4792
6fc6879b
JM
4793 /* RSNA Supplicant Key Management - INITIALIZE */
4794 eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
4795 eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
4796
4797 /* Initialize driver interface and register driver event handler before
4798 * L2 receive handler so that association events are processed before
4799 * EAPOL-Key packets if both become available for the same select()
4800 * call. */
73c00fd7 4801 if (wpas_init_driver(wpa_s, iface) < 0)
362f781e
JM
4802 return -1;
4803
6fc6879b
JM
4804 if (wpa_supplicant_init_wpa(wpa_s) < 0)
4805 return -1;
4806
4807 wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
4808 wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
4809 NULL);
4810 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
4811
4812 if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
4813 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
4814 wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
f049052b
BG
4815 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
4816 "dot11RSNAConfigPMKLifetime");
6fc6879b
JM
4817 return -1;
4818 }
4819
4820 if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
4821 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
4822 wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
f049052b 4823 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
6fc6879b
JM
4824 "dot11RSNAConfigPMKReauthThreshold");
4825 return -1;
4826 }
4827
4828 if (wpa_s->conf->dot11RSNAConfigSATimeout &&
4829 wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
4830 wpa_s->conf->dot11RSNAConfigSATimeout)) {
f049052b
BG
4831 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
4832 "dot11RSNAConfigSATimeout");
6fc6879b
JM
4833 return -1;
4834 }
4835
6bf731e8
CL
4836 wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
4837 &wpa_s->hw.num_modes,
4838 &wpa_s->hw.flags);
a1b790eb
JM
4839 if (wpa_s->hw.modes) {
4840 u16 i;
4841
4842 for (i = 0; i < wpa_s->hw.num_modes; i++) {
4843 if (wpa_s->hw.modes[i].vht_capab) {
4844 wpa_s->hw_capab = CAPAB_VHT;
4845 break;
4846 }
4847
4848 if (wpa_s->hw.modes[i].ht_capab &
4849 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)
4850 wpa_s->hw_capab = CAPAB_HT40;
4851 else if (wpa_s->hw.modes[i].ht_capab &&
4852 wpa_s->hw_capab == CAPAB_NO_HT_VHT)
4853 wpa_s->hw_capab = CAPAB_HT;
4854 }
4855 }
6bf731e8 4856
6cbdb0c5
JM
4857 capa_res = wpa_drv_get_capa(wpa_s, &capa);
4858 if (capa_res == 0) {
c58ab8f2 4859 wpa_s->drv_capa_known = 1;
814782b9 4860 wpa_s->drv_flags = capa.flags;
349493bd 4861 wpa_s->drv_enc = capa.enc;
04ee647d 4862 wpa_s->drv_smps_modes = capa.smps_modes;
f936b73c 4863 wpa_s->drv_rrm_flags = capa.rrm_flags;
4f73d88a 4864 wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
814782b9 4865 wpa_s->max_scan_ssids = capa.max_scan_ssids;
cbdf3507 4866 wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
32c02261
AS
4867 wpa_s->max_sched_scan_plans = capa.max_sched_scan_plans;
4868 wpa_s->max_sched_scan_plan_interval =
4869 capa.max_sched_scan_plan_interval;
4870 wpa_s->max_sched_scan_plan_iterations =
4871 capa.max_sched_scan_plan_iterations;
cbdf3507 4872 wpa_s->sched_scan_supported = capa.sched_scan_supported;
b59e6f26 4873 wpa_s->max_match_sets = capa.max_match_sets;
814782b9 4874 wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
c4ea4c5c 4875 wpa_s->max_stations = capa.max_stations;
8cd6b7bc
JB
4876 wpa_s->extended_capa = capa.extended_capa;
4877 wpa_s->extended_capa_mask = capa.extended_capa_mask;
4878 wpa_s->extended_capa_len = capa.extended_capa_len;
4752147d
IP
4879 wpa_s->num_multichan_concurrent =
4880 capa.num_multichan_concurrent;
471cd6e1 4881 wpa_s->wmm_ac_supported = capa.wmm_ac_supported;
56c76fa5
IP
4882
4883 if (capa.mac_addr_rand_scan_supported)
4884 wpa_s->mac_addr_rand_supported |= MAC_ADDR_RAND_SCAN;
4885 if (wpa_s->sched_scan_supported &&
4886 capa.mac_addr_rand_sched_scan_supported)
4887 wpa_s->mac_addr_rand_supported |=
4888 (MAC_ADDR_RAND_SCHED_SCAN | MAC_ADDR_RAND_PNO);
814782b9
JM
4889 }
4890 if (wpa_s->max_remain_on_chan == 0)
4891 wpa_s->max_remain_on_chan = 1000;
4892
c68f6200
AS
4893 /*
4894 * Only take p2p_mgmt parameters when P2P Device is supported.
4895 * Doing it here as it determines whether l2_packet_init() will be done
4896 * during wpa_supplicant_driver_init().
4897 */
4898 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)
4899 wpa_s->p2p_mgmt = iface->p2p_mgmt;
4900 else
4901 iface->p2p_mgmt = 1;
4902
4752147d
IP
4903 if (wpa_s->num_multichan_concurrent == 0)
4904 wpa_s->num_multichan_concurrent = 1;
4905
6fc6879b
JM
4906 if (wpa_supplicant_driver_init(wpa_s) < 0)
4907 return -1;
4908
281ff0aa 4909#ifdef CONFIG_TDLS
1c42b42f
JM
4910 if ((!iface->p2p_mgmt ||
4911 !(wpa_s->drv_flags &
4912 WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
4913 wpa_tdls_init(wpa_s->wpa))
281ff0aa
GP
4914 return -1;
4915#endif /* CONFIG_TDLS */
4916
315ce40a
JM
4917 if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
4918 wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
f049052b 4919 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to set country");
6d158490
LR
4920 return -1;
4921 }
4922
b36a3a65
AN
4923#ifdef CONFIG_FST
4924 if (wpa_s->conf->fst_group_id) {
4925 struct fst_iface_cfg cfg;
4926 struct fst_wpa_obj iface_obj;
4927
4928 fst_wpa_supplicant_fill_iface_obj(wpa_s, &iface_obj);
4929 os_strlcpy(cfg.group_id, wpa_s->conf->fst_group_id,
4930 sizeof(cfg.group_id));
4931 cfg.priority = wpa_s->conf->fst_priority;
4932 cfg.llt = wpa_s->conf->fst_llt;
4933
4934 wpa_s->fst = fst_attach(wpa_s->ifname, wpa_s->own_addr,
4935 &iface_obj, &cfg);
4936 if (!wpa_s->fst) {
4937 wpa_msg(wpa_s, MSG_ERROR,
4938 "FST: Cannot attach iface %s to group %s",
4939 wpa_s->ifname, cfg.group_id);
4940 return -1;
4941 }
4942 }
4943#endif /* CONFIG_FST */
4944
116654ce
JM
4945 if (wpas_wps_init(wpa_s))
4946 return -1;
4947
6fc6879b
JM
4948 if (wpa_supplicant_init_eapol(wpa_s) < 0)
4949 return -1;
4950 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
4951
4952 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
4953 if (wpa_s->ctrl_iface == NULL) {
4954 wpa_printf(MSG_ERROR,
4955 "Failed to initialize control interface '%s'.\n"
4956 "You may have another wpa_supplicant process "
4957 "already running or the file was\n"
4958 "left by an unclean termination of wpa_supplicant "
4959 "in which case you will need\n"
4960 "to manually remove this file before starting "
4961 "wpa_supplicant again.\n",
4962 wpa_s->conf->ctrl_interface);
4963 return -1;
4964 }
4965
04ea7b79
JM
4966 wpa_s->gas = gas_query_init(wpa_s);
4967 if (wpa_s->gas == NULL) {
4968 wpa_printf(MSG_ERROR, "Failed to initialize GAS query");
4969 return -1;
4970 }
4971
c68f6200 4972 if (iface->p2p_mgmt && wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
f049052b 4973 wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
b22128ef
JM
4974 return -1;
4975 }
b22128ef 4976
83922c2d
JM
4977 if (wpa_bss_init(wpa_s) < 0)
4978 return -1;
83922c2d 4979
e4fa8b12
EP
4980 /*
4981 * Set Wake-on-WLAN triggers, if configured.
4982 * Note: We don't restore/remove the triggers on shutdown (it doesn't
4983 * have effect anyway when the interface is down).
4984 */
6cbdb0c5 4985 if (capa_res == 0 && wpas_set_wowlan_triggers(wpa_s, &capa) < 0)
e4fa8b12
EP
4986 return -1;
4987
ec7b97ab
JM
4988#ifdef CONFIG_EAP_PROXY
4989{
4990 size_t len;
07041c6f
NJ
4991 wpa_s->mnc_len = eapol_sm_get_eap_proxy_imsi(wpa_s->eapol, wpa_s->imsi,
4992 &len);
ec7b97ab
JM
4993 if (wpa_s->mnc_len > 0) {
4994 wpa_s->imsi[len] = '\0';
4995 wpa_printf(MSG_DEBUG, "eap_proxy: IMSI %s (MNC length %d)",
4996 wpa_s->imsi, wpa_s->mnc_len);
4997 } else {
4998 wpa_printf(MSG_DEBUG, "eap_proxy: IMSI not available");
4999 }
5000}
5001#endif /* CONFIG_EAP_PROXY */
5002
f64adcd7
JM
5003 if (pcsc_reader_init(wpa_s) < 0)
5004 return -1;
5005
306ae225
JM
5006 if (wpas_init_ext_pw(wpa_s) < 0)
5007 return -1;
5008
b361d580
AK
5009 wpas_rrm_reset(wpa_s);
5010
32c02261
AS
5011 wpas_sched_scan_plans_set(wpa_s, wpa_s->conf->sched_scan_plans);
5012
ca9968a0
JM
5013#ifdef CONFIG_HS20
5014 hs20_init(wpa_s);
5015#endif /* CONFIG_HS20 */
92c6e2e3
DS
5016#ifdef CONFIG_MBO
5017 wpas_mbo_update_non_pref_chan(wpa_s, wpa_s->conf->non_pref_chan);
5018#endif /* CONFIG_MBO */
ca9968a0 5019
cc9985d1 5020 wpa_supplicant_set_default_scan_ies(wpa_s);
5021
6fc6879b
JM
5022 return 0;
5023}
5024
5025
2ee055b3 5026static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
df509539 5027 int notify, int terminate)
6fc6879b 5028{
26fc96e8
JM
5029 struct wpa_global *global = wpa_s->global;
5030 struct wpa_supplicant *iface, *prev;
5031
5032 if (wpa_s == wpa_s->parent)
5033 wpas_p2p_group_remove(wpa_s, "*");
5034
5035 iface = global->ifaces;
5036 while (iface) {
96a26ab7
LD
5037 if (iface->p2pdev == wpa_s)
5038 iface->p2pdev = iface->parent;
26fc96e8
JM
5039 if (iface == wpa_s || iface->parent != wpa_s) {
5040 iface = iface->next;
5041 continue;
5042 }
5043 wpa_printf(MSG_DEBUG,
5044 "Remove remaining child interface %s from parent %s",
5045 iface->ifname, wpa_s->ifname);
5046 prev = iface;
5047 iface = iface->next;
5048 wpa_supplicant_remove_iface(global, prev, terminate);
5049 }
5050
e679f140 5051 wpa_s->disconnected = 1;
6fc6879b
JM
5052 if (wpa_s->drv_priv) {
5053 wpa_supplicant_deauthenticate(wpa_s,
5054 WLAN_REASON_DEAUTH_LEAVING);
5055
6fc6879b
JM
5056 wpa_drv_set_countermeasures(wpa_s, 0);
5057 wpa_clear_keys(wpa_s, NULL);
5058 }
5059
8e56d189 5060 wpa_supplicant_cleanup(wpa_s);
bd10d938 5061 wpas_p2p_deinit_iface(wpa_s);
ab28911d 5062
1f965e62 5063 wpas_ctrl_radio_work_flush(wpa_s);
202dec2a
JM
5064 radio_remove_interface(wpa_s);
5065
b36a3a65
AN
5066#ifdef CONFIG_FST
5067 if (wpa_s->fst) {
5068 fst_detach(wpa_s->fst);
5069 wpa_s->fst = NULL;
5070 }
5071 if (wpa_s->received_mb_ies) {
5072 wpabuf_free(wpa_s->received_mb_ies);
5073 wpa_s->received_mb_ies = NULL;
5074 }
5075#endif /* CONFIG_FST */
5076
6fc6879b
JM
5077 if (wpa_s->drv_priv)
5078 wpa_drv_deinit(wpa_s);
2523ff6e
DS
5079
5080 if (notify)
5081 wpas_notify_iface_removed(wpa_s);
f0811516
DS
5082
5083 if (terminate)
5084 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
5085
5086 if (wpa_s->ctrl_iface) {
5087 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
5088 wpa_s->ctrl_iface = NULL;
5089 }
5090
603a3f34
JL
5091#ifdef CONFIG_MESH
5092 if (wpa_s->ifmsh) {
5093 wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh);
5094 wpa_s->ifmsh = NULL;
5095 }
5096#endif /* CONFIG_MESH */
5097
f0811516
DS
5098 if (wpa_s->conf != NULL) {
5099 wpa_config_free(wpa_s->conf);
5100 wpa_s->conf = NULL;
5101 }
18e00b5e 5102
a80651d0
KV
5103 os_free(wpa_s->ssids_from_scan_req);
5104
18e00b5e 5105 os_free(wpa_s);
6fc6879b
JM
5106}
5107
5108
2e997eec
RM
5109#ifdef CONFIG_MATCH_IFACE
5110
5111/**
5112 * wpa_supplicant_match_iface - Match an interface description to a name
5113 * @global: Pointer to global data from wpa_supplicant_init()
5114 * @ifname: Name of the interface to match
5115 * Returns: Pointer to the created interface description or %NULL on failure
5116 */
5117struct wpa_interface * wpa_supplicant_match_iface(struct wpa_global *global,
5118 const char *ifname)
5119{
5120 int i;
5121 struct wpa_interface *iface, *miface;
5122
5123 for (i = 0; i < global->params.match_iface_count; i++) {
5124 miface = &global->params.match_ifaces[i];
5125 if (!miface->ifname ||
5126 fnmatch(miface->ifname, ifname, 0) == 0) {
5127 iface = os_zalloc(sizeof(*iface));
5128 if (!iface)
5129 return NULL;
5130 *iface = *miface;
5131 iface->ifname = ifname;
5132 return iface;
5133 }
5134 }
5135
5136 return NULL;
5137}
5138
5139
5140/**
5141 * wpa_supplicant_match_existing - Match existing interfaces
5142 * @global: Pointer to global data from wpa_supplicant_init()
5143 * Returns: 0 on success, -1 on failure
5144 */
5145static int wpa_supplicant_match_existing(struct wpa_global *global)
5146{
5147 struct if_nameindex *ifi, *ifp;
5148 struct wpa_supplicant *wpa_s;
5149 struct wpa_interface *iface;
5150
5151 ifp = if_nameindex();
5152 if (!ifp) {
5153 wpa_printf(MSG_ERROR, "if_nameindex: %s", strerror(errno));
5154 return -1;
5155 }
5156
5157 for (ifi = ifp; ifi->if_name; ifi++) {
5158 wpa_s = wpa_supplicant_get_iface(global, ifi->if_name);
5159 if (wpa_s)
5160 continue;
5161 iface = wpa_supplicant_match_iface(global, ifi->if_name);
5162 if (iface) {
5163 wpa_s = wpa_supplicant_add_iface(global, iface, NULL);
5164 os_free(iface);
5165 if (wpa_s)
5166 wpa_s->matched = 1;
5167 }
5168 }
5169
5170 if_freenameindex(ifp);
5171 return 0;
5172}
5173
5174#endif /* CONFIG_MATCH_IFACE */
5175
5176
6fc6879b
JM
5177/**
5178 * wpa_supplicant_add_iface - Add a new network interface
5179 * @global: Pointer to global data from wpa_supplicant_init()
5180 * @iface: Interface configuration options
1772d348 5181 * @parent: Parent interface or %NULL to assign new interface as parent
6fc6879b
JM
5182 * Returns: Pointer to the created interface or %NULL on failure
5183 *
5184 * This function is used to add new network interfaces for %wpa_supplicant.
5185 * This can be called before wpa_supplicant_run() to add interfaces before the
5186 * main event loop has been started. In addition, new interfaces can be added
5187 * dynamically while %wpa_supplicant is already running. This could happen,
5188 * e.g., when a hotplug network adapter is inserted.
5189 */
5190struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
1772d348
JM
5191 struct wpa_interface *iface,
5192 struct wpa_supplicant *parent)
6fc6879b
JM
5193{
5194 struct wpa_supplicant *wpa_s;
d27df100 5195 struct wpa_interface t_iface;
8e56d189 5196 struct wpa_ssid *ssid;
6fc6879b
JM
5197
5198 if (global == NULL || iface == NULL)
5199 return NULL;
5200
1772d348 5201 wpa_s = wpa_supplicant_alloc(parent);
6fc6879b
JM
5202 if (wpa_s == NULL)
5203 return NULL;
5204
d8222ae3
JM
5205 wpa_s->global = global;
5206
d27df100
JM
5207 t_iface = *iface;
5208 if (global->params.override_driver) {
5209 wpa_printf(MSG_DEBUG, "Override interface parameter: driver "
5210 "('%s' -> '%s')",
5211 iface->driver, global->params.override_driver);
5212 t_iface.driver = global->params.override_driver;
5213 }
5214 if (global->params.override_ctrl_interface) {
5215 wpa_printf(MSG_DEBUG, "Override interface parameter: "
5216 "ctrl_interface ('%s' -> '%s')",
5217 iface->ctrl_interface,
5218 global->params.override_ctrl_interface);
5219 t_iface.ctrl_interface =
5220 global->params.override_ctrl_interface;
5221 }
5222 if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
6fc6879b
JM
5223 wpa_printf(MSG_DEBUG, "Failed to add interface %s",
5224 iface->ifname);
df509539 5225 wpa_supplicant_deinit_iface(wpa_s, 0, 0);
6fc6879b
JM
5226 return NULL;
5227 }
5228
21efc940
TB
5229 if (iface->p2p_mgmt == 0) {
5230 /* Notify the control interfaces about new iface */
5231 if (wpas_notify_iface_added(wpa_s)) {
5232 wpa_supplicant_deinit_iface(wpa_s, 1, 0);
5233 return NULL;
5234 }
1bd3f426 5235
21efc940
TB
5236 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
5237 wpas_notify_network_added(wpa_s, ssid);
5238 }
8e56d189 5239
6fc6879b
JM
5240 wpa_s->next = global->ifaces;
5241 global->ifaces = wpa_s;
5242
f049052b 5243 wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
99218999 5244 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
6fc6879b 5245
c3c4b3ed
JM
5246#ifdef CONFIG_P2P
5247 if (wpa_s->global->p2p == NULL &&
74802c09 5248 !wpa_s->global->p2p_disabled && !wpa_s->conf->p2p_disabled &&
c3c4b3ed 5249 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
f43c1ae7
IP
5250 wpas_p2p_add_p2pdev_interface(
5251 wpa_s, wpa_s->global->params.conf_p2p_dev) < 0) {
c3c4b3ed
JM
5252 wpa_printf(MSG_INFO,
5253 "P2P: Failed to enable P2P Device interface");
5254 /* Try to continue without. P2P will be disabled. */
5255 }
5256#endif /* CONFIG_P2P */
5257
6fc6879b
JM
5258 return wpa_s;
5259}
5260
5261
5262/**
5263 * wpa_supplicant_remove_iface - Remove a network interface
5264 * @global: Pointer to global data from wpa_supplicant_init()
5265 * @wpa_s: Pointer to the network interface to be removed
5266 * Returns: 0 if interface was removed, -1 if interface was not found
5267 *
5268 * This function can be used to dynamically remove network interfaces from
5269 * %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In
5270 * addition, this function is used to remove all remaining interfaces when
5271 * %wpa_supplicant is terminated.
5272 */
5273int wpa_supplicant_remove_iface(struct wpa_global *global,
df509539
DS
5274 struct wpa_supplicant *wpa_s,
5275 int terminate)
6fc6879b
JM
5276{
5277 struct wpa_supplicant *prev;
5b78493f
MH
5278#ifdef CONFIG_MESH
5279 unsigned int mesh_if_created = wpa_s->mesh_if_created;
5280 char *ifname = NULL;
5281#endif /* CONFIG_MESH */
6fc6879b
JM
5282
5283 /* Remove interface from the global list of interfaces */
5284 prev = global->ifaces;
5285 if (prev == wpa_s) {
5286 global->ifaces = wpa_s->next;
5287 } else {
5288 while (prev && prev->next != wpa_s)
5289 prev = prev->next;
5290 if (prev == NULL)
5291 return -1;
5292 prev->next = wpa_s->next;
5293 }
5294
f049052b 5295 wpa_dbg(wpa_s, MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
6fc6879b 5296
5b78493f
MH
5297#ifdef CONFIG_MESH
5298 if (mesh_if_created) {
5299 ifname = os_strdup(wpa_s->ifname);
5300 if (ifname == NULL) {
5301 wpa_dbg(wpa_s, MSG_ERROR,
5302 "mesh: Failed to malloc ifname");
5303 return -1;
5304 }
5305 }
5306#endif /* CONFIG_MESH */
5307
b22128ef
JM
5308 if (global->p2p_group_formation == wpa_s)
5309 global->p2p_group_formation = NULL;
dbca75f8
JM
5310 if (global->p2p_invite_group == wpa_s)
5311 global->p2p_invite_group = NULL;
df509539 5312 wpa_supplicant_deinit_iface(wpa_s, 1, terminate);
6fc6879b 5313
5b78493f
MH
5314#ifdef CONFIG_MESH
5315 if (mesh_if_created) {
5316 wpa_drv_if_remove(global->ifaces, WPA_IF_MESH, ifname);
5317 os_free(ifname);
5318 }
5319#endif /* CONFIG_MESH */
5320
6fc6879b
JM
5321 return 0;
5322}
5323
5324
cf83fb0b
PS
5325/**
5326 * wpa_supplicant_get_eap_mode - Get the current EAP mode
5327 * @wpa_s: Pointer to the network interface
5328 * Returns: Pointer to the eap mode or the string "UNKNOWN" if not found
5329 */
5330const char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s)
5331{
5332 const char *eapol_method;
5333
5334 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) == 0 &&
5335 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
5336 return "NO-EAP";
5337 }
5338
5339 eapol_method = eapol_sm_get_method_name(wpa_s->eapol);
5340 if (eapol_method == NULL)
5341 return "UNKNOWN-EAP";
5342
5343 return eapol_method;
5344}
5345
5346
6fc6879b
JM
5347/**
5348 * wpa_supplicant_get_iface - Get a new network interface
5349 * @global: Pointer to global data from wpa_supplicant_init()
5350 * @ifname: Interface name
5351 * Returns: Pointer to the interface or %NULL if not found
5352 */
5353struct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
5354 const char *ifname)
5355{
5356 struct wpa_supplicant *wpa_s;
5357
5358 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
5359 if (os_strcmp(wpa_s->ifname, ifname) == 0)
5360 return wpa_s;
5361 }
5362 return NULL;
5363}
5364
5365
50b16da1 5366#ifndef CONFIG_NO_WPA_MSG
4f1495ae
BG
5367static const char * wpa_supplicant_msg_ifname_cb(void *ctx)
5368{
5369 struct wpa_supplicant *wpa_s = ctx;
5370 if (wpa_s == NULL)
5371 return NULL;
5372 return wpa_s->ifname;
5373}
50b16da1 5374#endif /* CONFIG_NO_WPA_MSG */
4f1495ae
BG
5375
5376
8c0d0ff2
JM
5377#ifndef WPA_SUPPLICANT_CLEANUP_INTERVAL
5378#define WPA_SUPPLICANT_CLEANUP_INTERVAL 10
5379#endif /* WPA_SUPPLICANT_CLEANUP_INTERVAL */
5380
5381/* Periodic cleanup tasks */
5382static void wpas_periodic(void *eloop_ctx, void *timeout_ctx)
5383{
5384 struct wpa_global *global = eloop_ctx;
5385 struct wpa_supplicant *wpa_s;
5386
5387 eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0,
5388 wpas_periodic, global, NULL);
5389
5390#ifdef CONFIG_P2P
5391 if (global->p2p)
5392 p2p_expire_peers(global->p2p);
5393#endif /* CONFIG_P2P */
5394
3188aaba 5395 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
8c0d0ff2 5396 wpa_bss_flush_by_age(wpa_s, wpa_s->conf->bss_expiration_age);
3188aaba
JM
5397#ifdef CONFIG_AP
5398 ap_periodic(wpa_s);
5399#endif /* CONFIG_AP */
5400 }
8c0d0ff2
JM
5401}
5402
5403
6fc6879b
JM
5404/**
5405 * wpa_supplicant_init - Initialize %wpa_supplicant
5406 * @params: Parameters for %wpa_supplicant
5407 * Returns: Pointer to global %wpa_supplicant data, or %NULL on failure
5408 *
5409 * This function is used to initialize %wpa_supplicant. After successful
5410 * initialization, the returned data pointer can be used to add and remove
5411 * network interfaces, and eventually, to deinitialize %wpa_supplicant.
5412 */
5413struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
5414{
5415 struct wpa_global *global;
ac305589 5416 int ret, i;
6fc6879b
JM
5417
5418 if (params == NULL)
5419 return NULL;
5420
39e7d718
JM
5421#ifdef CONFIG_DRIVER_NDIS
5422 {
5423 void driver_ndis_init_ops(void);
5424 driver_ndis_init_ops();
5425 }
5426#endif /* CONFIG_DRIVER_NDIS */
5427
50b16da1 5428#ifndef CONFIG_NO_WPA_MSG
4f1495ae 5429 wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
50b16da1 5430#endif /* CONFIG_NO_WPA_MSG */
4f1495ae 5431
f4637fe0
JM
5432 if (params->wpa_debug_file_path)
5433 wpa_debug_open_file(params->wpa_debug_file_path);
5434 else
5435 wpa_debug_setup_stdout();
daa70d49
SL
5436 if (params->wpa_debug_syslog)
5437 wpa_debug_open_syslog();
4f68895e
JB
5438 if (params->wpa_debug_tracing) {
5439 ret = wpa_debug_open_linux_tracing();
5440 if (ret) {
5441 wpa_printf(MSG_ERROR,
5442 "Failed to enable trace logging");
5443 return NULL;
5444 }
5445 }
6fc6879b 5446
12760815 5447 ret = eap_register_methods();
6fc6879b
JM
5448 if (ret) {
5449 wpa_printf(MSG_ERROR, "Failed to register EAP methods");
5450 if (ret == -2)
5451 wpa_printf(MSG_ERROR, "Two or more EAP methods used "
5452 "the same EAP type.");
5453 return NULL;
5454 }
5455
5456 global = os_zalloc(sizeof(*global));
5457 if (global == NULL)
5458 return NULL;
b22128ef
JM
5459 dl_list_init(&global->p2p_srv_bonjour);
5460 dl_list_init(&global->p2p_srv_upnp);
6fc6879b
JM
5461 global->params.daemonize = params->daemonize;
5462 global->params.wait_for_monitor = params->wait_for_monitor;
5463 global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
5464 if (params->pid_file)
5465 global->params.pid_file = os_strdup(params->pid_file);
5466 if (params->ctrl_interface)
5467 global->params.ctrl_interface =
5468 os_strdup(params->ctrl_interface);
29257565
JM
5469 if (params->ctrl_interface_group)
5470 global->params.ctrl_interface_group =
5471 os_strdup(params->ctrl_interface_group);
d27df100
JM
5472 if (params->override_driver)
5473 global->params.override_driver =
5474 os_strdup(params->override_driver);
5475 if (params->override_ctrl_interface)
5476 global->params.override_ctrl_interface =
5477 os_strdup(params->override_ctrl_interface);
2e997eec
RM
5478#ifdef CONFIG_MATCH_IFACE
5479 global->params.match_iface_count = params->match_iface_count;
5480 if (params->match_iface_count) {
5481 global->params.match_ifaces =
5482 os_calloc(params->match_iface_count,
5483 sizeof(struct wpa_interface));
5484 os_memcpy(global->params.match_ifaces,
5485 params->match_ifaces,
5486 params->match_iface_count *
5487 sizeof(struct wpa_interface));
5488 }
5489#endif /* CONFIG_MATCH_IFACE */
d4e59795
G
5490#ifdef CONFIG_P2P
5491 if (params->conf_p2p_dev)
5492 global->params.conf_p2p_dev =
5493 os_strdup(params->conf_p2p_dev);
5494#endif /* CONFIG_P2P */
6fc6879b
JM
5495 wpa_debug_level = global->params.wpa_debug_level =
5496 params->wpa_debug_level;
5497 wpa_debug_show_keys = global->params.wpa_debug_show_keys =
5498 params->wpa_debug_show_keys;
5499 wpa_debug_timestamp = global->params.wpa_debug_timestamp =
5500 params->wpa_debug_timestamp;
5501
f19858f5
JM
5502 wpa_printf(MSG_DEBUG, "wpa_supplicant v" VERSION_STR);
5503
0456ea16 5504 if (eloop_init()) {
6fc6879b
JM
5505 wpa_printf(MSG_ERROR, "Failed to initialize event loop");
5506 wpa_supplicant_deinit(global);
5507 return NULL;
5508 }
5509
38e24575 5510 random_init(params->entropy_file);
d47fa330 5511
6fc6879b
JM
5512 global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
5513 if (global->ctrl_iface == NULL) {
5514 wpa_supplicant_deinit(global);
5515 return NULL;
5516 }
5517
dc461de4
WS
5518 if (wpas_notify_supplicant_initialized(global)) {
5519 wpa_supplicant_deinit(global);
5520 return NULL;
6fc6879b
JM
5521 }
5522
c5121837 5523 for (i = 0; wpa_drivers[i]; i++)
ac305589
JM
5524 global->drv_count++;
5525 if (global->drv_count == 0) {
5526 wpa_printf(MSG_ERROR, "No drivers enabled");
5527 wpa_supplicant_deinit(global);
5528 return NULL;
5529 }
faebdeaa 5530 global->drv_priv = os_calloc(global->drv_count, sizeof(void *));
ac305589
JM
5531 if (global->drv_priv == NULL) {
5532 wpa_supplicant_deinit(global);
5533 return NULL;
5534 }
ac305589 5535
9675ce35
JM
5536#ifdef CONFIG_WIFI_DISPLAY
5537 if (wifi_display_init(global) < 0) {
5538 wpa_printf(MSG_ERROR, "Failed to initialize Wi-Fi Display");
5539 wpa_supplicant_deinit(global);
5540 return NULL;
5541 }
5542#endif /* CONFIG_WIFI_DISPLAY */
5543
8c0d0ff2
JM
5544 eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0,
5545 wpas_periodic, global, NULL);
5546
6fc6879b
JM
5547 return global;
5548}
5549
5550
5551/**
5552 * wpa_supplicant_run - Run the %wpa_supplicant main event loop
5553 * @global: Pointer to global data from wpa_supplicant_init()
5554 * Returns: 0 after successful event loop run, -1 on failure
5555 *
5556 * This function starts the main event loop and continues running as long as
5557 * there are any remaining events. In most cases, this function is running as
5558 * long as the %wpa_supplicant process in still in use.
5559 */
5560int wpa_supplicant_run(struct wpa_global *global)
5561{
5562 struct wpa_supplicant *wpa_s;
5563
5564 if (global->params.daemonize &&
2e69bdd1
RM
5565 (wpa_supplicant_daemon(global->params.pid_file) ||
5566 eloop_sock_requeue()))
6fc6879b
JM
5567 return -1;
5568
2e997eec
RM
5569#ifdef CONFIG_MATCH_IFACE
5570 if (wpa_supplicant_match_existing(global))
5571 return -1;
5572#endif
5573
6fc6879b
JM
5574 if (global->params.wait_for_monitor) {
5575 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
ede77701 5576 if (wpa_s->ctrl_iface && !wpa_s->p2p_mgmt)
6fc6879b
JM
5577 wpa_supplicant_ctrl_iface_wait(
5578 wpa_s->ctrl_iface);
5579 }
5580
0456ea16
JM
5581 eloop_register_signal_terminate(wpa_supplicant_terminate, global);
5582 eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
6fc6879b
JM
5583
5584 eloop_run();
5585
5586 return 0;
5587}
5588
5589
5590/**
5591 * wpa_supplicant_deinit - Deinitialize %wpa_supplicant
5592 * @global: Pointer to global data from wpa_supplicant_init()
5593 *
5594 * This function is called to deinitialize %wpa_supplicant and to free all
5595 * allocated resources. Remaining network interfaces will also be removed.
5596 */
5597void wpa_supplicant_deinit(struct wpa_global *global)
5598{
ac305589
JM
5599 int i;
5600
6fc6879b
JM
5601 if (global == NULL)
5602 return;
5603
8c0d0ff2
JM
5604 eloop_cancel_timeout(wpas_periodic, global, NULL);
5605
9675ce35
JM
5606#ifdef CONFIG_WIFI_DISPLAY
5607 wifi_display_deinit(global);
5608#endif /* CONFIG_WIFI_DISPLAY */
b22128ef 5609
6fc6879b 5610 while (global->ifaces)
df509539 5611 wpa_supplicant_remove_iface(global, global->ifaces, 1);
6fc6879b
JM
5612
5613 if (global->ctrl_iface)
5614 wpa_supplicant_global_ctrl_iface_deinit(global->ctrl_iface);
dc461de4
WS
5615
5616 wpas_notify_supplicant_deinitialized(global);
6fc6879b
JM
5617
5618 eap_peer_unregister_methods();
3ec97afe
JM
5619#ifdef CONFIG_AP
5620 eap_server_unregister_methods();
5621#endif /* CONFIG_AP */
6fc6879b 5622
c5121837 5623 for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
ac305589
JM
5624 if (!global->drv_priv[i])
5625 continue;
c5121837 5626 wpa_drivers[i]->global_deinit(global->drv_priv[i]);
ac305589
JM
5627 }
5628 os_free(global->drv_priv);
5629
d47fa330
JM
5630 random_deinit();
5631
6fc6879b
JM
5632 eloop_destroy();
5633
5634 if (global->params.pid_file) {
5635 os_daemonize_terminate(global->params.pid_file);
5636 os_free(global->params.pid_file);
5637 }
5638 os_free(global->params.ctrl_interface);
29257565 5639 os_free(global->params.ctrl_interface_group);
d27df100
JM
5640 os_free(global->params.override_driver);
5641 os_free(global->params.override_ctrl_interface);
2e997eec
RM
5642#ifdef CONFIG_MATCH_IFACE
5643 os_free(global->params.match_ifaces);
5644#endif /* CONFIG_MATCH_IFACE */
d4e59795
G
5645#ifdef CONFIG_P2P
5646 os_free(global->params.conf_p2p_dev);
5647#endif /* CONFIG_P2P */
6fc6879b 5648
af8a827b 5649 os_free(global->p2p_disallow_freq.range);
253f2e37 5650 os_free(global->p2p_go_avoid_freq.range);
01a57fe4 5651 os_free(global->add_psk);
6f3bc72b 5652
6fc6879b 5653 os_free(global);
daa70d49 5654 wpa_debug_close_syslog();
6fc6879b 5655 wpa_debug_close_file();
4f68895e 5656 wpa_debug_close_linux_tracing();
6fc6879b 5657}
611aea7d
JM
5658
5659
5660void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
5661{
849b5dc7
JM
5662 if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
5663 wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
5664 char country[3];
5665 country[0] = wpa_s->conf->country[0];
5666 country[1] = wpa_s->conf->country[1];
5667 country[2] = '\0';
5668 if (wpa_drv_set_country(wpa_s, country) < 0) {
5669 wpa_printf(MSG_ERROR, "Failed to set country code "
5670 "'%s'", country);
5671 }
5672 }
5673
306ae225
JM
5674 if (wpa_s->conf->changed_parameters & CFG_CHANGED_EXT_PW_BACKEND)
5675 wpas_init_ext_pw(wpa_s);
5676
bea48f77
JM
5677 if (wpa_s->conf->changed_parameters & CFG_CHANGED_SCHED_SCAN_PLANS)
5678 wpas_sched_scan_plans_set(wpa_s, wpa_s->conf->sched_scan_plans);
5679
611aea7d
JM
5680#ifdef CONFIG_WPS
5681 wpas_wps_update_config(wpa_s);
5682#endif /* CONFIG_WPS */
b22128ef 5683 wpas_p2p_update_config(wpa_s);
611aea7d
JM
5684 wpa_s->conf->changed_parameters = 0;
5685}
2f9c6aa6
JM
5686
5687
e1117c1c 5688void add_freq(int *freqs, int *num_freqs, int freq)
0fb337c1
JM
5689{
5690 int i;
5691
5692 for (i = 0; i < *num_freqs; i++) {
5693 if (freqs[i] == freq)
5694 return;
5695 }
5696
5697 freqs[*num_freqs] = freq;
5698 (*num_freqs)++;
5699}
5700
5701
5702static int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s)
5703{
5704 struct wpa_bss *bss, *cbss;
5705 const int max_freqs = 10;
5706 int *freqs;
5707 int num_freqs = 0;
5708
faebdeaa 5709 freqs = os_calloc(max_freqs + 1, sizeof(int));
0fb337c1
JM
5710 if (freqs == NULL)
5711 return NULL;
5712
5713 cbss = wpa_s->current_bss;
5714
5715 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
5716 if (bss == cbss)
5717 continue;
5718 if (bss->ssid_len == cbss->ssid_len &&
5719 os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
5720 wpa_blacklist_get(wpa_s, bss->bssid) == NULL) {
5721 add_freq(freqs, &num_freqs, bss->freq);
5722 if (num_freqs == max_freqs)
5723 break;
5724 }
5725 }
5726
5727 if (num_freqs == 0) {
5728 os_free(freqs);
5729 freqs = NULL;
5730 }
5731
5732 return freqs;
5733}
5734
5735
5736void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
5737{
5738 int timeout;
5739 int count;
5740 int *freqs = NULL;
5741
6ac4b15e
JM
5742 wpas_connect_work_done(wpa_s);
5743
5fd9fb27
JM
5744 /*
5745 * Remove possible authentication timeout since the connection failed.
5746 */
5747 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
5748
c2805909
JM
5749 /*
5750 * There is no point in blacklisting the AP if this event is
5751 * generated based on local request to disconnect.
5752 */
5753 if (wpa_s->own_disconnect_req) {
5754 wpa_s->own_disconnect_req = 0;
5755 wpa_dbg(wpa_s, MSG_DEBUG,
5756 "Ignore connection failure due to local request to disconnect");
5757 return;
5758 }
0cdb93fe 5759 if (wpa_s->disconnected) {
0cdb93fe
JM
5760 wpa_dbg(wpa_s, MSG_DEBUG, "Ignore connection failure "
5761 "indication since interface has been put into "
5762 "disconnected state");
5763 return;
5764 }
5765
0fb337c1
JM
5766 /*
5767 * Add the failed BSSID into the blacklist and speed up next scan
5768 * attempt if there could be other APs that could accept association.
5769 * The current blacklist count indicates how many times we have tried
5770 * connecting to this AP and multiple attempts mean that other APs are
5771 * either not available or has already been tried, so that we can start
5772 * increasing the delay here to avoid constant scanning.
5773 */
5774 count = wpa_blacklist_add(wpa_s, bssid);
5775 if (count == 1 && wpa_s->current_bss) {
5776 /*
5777 * This BSS was not in the blacklist before. If there is
5778 * another BSS available for the same ESS, we should try that
5779 * next. Otherwise, we may as well try this one once more
5780 * before allowing other, likely worse, ESSes to be considered.
5781 */
5782 freqs = get_bss_freqs_in_ess(wpa_s);
5783 if (freqs) {
f049052b
BG
5784 wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
5785 "has been seen; try it next");
0fb337c1
JM
5786 wpa_blacklist_add(wpa_s, bssid);
5787 /*
5788 * On the next scan, go through only the known channels
5789 * used in this ESS based on previous scans to speed up
5790 * common load balancing use case.
5791 */
5792 os_free(wpa_s->next_scan_freqs);
5793 wpa_s->next_scan_freqs = freqs;
5794 }
5795 }
5796
f1a52633
JM
5797 /*
5798 * Add previous failure count in case the temporary blacklist was
5799 * cleared due to no other BSSes being available.
5800 */
5801 count += wpa_s->extra_blacklist_count;
5802
dd579704
JM
5803 if (count > 3 && wpa_s->current_ssid) {
5804 wpa_printf(MSG_DEBUG, "Continuous association failures - "
5805 "consider temporary network disabling");
b19c098e 5806 wpas_auth_failed(wpa_s, "CONN_FAILED");
dd579704
JM
5807 }
5808
0fb337c1
JM
5809 switch (count) {
5810 case 1:
5811 timeout = 100;
5812 break;
5813 case 2:
5814 timeout = 500;
5815 break;
5816 case 3:
5817 timeout = 1000;
5818 break;
f1a52633 5819 case 4:
0fb337c1 5820 timeout = 5000;
f1a52633
JM
5821 break;
5822 default:
5823 timeout = 10000;
5824 break;
0fb337c1
JM
5825 }
5826
f1a52633
JM
5827 wpa_dbg(wpa_s, MSG_DEBUG, "Blacklist count %d --> request scan in %d "
5828 "ms", count, timeout);
5829
0fb337c1
JM
5830 /*
5831 * TODO: if more than one possible AP is available in scan results,
5832 * could try the other ones before requesting a new scan.
5833 */
5834 wpa_supplicant_req_scan(wpa_s, timeout / 1000,
5835 1000 * (timeout % 1000));
5836}
22628eca
JM
5837
5838
5839int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
5840{
5841 return wpa_s->conf->ap_scan == 2 ||
5842 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
5843}
d2118814
JM
5844
5845
5846#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
5847int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
5848 struct wpa_ssid *ssid,
5849 const char *field,
5850 const char *value)
5851{
5852#ifdef IEEE8021X_EAPOL
5853 struct eap_peer_config *eap = &ssid->eap;
5854
5855 wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
5856 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
5857 (const u8 *) value, os_strlen(value));
5858
5859 switch (wpa_supplicant_ctrl_req_from_string(field)) {
5860 case WPA_CTRL_REQ_EAP_IDENTITY:
5861 os_free(eap->identity);
5862 eap->identity = (u8 *) os_strdup(value);
5863 eap->identity_len = os_strlen(value);
5864 eap->pending_req_identity = 0;
5865 if (ssid == wpa_s->current_ssid)
5866 wpa_s->reassociate = 1;
5867 break;
5868 case WPA_CTRL_REQ_EAP_PASSWORD:
19c48da0 5869 bin_clear_free(eap->password, eap->password_len);
d2118814
JM
5870 eap->password = (u8 *) os_strdup(value);
5871 eap->password_len = os_strlen(value);
5872 eap->pending_req_password = 0;
5873 if (ssid == wpa_s->current_ssid)
5874 wpa_s->reassociate = 1;
5875 break;
5876 case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
19c48da0 5877 bin_clear_free(eap->new_password, eap->new_password_len);
d2118814
JM
5878 eap->new_password = (u8 *) os_strdup(value);
5879 eap->new_password_len = os_strlen(value);
5880 eap->pending_req_new_password = 0;
5881 if (ssid == wpa_s->current_ssid)
5882 wpa_s->reassociate = 1;
5883 break;
5884 case WPA_CTRL_REQ_EAP_PIN:
19c48da0 5885 str_clear_free(eap->pin);
d2118814
JM
5886 eap->pin = os_strdup(value);
5887 eap->pending_req_pin = 0;
5888 if (ssid == wpa_s->current_ssid)
5889 wpa_s->reassociate = 1;
5890 break;
5891 case WPA_CTRL_REQ_EAP_OTP:
19c48da0 5892 bin_clear_free(eap->otp, eap->otp_len);
d2118814
JM
5893 eap->otp = (u8 *) os_strdup(value);
5894 eap->otp_len = os_strlen(value);
5895 os_free(eap->pending_req_otp);
5896 eap->pending_req_otp = NULL;
5897 eap->pending_req_otp_len = 0;
5898 break;
5899 case WPA_CTRL_REQ_EAP_PASSPHRASE:
19c48da0
JM
5900 str_clear_free(eap->private_key_passwd);
5901 eap->private_key_passwd = os_strdup(value);
d2118814
JM
5902 eap->pending_req_passphrase = 0;
5903 if (ssid == wpa_s->current_ssid)
5904 wpa_s->reassociate = 1;
5905 break;
a5d44ac0 5906 case WPA_CTRL_REQ_SIM:
19c48da0 5907 str_clear_free(eap->external_sim_resp);
a5d44ac0
JM
5908 eap->external_sim_resp = os_strdup(value);
5909 break;
a52410c2
JM
5910 case WPA_CTRL_REQ_PSK_PASSPHRASE:
5911 if (wpa_config_set(ssid, "psk", value, 0) < 0)
5912 return -1;
5913 ssid->mem_only_psk = 1;
5914 if (ssid->passphrase)
5915 wpa_config_update_psk(ssid);
5916 if (wpa_s->wpa_state == WPA_SCANNING && !wpa_s->scanning)
5917 wpa_supplicant_req_scan(wpa_s, 0, 0);
5918 break;
3c108b75
JM
5919 case WPA_CTRL_REQ_EXT_CERT_CHECK:
5920 if (eap->pending_ext_cert_check != PENDING_CHECK)
5921 return -1;
5922 if (os_strcmp(value, "good") == 0)
5923 eap->pending_ext_cert_check = EXT_CERT_CHECK_GOOD;
5924 else if (os_strcmp(value, "bad") == 0)
5925 eap->pending_ext_cert_check = EXT_CERT_CHECK_BAD;
5926 else
5927 return -1;
5928 break;
d2118814
JM
5929 default:
5930 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
5931 return -1;
5932 }
5933
5934 return 0;
5935#else /* IEEE8021X_EAPOL */
5936 wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
5937 return -1;
5938#endif /* IEEE8021X_EAPOL */
5939}
5940#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
349493bd
JM
5941
5942
5943int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
5944{
5945 int i;
5946 unsigned int drv_enc;
5947
44b9ea5b
JM
5948 if (wpa_s->p2p_mgmt)
5949 return 1; /* no normal network profiles on p2p_mgmt interface */
5950
349493bd
JM
5951 if (ssid == NULL)
5952 return 1;
5953
5954 if (ssid->disabled)
5955 return 1;
5956
9feadba1 5957 if (wpa_s->drv_capa_known)
349493bd
JM
5958 drv_enc = wpa_s->drv_enc;
5959 else
5960 drv_enc = (unsigned int) -1;
5961
5962 for (i = 0; i < NUM_WEP_KEYS; i++) {
5963 size_t len = ssid->wep_key_len[i];
5964 if (len == 0)
5965 continue;
5966 if (len == 5 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40))
5967 continue;
5968 if (len == 13 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104))
5969 continue;
5970 if (len == 16 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP128))
5971 continue;
5972 return 1; /* invalid WEP key */
5973 }
5974
9173b16f 5975 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
a52410c2
JM
5976 (!ssid->passphrase || ssid->ssid_len != 0) && !ssid->ext_psk &&
5977 !ssid->mem_only_psk)
2518aad3
JM
5978 return 1;
5979
349493bd
JM
5980 return 0;
5981}
b9cfc09a
JJ
5982
5983
3f56a2b7
JM
5984int wpas_get_ssid_pmf(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
5985{
5986#ifdef CONFIG_IEEE80211W
5987 if (ssid == NULL || ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT) {
5988 if (wpa_s->conf->pmf == MGMT_FRAME_PROTECTION_OPTIONAL &&
5989 !(wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_BIP)) {
5990 /*
5991 * Driver does not support BIP -- ignore pmf=1 default
5992 * since the connection with PMF would fail and the
5993 * configuration does not require PMF to be enabled.
5994 */
5995 return NO_MGMT_FRAME_PROTECTION;
5996 }
5997
22950049
JM
5998 if (ssid &&
5999 (ssid->key_mgmt &
6000 ~(WPA_KEY_MGMT_NONE | WPA_KEY_MGMT_WPS |
6001 WPA_KEY_MGMT_IEEE8021X_NO_WPA)) == 0) {
6002 /*
6003 * Do not use the default PMF value for non-RSN networks
6004 * since PMF is available only with RSN and pmf=2
6005 * configuration would otherwise prevent connections to
6006 * all open networks.
6007 */
6008 return NO_MGMT_FRAME_PROTECTION;
6009 }
6010
3f56a2b7
JM
6011 return wpa_s->conf->pmf;
6012 }
6013
6014 return ssid->ieee80211w;
6015#else /* CONFIG_IEEE80211W */
6016 return NO_MGMT_FRAME_PROTECTION;
6017#endif /* CONFIG_IEEE80211W */
6018}
6019
6020
b9cfc09a
JJ
6021int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
6022{
6023 if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
6024 return 1;
6025 if (wpa_s->global->conc_pref == WPA_CONC_PREF_STA)
6026 return 0;
6027 return -1;
6028}
00e5e3d5
JM
6029
6030
b19c098e 6031void wpas_auth_failed(struct wpa_supplicant *wpa_s, char *reason)
00e5e3d5
JM
6032{
6033 struct wpa_ssid *ssid = wpa_s->current_ssid;
6034 int dur;
4e1eae1d 6035 struct os_reltime now;
00e5e3d5
JM
6036
6037 if (ssid == NULL) {
6038 wpa_printf(MSG_DEBUG, "Authentication failure but no known "
6039 "SSID block");
6040 return;
6041 }
6042
6043 if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
6044 return;
6045
6046 ssid->auth_failures++;
cbf41ca7
SL
6047
6048#ifdef CONFIG_P2P
6049 if (ssid->p2p_group &&
6050 (wpa_s->p2p_in_provisioning || wpa_s->show_group_started)) {
6051 /*
6052 * Skip the wait time since there is a short timeout on the
6053 * connection to a P2P group.
6054 */
6055 return;
6056 }
6057#endif /* CONFIG_P2P */
6058
00e5e3d5
JM
6059 if (ssid->auth_failures > 50)
6060 dur = 300;
00e5e3d5 6061 else if (ssid->auth_failures > 10)
8a77f1be 6062 dur = 120;
00e5e3d5 6063 else if (ssid->auth_failures > 5)
8a77f1be
JM
6064 dur = 90;
6065 else if (ssid->auth_failures > 3)
6066 dur = 60;
6067 else if (ssid->auth_failures > 2)
00e5e3d5
JM
6068 dur = 30;
6069 else if (ssid->auth_failures > 1)
6070 dur = 20;
6071 else
6072 dur = 10;
6073
8a77f1be
JM
6074 if (ssid->auth_failures > 1 &&
6075 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt))
6076 dur += os_random() % (ssid->auth_failures * 10);
6077
4e1eae1d 6078 os_get_reltime(&now);
00e5e3d5
JM
6079 if (now.sec + dur <= ssid->disabled_until.sec)
6080 return;
6081
6082 ssid->disabled_until.sec = now.sec + dur;
6083
6084 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TEMP_DISABLED
b19c098e 6085 "id=%d ssid=\"%s\" auth_failures=%u duration=%d reason=%s",
00e5e3d5 6086 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
b19c098e 6087 ssid->auth_failures, dur, reason);
00e5e3d5
JM
6088}
6089
6090
6091void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
6092 struct wpa_ssid *ssid, int clear_failures)
6093{
6094 if (ssid == NULL)
6095 return;
6096
6097 if (ssid->disabled_until.sec) {
6098 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REENABLED
6099 "id=%d ssid=\"%s\"",
6100 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
6101 }
6102 ssid->disabled_until.sec = 0;
6103 ssid->disabled_until.usec = 0;
6104 if (clear_failures)
6105 ssid->auth_failures = 0;
6106}
6407f413
JM
6107
6108
6109int disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid)
6110{
6111 size_t i;
6112
6113 if (wpa_s->disallow_aps_bssid == NULL)
6114 return 0;
6115
6116 for (i = 0; i < wpa_s->disallow_aps_bssid_count; i++) {
6117 if (os_memcmp(wpa_s->disallow_aps_bssid + i * ETH_ALEN,
6118 bssid, ETH_ALEN) == 0)
6119 return 1;
6120 }
6121
6122 return 0;
6123}
6124
6125
6126int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
6127 size_t ssid_len)
6128{
6129 size_t i;
6130
6131 if (wpa_s->disallow_aps_ssid == NULL || ssid == NULL)
6132 return 0;
6133
6134 for (i = 0; i < wpa_s->disallow_aps_ssid_count; i++) {
6135 struct wpa_ssid_value *s = &wpa_s->disallow_aps_ssid[i];
6136 if (ssid_len == s->ssid_len &&
6137 os_memcmp(ssid, s->ssid, ssid_len) == 0)
6138 return 1;
6139 }
6140
6141 return 0;
6142}
9796a86c
JM
6143
6144
6145/**
6146 * wpas_request_connection - Request a new connection
6147 * @wpa_s: Pointer to the network interface
6148 *
6149 * This function is used to request a new connection to be found. It will mark
6150 * the interface to allow reassociation and request a new scan to find a
6151 * suitable network to connect to.
6152 */
6153void wpas_request_connection(struct wpa_supplicant *wpa_s)
6154{
6155 wpa_s->normal_scans = 0;
5214f4fa 6156 wpa_s->scan_req = NORMAL_SCAN_REQ;
9796a86c
JM
6157 wpa_supplicant_reinit_autoscan(wpa_s);
6158 wpa_s->extra_blacklist_count = 0;
6159 wpa_s->disconnected = 0;
6160 wpa_s->reassociate = 1;
5e24beae
MH
6161
6162 if (wpa_supplicant_fast_associate(wpa_s) != 1)
6163 wpa_supplicant_req_scan(wpa_s, 0, 0);
0c5f01fd
B
6164 else
6165 wpa_s->reattach = 0;
9796a86c 6166}
36b9883d
DG
6167
6168
5f040be4
RP
6169/**
6170 * wpas_request_disconnection - Request disconnection
6171 * @wpa_s: Pointer to the network interface
6172 *
6173 * This function is used to request disconnection from the currently connected
6174 * network. This will stop any ongoing scans and initiate deauthentication.
6175 */
6176void wpas_request_disconnection(struct wpa_supplicant *wpa_s)
6177{
6178#ifdef CONFIG_SME
6179 wpa_s->sme.prev_bssid_set = 0;
6180#endif /* CONFIG_SME */
6181 wpa_s->reassociate = 0;
6182 wpa_s->disconnected = 1;
6183 wpa_supplicant_cancel_sched_scan(wpa_s);
6184 wpa_supplicant_cancel_scan(wpa_s);
6185 wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
6186 eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
6187}
6188
6189
a0c90bb0
IP
6190void dump_freq_data(struct wpa_supplicant *wpa_s, const char *title,
6191 struct wpa_used_freq_data *freqs_data,
6192 unsigned int len)
6193{
6194 unsigned int i;
6195
6196 wpa_dbg(wpa_s, MSG_DEBUG, "Shared frequencies (len=%u): %s",
6197 len, title);
6198 for (i = 0; i < len; i++) {
6199 struct wpa_used_freq_data *cur = &freqs_data[i];
6200 wpa_dbg(wpa_s, MSG_DEBUG, "freq[%u]: %d, flags=0x%X",
6201 i, cur->freq, cur->flags);
6202 }
6203}
6204
6205
53c5dfc2
IP
6206/*
6207 * Find the operating frequencies of any of the virtual interfaces that
a0c90bb0
IP
6208 * are using the same radio as the current interface, and in addition, get
6209 * information about the interface types that are using the frequency.
53c5dfc2 6210 */
a0c90bb0
IP
6211int get_shared_radio_freqs_data(struct wpa_supplicant *wpa_s,
6212 struct wpa_used_freq_data *freqs_data,
6213 unsigned int len)
53c5dfc2 6214{
53c5dfc2
IP
6215 struct wpa_supplicant *ifs;
6216 u8 bssid[ETH_ALEN];
6217 int freq;
6218 unsigned int idx = 0, i;
6219
217cf499
JM
6220 wpa_dbg(wpa_s, MSG_DEBUG,
6221 "Determining shared radio frequencies (max len %u)", len);
a0c90bb0 6222 os_memset(freqs_data, 0, sizeof(struct wpa_used_freq_data) * len);
53c5dfc2 6223
0ad3b9c4
JM
6224 dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
6225 radio_list) {
a0c90bb0
IP
6226 if (idx == len)
6227 break;
6228
53c5dfc2
IP
6229 if (ifs->current_ssid == NULL || ifs->assoc_freq == 0)
6230 continue;
6231
6232 if (ifs->current_ssid->mode == WPAS_MODE_AP ||
241c3333
MH
6233 ifs->current_ssid->mode == WPAS_MODE_P2P_GO ||
6234 ifs->current_ssid->mode == WPAS_MODE_MESH)
53c5dfc2
IP
6235 freq = ifs->current_ssid->frequency;
6236 else if (wpa_drv_get_bssid(ifs, bssid) == 0)
6237 freq = ifs->assoc_freq;
6238 else
6239 continue;
6240
6241 /* Hold only distinct freqs */
6242 for (i = 0; i < idx; i++)
a0c90bb0 6243 if (freqs_data[i].freq == freq)
53c5dfc2
IP
6244 break;
6245
6246 if (i == idx)
a0c90bb0
IP
6247 freqs_data[idx++].freq = freq;
6248
6249 if (ifs->current_ssid->mode == WPAS_MODE_INFRA) {
22264b3c 6250 freqs_data[i].flags |= ifs->current_ssid->p2p_group ?
a0c90bb0
IP
6251 WPA_FREQ_USED_BY_P2P_CLIENT :
6252 WPA_FREQ_USED_BY_INFRA_STATION;
6253 }
53c5dfc2 6254 }
217cf499 6255
a0c90bb0 6256 dump_freq_data(wpa_s, "completed iteration", freqs_data, idx);
53c5dfc2
IP
6257 return idx;
6258}
a0c90bb0
IP
6259
6260
6261/*
6262 * Find the operating frequencies of any of the virtual interfaces that
6263 * are using the same radio as the current interface.
6264 */
6265int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
6266 int *freq_array, unsigned int len)
6267{
6268 struct wpa_used_freq_data *freqs_data;
6269 int num, i;
6270
6271 os_memset(freq_array, 0, sizeof(int) * len);
6272
6273 freqs_data = os_calloc(len, sizeof(struct wpa_used_freq_data));
6274 if (!freqs_data)
6275 return -1;
6276
6277 num = get_shared_radio_freqs_data(wpa_s, freqs_data, len);
6278 for (i = 0; i < num; i++)
6279 freq_array[i] = freqs_data[i].freq;
6280
6281 os_free(freqs_data);
6282
6283 return num;
6284}
b361d580
AK
6285
6286
af041f99
AA
6287struct wpa_supplicant *
6288wpas_vendor_elem(struct wpa_supplicant *wpa_s, enum wpa_vendor_elem_frame frame)
6289{
6290 switch (frame) {
6291#ifdef CONFIG_P2P
6292 case VENDOR_ELEM_PROBE_REQ_P2P:
6293 case VENDOR_ELEM_PROBE_RESP_P2P:
6294 case VENDOR_ELEM_PROBE_RESP_P2P_GO:
6295 case VENDOR_ELEM_BEACON_P2P_GO:
6296 case VENDOR_ELEM_P2P_PD_REQ:
6297 case VENDOR_ELEM_P2P_PD_RESP:
6298 case VENDOR_ELEM_P2P_GO_NEG_REQ:
6299 case VENDOR_ELEM_P2P_GO_NEG_RESP:
6300 case VENDOR_ELEM_P2P_GO_NEG_CONF:
6301 case VENDOR_ELEM_P2P_INV_REQ:
6302 case VENDOR_ELEM_P2P_INV_RESP:
6303 case VENDOR_ELEM_P2P_ASSOC_REQ:
6304 case VENDOR_ELEM_P2P_ASSOC_RESP:
ba307f85 6305 return wpa_s->p2pdev;
af041f99
AA
6306#endif /* CONFIG_P2P */
6307 default:
6308 return wpa_s;
6309 }
6310}
6311
6312
6313void wpas_vendor_elem_update(struct wpa_supplicant *wpa_s)
6314{
6315 unsigned int i;
6316 char buf[30];
6317
6318 wpa_printf(MSG_DEBUG, "Update vendor elements");
6319
6320 for (i = 0; i < NUM_VENDOR_ELEM_FRAMES; i++) {
6321 if (wpa_s->vendor_elem[i]) {
6322 int res;
6323
6324 res = os_snprintf(buf, sizeof(buf), "frame[%u]", i);
6325 if (!os_snprintf_error(sizeof(buf), res)) {
6326 wpa_hexdump_buf(MSG_DEBUG, buf,
6327 wpa_s->vendor_elem[i]);
6328 }
6329 }
6330 }
6331
6332#ifdef CONFIG_P2P
6333 if (wpa_s->parent == wpa_s &&
6334 wpa_s->global->p2p &&
6335 !wpa_s->global->p2p_disabled)
6336 p2p_set_vendor_elems(wpa_s->global->p2p, wpa_s->vendor_elem);
6337#endif /* CONFIG_P2P */
6338}
6339
6340
6341int wpas_vendor_elem_remove(struct wpa_supplicant *wpa_s, int frame,
6342 const u8 *elem, size_t len)
6343{
6344 u8 *ie, *end;
6345
6346 ie = wpabuf_mhead_u8(wpa_s->vendor_elem[frame]);
6347 end = ie + wpabuf_len(wpa_s->vendor_elem[frame]);
6348
6349 for (; ie + 1 < end; ie += 2 + ie[1]) {
6350 if (ie + len > end)
6351 break;
6352 if (os_memcmp(ie, elem, len) != 0)
6353 continue;
6354
6355 if (wpabuf_len(wpa_s->vendor_elem[frame]) == len) {
6356 wpabuf_free(wpa_s->vendor_elem[frame]);
6357 wpa_s->vendor_elem[frame] = NULL;
6358 } else {
6359 os_memmove(ie, ie + len, end - (ie + len));
6360 wpa_s->vendor_elem[frame]->used -= len;
6361 }
6362 wpas_vendor_elem_update(wpa_s);
6363 return 0;
6364 }
6365
6366 return -1;
6367}
ea69d973
AS
6368
6369
6370struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes,
6371 u16 num_modes, enum hostapd_hw_mode mode)
6372{
6373 u16 i;
6374
6375 for (i = 0; i < num_modes; i++) {
6376 if (modes[i].mode == mode)
6377 return &modes[i];
6378 }
6379
6380 return NULL;
6381}
dd599908
AS
6382
6383
6384static struct
6385wpa_bss_tmp_disallowed * wpas_get_disallowed_bss(struct wpa_supplicant *wpa_s,
6386 const u8 *bssid)
6387{
6388 struct wpa_bss_tmp_disallowed *bss;
6389
6390 dl_list_for_each(bss, &wpa_s->bss_tmp_disallowed,
6391 struct wpa_bss_tmp_disallowed, list) {
6392 if (os_memcmp(bssid, bss->bssid, ETH_ALEN) == 0)
6393 return bss;
6394 }
6395
6396 return NULL;
6397}
6398
6399
6400void wpa_bss_tmp_disallow(struct wpa_supplicant *wpa_s, const u8 *bssid,
6401 unsigned int sec)
6402{
6403 struct wpa_bss_tmp_disallowed *bss;
6404 struct os_reltime until;
6405
6406 os_get_reltime(&until);
6407 until.sec += sec;
6408
6409 bss = wpas_get_disallowed_bss(wpa_s, bssid);
6410 if (bss) {
6411 bss->disallowed_until = until;
6412 return;
6413 }
6414
6415 bss = os_malloc(sizeof(*bss));
6416 if (!bss) {
6417 wpa_printf(MSG_DEBUG,
6418 "Failed to allocate memory for temp disallow BSS");
6419 return;
6420 }
6421
6422 bss->disallowed_until = until;
6423 os_memcpy(bss->bssid, bssid, ETH_ALEN);
6424 dl_list_add(&wpa_s->bss_tmp_disallowed, &bss->list);
6425}
6426
6427
6428int wpa_is_bss_tmp_disallowed(struct wpa_supplicant *wpa_s, const u8 *bssid)
6429{
d010048c 6430 struct wpa_bss_tmp_disallowed *bss = NULL, *tmp, *prev;
dd599908
AS
6431 struct os_reltime now, age;
6432
6433 os_get_reltime(&now);
6434
d010048c
JM
6435 dl_list_for_each_safe(tmp, prev, &wpa_s->bss_tmp_disallowed,
6436 struct wpa_bss_tmp_disallowed, list) {
6437 if (!os_reltime_before(&now, &tmp->disallowed_until)) {
6438 /* This BSS is not disallowed anymore */
6439 dl_list_del(&tmp->list);
6440 os_free(tmp);
6441 continue;
6442 }
6443 if (os_memcmp(bssid, tmp->bssid, ETH_ALEN) == 0) {
6444 bss = tmp;
6445 break;
6446 }
6447 }
dd599908
AS
6448 if (!bss)
6449 return 0;
6450
d010048c
JM
6451 os_reltime_sub(&bss->disallowed_until, &now, &age);
6452 wpa_printf(MSG_DEBUG,
6453 "BSS " MACSTR " disabled for %ld.%0ld seconds",
6454 MAC2STR(bss->bssid), age.sec, age.usec);
6455 return 1;
dd599908 6456}