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