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