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