]> git.ipfire.org Git - thirdparty/hostap.git/blame - wpa_supplicant/wpa_supplicant.c
HS 2.0 server: Remove redundant NULL check
[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 }
5d30f927
BR
1694 }
1695
1696 if (rand_style > 0 && !wpa_s->reassoc_same_ess) {
a313d17d 1697 if (wpas_update_random_addr(wpa_s, rand_style) < 0)
c267753b
JM
1698 return;
1699 wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
5d30f927 1700 } else if (rand_style == 0 && wpa_s->mac_addr_changed) {
c267753b
JM
1701 if (wpa_drv_set_mac_addr(wpa_s, NULL) < 0) {
1702 wpa_msg(wpa_s, MSG_INFO,
1703 "Could not restore permanent MAC address");
1704 return;
1705 }
1706 wpa_s->mac_addr_changed = 0;
1707 if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
1708 wpa_msg(wpa_s, MSG_INFO,
1709 "Could not update MAC address information");
1710 return;
1711 }
1712 wpa_msg(wpa_s, MSG_DEBUG, "Using permanent MAC address");
1713 }
1714 wpa_s->last_ssid = ssid;
1715
78177a00
JM
1716#ifdef CONFIG_IBSS_RSN
1717 ibss_rsn_deinit(wpa_s->ibss_rsn);
1718 wpa_s->ibss_rsn = NULL;
1719#endif /* CONFIG_IBSS_RSN */
1720
2c5d725c
JM
1721 if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
1722 ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
1581b38b
JM
1723#ifdef CONFIG_AP
1724 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) {
f049052b
BG
1725 wpa_msg(wpa_s, MSG_INFO, "Driver does not support AP "
1726 "mode");
1581b38b
JM
1727 return;
1728 }
8c981d17
DW
1729 if (wpa_supplicant_create_ap(wpa_s, ssid) < 0) {
1730 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
b2b688d1
VKE
1731 if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
1732 wpas_p2p_ap_setup_failed(wpa_s);
8c981d17
DW
1733 return;
1734 }
8f770587 1735 wpa_s->current_bss = bss;
1581b38b 1736#else /* CONFIG_AP */
f049052b
BG
1737 wpa_msg(wpa_s, MSG_ERROR, "AP mode support not included in "
1738 "the build");
1581b38b
JM
1739#endif /* CONFIG_AP */
1740 return;
1741 }
1742
603a3f34
JL
1743 if (ssid->mode == WPAS_MODE_MESH) {
1744#ifdef CONFIG_MESH
1745 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MESH)) {
1746 wpa_msg(wpa_s, MSG_INFO,
1747 "Driver does not support mesh mode");
1748 return;
1749 }
1750 if (bss)
1751 ssid->frequency = bss->freq;
1752 if (wpa_supplicant_join_mesh(wpa_s, ssid) < 0) {
1753 wpa_msg(wpa_s, MSG_ERROR, "Could not join mesh");
1754 return;
1755 }
1756 wpa_s->current_bss = bss;
6174de66
JM
1757 wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_STARTED "ssid=\"%s\" id=%d",
1758 wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
1759 ssid->id);
603a3f34
JL
1760#else /* CONFIG_MESH */
1761 wpa_msg(wpa_s, MSG_ERROR,
1762 "mesh mode support not included in the build");
1763#endif /* CONFIG_MESH */
1764 return;
1765 }
1766
52c9e6f3 1767#ifdef CONFIG_TDLS
95cb2d88
JM
1768 if (bss)
1769 wpa_tdls_ap_ies(wpa_s->wpa, (const u8 *) (bss + 1),
1770 bss->ie_len);
52c9e6f3
JM
1771#endif /* CONFIG_TDLS */
1772
5cc4d64b
JM
1773 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
1774 ssid->mode == IEEE80211_MODE_INFRA) {
c2a04078
JM
1775 sme_authenticate(wpa_s, bss, ssid);
1776 return;
1777 }
1778
6ac4b15e
JM
1779 if (wpa_s->connect_work) {
1780 wpa_dbg(wpa_s, MSG_DEBUG, "Reject wpa_supplicant_associate() call since connect_work exist");
1781 return;
1782 }
1783
f0e30c84
JM
1784 if (radio_work_pending(wpa_s, "connect")) {
1785 wpa_dbg(wpa_s, MSG_DEBUG, "Reject wpa_supplicant_associate() call since pending work exist");
1786 return;
1787 }
1788
4ead7cfd
KV
1789 wpas_abort_ongoing_scan(wpa_s);
1790
6ac4b15e
JM
1791 cwork = os_zalloc(sizeof(*cwork));
1792 if (cwork == NULL)
1793 return;
1794
1795 cwork->bss = bss;
1796 cwork->ssid = ssid;
1797
1798 if (radio_add_work(wpa_s, bss ? bss->freq : 0, "connect", 1,
1799 wpas_start_assoc_cb, cwork) < 0) {
1800 os_free(cwork);
1801 }
1802}
1803
1804
98479dc9
JD
1805static int bss_is_ibss(struct wpa_bss *bss)
1806{
1807 return (bss->caps & (IEEE80211_CAP_ESS | IEEE80211_CAP_IBSS)) ==
1808 IEEE80211_CAP_IBSS;
1809}
1810
1811
a65efbfb
PO
1812static int drv_supports_vht(struct wpa_supplicant *wpa_s,
1813 const struct wpa_ssid *ssid)
1814{
1815 enum hostapd_hw_mode hw_mode;
1816 struct hostapd_hw_modes *mode = NULL;
1817 u8 channel;
1818 int i;
1819
1820#ifdef CONFIG_HT_OVERRIDES
1821 if (ssid->disable_ht)
1822 return 0;
1823#endif /* CONFIG_HT_OVERRIDES */
1824
1825 hw_mode = ieee80211_freq_to_chan(ssid->frequency, &channel);
1826 if (hw_mode == NUM_HOSTAPD_MODES)
1827 return 0;
1828 for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
1829 if (wpa_s->hw.modes[i].mode == hw_mode) {
1830 mode = &wpa_s->hw.modes[i];
1831 break;
1832 }
1833 }
1834
1835 if (!mode)
1836 return 0;
1837
1838 return mode->vht_capab != 0;
1839}
1840
1841
54fe48b9
JM
1842void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s,
1843 const struct wpa_ssid *ssid,
1844 struct hostapd_freq_params *freq)
1830817e
JD
1845{
1846 enum hostapd_hw_mode hw_mode;
1847 struct hostapd_hw_modes *mode = NULL;
6b8b0774
JD
1848 int ht40plus[] = { 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157,
1849 184, 192 };
563ee183 1850 int vht80[] = { 36, 52, 100, 116, 132, 149 };
6b8b0774 1851 struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL;
1830817e 1852 u8 channel;
98479dc9 1853 int i, chan_idx, ht40 = -1, res, obss_scan = 1;
0f29bc68 1854 unsigned int j, k;
563ee183 1855 struct hostapd_freq_params vht_freq;
0f29bc68
AK
1856 int chwidth, seg0, seg1;
1857 u32 vht_caps = 0;
1830817e
JD
1858
1859 freq->freq = ssid->frequency;
1860
98479dc9
JD
1861 for (j = 0; j < wpa_s->last_scan_res_used; j++) {
1862 struct wpa_bss *bss = wpa_s->last_scan_res[j];
1863
1864 if (ssid->mode != WPAS_MODE_IBSS)
1865 break;
1866
1867 /* Don't adjust control freq in case of fixed_freq */
1868 if (ssid->fixed_freq)
1869 break;
1870
1871 if (!bss_is_ibss(bss))
1872 continue;
1873
1874 if (ssid->ssid_len == bss->ssid_len &&
1875 os_memcmp(ssid->ssid, bss->ssid, bss->ssid_len) == 0) {
1876 wpa_printf(MSG_DEBUG,
1877 "IBSS already found in scan results, adjust control freq: %d",
1878 bss->freq);
1879 freq->freq = bss->freq;
1880 obss_scan = 0;
1881 break;
1882 }
1883 }
1884
1830817e
JD
1885 /* For IBSS check HT_IBSS flag */
1886 if (ssid->mode == WPAS_MODE_IBSS &&
1887 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_HT_IBSS))
1888 return;
1889
d9a9bc04
JD
1890 if (wpa_s->group_cipher == WPA_CIPHER_WEP40 ||
1891 wpa_s->group_cipher == WPA_CIPHER_WEP104 ||
1892 wpa_s->pairwise_cipher == WPA_CIPHER_TKIP) {
1893 wpa_printf(MSG_DEBUG,
1894 "IBSS: WEP/TKIP detected, do not try to enable HT");
1895 return;
1896 }
1897
98479dc9 1898 hw_mode = ieee80211_freq_to_chan(freq->freq, &channel);
1830817e
JD
1899 for (i = 0; wpa_s->hw.modes && i < wpa_s->hw.num_modes; i++) {
1900 if (wpa_s->hw.modes[i].mode == hw_mode) {
1901 mode = &wpa_s->hw.modes[i];
1902 break;
1903 }
1904 }
1905
1906 if (!mode)
1907 return;
1908
3388e7b9
MH
1909#ifdef CONFIG_HT_OVERRIDES
1910 if (ssid->disable_ht) {
1911 freq->ht_enabled = 0;
1912 return;
1913 }
1914#endif /* CONFIG_HT_OVERRIDES */
1915
1830817e 1916 freq->ht_enabled = ht_supported(mode);
6b8b0774
JD
1917 if (!freq->ht_enabled)
1918 return;
1919
1920 /* Setup higher BW only for 5 GHz */
1921 if (mode->mode != HOSTAPD_MODE_IEEE80211A)
1922 return;
1923
1924 for (chan_idx = 0; chan_idx < mode->num_channels; chan_idx++) {
1925 pri_chan = &mode->channels[chan_idx];
1926 if (pri_chan->chan == channel)
1927 break;
1928 pri_chan = NULL;
1929 }
1930 if (!pri_chan)
1931 return;
1932
1933 /* Check primary channel flags */
1934 if (pri_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
1935 return;
1936
05aed438
MH
1937#ifdef CONFIG_HT_OVERRIDES
1938 if (ssid->disable_ht40)
1939 return;
1940#endif /* CONFIG_HT_OVERRIDES */
1941
6b8b0774
JD
1942 /* Check/setup HT40+/HT40- */
1943 for (j = 0; j < ARRAY_SIZE(ht40plus); j++) {
1944 if (ht40plus[j] == channel) {
1945 ht40 = 1;
1946 break;
1947 }
1948 }
1949
1950 /* Find secondary channel */
1951 for (i = 0; i < mode->num_channels; i++) {
1952 sec_chan = &mode->channels[i];
1953 if (sec_chan->chan == channel + ht40 * 4)
1954 break;
1955 sec_chan = NULL;
1956 }
1957 if (!sec_chan)
1958 return;
1959
1960 /* Check secondary channel flags */
1961 if (sec_chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
1962 return;
1963
1964 freq->channel = pri_chan->chan;
1965
ecba4509 1966 if (ht40 == -1) {
6b8b0774
JD
1967 if (!(pri_chan->flag & HOSTAPD_CHAN_HT40MINUS))
1968 return;
ecba4509 1969 } else {
6b8b0774
JD
1970 if (!(pri_chan->flag & HOSTAPD_CHAN_HT40PLUS))
1971 return;
6b8b0774 1972 }
ecba4509 1973 freq->sec_channel_offset = ht40;
6b8b0774 1974
ecba4509 1975 if (obss_scan) {
6b8b0774
JD
1976 struct wpa_scan_results *scan_res;
1977
1978 scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
1979 if (scan_res == NULL) {
1980 /* Back to HT20 */
1981 freq->sec_channel_offset = 0;
1982 return;
1983 }
1984
1985 res = check_40mhz_5g(mode, scan_res, pri_chan->chan,
1986 sec_chan->chan);
1987 switch (res) {
1988 case 0:
1989 /* Back to HT20 */
1990 freq->sec_channel_offset = 0;
1991 break;
1992 case 1:
1993 /* Configuration allowed */
1994 break;
1995 case 2:
1996 /* Switch pri/sec channels */
1997 freq->freq = hw_get_freq(mode, sec_chan->chan);
1998 freq->sec_channel_offset = -freq->sec_channel_offset;
1999 freq->channel = sec_chan->chan;
2000 break;
2001 default:
2002 freq->sec_channel_offset = 0;
2003 break;
2004 }
2005
2006 wpa_scan_results_free(scan_res);
2007 }
2008
2009 wpa_printf(MSG_DEBUG,
2010 "IBSS/mesh: setup freq channel %d, sec_channel_offset %d",
2011 freq->channel, freq->sec_channel_offset);
563ee183 2012
a65efbfb 2013 if (!drv_supports_vht(wpa_s, ssid))
563ee183
JD
2014 return;
2015
2016 /* For IBSS check VHT_IBSS flag */
a65efbfb
PO
2017 if (ssid->mode == WPAS_MODE_IBSS &&
2018 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_VHT_IBSS))
563ee183
JD
2019 return;
2020
2021 vht_freq = *freq;
2022
2023 vht_freq.vht_enabled = vht_supported(mode);
2024 if (!vht_freq.vht_enabled)
2025 return;
2026
2027 /* setup center_freq1, bandwidth */
2028 for (j = 0; j < ARRAY_SIZE(vht80); j++) {
2029 if (freq->channel >= vht80[j] &&
2030 freq->channel < vht80[j] + 16)
2031 break;
2032 }
2033
2034 if (j == ARRAY_SIZE(vht80))
2035 return;
2036
2037 for (i = vht80[j]; i < vht80[j] + 16; i += 4) {
2038 struct hostapd_channel_data *chan;
2039
2040 chan = hw_get_channel_chan(mode, i, NULL);
2041 if (!chan)
2042 return;
2043
2044 /* Back to HT configuration if channel not usable */
2045 if (chan->flag & (HOSTAPD_CHAN_DISABLED | HOSTAPD_CHAN_NO_IR))
2046 return;
2047 }
2048
0f29bc68
AK
2049 chwidth = VHT_CHANWIDTH_80MHZ;
2050 seg0 = vht80[j] + 6;
2051 seg1 = 0;
2052
2053 if (ssid->max_oper_chwidth == VHT_CHANWIDTH_80P80MHZ) {
2054 /* setup center_freq2, bandwidth */
2055 for (k = 0; k < ARRAY_SIZE(vht80); k++) {
2056 /* Only accept 80 MHz segments separated by a gap */
2057 if (j == k || abs(vht80[j] - vht80[k]) == 16)
2058 continue;
2059 for (i = vht80[k]; i < vht80[k] + 16; i += 4) {
2060 struct hostapd_channel_data *chan;
2061
2062 chan = hw_get_channel_chan(mode, i, NULL);
2063 if (!chan)
2064 continue;
2065
2066 if (chan->flag & (HOSTAPD_CHAN_DISABLED |
2067 HOSTAPD_CHAN_NO_IR |
2068 HOSTAPD_CHAN_RADAR))
2069 continue;
2070
2071 /* Found a suitable second segment for 80+80 */
2072 chwidth = VHT_CHANWIDTH_80P80MHZ;
2073 vht_caps |=
2074 VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
2075 seg1 = vht80[k] + 6;
2076 }
2077
2078 if (chwidth == VHT_CHANWIDTH_80P80MHZ)
2079 break;
2080 }
331f0774
JM
2081 } else if (ssid->max_oper_chwidth == VHT_CHANWIDTH_160MHZ) {
2082 if (freq->freq == 5180) {
2083 chwidth = VHT_CHANWIDTH_160MHZ;
2084 vht_caps |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
2085 seg0 = 50;
2086 } else if (freq->freq == 5520) {
2087 chwidth = VHT_CHANWIDTH_160MHZ;
2088 vht_caps |= VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
2089 seg0 = 114;
2090 }
0f29bc68
AK
2091 }
2092
563ee183
JD
2093 if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq,
2094 freq->channel, freq->ht_enabled,
2095 vht_freq.vht_enabled,
2096 freq->sec_channel_offset,
0f29bc68 2097 chwidth, seg0, seg1, vht_caps) != 0)
563ee183
JD
2098 return;
2099
2100 *freq = vht_freq;
2101
2102 wpa_printf(MSG_DEBUG, "IBSS: VHT setup freq cf1 %d, cf2 %d, bw %d",
2103 freq->center_freq1, freq->center_freq2, freq->bandwidth);
1830817e
JD
2104}
2105
2106
6ac4b15e
JM
2107static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
2108{
2109 struct wpa_connect_work *cwork = work->ctx;
2110 struct wpa_bss *bss = cwork->bss;
2111 struct wpa_ssid *ssid = cwork->ssid;
2112 struct wpa_supplicant *wpa_s = work->wpa_s;
2113 u8 wpa_ie[200];
2114 size_t wpa_ie_len;
2115 int use_crypt, ret, i, bssid_changed;
2116 int algs = WPA_AUTH_ALG_OPEN;
2117 unsigned int cipher_pairwise, cipher_group;
2118 struct wpa_driver_associate_params params;
2119 int wep_keys_set = 0;
2120 int assoc_failed = 0;
2121 struct wpa_ssid *old_ssid;
6a5ee810 2122 u8 prev_bssid[ETH_ALEN];
6ac4b15e
JM
2123#ifdef CONFIG_HT_OVERRIDES
2124 struct ieee80211_ht_capabilities htcaps;
2125 struct ieee80211_ht_capabilities htcaps_mask;
2126#endif /* CONFIG_HT_OVERRIDES */
6aa1cd4e
PS
2127#ifdef CONFIG_VHT_OVERRIDES
2128 struct ieee80211_vht_capabilities vhtcaps;
2129 struct ieee80211_vht_capabilities vhtcaps_mask;
2130#endif /* CONFIG_VHT_OVERRIDES */
5e57ba25
AS
2131#ifdef CONFIG_MBO
2132 const u8 *mbo = NULL;
2133#endif /* CONFIG_MBO */
6ac4b15e
JM
2134
2135 if (deinit) {
b3253ebb
AO
2136 if (work->started) {
2137 wpa_s->connect_work = NULL;
2138
2139 /* cancel possible auth. timeout */
2140 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s,
2141 NULL);
2142 }
6ac4b15e
JM
2143 wpas_connect_work_free(cwork);
2144 return;
2145 }
2146
2147 wpa_s->connect_work = work;
2148
6108536d
HW
2149 if (cwork->bss_removed || !wpas_valid_bss_ssid(wpa_s, bss, ssid) ||
2150 wpas_network_disabled(wpa_s, ssid)) {
6ac4b15e
JM
2151 wpa_dbg(wpa_s, MSG_DEBUG, "BSS/SSID entry for association not valid anymore - drop connection attempt");
2152 wpas_connect_work_done(wpa_s);
2153 return;
2154 }
2155
6a5ee810 2156 os_memcpy(prev_bssid, wpa_s->bssid, ETH_ALEN);
0c80427d 2157 os_memset(&params, 0, sizeof(params));
6fc6879b 2158 wpa_s->reassociate = 0;
c60ba9f7 2159 wpa_s->eap_expected_failure = 0;
76d81b32
JM
2160 if (bss &&
2161 (!wpas_driver_bss_selection(wpa_s) || wpas_wps_searching(wpa_s))) {
6fc6879b 2162#ifdef CONFIG_IEEE80211R
6fa81a3b 2163 const u8 *ie, *md = NULL;
6fc6879b 2164#endif /* CONFIG_IEEE80211R */
6fc6879b
JM
2165 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
2166 " (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid),
6fa81a3b 2167 wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq);
8bac466b 2168 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
6fc6879b
JM
2169 os_memset(wpa_s->bssid, 0, ETH_ALEN);
2170 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
8bac466b
JM
2171 if (bssid_changed)
2172 wpas_notify_bssid_changed(wpa_s);
6fc6879b 2173#ifdef CONFIG_IEEE80211R
6fa81a3b 2174 ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
6fc6879b
JM
2175 if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
2176 md = ie + 2;
e7846b68 2177 wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
91a05482
JM
2178 if (md) {
2179 /* Prepare for the next transition */
76b7981d 2180 wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
91a05482 2181 }
6fc6879b 2182#endif /* CONFIG_IEEE80211R */
24c23d1b
JM
2183#ifdef CONFIG_WPS
2184 } else if ((ssid->ssid == NULL || ssid->ssid_len == 0) &&
2185 wpa_s->conf->ap_scan == 2 &&
2186 (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
2187 /* Use ap_scan==1 style network selection to find the network
2188 */
74656400 2189 wpas_connect_work_done(wpa_s);
4115303b 2190 wpa_s->scan_req = MANUAL_SCAN_REQ;
24c23d1b
JM
2191 wpa_s->reassociate = 1;
2192 wpa_supplicant_req_scan(wpa_s, 0, 0);
2193 return;
2194#endif /* CONFIG_WPS */
6fc6879b
JM
2195 } else {
2196 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
2197 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
04e3d815
MK
2198 if (bss)
2199 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
2200 else
2201 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
6fc6879b 2202 }
0d0f7ecb
MS
2203 if (!wpa_s->pno)
2204 wpa_supplicant_cancel_sched_scan(wpa_s);
2205
6fc6879b
JM
2206 wpa_supplicant_cancel_scan(wpa_s);
2207
2208 /* Starting new association, so clear the possibly used WPA IE from the
2209 * previous association. */
2210 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
2211
2212#ifdef IEEE8021X_EAPOL
2213 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
2214 if (ssid->leap) {
2215 if (ssid->non_leap == 0)
abd9fafa 2216 algs = WPA_AUTH_ALG_LEAP;
6fc6879b 2217 else
abd9fafa 2218 algs |= WPA_AUTH_ALG_LEAP;
6fc6879b
JM
2219 }
2220 }
2221#endif /* IEEE8021X_EAPOL */
f049052b 2222 wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs);
6fc6879b 2223 if (ssid->auth_alg) {
abd9fafa 2224 algs = ssid->auth_alg;
f049052b
BG
2225 wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: "
2226 "0x%x", algs);
6fc6879b 2227 }
6fc6879b 2228
6fa81a3b
JM
2229 if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
2230 wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
0bf927a0 2231 wpa_key_mgmt_wpa(ssid->key_mgmt)) {
6fc6879b 2232 int try_opportunistic;
6e202021
JM
2233 try_opportunistic = (ssid->proactive_key_caching < 0 ?
2234 wpa_s->conf->okc :
2235 ssid->proactive_key_caching) &&
6fc6879b
JM
2236 (ssid->proto & WPA_PROTO_RSN);
2237 if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
b2a12c4f 2238 ssid, try_opportunistic) == 0)
ba422613 2239 eapol_sm_notify_pmkid_attempt(wpa_s->eapol);
6fc6879b
JM
2240 wpa_ie_len = sizeof(wpa_ie);
2241 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
2242 wpa_ie, &wpa_ie_len)) {
f049052b
BG
2243 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
2244 "key management and encryption suites");
74656400 2245 wpas_connect_work_done(wpa_s);
6fc6879b
JM
2246 return;
2247 }
a3f7e518
JM
2248 } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && bss &&
2249 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
2250 /*
2251 * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
2252 * use non-WPA since the scan results did not indicate that the
2253 * AP is using WPA or WPA2.
2254 */
2255 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
2256 wpa_ie_len = 0;
2257 wpa_s->wpa_proto = 0;
0bf927a0 2258 } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
6fc6879b
JM
2259 wpa_ie_len = sizeof(wpa_ie);
2260 if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
2261 wpa_ie, &wpa_ie_len)) {
f049052b
BG
2262 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
2263 "key management and encryption suites (no "
2264 "scan results)");
74656400 2265 wpas_connect_work_done(wpa_s);
6fc6879b
JM
2266 return;
2267 }
ad08c363
JM
2268#ifdef CONFIG_WPS
2269 } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
b01c18a8
JM
2270 struct wpabuf *wps_ie;
2271 wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
ad08c363
JM
2272 if (wps_ie && wpabuf_len(wps_ie) <= sizeof(wpa_ie)) {
2273 wpa_ie_len = wpabuf_len(wps_ie);
2274 os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
24386985
JM
2275 } else
2276 wpa_ie_len = 0;
ad08c363
JM
2277 wpabuf_free(wps_ie);
2278 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
0c80427d
JM
2279 if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY))
2280 params.wps = WPS_MODE_PRIVACY;
2281 else
2282 params.wps = WPS_MODE_OPEN;
cf546f1a 2283 wpa_s->wpa_proto = 0;
ad08c363 2284#endif /* CONFIG_WPS */
6fc6879b
JM
2285 } else {
2286 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
2287 wpa_ie_len = 0;
cf546f1a 2288 wpa_s->wpa_proto = 0;
6fc6879b
JM
2289 }
2290
5f3a6aa0
JM
2291#ifdef CONFIG_P2P
2292 if (wpa_s->global->p2p) {
2293 u8 *pos;
2294 size_t len;
2295 int res;
5f3a6aa0
JM
2296 pos = wpa_ie + wpa_ie_len;
2297 len = sizeof(wpa_ie) - wpa_ie_len;
b8a8d677
JM
2298 res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
2299 ssid->p2p_group);
5f3a6aa0
JM
2300 if (res >= 0)
2301 wpa_ie_len += res;
2302 }
72044390
JM
2303
2304 wpa_s->cross_connect_disallowed = 0;
2305 if (bss) {
2306 struct wpabuf *p2p;
2307 p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
2308 if (p2p) {
2309 wpa_s->cross_connect_disallowed =
2310 p2p_get_cross_connect_disallowed(p2p);
2311 wpabuf_free(p2p);
f049052b
BG
2312 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: WLAN AP %s cross "
2313 "connection",
2314 wpa_s->cross_connect_disallowed ?
2315 "disallows" : "allows");
72044390
JM
2316 }
2317 }
25ef8529
JM
2318
2319 os_memset(wpa_s->p2p_ip_addr_info, 0, sizeof(wpa_s->p2p_ip_addr_info));
5f3a6aa0
JM
2320#endif /* CONFIG_P2P */
2321
5e57ba25
AS
2322#ifdef CONFIG_MBO
2323 if (bss) {
2324 mbo = wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE);
2325 if (mbo) {
2326 int len;
2327
2328 len = wpas_mbo_supp_op_class_ie(wpa_s, bss->freq,
2329 wpa_ie + wpa_ie_len,
2330 sizeof(wpa_ie) -
2331 wpa_ie_len);
2332 if (len > 0)
2333 wpa_ie_len += len;
2334 }
2335 }
2336#endif /* CONFIG_MBO */
2337
8b3b803a
AH
2338 /*
2339 * Workaround: Add Extended Capabilities element only if the AP
2340 * included this element in Beacon/Probe Response frames. Some older
2341 * APs seem to have interoperability issues if this element is
2342 * included, so while the standard may require us to include the
2343 * element in all cases, it is justifiable to skip it to avoid
2344 * interoperability issues.
2345 */
cc9a2575
KV
2346 if (ssid->p2p_group)
2347 wpa_drv_get_ext_capa(wpa_s, WPA_IF_P2P_CLIENT);
2348 else
2349 wpa_drv_get_ext_capa(wpa_s, WPA_IF_STATION);
2350
8b3b803a 2351 if (!bss || wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB)) {
0bbaa9b9 2352 u8 ext_capab[18];
8b3b803a 2353 int ext_capab_len;
0bbaa9b9
JM
2354 ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
2355 sizeof(ext_capab));
8b3b803a
AH
2356 if (ext_capab_len > 0) {
2357 u8 *pos = wpa_ie;
2358 if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)
2359 pos += 2 + pos[1];
2360 os_memmove(pos + ext_capab_len, pos,
2361 wpa_ie_len - (pos - wpa_ie));
2362 wpa_ie_len += ext_capab_len;
2363 os_memcpy(pos, ext_capab, ext_capab_len);
2364 }
92cbcf91 2365 }
92cbcf91 2366
c484b198
AS
2367#ifdef CONFIG_HS20
2368 if (is_hs20_network(wpa_s, ssid, bss)) {
2369 struct wpabuf *hs20;
2370
2371 hs20 = wpabuf_alloc(20);
2372 if (hs20) {
2373 int pps_mo_id = hs20_get_pps_mo_id(wpa_s, ssid);
2374 size_t len;
2375
2376 wpas_hs20_add_indication(hs20, pps_mo_id);
2377 len = sizeof(wpa_ie) - wpa_ie_len;
2378 if (wpabuf_len(hs20) <= len) {
2379 os_memcpy(wpa_ie + wpa_ie_len,
2380 wpabuf_head(hs20), wpabuf_len(hs20));
2381 wpa_ie_len += wpabuf_len(hs20);
2382 }
2383 wpabuf_free(hs20);
ece4ac5f
MG
2384
2385 hs20_configure_frame_filters(wpa_s);
c484b198
AS
2386 }
2387 }
2388#endif /* CONFIG_HS20 */
2389
d29fa3a7
JM
2390 if (wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ]) {
2391 struct wpabuf *buf = wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ];
2392 size_t len;
2393
2394 len = sizeof(wpa_ie) - wpa_ie_len;
2395 if (wpabuf_len(buf) <= len) {
2396 os_memcpy(wpa_ie + wpa_ie_len,
2397 wpabuf_head(buf), wpabuf_len(buf));
2398 wpa_ie_len += wpabuf_len(buf);
2399 }
2400 }
2401
b36a3a65
AN
2402#ifdef CONFIG_FST
2403 if (wpa_s->fst_ies) {
2404 int fst_ies_len = wpabuf_len(wpa_s->fst_ies);
2405
2406 if (wpa_ie_len + fst_ies_len <= sizeof(wpa_ie)) {
2407 os_memcpy(wpa_ie + wpa_ie_len,
2408 wpabuf_head(wpa_s->fst_ies), fst_ies_len);
2409 wpa_ie_len += fst_ies_len;
2410 }
2411 }
2412#endif /* CONFIG_FST */
2413
92c6e2e3 2414#ifdef CONFIG_MBO
5e57ba25
AS
2415 if (mbo) {
2416 int len;
92c6e2e3 2417
5e57ba25
AS
2418 len = wpas_mbo_ie(wpa_s, wpa_ie + wpa_ie_len,
2419 sizeof(wpa_ie) - wpa_ie_len);
2420 if (len >= 0)
2421 wpa_ie_len += len;
92c6e2e3
DS
2422 }
2423#endif /* CONFIG_MBO */
2424
6fc6879b
JM
2425 wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
2426 use_crypt = 1;
4848a38d
JM
2427 cipher_pairwise = wpa_s->pairwise_cipher;
2428 cipher_group = wpa_s->group_cipher;
6fc6879b
JM
2429 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
2430 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
2431 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
2432 use_crypt = 0;
2433 if (wpa_set_wep_keys(wpa_s, ssid)) {
2434 use_crypt = 1;
2435 wep_keys_set = 1;
2436 }
2437 }
ad08c363
JM
2438 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
2439 use_crypt = 0;
6fc6879b
JM
2440
2441#ifdef IEEE8021X_EAPOL
2442 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
2443 if ((ssid->eapol_flags &
2444 (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
2445 EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 &&
2446 !wep_keys_set) {
2447 use_crypt = 0;
2448 } else {
2449 /* Assume that dynamic WEP-104 keys will be used and
2450 * set cipher suites in order for drivers to expect
2451 * encryption. */
4848a38d 2452 cipher_pairwise = cipher_group = WPA_CIPHER_WEP104;
6fc6879b
JM
2453 }
2454 }
2455#endif /* IEEE8021X_EAPOL */
2456
2457 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
2458 /* Set the key before (and later after) association */
2459 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
2460 }
2461
6fc6879b 2462 wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
6fc6879b 2463 if (bss) {
6fa81a3b
JM
2464 params.ssid = bss->ssid;
2465 params.ssid_len = bss->ssid_len;
4b5b8a53
JM
2466 if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set ||
2467 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) {
f15854d1
JM
2468 wpa_printf(MSG_DEBUG, "Limit connection to BSSID "
2469 MACSTR " freq=%u MHz based on scan results "
4b5b8a53 2470 "(bssid_set=%d wps=%d)",
f15854d1 2471 MAC2STR(bss->bssid), bss->freq,
4b5b8a53
JM
2472 ssid->bssid_set,
2473 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS);
22628eca 2474 params.bssid = bss->bssid;
4ec68377 2475 params.freq.freq = bss->freq;
22628eca 2476 }
7ac7fd43
DS
2477 params.bssid_hint = bss->bssid;
2478 params.freq_hint = bss->freq;
b9074912 2479 params.pbss = bss_is_pbss(bss);
6fc6879b
JM
2480 } else {
2481 params.ssid = ssid->ssid;
2482 params.ssid_len = ssid->ssid_len;
90f14962 2483 params.pbss = (ssid->pbss != 2) ? ssid->pbss : 0;
6fc6879b 2484 }
9e2af29f
NC
2485
2486 if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&
2487 wpa_s->conf->ap_scan == 2) {
2488 params.bssid = ssid->bssid;
2489 params.fixed_bssid = 1;
2490 }
2491
603a3f34
JL
2492 /* Initial frequency for IBSS/mesh */
2493 if ((ssid->mode == WPAS_MODE_IBSS || ssid->mode == WPAS_MODE_MESH) &&
1830817e
JD
2494 ssid->frequency > 0 && params.freq.freq == 0)
2495 ibss_mesh_setup_freq(wpa_s, ssid, &params.freq);
dc152f32 2496
8f05577d 2497 if (ssid->mode == WPAS_MODE_IBSS) {
4d9e6fba 2498 params.fixed_freq = ssid->fixed_freq;
8f05577d
JM
2499 if (ssid->beacon_int)
2500 params.beacon_int = ssid->beacon_int;
2501 else
2502 params.beacon_int = wpa_s->conf->beacon_int;
2503 }
2504
6fc6879b
JM
2505 params.wpa_ie = wpa_ie;
2506 params.wpa_ie_len = wpa_ie_len;
2507 params.pairwise_suite = cipher_pairwise;
2508 params.group_suite = cipher_group;
4848a38d 2509 params.key_mgmt_suite = wpa_s->key_mgmt;
64fa840a 2510 params.wpa_proto = wpa_s->wpa_proto;
6fc6879b
JM
2511 params.auth_alg = algs;
2512 params.mode = ssid->mode;
1f6c0ab8 2513 params.bg_scan_period = ssid->bg_scan_period;
6fc6879b
JM
2514 for (i = 0; i < NUM_WEP_KEYS; i++) {
2515 if (ssid->wep_key_len[i])
2516 params.wep_key[i] = ssid->wep_key[i];
2517 params.wep_key_len[i] = ssid->wep_key_len[i];
2518 }
2519 params.wep_tx_keyidx = ssid->wep_tx_keyidx;
2520
c2a04078 2521 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
4848a38d
JM
2522 (params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
2523 params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK)) {
6fc6879b
JM
2524 params.passphrase = ssid->passphrase;
2525 if (ssid->psk_set)
2526 params.psk = ssid->psk;
b41f2684
CL
2527 }
2528
2529 if (wpa_s->conf->key_mgmt_offload) {
2530 if (params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X ||
666497c8 2531 params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SHA256 ||
5e3b5197
JM
2532 params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B ||
2533 params.key_mgmt_suite == WPA_KEY_MGMT_IEEE8021X_SUITE_B_192)
b41f2684
CL
2534 params.req_key_mgmt_offload =
2535 ssid->proactive_key_caching < 0 ?
2536 wpa_s->conf->okc : ssid->proactive_key_caching;
2537 else
2538 params.req_key_mgmt_offload = 1;
2539
2540 if ((params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
2541 params.key_mgmt_suite == WPA_KEY_MGMT_PSK_SHA256 ||
2542 params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK) &&
2543 ssid->psk_set)
2544 params.psk = ssid->psk;
6fc6879b
JM
2545 }
2546
36b15723
JM
2547 params.drop_unencrypted = use_crypt;
2548
6fc6879b 2549#ifdef CONFIG_IEEE80211W
3f56a2b7 2550 params.mgmt_frame_protection = wpas_get_ssid_pmf(wpa_s, ssid);
62d49803 2551 if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
6fa81a3b 2552 const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
97d3497e
JM
2553 struct wpa_ie_data ie;
2554 if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
2555 ie.capabilities &
2556 (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
f049052b
BG
2557 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected AP supports "
2558 "MFP: require MFP");
97d3497e
JM
2559 params.mgmt_frame_protection =
2560 MGMT_FRAME_PROTECTION_REQUIRED;
2561 }
2562 }
6fc6879b
JM
2563#endif /* CONFIG_IEEE80211W */
2564
ffad8858 2565 params.p2p = ssid->p2p_group;
6e3f4b89 2566
ba307f85
LD
2567 if (wpa_s->p2pdev->set_sta_uapsd)
2568 params.uapsd = wpa_s->p2pdev->sta_uapsd;
eea2fd9e
JM
2569 else
2570 params.uapsd = -1;
2571
80e8a5ee
BG
2572#ifdef CONFIG_HT_OVERRIDES
2573 os_memset(&htcaps, 0, sizeof(htcaps));
2574 os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
2575 params.htcaps = (u8 *) &htcaps;
2576 params.htcaps_mask = (u8 *) &htcaps_mask;
2577 wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
2578#endif /* CONFIG_HT_OVERRIDES */
6aa1cd4e
PS
2579#ifdef CONFIG_VHT_OVERRIDES
2580 os_memset(&vhtcaps, 0, sizeof(vhtcaps));
2581 os_memset(&vhtcaps_mask, 0, sizeof(vhtcaps_mask));
2582 params.vhtcaps = &vhtcaps;
2583 params.vhtcaps_mask = &vhtcaps_mask;
95ff3069 2584 wpa_supplicant_apply_vht_overrides(wpa_s, ssid, &params);
6aa1cd4e 2585#endif /* CONFIG_VHT_OVERRIDES */
80e8a5ee 2586
8567866d
JJ
2587#ifdef CONFIG_P2P
2588 /*
2589 * If multi-channel concurrency is not supported, check for any
2590 * frequency conflict. In case of any frequency conflict, remove the
2591 * least prioritized connection.
2592 */
2593 if (wpa_s->num_multichan_concurrent < 2) {
d0df6437
IP
2594 int freq, num;
2595 num = get_shared_radio_freqs(wpa_s, &freq, 1);
4ec68377 2596 if (num > 0 && freq > 0 && freq != params.freq.freq) {
d0df6437
IP
2597 wpa_printf(MSG_DEBUG,
2598 "Assoc conflicting freq found (%d != %d)",
4ec68377
JD
2599 freq, params.freq.freq);
2600 if (wpas_p2p_handle_frequency_conflicts(
74656400
SD
2601 wpa_s, params.freq.freq, ssid) < 0) {
2602 wpas_connect_work_done(wpa_s);
8567866d 2603 return;
74656400 2604 }
8567866d
JJ
2605 }
2606 }
2607#endif /* CONFIG_P2P */
2608
6a5ee810
JM
2609 if (wpa_s->reassoc_same_ess && !is_zero_ether_addr(prev_bssid) &&
2610 wpa_s->current_ssid)
2611 params.prev_bssid = prev_bssid;
2612
17fbb751 2613 ret = wpa_drv_associate(wpa_s, &params);
6fc6879b
JM
2614 if (ret < 0) {
2615 wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
2616 "failed");
871f4dd0
JM
2617 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SANE_ERROR_CODES) {
2618 /*
2619 * The driver is known to mean what is saying, so we
2620 * can stop right here; the association will not
2621 * succeed.
2622 */
2623 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
c1c02342 2624 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
871f4dd0
JM
2625 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
2626 return;
2627 }
6fc6879b
JM
2628 /* try to continue anyway; new association will be tried again
2629 * after timeout */
2630 assoc_failed = 1;
2631 }
2632
2633 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
2634 /* Set the key after the association just in case association
2635 * cleared the previously configured key. */
2636 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
2637 /* No need to timeout authentication since there is no key
2638 * management. */
2639 wpa_supplicant_cancel_auth_timeout(wpa_s);
2640 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
53895c3b 2641#ifdef CONFIG_IBSS_RSN
d7dcba70 2642 } else if (ssid->mode == WPAS_MODE_IBSS &&
53895c3b
JM
2643 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
2644 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
2645 /*
2646 * RSN IBSS authentication is per-STA and we can disable the
2647 * per-BSSID authentication.
2648 */
2649 wpa_supplicant_cancel_auth_timeout(wpa_s);
53895c3b 2650#endif /* CONFIG_IBSS_RSN */
6fc6879b
JM
2651 } else {
2652 /* Timeout for IEEE 802.11 authentication and association */
1d3c75b3
DW
2653 int timeout = 60;
2654
2655 if (assoc_failed) {
2656 /* give IBSS a bit more time */
d7dcba70 2657 timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5;
1d3c75b3
DW
2658 } else if (wpa_s->conf->ap_scan == 1) {
2659 /* give IBSS a bit more time */
d7dcba70 2660 timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10;
1d3c75b3 2661 }
6fc6879b
JM
2662 wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
2663 }
2664
66562e9c
JM
2665 if (wep_keys_set &&
2666 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC)) {
6fc6879b
JM
2667 /* Set static WEP keys again */
2668 wpa_set_wep_keys(wpa_s, ssid);
2669 }
2670
2671 if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
2672 /*
2673 * Do not allow EAP session resumption between different
2674 * network configurations.
2675 */
2676 eapol_sm_invalidate_cached_session(wpa_s->eapol);
2677 }
8bac466b 2678 old_ssid = wpa_s->current_ssid;
6fc6879b 2679 wpa_s->current_ssid = ssid;
ece4ac5f
MG
2680
2681 if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
4d3be9cd 2682 wpa_s->current_bss = bss;
ece4ac5f
MG
2683#ifdef CONFIG_HS20
2684 hs20_configure_frame_filters(wpa_s);
2685#endif /* CONFIG_HS20 */
2686 }
2687
6fc6879b
JM
2688 wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
2689 wpa_supplicant_initiate_eapol(wpa_s);
8bac466b
JM
2690 if (old_ssid != wpa_s->current_ssid)
2691 wpas_notify_network_changed(wpa_s);
6fc6879b
JM
2692}
2693
2694
09f58c09
JM
2695static void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s,
2696 const u8 *addr)
2697{
2698 struct wpa_ssid *old_ssid;
2699
c155305f 2700 wpas_connect_work_done(wpa_s);
09f58c09 2701 wpa_clear_keys(wpa_s, addr);
09f58c09 2702 old_ssid = wpa_s->current_ssid;
0d30cc24 2703 wpa_supplicant_mark_disassoc(wpa_s);
09f58c09
JM
2704 wpa_sm_set_config(wpa_s->wpa, NULL);
2705 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
2706 if (old_ssid != wpa_s->current_ssid)
2707 wpas_notify_network_changed(wpa_s);
2708 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
2709}
2710
2711
6fc6879b
JM
2712/**
2713 * wpa_supplicant_deauthenticate - Deauthenticate the current connection
2714 * @wpa_s: Pointer to wpa_supplicant data
2715 * @reason_code: IEEE 802.11 reason code for the deauthenticate frame
2716 *
073ab58f 2717 * This function is used to request %wpa_supplicant to deauthenticate from the
6fc6879b
JM
2718 * current AP.
2719 */
2720void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
2721 int reason_code)
2722{
2723 u8 *addr = NULL;
ef48ff94 2724 union wpa_event_data event;
42d23547 2725 int zero_addr = 0;
8bac466b 2726
42d23547
JM
2727 wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
2728 " pending_bssid=" MACSTR " reason=%d state=%s",
2729 MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
2730 reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state));
2731
04e3d815
MK
2732 if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
2733 (wpa_s->wpa_state == WPA_AUTHENTICATING ||
2734 wpa_s->wpa_state == WPA_ASSOCIATING))
42d23547 2735 addr = wpa_s->pending_bssid;
04e3d815
MK
2736 else if (!is_zero_ether_addr(wpa_s->bssid))
2737 addr = wpa_s->bssid;
42d23547
JM
2738 else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
2739 /*
2740 * When using driver-based BSS selection, we may not know the
2741 * BSSID with which we are currently trying to associate. We
2742 * need to notify the driver of this disconnection even in such
2743 * a case, so use the all zeros address here.
2744 */
6fc6879b 2745 addr = wpa_s->bssid;
42d23547
JM
2746 zero_addr = 1;
2747 }
2748
7b44ff2c
SD
2749#ifdef CONFIG_TDLS
2750 wpa_tdls_teardown_peers(wpa_s->wpa);
2751#endif /* CONFIG_TDLS */
2752
603a3f34
JL
2753#ifdef CONFIG_MESH
2754 if (wpa_s->ifmsh) {
6174de66
JM
2755 wpa_msg(wpa_s, MSG_INFO, MESH_GROUP_REMOVED "%s",
2756 wpa_s->ifname);
603a3f34
JL
2757 wpa_supplicant_leave_mesh(wpa_s);
2758 }
2759#endif /* CONFIG_MESH */
2760
42d23547
JM
2761 if (addr) {
2762 wpa_drv_deauthenticate(wpa_s, addr, reason_code);
ef48ff94
JM
2763 os_memset(&event, 0, sizeof(event));
2764 event.deauth_info.reason_code = (u16) reason_code;
2765 event.deauth_info.locally_generated = 1;
2766 wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
42d23547
JM
2767 if (zero_addr)
2768 addr = NULL;
6fc6879b 2769 }
09f58c09
JM
2770
2771 wpa_supplicant_clear_connection(wpa_s, addr);
6fc6879b
JM
2772}
2773
dca1a511
DS
2774static void wpa_supplicant_enable_one_network(struct wpa_supplicant *wpa_s,
2775 struct wpa_ssid *ssid)
2776{
2777 if (!ssid || !ssid->disabled || ssid->disabled == 2)
2778 return;
2779
2780 ssid->disabled = 0;
2781 wpas_clear_temp_disabled(wpa_s, ssid, 1);
2782 wpas_notify_network_enabled_changed(wpa_s, ssid);
2783
2784 /*
2785 * Try to reassociate since there is no current configuration and a new
2786 * network was made available.
2787 */
d2592497 2788 if (!wpa_s->current_ssid && !wpa_s->disconnected)
dca1a511
DS
2789 wpa_s->reassociate = 1;
2790}
2791
6fc6879b 2792
d015bb05
RP
2793/**
2794 * wpa_supplicant_add_network - Add a new network
2795 * @wpa_s: wpa_supplicant structure for a network interface
2796 * Returns: The new network configuration or %NULL if operation failed
2797 *
2798 * This function performs the following operations:
2799 * 1. Adds a new network.
2800 * 2. Send network addition notification.
2801 * 3. Marks the network disabled.
2802 * 4. Set network default parameters.
2803 */
2804struct wpa_ssid * wpa_supplicant_add_network(struct wpa_supplicant *wpa_s)
2805{
2806 struct wpa_ssid *ssid;
2807
2808 ssid = wpa_config_add_network(wpa_s->conf);
2809 if (!ssid)
2810 return NULL;
2811 wpas_notify_network_added(wpa_s, ssid);
2812 ssid->disabled = 1;
2813 wpa_config_set_network_defaults(ssid);
2814
2815 return ssid;
2816}
2817
2818
2819/**
2820 * wpa_supplicant_remove_network - Remove a configured network based on id
2821 * @wpa_s: wpa_supplicant structure for a network interface
2822 * @id: Unique network id to search for
2823 * Returns: 0 on success, or -1 if the network was not found, -2 if the network
2824 * could not be removed
2825 *
2826 * This function performs the following operations:
2827 * 1. Removes the network.
2828 * 2. Send network removal notification.
2829 * 3. Update internal state machines.
2830 * 4. Stop any running sched scans.
2831 */
2832int wpa_supplicant_remove_network(struct wpa_supplicant *wpa_s, int id)
2833{
2834 struct wpa_ssid *ssid;
2835 int was_disabled;
2836
2837 ssid = wpa_config_get_network(wpa_s->conf, id);
2838 if (!ssid)
2839 return -1;
2840 wpas_notify_network_removed(wpa_s, ssid);
2841
2842 if (wpa_s->last_ssid == ssid)
2843 wpa_s->last_ssid = NULL;
2844
2845 if (ssid == wpa_s->current_ssid || !wpa_s->current_ssid) {
2846#ifdef CONFIG_SME
2847 wpa_s->sme.prev_bssid_set = 0;
2848#endif /* CONFIG_SME */
2849 /*
2850 * Invalidate the EAP session cache if the current or
2851 * previously used network is removed.
2852 */
2853 eapol_sm_invalidate_cached_session(wpa_s->eapol);
2854 }
2855
2856 if (ssid == wpa_s->current_ssid) {
2857 wpa_sm_set_config(wpa_s->wpa, NULL);
2858 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
2859
2860 if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
2861 wpa_s->own_disconnect_req = 1;
2862 wpa_supplicant_deauthenticate(wpa_s,
2863 WLAN_REASON_DEAUTH_LEAVING);
2864 }
2865
2866 was_disabled = ssid->disabled;
2867
2868 if (wpa_config_remove_network(wpa_s->conf, id) < 0)
2869 return -2;
2870
2871 if (!was_disabled && wpa_s->sched_scanning) {
2872 wpa_printf(MSG_DEBUG,
2873 "Stop ongoing sched_scan to remove network from filters");
2874 wpa_supplicant_cancel_sched_scan(wpa_s);
2875 wpa_supplicant_req_scan(wpa_s, 0, 0);
2876 }
2877
2878 return 0;
2879}
2880
2881
86b89452
WS
2882/**
2883 * wpa_supplicant_enable_network - Mark a configured network as enabled
2884 * @wpa_s: wpa_supplicant structure for a network interface
2885 * @ssid: wpa_ssid structure for a configured network or %NULL
2886 *
2887 * Enables the specified network or all networks if no network specified.
2888 */
2889void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
2890 struct wpa_ssid *ssid)
2891{
86b89452 2892 if (ssid == NULL) {
14f79078
JM
2893 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
2894 wpa_supplicant_enable_one_network(wpa_s, ssid);
dca1a511
DS
2895 } else
2896 wpa_supplicant_enable_one_network(wpa_s, ssid);
86b89452 2897
5a1d9d1a
JM
2898 if (wpa_s->reassociate && !wpa_s->disconnected &&
2899 (!wpa_s->current_ssid ||
2900 wpa_s->wpa_state == WPA_DISCONNECTED ||
2901 wpa_s->wpa_state == WPA_SCANNING)) {
dca1a511
DS
2902 if (wpa_s->sched_scanning) {
2903 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to add "
2904 "new network to scan filters");
2905 wpa_supplicant_cancel_sched_scan(wpa_s);
2906 }
86b89452 2907
35d40309
JM
2908 if (wpa_supplicant_fast_associate(wpa_s) != 1) {
2909 wpa_s->scan_req = NORMAL_SCAN_REQ;
dad153d1 2910 wpa_supplicant_req_scan(wpa_s, 0, 0);
35d40309 2911 }
86b89452
WS
2912 }
2913}
2914
2915
2916/**
2917 * wpa_supplicant_disable_network - Mark a configured network as disabled
2918 * @wpa_s: wpa_supplicant structure for a network interface
2919 * @ssid: wpa_ssid structure for a configured network or %NULL
2920 *
2921 * Disables the specified network or all networks if no network specified.
2922 */
2923void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
2924 struct wpa_ssid *ssid)
2925{
2926 struct wpa_ssid *other_ssid;
2927 int was_disabled;
2928
2929 if (ssid == NULL) {
725fc39e
DS
2930 if (wpa_s->sched_scanning)
2931 wpa_supplicant_cancel_sched_scan(wpa_s);
2932
4dac0245
JM
2933 for (other_ssid = wpa_s->conf->ssid; other_ssid;
2934 other_ssid = other_ssid->next) {
86b89452 2935 was_disabled = other_ssid->disabled;
4dac0245
JM
2936 if (was_disabled == 2)
2937 continue; /* do not change persistent P2P group
2938 * data */
86b89452
WS
2939
2940 other_ssid->disabled = 1;
2941
2942 if (was_disabled != other_ssid->disabled)
2943 wpas_notify_network_enabled_changed(
2944 wpa_s, other_ssid);
86b89452
WS
2945 }
2946 if (wpa_s->current_ssid)
07783eaa 2947 wpa_supplicant_deauthenticate(
86b89452 2948 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
4dac0245 2949 } else if (ssid->disabled != 2) {
86b89452 2950 if (ssid == wpa_s->current_ssid)
07783eaa 2951 wpa_supplicant_deauthenticate(
86b89452
WS
2952 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
2953
2954 was_disabled = ssid->disabled;
2955
2956 ssid->disabled = 1;
2957
725fc39e 2958 if (was_disabled != ssid->disabled) {
86b89452 2959 wpas_notify_network_enabled_changed(wpa_s, ssid);
725fc39e
DS
2960 if (wpa_s->sched_scanning) {
2961 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan "
2962 "to remove network from filters");
2963 wpa_supplicant_cancel_sched_scan(wpa_s);
2964 wpa_supplicant_req_scan(wpa_s, 0, 0);
2965 }
2966 }
86b89452
WS
2967 }
2968}
2969
2970
2971/**
2972 * wpa_supplicant_select_network - Attempt association with a network
2973 * @wpa_s: wpa_supplicant structure for a network interface
2974 * @ssid: wpa_ssid structure for a configured network or %NULL for any network
2975 */
2976void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
2977 struct wpa_ssid *ssid)
2978{
2979
2980 struct wpa_ssid *other_ssid;
d93dfbd5 2981 int disconnected = 0;
86b89452 2982
d93dfbd5 2983 if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
e66bcedd
JM
2984 if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
2985 wpa_s->own_disconnect_req = 1;
07783eaa 2986 wpa_supplicant_deauthenticate(
86b89452 2987 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
d93dfbd5
JM
2988 disconnected = 1;
2989 }
86b89452 2990
00e5e3d5
JM
2991 if (ssid)
2992 wpas_clear_temp_disabled(wpa_s, ssid, 1);
2993
86b89452
WS
2994 /*
2995 * Mark all other networks disabled or mark all networks enabled if no
2996 * network specified.
2997 */
4dac0245
JM
2998 for (other_ssid = wpa_s->conf->ssid; other_ssid;
2999 other_ssid = other_ssid->next) {
86b89452 3000 int was_disabled = other_ssid->disabled;
4dac0245
JM
3001 if (was_disabled == 2)
3002 continue; /* do not change persistent P2P group data */
86b89452
WS
3003
3004 other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
00e5e3d5
JM
3005 if (was_disabled && !other_ssid->disabled)
3006 wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
86b89452
WS
3007
3008 if (was_disabled != other_ssid->disabled)
3009 wpas_notify_network_enabled_changed(wpa_s, other_ssid);
86b89452 3010 }
2a6f78fb 3011
d38c7be0
JM
3012 if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid &&
3013 wpa_s->wpa_state >= WPA_AUTHENTICATING) {
2a6f78fb
JJ
3014 /* We are already associated with the selected network */
3015 wpa_printf(MSG_DEBUG, "Already associated with the "
3016 "selected network - do nothing");
3017 return;
3018 }
3019
25a8f9e3 3020 if (ssid) {
96efeeb6 3021 wpa_s->current_ssid = ssid;
25a8f9e3 3022 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
603a3f34
JL
3023 wpa_s->connect_without_scan =
3024 (ssid->mode == WPAS_MODE_MESH) ? ssid : NULL;
701f3961
AS
3025
3026 /*
3027 * Don't optimize next scan freqs since a new ESS has been
3028 * selected.
3029 */
3030 os_free(wpa_s->next_scan_freqs);
3031 wpa_s->next_scan_freqs = NULL;
603a3f34
JL
3032 } else {
3033 wpa_s->connect_without_scan = NULL;
25a8f9e3 3034 }
603a3f34 3035
86b89452
WS
3036 wpa_s->disconnected = 0;
3037 wpa_s->reassociate = 1;
cecdddc1 3038
e4a35f07 3039 if (wpa_s->connect_without_scan ||
35d40309
JM
3040 wpa_supplicant_fast_associate(wpa_s) != 1) {
3041 wpa_s->scan_req = NORMAL_SCAN_REQ;
be7ebd89 3042 wpas_scan_reset_sched_scan(wpa_s);
cecdddc1 3043 wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
35d40309 3044 }
86b89452 3045
a1641d26
JM
3046 if (ssid)
3047 wpas_notify_network_selected(wpa_s, ssid);
86b89452
WS
3048}
3049
3050
bdec7ee5
MS
3051/**
3052 * wpas_set_pkcs11_engine_and_module_path - Set PKCS #11 engine and module path
3053 * @wpa_s: wpa_supplicant structure for a network interface
3054 * @pkcs11_engine_path: PKCS #11 engine path or NULL
3055 * @pkcs11_module_path: PKCS #11 module path or NULL
3056 * Returns: 0 on success; -1 on failure
3057 *
3058 * Sets the PKCS #11 engine and module path. Both have to be NULL or a valid
3059 * path. If resetting the EAPOL state machine with the new PKCS #11 engine and
3060 * module path fails the paths will be reset to the default value (NULL).
3061 */
3062int wpas_set_pkcs11_engine_and_module_path(struct wpa_supplicant *wpa_s,
3063 const char *pkcs11_engine_path,
3064 const char *pkcs11_module_path)
3065{
3066 char *pkcs11_engine_path_copy = NULL;
3067 char *pkcs11_module_path_copy = NULL;
3068
3069 if (pkcs11_engine_path != NULL) {
3070 pkcs11_engine_path_copy = os_strdup(pkcs11_engine_path);
3071 if (pkcs11_engine_path_copy == NULL)
3072 return -1;
3073 }
3074 if (pkcs11_module_path != NULL) {
3075 pkcs11_module_path_copy = os_strdup(pkcs11_module_path);
04c366cb 3076 if (pkcs11_module_path_copy == NULL) {
bdec7ee5
MS
3077 os_free(pkcs11_engine_path_copy);
3078 return -1;
3079 }
3080 }
3081
3082 os_free(wpa_s->conf->pkcs11_engine_path);
3083 os_free(wpa_s->conf->pkcs11_module_path);
3084 wpa_s->conf->pkcs11_engine_path = pkcs11_engine_path_copy;
3085 wpa_s->conf->pkcs11_module_path = pkcs11_module_path_copy;
3086
3087 wpa_sm_set_eapol(wpa_s->wpa, NULL);
3088 eapol_sm_deinit(wpa_s->eapol);
3089 wpa_s->eapol = NULL;
3090 if (wpa_supplicant_init_eapol(wpa_s)) {
3091 /* Error -> Reset paths to the default value (NULL) once. */
3092 if (pkcs11_engine_path != NULL && pkcs11_module_path != NULL)
3093 wpas_set_pkcs11_engine_and_module_path(wpa_s, NULL,
3094 NULL);
3095
3096 return -1;
3097 }
3098 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
3099
3100 return 0;
3101}
3102
3103
86b89452
WS
3104/**
3105 * wpa_supplicant_set_ap_scan - Set AP scan mode for interface
3106 * @wpa_s: wpa_supplicant structure for a network interface
3107 * @ap_scan: AP scan mode
3108 * Returns: 0 if succeed or -1 if ap_scan has an invalid value
3109 *
3110 */
3111int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
3112{
3113
3114 int old_ap_scan;
3115
3116 if (ap_scan < 0 || ap_scan > 2)
3117 return -1;
3118
8406cd35
JM
3119 if (ap_scan == 2 && os_strcmp(wpa_s->driver->name, "nl80211") == 0) {
3120 wpa_printf(MSG_INFO,
3121 "Note: nl80211 driver interface is not designed to be used with ap_scan=2; this can result in connection failures");
3122 }
3123
48f8e036
DS
3124#ifdef ANDROID
3125 if (ap_scan == 2 && ap_scan != wpa_s->conf->ap_scan &&
3126 wpa_s->wpa_state >= WPA_ASSOCIATING &&
3127 wpa_s->wpa_state < WPA_COMPLETED) {
3128 wpa_printf(MSG_ERROR, "ap_scan = %d (%d) rejected while "
3129 "associating", wpa_s->conf->ap_scan, ap_scan);
3130 return 0;
3131 }
3132#endif /* ANDROID */
3133
86b89452
WS
3134 old_ap_scan = wpa_s->conf->ap_scan;
3135 wpa_s->conf->ap_scan = ap_scan;
3136
3137 if (old_ap_scan != wpa_s->conf->ap_scan)
3138 wpas_notify_ap_scan_changed(wpa_s);
3139
3140 return 0;
3141}
3142
3143
78633c37
SL
3144/**
3145 * wpa_supplicant_set_bss_expiration_age - Set BSS entry expiration age
3146 * @wpa_s: wpa_supplicant structure for a network interface
3147 * @expire_age: Expiration age in seconds
3148 * Returns: 0 if succeed or -1 if expire_age has an invalid value
3149 *
3150 */
3151int wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
3152 unsigned int bss_expire_age)
3153{
3154 if (bss_expire_age < 10) {
3155 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration age %u",
3156 bss_expire_age);
3157 return -1;
3158 }
3159 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration age: %d sec",
3160 bss_expire_age);
3161 wpa_s->conf->bss_expiration_age = bss_expire_age;
3162
3163 return 0;
3164}
3165
3166
3167/**
3168 * wpa_supplicant_set_bss_expiration_count - Set BSS entry expiration scan count
3169 * @wpa_s: wpa_supplicant structure for a network interface
3170 * @expire_count: number of scans after which an unseen BSS is reclaimed
3171 * Returns: 0 if succeed or -1 if expire_count has an invalid value
3172 *
3173 */
3174int wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
3175 unsigned int bss_expire_count)
3176{
3177 if (bss_expire_count < 1) {
3178 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration count %u",
3179 bss_expire_count);
3180 return -1;
3181 }
3182 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration scan count: %u",
3183 bss_expire_count);
3184 wpa_s->conf->bss_expiration_scan_count = bss_expire_count;
3185
3186 return 0;
3187}
3188
3189
c6e86b63
MA
3190/**
3191 * wpa_supplicant_set_scan_interval - Set scan interval
3192 * @wpa_s: wpa_supplicant structure for a network interface
3193 * @scan_interval: scan interval in seconds
3194 * Returns: 0 if succeed or -1 if scan_interval has an invalid value
3195 *
3196 */
3197int wpa_supplicant_set_scan_interval(struct wpa_supplicant *wpa_s,
3198 int scan_interval)
3199{
3200 if (scan_interval < 0) {
3201 wpa_msg(wpa_s, MSG_ERROR, "Invalid scan interval %d",
3202 scan_interval);
3203 return -1;
3204 }
3205 wpa_msg(wpa_s, MSG_DEBUG, "Setting scan interval: %d sec",
3206 scan_interval);
9e737f08 3207 wpa_supplicant_update_scan_int(wpa_s, scan_interval);
c6e86b63
MA
3208
3209 return 0;
3210}
3211
3212
86b89452
WS
3213/**
3214 * wpa_supplicant_set_debug_params - Set global debug params
3215 * @global: wpa_global structure
3216 * @debug_level: debug level
3217 * @debug_timestamp: determines if show timestamp in debug data
3218 * @debug_show_keys: determines if show keys in debug data
3219 * Returns: 0 if succeed or -1 if debug_level has wrong value
3220 */
3221int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
3222 int debug_timestamp, int debug_show_keys)
3223{
3224
3225 int old_level, old_timestamp, old_show_keys;
3226
3227 /* check for allowed debuglevels */
14dc0011
PS
3228 if (debug_level != MSG_EXCESSIVE &&
3229 debug_level != MSG_MSGDUMP &&
86b89452
WS
3230 debug_level != MSG_DEBUG &&
3231 debug_level != MSG_INFO &&
3232 debug_level != MSG_WARNING &&
3233 debug_level != MSG_ERROR)
3234 return -1;
3235
3236 old_level = wpa_debug_level;
3237 old_timestamp = wpa_debug_timestamp;
3238 old_show_keys = wpa_debug_show_keys;
3239
3240 wpa_debug_level = debug_level;
3241 wpa_debug_timestamp = debug_timestamp ? 1 : 0;
3242 wpa_debug_show_keys = debug_show_keys ? 1 : 0;
3243
db9133ac
WS
3244 if (wpa_debug_level != old_level)
3245 wpas_notify_debug_level_changed(global);
3246 if (wpa_debug_timestamp != old_timestamp)
3247 wpas_notify_debug_timestamp_changed(global);
3248 if (wpa_debug_show_keys != old_show_keys)
3249 wpas_notify_debug_show_keys_changed(global);
86b89452
WS
3250
3251 return 0;
3252}
3253
3254
6fc6879b
JM
3255/**
3256 * wpa_supplicant_get_ssid - Get a pointer to the current network structure
3257 * @wpa_s: Pointer to wpa_supplicant data
3258 * Returns: A pointer to the current network structure or %NULL on failure
3259 */
3260struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
3261{
3262 struct wpa_ssid *entry;
eaa8eefe 3263 u8 ssid[SSID_MAX_LEN];
6fc6879b
JM
3264 int res;
3265 size_t ssid_len;
3266 u8 bssid[ETH_ALEN];
3267 int wired;
3268
17fbb751
JM
3269 res = wpa_drv_get_ssid(wpa_s, ssid);
3270 if (res < 0) {
3271 wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
3272 "driver");
3273 return NULL;
6fc6879b 3274 }
17fbb751 3275 ssid_len = res;
6fc6879b 3276
17fbb751 3277 if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
f049052b
BG
3278 wpa_msg(wpa_s, MSG_WARNING, "Could not read BSSID from "
3279 "driver");
6fc6879b
JM
3280 return NULL;
3281 }
3282
c2a04078
JM
3283 wired = wpa_s->conf->ap_scan == 0 &&
3284 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
6fc6879b
JM
3285
3286 entry = wpa_s->conf->ssid;
3287 while (entry) {
349493bd 3288 if (!wpas_network_disabled(wpa_s, entry) &&
6fc6879b
JM
3289 ((ssid_len == entry->ssid_len &&
3290 os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
3291 (!entry->bssid_set ||
3292 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
3293 return entry;
24c23d1b 3294#ifdef CONFIG_WPS
349493bd 3295 if (!wpas_network_disabled(wpa_s, entry) &&
24c23d1b
JM
3296 (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
3297 (entry->ssid == NULL || entry->ssid_len == 0) &&
3298 (!entry->bssid_set ||
3299 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
3300 return entry;
3301#endif /* CONFIG_WPS */
7d232e23 3302
349493bd 3303 if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
7d232e23
ZC
3304 entry->ssid_len == 0 &&
3305 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
3306 return entry;
3307
6fc6879b
JM
3308 entry = entry->next;
3309 }
3310
3311 return NULL;
3312}
3313
3314
7756114f
JM
3315static int select_driver(struct wpa_supplicant *wpa_s, int i)
3316{
3317 struct wpa_global *global = wpa_s->global;
3318
3319 if (wpa_drivers[i]->global_init && global->drv_priv[i] == NULL) {
45e3fc72 3320 global->drv_priv[i] = wpa_drivers[i]->global_init(global);
7756114f
JM
3321 if (global->drv_priv[i] == NULL) {
3322 wpa_printf(MSG_ERROR, "Failed to initialize driver "
3323 "'%s'", wpa_drivers[i]->name);
3324 return -1;
3325 }
3326 }
3327
3328 wpa_s->driver = wpa_drivers[i];
3329 wpa_s->global_drv_priv = global->drv_priv[i];
3330
3331 return 0;
3332}
3333
3334
6fc6879b
JM
3335static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
3336 const char *name)
3337{
3338 int i;
362f781e 3339 size_t len;
74b1c84a 3340 const char *pos, *driver = name;
6fc6879b
JM
3341
3342 if (wpa_s == NULL)
3343 return -1;
3344
c5121837 3345 if (wpa_drivers[0] == NULL) {
f049052b
BG
3346 wpa_msg(wpa_s, MSG_ERROR, "No driver interfaces build into "
3347 "wpa_supplicant");
6fc6879b
JM
3348 return -1;
3349 }
3350
3351 if (name == NULL) {
3352 /* default to first driver in the list */
7756114f 3353 return select_driver(wpa_s, 0);
6fc6879b
JM
3354 }
3355
74b1c84a
SO
3356 do {
3357 pos = os_strchr(driver, ',');
3358 if (pos)
3359 len = pos - driver;
3360 else
3361 len = os_strlen(driver);
3362
3363 for (i = 0; wpa_drivers[i]; i++) {
3364 if (os_strlen(wpa_drivers[i]->name) == len &&
3365 os_strncmp(driver, wpa_drivers[i]->name, len) ==
0f4668ce
DW
3366 0) {
3367 /* First driver that succeeds wins */
3368 if (select_driver(wpa_s, i) == 0)
3369 return 0;
3370 }
6fc6879b 3371 }
74b1c84a
SO
3372
3373 driver = pos + 1;
3374 } while (pos);
6fc6879b 3375
f049052b 3376 wpa_msg(wpa_s, MSG_ERROR, "Unsupported driver '%s'", name);
6fc6879b
JM
3377 return -1;
3378}
3379
3380
a8e0505b
JM
3381/**
3382 * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
3383 * @ctx: Context pointer (wpa_s); this is the ctx variable registered
3384 * with struct wpa_driver_ops::init()
3385 * @src_addr: Source address of the EAPOL frame
3386 * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
3387 * @len: Length of the EAPOL data
3388 *
3389 * This function is called for each received EAPOL frame. Most driver
3390 * interfaces rely on more generic OS mechanism for receiving frames through
3391 * l2_packet, but if such a mechanism is not available, the driver wrapper may
3392 * take care of received EAPOL frames and deliver them to the core supplicant
3393 * code by calling this function.
3394 */
6fc6879b
JM
3395void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
3396 const u8 *buf, size_t len)
3397{
3398 struct wpa_supplicant *wpa_s = ctx;
3399
f049052b 3400 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
6fc6879b
JM
3401 wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
3402
02adead5
MK
3403#ifdef CONFIG_TESTING_OPTIONS
3404 if (wpa_s->ignore_auth_resp) {
3405 wpa_printf(MSG_INFO, "RX EAPOL - ignore_auth_resp active!");
3406 return;
3407 }
3408#endif /* CONFIG_TESTING_OPTIONS */
3409
db76aa64
JM
3410#ifdef CONFIG_PEERKEY
3411 if (wpa_s->wpa_state > WPA_ASSOCIATED && wpa_s->current_ssid &&
3412 wpa_s->current_ssid->peerkey &&
3413 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
3414 wpa_sm_rx_eapol_peerkey(wpa_s->wpa, src_addr, buf, len) == 1) {
3415 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: Processed PeerKey EAPOL-Key");
3416 return;
3417 }
3418#endif /* CONFIG_PEERKEY */
3419
3ab35a66
JM
3420 if (wpa_s->wpa_state < WPA_ASSOCIATED ||
3421 (wpa_s->last_eapol_matches_bssid &&
3422#ifdef CONFIG_AP
3423 !wpa_s->ap_iface &&
3424#endif /* CONFIG_AP */
3425 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) != 0)) {
1ff73338
JM
3426 /*
3427 * There is possible race condition between receiving the
3428 * association event and the EAPOL frame since they are coming
3429 * through different paths from the driver. In order to avoid
3430 * issues in trying to process the EAPOL frame before receiving
3431 * association information, lets queue it for processing until
3ab35a66
JM
3432 * the association event is received. This may also be needed in
3433 * driver-based roaming case, so also use src_addr != BSSID as a
3434 * trigger if we have previously confirmed that the
3435 * Authenticator uses BSSID as the src_addr (which is not the
3436 * case with wired IEEE 802.1X).
1ff73338 3437 */
f049052b 3438 wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing "
3ab35a66
JM
3439 "of received EAPOL frame (state=%s bssid=" MACSTR ")",
3440 wpa_supplicant_state_txt(wpa_s->wpa_state),
3441 MAC2STR(wpa_s->bssid));
1ff73338
JM
3442 wpabuf_free(wpa_s->pending_eapol_rx);
3443 wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
3444 if (wpa_s->pending_eapol_rx) {
c2be937c 3445 os_get_reltime(&wpa_s->pending_eapol_rx_time);
1ff73338
JM
3446 os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
3447 ETH_ALEN);
3448 }
3449 return;
3450 }
3451
3ab35a66
JM
3452 wpa_s->last_eapol_matches_bssid =
3453 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) == 0;
3454
db149ac9
JM
3455#ifdef CONFIG_AP
3456 if (wpa_s->ap_iface) {
3457 wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
3458 return;
3459 }
3460#endif /* CONFIG_AP */
3461
6fc6879b 3462 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
f049052b
BG
3463 wpa_dbg(wpa_s, MSG_DEBUG, "Ignored received EAPOL frame since "
3464 "no key management is configured");
6fc6879b
JM
3465 return;
3466 }
3467
3468 if (wpa_s->eapol_received == 0 &&
c2a04078 3469 (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
56586197 3470 !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
9c972abb
JM
3471 wpa_s->wpa_state != WPA_COMPLETED) &&
3472 (wpa_s->current_ssid == NULL ||
3473 wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) {
6fc6879b 3474 /* Timeout for completing IEEE 802.1X and WPA authentication */
5add4101
JM
3475 int timeout = 10;
3476
3477 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
3478 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
3479 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) {
3480 /* Use longer timeout for IEEE 802.1X/EAP */
3481 timeout = 70;
3482 }
3483
c7dafdf9 3484#ifdef CONFIG_WPS
5add4101
JM
3485 if (wpa_s->current_ssid && wpa_s->current_bss &&
3486 (wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS) &&
3487 eap_is_wps_pin_enrollee(&wpa_s->current_ssid->eap)) {
3488 /*
3489 * Use shorter timeout if going through WPS AP iteration
3490 * for PIN config method with an AP that does not
3491 * advertise Selected Registrar.
3492 */
3493 struct wpabuf *wps_ie;
3494
3495 wps_ie = wpa_bss_get_vendor_ie_multi(
3496 wpa_s->current_bss, WPS_IE_VENDOR_TYPE);
0ef1e290
JM
3497 if (wps_ie &&
3498 !wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1))
5add4101
JM
3499 timeout = 10;
3500 wpabuf_free(wps_ie);
3501 }
c7dafdf9 3502#endif /* CONFIG_WPS */
5add4101
JM
3503
3504 wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
6fc6879b
JM
3505 }
3506 wpa_s->eapol_received++;
3507
3508 if (wpa_s->countermeasures) {
f049052b
BG
3509 wpa_msg(wpa_s, MSG_INFO, "WPA: Countermeasures - dropped "
3510 "EAPOL packet");
6fc6879b
JM
3511 return;
3512 }
3513
8be18440
JM
3514#ifdef CONFIG_IBSS_RSN
3515 if (wpa_s->current_ssid &&
d7dcba70 3516 wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
8be18440
JM
3517 ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
3518 return;
3519 }
3520#endif /* CONFIG_IBSS_RSN */
3521
6fc6879b
JM
3522 /* Source address of the incoming EAPOL frame could be compared to the
3523 * current BSSID. However, it is possible that a centralized
3524 * Authenticator could be using another MAC address than the BSSID of
3525 * an AP, so just allow any address to be used for now. The replies are
3526 * still sent to the current BSSID (if available), though. */
3527
3528 os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
56586197 3529 if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
6fc6879b
JM
3530 eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
3531 return;
3532 wpa_drv_poll(wpa_s);
c2a04078 3533 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
6fc6879b 3534 wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
56586197 3535 else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
6fc6879b
JM
3536 /*
3537 * Set portValid = TRUE here since we are going to skip 4-way
3538 * handshake processing which would normally set portValid. We
3539 * need this to allow the EAPOL state machines to be completed
3540 * without going through EAPOL-Key handshake.
3541 */
3542 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
3543 }
3544}
3545
3546
bfba8deb 3547int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
6fc6879b 3548{
2961bfa8
JM
3549 if ((!wpa_s->p2p_mgmt ||
3550 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
3551 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
bfba8deb 3552 l2_packet_deinit(wpa_s->l2);
6fc6879b
JM
3553 wpa_s->l2 = l2_packet_init(wpa_s->ifname,
3554 wpa_drv_get_mac_addr(wpa_s),
3555 ETH_P_EAPOL,
3556 wpa_supplicant_rx_eapol, wpa_s, 0);
3557 if (wpa_s->l2 == NULL)
3558 return -1;
fdadd5fe
JM
3559 } else {
3560 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
3561 if (addr)
3562 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
6fc6879b
JM
3563 }
3564
3565 if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
f049052b 3566 wpa_msg(wpa_s, MSG_ERROR, "Failed to get own L2 address");
6fc6879b
JM
3567 return -1;
3568 }
3569
c267753b
JM
3570 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
3571
bfba8deb
JM
3572 return 0;
3573}
3574
3575
25f839c6
JM
3576static void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr,
3577 const u8 *buf, size_t len)
3578{
3579 struct wpa_supplicant *wpa_s = ctx;
3580 const struct l2_ethhdr *eth;
3581
3582 if (len < sizeof(*eth))
3583 return;
3584 eth = (const struct l2_ethhdr *) buf;
3585
3586 if (os_memcmp(eth->h_dest, wpa_s->own_addr, ETH_ALEN) != 0 &&
3587 !(eth->h_dest[0] & 0x01)) {
3588 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
3589 " (bridge - not for this interface - ignore)",
3590 MAC2STR(src_addr), MAC2STR(eth->h_dest));
3591 return;
3592 }
3593
3594 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
3595 " (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest));
3596 wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth),
3597 len - sizeof(*eth));
3598}
3599
3600
bfba8deb
JM
3601/**
3602 * wpa_supplicant_driver_init - Initialize driver interface parameters
3603 * @wpa_s: Pointer to wpa_supplicant data
3604 * Returns: 0 on success, -1 on failure
3605 *
3606 * This function is called to initialize driver interface parameters.
3607 * wpa_drv_init() must have been called before this function to initialize the
3608 * driver interface.
3609 */
3610int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
3611{
3612 static int interface_count = 0;
3613
3614 if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
3615 return -1;
3616
c68f6200
AS
3617 wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
3618 MAC2STR(wpa_s->own_addr));
a313d17d 3619 os_memcpy(wpa_s->perm_addr, wpa_s->own_addr, ETH_ALEN);
c68f6200
AS
3620 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
3621
6fc6879b 3622 if (wpa_s->bridge_ifname[0]) {
f049052b
BG
3623 wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
3624 "interface '%s'", wpa_s->bridge_ifname);
e6dd8196
JM
3625 wpa_s->l2_br = l2_packet_init_bridge(
3626 wpa_s->bridge_ifname, wpa_s->ifname, wpa_s->own_addr,
3627 ETH_P_EAPOL, wpa_supplicant_rx_eapol_bridge, wpa_s, 1);
6fc6879b 3628 if (wpa_s->l2_br == NULL) {
f049052b
BG
3629 wpa_msg(wpa_s, MSG_ERROR, "Failed to open l2_packet "
3630 "connection for the bridge interface '%s'",
3631 wpa_s->bridge_ifname);
6fc6879b
JM
3632 return -1;
3633 }
3634 }
3635
8406cd35
JM
3636 if (wpa_s->conf->ap_scan == 2 &&
3637 os_strcmp(wpa_s->driver->name, "nl80211") == 0) {
3638 wpa_printf(MSG_INFO,
3639 "Note: nl80211 driver interface is not designed to be used with ap_scan=2; this can result in connection failures");
3640 }
3641
6fc6879b
JM
3642 wpa_clear_keys(wpa_s, NULL);
3643
3644 /* Make sure that TKIP countermeasures are not left enabled (could
3645 * happen if wpa_supplicant is killed during countermeasures. */
3646 wpa_drv_set_countermeasures(wpa_s, 0);
3647
f049052b 3648 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
6fc6879b
JM
3649 wpa_drv_flush_pmkid(wpa_s);
3650
ba2a573c 3651 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
b3aa456b
ES
3652 wpa_s->prev_scan_wildcard = 0;
3653
349493bd 3654 if (wpa_supplicant_enabled_networks(wpa_s)) {
a0e9d892
AS
3655 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
3656 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
3657 interface_count = 0;
3658 }
ee82e33d 3659#ifndef ANDROID
3a94adbf 3660 if (!wpa_s->p2p_mgmt &&
5d0d72a3
BG
3661 wpa_supplicant_delayed_sched_scan(wpa_s,
3662 interface_count % 3,
6a90053c 3663 100000))
5d0d72a3 3664 wpa_supplicant_req_scan(wpa_s, interface_count % 3,
a4cba8f1 3665 100000);
ee82e33d 3666#endif /* ANDROID */
74e259ec
JM
3667 interface_count++;
3668 } else
3669 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
6fc6879b
JM
3670
3671 return 0;
3672}
3673
3674
3675static int wpa_supplicant_daemon(const char *pid_file)
3676{
3677 wpa_printf(MSG_DEBUG, "Daemonize..");
3678 return os_daemonize(pid_file);
3679}
3680
3681
1772d348
JM
3682static struct wpa_supplicant *
3683wpa_supplicant_alloc(struct wpa_supplicant *parent)
6fc6879b
JM
3684{
3685 struct wpa_supplicant *wpa_s;
3686
3687 wpa_s = os_zalloc(sizeof(*wpa_s));
3688 if (wpa_s == NULL)
3689 return NULL;
4115303b 3690 wpa_s->scan_req = INITIAL_SCAN_REQ;
67b9bd08 3691 wpa_s->scan_interval = 5;
c302f207 3692 wpa_s->new_connection = 1;
1772d348 3693 wpa_s->parent = parent ? parent : wpa_s;
ba307f85 3694 wpa_s->p2pdev = wpa_s->parent;
cbdf3507 3695 wpa_s->sched_scanning = 0;
6fc6879b 3696
dd599908
AS
3697 dl_list_init(&wpa_s->bss_tmp_disallowed);
3698
6fc6879b
JM
3699 return wpa_s;
3700}
3701
3702
80e8a5ee
BG
3703#ifdef CONFIG_HT_OVERRIDES
3704
3705static int wpa_set_htcap_mcs(struct wpa_supplicant *wpa_s,
3706 struct ieee80211_ht_capabilities *htcaps,
3707 struct ieee80211_ht_capabilities *htcaps_mask,
3708 const char *ht_mcs)
3709{
3710 /* parse ht_mcs into hex array */
3711 int i;
3712 const char *tmp = ht_mcs;
3713 char *end = NULL;
3714
3715 /* If ht_mcs is null, do not set anything */
3716 if (!ht_mcs)
3717 return 0;
3718
3719 /* This is what we are setting in the kernel */
3720 os_memset(&htcaps->supported_mcs_set, 0, IEEE80211_HT_MCS_MASK_LEN);
3721
3722 wpa_msg(wpa_s, MSG_DEBUG, "set_htcap, ht_mcs -:%s:-", ht_mcs);
3723
3724 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
3725 errno = 0;
3726 long v = strtol(tmp, &end, 16);
3727 if (errno == 0) {
3728 wpa_msg(wpa_s, MSG_DEBUG,
3729 "htcap value[%i]: %ld end: %p tmp: %p",
3730 i, v, end, tmp);
3731 if (end == tmp)
3732 break;
3733
3734 htcaps->supported_mcs_set[i] = v;
3735 tmp = end;
3736 } else {
3737 wpa_msg(wpa_s, MSG_ERROR,
3738 "Failed to parse ht-mcs: %s, error: %s\n",
3739 ht_mcs, strerror(errno));
3740 return -1;
3741 }
3742 }
3743
3744 /*
3745 * If we were able to parse any values, then set mask for the MCS set.
3746 */
3747 if (i) {
3748 os_memset(&htcaps_mask->supported_mcs_set, 0xff,
3749 IEEE80211_HT_MCS_MASK_LEN - 1);
3750 /* skip the 3 reserved bits */
3751 htcaps_mask->supported_mcs_set[IEEE80211_HT_MCS_MASK_LEN - 1] =
3752 0x1f;
3753 }
3754
3755 return 0;
3756}
3757
3758
3759static int wpa_disable_max_amsdu(struct wpa_supplicant *wpa_s,
3760 struct ieee80211_ht_capabilities *htcaps,
3761 struct ieee80211_ht_capabilities *htcaps_mask,
3762 int disabled)
3763{
5bc28571 3764 le16 msk;
80e8a5ee
BG
3765
3766 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
3767
3768 if (disabled == -1)
3769 return 0;
3770
3771 msk = host_to_le16(HT_CAP_INFO_MAX_AMSDU_SIZE);
3772 htcaps_mask->ht_capabilities_info |= msk;
3773 if (disabled)
3774 htcaps->ht_capabilities_info &= msk;
3775 else
3776 htcaps->ht_capabilities_info |= msk;
3777
3778 return 0;
3779}
3780
3781
3782static int wpa_set_ampdu_factor(struct wpa_supplicant *wpa_s,
3783 struct ieee80211_ht_capabilities *htcaps,
3784 struct ieee80211_ht_capabilities *htcaps_mask,
3785 int factor)
3786{
3787 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
3788
3789 if (factor == -1)
3790 return 0;
3791
3792 if (factor < 0 || factor > 3) {
3793 wpa_msg(wpa_s, MSG_ERROR, "ampdu_factor: %d out of range. "
3794 "Must be 0-3 or -1", factor);
3795 return -EINVAL;
3796 }
3797
3798 htcaps_mask->a_mpdu_params |= 0x3; /* 2 bits for factor */
3799 htcaps->a_mpdu_params &= ~0x3;
3800 htcaps->a_mpdu_params |= factor & 0x3;
3801
3802 return 0;
3803}
3804
3805
3806static int wpa_set_ampdu_density(struct wpa_supplicant *wpa_s,
3807 struct ieee80211_ht_capabilities *htcaps,
3808 struct ieee80211_ht_capabilities *htcaps_mask,
3809 int density)
3810{
3811 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
3812
3813 if (density == -1)
3814 return 0;
3815
3816 if (density < 0 || density > 7) {
3817 wpa_msg(wpa_s, MSG_ERROR,
3818 "ampdu_density: %d out of range. Must be 0-7 or -1.",
3819 density);
3820 return -EINVAL;
3821 }
3822
3823 htcaps_mask->a_mpdu_params |= 0x1C;
3824 htcaps->a_mpdu_params &= ~(0x1C);
3825 htcaps->a_mpdu_params |= (density << 2) & 0x1C;
3826
3827 return 0;
3828}
3829
3830
3831static int wpa_set_disable_ht40(struct wpa_supplicant *wpa_s,
3832 struct ieee80211_ht_capabilities *htcaps,
3833 struct ieee80211_ht_capabilities *htcaps_mask,
3834 int disabled)
3835{
3836 /* Masking these out disables HT40 */
5bc28571
JM
3837 le16 msk = host_to_le16(HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET |
3838 HT_CAP_INFO_SHORT_GI40MHZ);
80e8a5ee
BG
3839
3840 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
3841
3842 if (disabled)
3843 htcaps->ht_capabilities_info &= ~msk;
3844 else
3845 htcaps->ht_capabilities_info |= msk;
3846
3847 htcaps_mask->ht_capabilities_info |= msk;
3848
3849 return 0;
3850}
3851
3852
a90497f8
BG
3853static int wpa_set_disable_sgi(struct wpa_supplicant *wpa_s,
3854 struct ieee80211_ht_capabilities *htcaps,
3855 struct ieee80211_ht_capabilities *htcaps_mask,
3856 int disabled)
3857{
3858 /* Masking these out disables SGI */
5bc28571
JM
3859 le16 msk = host_to_le16(HT_CAP_INFO_SHORT_GI20MHZ |
3860 HT_CAP_INFO_SHORT_GI40MHZ);
a90497f8
BG
3861
3862 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_sgi: %d", disabled);
3863
3864 if (disabled)
3865 htcaps->ht_capabilities_info &= ~msk;
3866 else
3867 htcaps->ht_capabilities_info |= msk;
3868
3869 htcaps_mask->ht_capabilities_info |= msk;
3870
3871 return 0;
3872}
3873
3874
39a5800f
PK
3875static int wpa_set_disable_ldpc(struct wpa_supplicant *wpa_s,
3876 struct ieee80211_ht_capabilities *htcaps,
3877 struct ieee80211_ht_capabilities *htcaps_mask,
3878 int disabled)
3879{
3880 /* Masking these out disables LDPC */
5bc28571 3881 le16 msk = host_to_le16(HT_CAP_INFO_LDPC_CODING_CAP);
39a5800f
PK
3882
3883 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ldpc: %d", disabled);
3884
3885 if (disabled)
3886 htcaps->ht_capabilities_info &= ~msk;
3887 else
3888 htcaps->ht_capabilities_info |= msk;
3889
3890 htcaps_mask->ht_capabilities_info |= msk;
3891
3892 return 0;
3893}
3894
3895
80e8a5ee
BG
3896void wpa_supplicant_apply_ht_overrides(
3897 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
3898 struct wpa_driver_associate_params *params)
3899{
3900 struct ieee80211_ht_capabilities *htcaps;
3901 struct ieee80211_ht_capabilities *htcaps_mask;
3902
3903 if (!ssid)
3904 return;
3905
3906 params->disable_ht = ssid->disable_ht;
3907 if (!params->htcaps || !params->htcaps_mask)
3908 return;
3909
3910 htcaps = (struct ieee80211_ht_capabilities *) params->htcaps;
3911 htcaps_mask = (struct ieee80211_ht_capabilities *) params->htcaps_mask;
3912 wpa_set_htcap_mcs(wpa_s, htcaps, htcaps_mask, ssid->ht_mcs);
3913 wpa_disable_max_amsdu(wpa_s, htcaps, htcaps_mask,
3914 ssid->disable_max_amsdu);
3915 wpa_set_ampdu_factor(wpa_s, htcaps, htcaps_mask, ssid->ampdu_factor);
3916 wpa_set_ampdu_density(wpa_s, htcaps, htcaps_mask, ssid->ampdu_density);
3917 wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40);
a90497f8 3918 wpa_set_disable_sgi(wpa_s, htcaps, htcaps_mask, ssid->disable_sgi);
39a5800f 3919 wpa_set_disable_ldpc(wpa_s, htcaps, htcaps_mask, ssid->disable_ldpc);
d41cc8cc
JM
3920
3921 if (ssid->ht40_intolerant) {
5bc28571 3922 le16 bit = host_to_le16(HT_CAP_INFO_40MHZ_INTOLERANT);
d41cc8cc
JM
3923 htcaps->ht_capabilities_info |= bit;
3924 htcaps_mask->ht_capabilities_info |= bit;
3925 }
80e8a5ee
BG
3926}
3927
3928#endif /* CONFIG_HT_OVERRIDES */
3929
3930
e9ee8dc3
JB
3931#ifdef CONFIG_VHT_OVERRIDES
3932void wpa_supplicant_apply_vht_overrides(
3933 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
3934 struct wpa_driver_associate_params *params)
3935{
3936 struct ieee80211_vht_capabilities *vhtcaps;
3937 struct ieee80211_vht_capabilities *vhtcaps_mask;
3938
3939 if (!ssid)
3940 return;
3941
3942 params->disable_vht = ssid->disable_vht;
3943
3944 vhtcaps = (void *) params->vhtcaps;
3945 vhtcaps_mask = (void *) params->vhtcaps_mask;
3946
3947 if (!vhtcaps || !vhtcaps_mask)
3948 return;
3949
4d8d710f
JM
3950 vhtcaps->vht_capabilities_info = host_to_le32(ssid->vht_capa);
3951 vhtcaps_mask->vht_capabilities_info = host_to_le32(ssid->vht_capa_mask);
e9ee8dc3 3952
4f560cde
EP
3953#ifdef CONFIG_HT_OVERRIDES
3954 /* if max ampdu is <= 3, we have to make the HT cap the same */
b0f33467
JM
3955 if (ssid->vht_capa_mask & VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX) {
3956 int max_ampdu;
3957
3958 max_ampdu = (ssid->vht_capa &
3959 VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX) >>
3960 VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX_SHIFT;
4f560cde
EP
3961
3962 max_ampdu = max_ampdu < 3 ? max_ampdu : 3;
3963 wpa_set_ampdu_factor(wpa_s,
3964 (void *) params->htcaps,
3965 (void *) params->htcaps_mask,
3966 max_ampdu);
3967 }
3968#endif /* CONFIG_HT_OVERRIDES */
3969
e9ee8dc3
JB
3970#define OVERRIDE_MCS(i) \
3971 if (ssid->vht_tx_mcs_nss_ ##i >= 0) { \
3972 vhtcaps_mask->vht_supported_mcs_set.tx_map |= \
4d8d710f 3973 host_to_le16(3 << 2 * (i - 1)); \
e9ee8dc3 3974 vhtcaps->vht_supported_mcs_set.tx_map |= \
4d8d710f
JM
3975 host_to_le16(ssid->vht_tx_mcs_nss_ ##i << \
3976 2 * (i - 1)); \
e9ee8dc3
JB
3977 } \
3978 if (ssid->vht_rx_mcs_nss_ ##i >= 0) { \
3979 vhtcaps_mask->vht_supported_mcs_set.rx_map |= \
4d8d710f 3980 host_to_le16(3 << 2 * (i - 1)); \
e9ee8dc3 3981 vhtcaps->vht_supported_mcs_set.rx_map |= \
4d8d710f
JM
3982 host_to_le16(ssid->vht_rx_mcs_nss_ ##i << \
3983 2 * (i - 1)); \
e9ee8dc3
JB
3984 }
3985
3986 OVERRIDE_MCS(1);
3987 OVERRIDE_MCS(2);
3988 OVERRIDE_MCS(3);
3989 OVERRIDE_MCS(4);
3990 OVERRIDE_MCS(5);
3991 OVERRIDE_MCS(6);
3992 OVERRIDE_MCS(7);
3993 OVERRIDE_MCS(8);
3994}
3995#endif /* CONFIG_VHT_OVERRIDES */
3996
3997
f64adcd7
JM
3998static int pcsc_reader_init(struct wpa_supplicant *wpa_s)
3999{
4000#ifdef PCSC_FUNCS
4001 size_t len;
4002
4003 if (!wpa_s->conf->pcsc_reader)
4004 return 0;
4005
22cf7d73 4006 wpa_s->scard = scard_init(wpa_s->conf->pcsc_reader);
f64adcd7
JM
4007 if (!wpa_s->scard)
4008 return 1;
4009
4010 if (wpa_s->conf->pcsc_pin &&
4011 scard_set_pin(wpa_s->scard, wpa_s->conf->pcsc_pin) < 0) {
4012 scard_deinit(wpa_s->scard);
4013 wpa_s->scard = NULL;
4014 wpa_msg(wpa_s, MSG_ERROR, "PC/SC PIN validation failed");
4015 return -1;
4016 }
4017
4018 len = sizeof(wpa_s->imsi) - 1;
4019 if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
4020 scard_deinit(wpa_s->scard);
4021 wpa_s->scard = NULL;
4022 wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
4023 return -1;
4024 }
4025 wpa_s->imsi[len] = '\0';
4026
4027 wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
4028
4029 wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
4030 wpa_s->imsi, wpa_s->mnc_len);
4031
4032 wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
4033 eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
4034#endif /* PCSC_FUNCS */
4035
4036 return 0;
4037}
4038
4039
306ae225
JM
4040int wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
4041{
4042 char *val, *pos;
4043
4044 ext_password_deinit(wpa_s->ext_pw);
4045 wpa_s->ext_pw = NULL;
4046 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, NULL);
4047
4048 if (!wpa_s->conf->ext_password_backend)
4049 return 0;
4050
4051 val = os_strdup(wpa_s->conf->ext_password_backend);
4052 if (val == NULL)
4053 return -1;
4054 pos = os_strchr(val, ':');
4055 if (pos)
4056 *pos++ = '\0';
4057
4058 wpa_printf(MSG_DEBUG, "EXT PW: Initialize backend '%s'", val);
4059
4060 wpa_s->ext_pw = ext_password_init(val, pos);
4061 os_free(val);
4062 if (wpa_s->ext_pw == NULL) {
4063 wpa_printf(MSG_DEBUG, "EXT PW: Failed to initialize backend");
4064 return -1;
4065 }
4066 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, wpa_s->ext_pw);
4067
4068 return 0;
4069}
4070
4071
b36a3a65
AN
4072#ifdef CONFIG_FST
4073
4074static const u8 * wpas_fst_get_bssid_cb(void *ctx)
4075{
4076 struct wpa_supplicant *wpa_s = ctx;
4077
4078 return (is_zero_ether_addr(wpa_s->bssid) ||
4079 wpa_s->wpa_state != WPA_COMPLETED) ? NULL : wpa_s->bssid;
4080}
4081
4082
4083static void wpas_fst_get_channel_info_cb(void *ctx,
4084 enum hostapd_hw_mode *hw_mode,
4085 u8 *channel)
4086{
4087 struct wpa_supplicant *wpa_s = ctx;
4088
4089 if (wpa_s->current_bss) {
4090 *hw_mode = ieee80211_freq_to_chan(wpa_s->current_bss->freq,
4091 channel);
4092 } else if (wpa_s->hw.num_modes) {
4093 *hw_mode = wpa_s->hw.modes[0].mode;
4094 } else {
4095 WPA_ASSERT(0);
4096 *hw_mode = 0;
4097 }
4098}
4099
4100
4101static int wpas_fst_get_hw_modes(void *ctx, struct hostapd_hw_modes **modes)
4102{
4103 struct wpa_supplicant *wpa_s = ctx;
4104
4105 *modes = wpa_s->hw.modes;
4106 return wpa_s->hw.num_modes;
4107}
4108
4109
84bcb4e7 4110static void wpas_fst_set_ies_cb(void *ctx, const struct wpabuf *fst_ies)
b36a3a65
AN
4111{
4112 struct wpa_supplicant *wpa_s = ctx;
4113
b7a07937 4114 wpa_hexdump_buf(MSG_DEBUG, "FST: Set IEs", fst_ies);
b36a3a65
AN
4115 wpa_s->fst_ies = fst_ies;
4116}
4117
4118
4119static int wpas_fst_send_action_cb(void *ctx, const u8 *da, struct wpabuf *data)
4120{
4121 struct wpa_supplicant *wpa_s = ctx;
4122
4123 WPA_ASSERT(os_memcmp(wpa_s->bssid, da, ETH_ALEN) == 0);
4124 return wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
4125 wpa_s->own_addr, wpa_s->bssid,
4126 wpabuf_head(data), wpabuf_len(data),
4127 0);
4128}
4129
4130
a0f04da5 4131static const struct wpabuf * wpas_fst_get_mb_ie_cb(void *ctx, const u8 *addr)
b36a3a65
AN
4132{
4133 struct wpa_supplicant *wpa_s = ctx;
4134
4135 WPA_ASSERT(os_memcmp(wpa_s->bssid, addr, ETH_ALEN) == 0);
4136 return wpa_s->received_mb_ies;
4137}
4138
4139
4140static void wpas_fst_update_mb_ie_cb(void *ctx, const u8 *addr,
4141 const u8 *buf, size_t size)
4142{
4143 struct wpa_supplicant *wpa_s = ctx;
4144 struct mb_ies_info info;
4145
4146 WPA_ASSERT(os_memcmp(wpa_s->bssid, addr, ETH_ALEN) == 0);
4147
4148 if (!mb_ies_info_by_ies(&info, buf, size)) {
4149 wpabuf_free(wpa_s->received_mb_ies);
4150 wpa_s->received_mb_ies = mb_ies_by_info(&info);
4151 }
4152}
4153
4154
39cdd3a0
JM
4155static const u8 * wpas_fst_get_peer_first(void *ctx,
4156 struct fst_get_peer_ctx **get_ctx,
4157 Boolean mb_only)
b36a3a65
AN
4158{
4159 struct wpa_supplicant *wpa_s = ctx;
4160
4161 *get_ctx = NULL;
4162 if (!is_zero_ether_addr(wpa_s->bssid))
4163 return (wpa_s->received_mb_ies || !mb_only) ?
4164 wpa_s->bssid : NULL;
4165 return NULL;
4166}
4167
4168
39cdd3a0
JM
4169static const u8 * wpas_fst_get_peer_next(void *ctx,
4170 struct fst_get_peer_ctx **get_ctx,
4171 Boolean mb_only)
b36a3a65
AN
4172{
4173 return NULL;
4174}
4175
4176void fst_wpa_supplicant_fill_iface_obj(struct wpa_supplicant *wpa_s,
4177 struct fst_wpa_obj *iface_obj)
4178{
4179 iface_obj->ctx = wpa_s;
4180 iface_obj->get_bssid = wpas_fst_get_bssid_cb;
4181 iface_obj->get_channel_info = wpas_fst_get_channel_info_cb;
4182 iface_obj->get_hw_modes = wpas_fst_get_hw_modes;
4183 iface_obj->set_ies = wpas_fst_set_ies_cb;
4184 iface_obj->send_action = wpas_fst_send_action_cb;
4185 iface_obj->get_mb_ie = wpas_fst_get_mb_ie_cb;
4186 iface_obj->update_mb_ie = wpas_fst_update_mb_ie_cb;
4187 iface_obj->get_peer_first = wpas_fst_get_peer_first;
4188 iface_obj->get_peer_next = wpas_fst_get_peer_next;
4189}
4190#endif /* CONFIG_FST */
4191
a520bf4a 4192static int wpas_set_wowlan_triggers(struct wpa_supplicant *wpa_s,
6cbdb0c5 4193 const struct wpa_driver_capa *capa)
e4fa8b12 4194{
88cb27c7
DS
4195 struct wowlan_triggers *triggers;
4196 int ret = 0;
e4fa8b12
EP
4197
4198 if (!wpa_s->conf->wowlan_triggers)
4199 return 0;
4200
88cb27c7
DS
4201 triggers = wpa_get_wowlan_triggers(wpa_s->conf->wowlan_triggers, capa);
4202 if (triggers) {
4203 ret = wpa_drv_wowlan(wpa_s, triggers);
4204 os_free(triggers);
e4fa8b12 4205 }
e4fa8b12
EP
4206 return ret;
4207}
4208
4209
2b6e9f91 4210enum wpa_radio_work_band wpas_freq_to_band(int freq)
e903d32d
KV
4211{
4212 if (freq < 3000)
4213 return BAND_2_4_GHZ;
4214 if (freq > 50000)
4215 return BAND_60_GHZ;
4216 return BAND_5_GHZ;
4217}
4218
4219
2b6e9f91 4220unsigned int wpas_get_bands(struct wpa_supplicant *wpa_s, const int *freqs)
e903d32d
KV
4221{
4222 int i;
4223 unsigned int band = 0;
4224
4225 if (freqs) {
4226 /* freqs are specified for the radio work */
4227 for (i = 0; freqs[i]; i++)
4228 band |= wpas_freq_to_band(freqs[i]);
4229 } else {
4230 /*
4231 * freqs are not specified, implies all
4232 * the supported freqs by HW
4233 */
4234 for (i = 0; i < wpa_s->hw.num_modes; i++) {
4235 if (wpa_s->hw.modes[i].num_channels != 0) {
4236 if (wpa_s->hw.modes[i].mode ==
4237 HOSTAPD_MODE_IEEE80211B ||
4238 wpa_s->hw.modes[i].mode ==
4239 HOSTAPD_MODE_IEEE80211G)
4240 band |= BAND_2_4_GHZ;
4241 else if (wpa_s->hw.modes[i].mode ==
4242 HOSTAPD_MODE_IEEE80211A)
4243 band |= BAND_5_GHZ;
4244 else if (wpa_s->hw.modes[i].mode ==
4245 HOSTAPD_MODE_IEEE80211AD)
4246 band |= BAND_60_GHZ;
4247 else if (wpa_s->hw.modes[i].mode ==
4248 HOSTAPD_MODE_IEEE80211ANY)
4249 band = BAND_2_4_GHZ | BAND_5_GHZ |
4250 BAND_60_GHZ;
4251 }
4252 }
4253 }
4254
4255 return band;
4256}
4257
4258
202dec2a
JM
4259static struct wpa_radio * radio_add_interface(struct wpa_supplicant *wpa_s,
4260 const char *rn)
4261{
4262 struct wpa_supplicant *iface = wpa_s->global->ifaces;
4263 struct wpa_radio *radio;
4264
4265 while (rn && iface) {
4266 radio = iface->radio;
4267 if (radio && os_strcmp(rn, radio->name) == 0) {
4268 wpa_printf(MSG_DEBUG, "Add interface %s to existing radio %s",
4269 wpa_s->ifname, rn);
4270 dl_list_add(&radio->ifaces, &wpa_s->radio_list);
4271 return radio;
4272 }
b154a24e
TB
4273
4274 iface = iface->next;
202dec2a
JM
4275 }
4276
4277 wpa_printf(MSG_DEBUG, "Add interface %s to a new radio %s",
4278 wpa_s->ifname, rn ? rn : "N/A");
4279 radio = os_zalloc(sizeof(*radio));
4280 if (radio == NULL)
4281 return NULL;
4282
4283 if (rn)
4284 os_strlcpy(radio->name, rn, sizeof(radio->name));
4285 dl_list_init(&radio->ifaces);
b1ae396f 4286 dl_list_init(&radio->work);
202dec2a
JM
4287 dl_list_add(&radio->ifaces, &wpa_s->radio_list);
4288
4289 return radio;
4290}
4291
4292
b1ae396f
JM
4293static void radio_work_free(struct wpa_radio_work *work)
4294{
d12a51b5
JM
4295 if (work->wpa_s->scan_work == work) {
4296 /* This should not really happen. */
4297 wpa_dbg(work->wpa_s, MSG_INFO, "Freeing radio work '%s'@%p (started=%d) that is marked as scan_work",
4298 work->type, work, work->started);
4299 work->wpa_s->scan_work = NULL;
4300 }
4301
1b5d4714
JM
4302#ifdef CONFIG_P2P
4303 if (work->wpa_s->p2p_scan_work == work) {
4304 /* This should not really happen. */
4305 wpa_dbg(work->wpa_s, MSG_INFO, "Freeing radio work '%s'@%p (started=%d) that is marked as p2p_scan_work",
4306 work->type, work, work->started);
4307 work->wpa_s->p2p_scan_work = NULL;
4308 }
4309#endif /* CONFIG_P2P */
4310
e903d32d
KV
4311 if (work->started) {
4312 work->wpa_s->radio->num_active_works--;
4313 wpa_dbg(work->wpa_s, MSG_DEBUG,
4314 "radio_work_free('%s'@%p: num_active_works --> %u",
4315 work->type, work,
4316 work->wpa_s->radio->num_active_works);
4317 }
4318
b1ae396f
JM
4319 dl_list_del(&work->list);
4320 os_free(work);
4321}
4322
4323
e903d32d
KV
4324static struct wpa_radio_work * radio_work_get_next_work(struct wpa_radio *radio)
4325{
4326 struct wpa_radio_work *active_work = NULL;
4327 struct wpa_radio_work *tmp;
4328
4329 /* Get the active work to know the type and band. */
4330 dl_list_for_each(tmp, &radio->work, struct wpa_radio_work, list) {
4331 if (tmp->started) {
4332 active_work = tmp;
4333 break;
4334 }
4335 }
4336
4337 if (!active_work) {
4338 /* No active work, start one */
4339 radio->num_active_works = 0;
4340 dl_list_for_each(tmp, &radio->work, struct wpa_radio_work,
4341 list) {
4342 if (os_strcmp(tmp->type, "scan") == 0 &&
4343 radio->external_scan_running &&
4344 (((struct wpa_driver_scan_params *)
4345 tmp->ctx)->only_new_results ||
4346 tmp->wpa_s->clear_driver_scan_cache))
4347 continue;
4348 return tmp;
4349 }
4350 return NULL;
4351 }
4352
4353 if (os_strcmp(active_work->type, "sme-connect") == 0 ||
4354 os_strcmp(active_work->type, "connect") == 0) {
4355 /*
4356 * If the active work is either connect or sme-connect,
4357 * do not parallelize them with other radio works.
4358 */
4359 wpa_dbg(active_work->wpa_s, MSG_DEBUG,
4360 "Do not parallelize radio work with %s",
4361 active_work->type);
4362 return NULL;
4363 }
4364
4365 dl_list_for_each(tmp, &radio->work, struct wpa_radio_work, list) {
4366 if (tmp->started)
4367 continue;
4368
4369 /*
4370 * If connect or sme-connect are enqueued, parallelize only
4371 * those operations ahead of them in the queue.
4372 */
4373 if (os_strcmp(tmp->type, "connect") == 0 ||
4374 os_strcmp(tmp->type, "sme-connect") == 0)
4375 break;
4376
4377 /*
4378 * Check that the radio works are distinct and
4379 * on different bands.
4380 */
4381 if (os_strcmp(active_work->type, tmp->type) != 0 &&
4382 (active_work->bands != tmp->bands)) {
4383 /*
4384 * If a scan has to be scheduled through nl80211 scan
4385 * interface and if an external scan is already running,
4386 * do not schedule the scan since it is likely to get
4387 * rejected by kernel.
4388 */
4389 if (os_strcmp(tmp->type, "scan") == 0 &&
4390 radio->external_scan_running &&
4391 (((struct wpa_driver_scan_params *)
4392 tmp->ctx)->only_new_results ||
4393 tmp->wpa_s->clear_driver_scan_cache))
4394 continue;
4395
4396 wpa_dbg(active_work->wpa_s, MSG_DEBUG,
4397 "active_work:%s new_work:%s",
4398 active_work->type, tmp->type);
4399 return tmp;
4400 }
4401 }
4402
4403 /* Did not find a radio work to schedule in parallel. */
4404 return NULL;
4405}
4406
4407
b1ae396f
JM
4408static void radio_start_next_work(void *eloop_ctx, void *timeout_ctx)
4409{
4410 struct wpa_radio *radio = eloop_ctx;
4411 struct wpa_radio_work *work;
4412 struct os_reltime now, diff;
6428d0a7 4413 struct wpa_supplicant *wpa_s;
b1ae396f
JM
4414
4415 work = dl_list_first(&radio->work, struct wpa_radio_work, list);
e903d32d
KV
4416 if (work == NULL) {
4417 radio->num_active_works = 0;
b1ae396f 4418 return;
e903d32d 4419 }
b1ae396f 4420
6428d0a7
JM
4421 wpa_s = dl_list_first(&radio->ifaces, struct wpa_supplicant,
4422 radio_list);
e903d32d
KV
4423
4424 if (!(wpa_s &&
4425 wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS)) {
4426 if (work->started)
4427 return; /* already started and still in progress */
4428
4429 if (wpa_s && wpa_s->radio->external_scan_running) {
4430 wpa_printf(MSG_DEBUG, "Delay radio work start until externally triggered scan completes");
4431 return;
4432 }
4433 } else {
4434 work = NULL;
4435 if (radio->num_active_works < MAX_ACTIVE_WORKS) {
4436 /* get the work to schedule next */
4437 work = radio_work_get_next_work(radio);
4438 }
4439 if (!work)
4440 return;
6428d0a7
JM
4441 }
4442
e903d32d 4443 wpa_s = work->wpa_s;
b1ae396f
JM
4444 os_get_reltime(&now);
4445 os_reltime_sub(&now, &work->time, &diff);
e903d32d
KV
4446 wpa_dbg(wpa_s, MSG_DEBUG,
4447 "Starting radio work '%s'@%p after %ld.%06ld second wait",
b1ae396f
JM
4448 work->type, work, diff.sec, diff.usec);
4449 work->started = 1;
4450 work->time = now;
e903d32d
KV
4451 radio->num_active_works++;
4452
b1ae396f 4453 work->cb(work, 0);
e903d32d
KV
4454
4455 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS) &&
4456 radio->num_active_works < MAX_ACTIVE_WORKS)
4457 radio_work_check_next(wpa_s);
b1ae396f
JM
4458}
4459
4460
b3253ebb
AO
4461/*
4462 * This function removes both started and pending radio works running on
4463 * the provided interface's radio.
4464 * Prior to the removal of the radio work, its callback (cb) is called with
4465 * deinit set to be 1. Each work's callback is responsible for clearing its
4466 * internal data and restoring to a correct state.
4467 * @wpa_s: wpa_supplicant data
4468 * @type: type of works to be removed
4469 * @remove_all: 1 to remove all the works on this radio, 0 to remove only
4470 * this interface's works.
4471 */
4472void radio_remove_works(struct wpa_supplicant *wpa_s,
4473 const char *type, int remove_all)
b1ae396f
JM
4474{
4475 struct wpa_radio_work *work, *tmp;
4476 struct wpa_radio *radio = wpa_s->radio;
4477
4478 dl_list_for_each_safe(work, tmp, &radio->work, struct wpa_radio_work,
4479 list) {
b3253ebb 4480 if (type && os_strcmp(type, work->type) != 0)
b1ae396f 4481 continue;
b3253ebb
AO
4482
4483 /* skip other ifaces' works */
4484 if (!remove_all && work->wpa_s != wpa_s)
b1ae396f 4485 continue;
b3253ebb
AO
4486
4487 wpa_dbg(wpa_s, MSG_DEBUG, "Remove radio work '%s'@%p%s",
4488 work->type, work, work->started ? " (started)" : "");
b1ae396f
JM
4489 work->cb(work, 1);
4490 radio_work_free(work);
4491 }
b3253ebb
AO
4492
4493 /* in case we removed the started work */
4494 radio_work_check_next(wpa_s);
b1ae396f
JM
4495}
4496
4497
202dec2a
JM
4498static void radio_remove_interface(struct wpa_supplicant *wpa_s)
4499{
4500 struct wpa_radio *radio = wpa_s->radio;
4501
4502 if (!radio)
4503 return;
4504
4505 wpa_printf(MSG_DEBUG, "Remove interface %s from radio %s",
4506 wpa_s->ifname, radio->name);
4507 dl_list_del(&wpa_s->radio_list);
c46235aa
AO
4508 radio_remove_works(wpa_s, NULL, 0);
4509 wpa_s->radio = NULL;
4510 if (!dl_list_empty(&radio->ifaces))
202dec2a
JM
4511 return; /* Interfaces remain for this radio */
4512
4513 wpa_printf(MSG_DEBUG, "Remove radio %s", radio->name);
b1ae396f 4514 eloop_cancel_timeout(radio_start_next_work, radio, NULL);
202dec2a
JM
4515 os_free(radio);
4516}
4517
4518
6428d0a7 4519void radio_work_check_next(struct wpa_supplicant *wpa_s)
b1ae396f
JM
4520{
4521 struct wpa_radio *radio = wpa_s->radio;
4522
4523 if (dl_list_empty(&radio->work))
4524 return;
e3745228
JM
4525 if (wpa_s->ext_work_in_progress) {
4526 wpa_printf(MSG_DEBUG,
4527 "External radio work in progress - delay start of pending item");
4528 return;
4529 }
b1ae396f
JM
4530 eloop_cancel_timeout(radio_start_next_work, radio, NULL);
4531 eloop_register_timeout(0, 0, radio_start_next_work, radio, NULL);
4532}
4533
4534
4535/**
4536 * radio_add_work - Add a radio work item
4537 * @wpa_s: Pointer to wpa_supplicant data
4538 * @freq: Frequency of the offchannel operation in MHz or 0
4539 * @type: Unique identifier for each type of work
4540 * @next: Force as the next work to be executed
4541 * @cb: Callback function for indicating when radio is available
4542 * @ctx: Context pointer for the work (work->ctx in cb())
4543 * Returns: 0 on success, -1 on failure
4544 *
4545 * This function is used to request time for an operation that requires
4546 * exclusive radio control. Once the radio is available, the registered callback
4547 * function will be called. radio_work_done() must be called once the exclusive
4548 * radio operation has been completed, so that the radio is freed for other
4549 * operations. The special case of deinit=1 is used to free the context data
4550 * during interface removal. That does not allow the callback function to start
4551 * the radio operation, i.e., it must free any resources allocated for the radio
4552 * work and return.
4553 *
4554 * The @freq parameter can be used to indicate a single channel on which the
4555 * offchannel operation will occur. This may allow multiple radio work
4556 * operations to be performed in parallel if they apply for the same channel.
4557 * Setting this to 0 indicates that the work item may use multiple channels or
4558 * requires exclusive control of the radio.
4559 */
4560int radio_add_work(struct wpa_supplicant *wpa_s, unsigned int freq,
4561 const char *type, int next,
4562 void (*cb)(struct wpa_radio_work *work, int deinit),
4563 void *ctx)
4564{
e903d32d 4565 struct wpa_radio *radio = wpa_s->radio;
b1ae396f
JM
4566 struct wpa_radio_work *work;
4567 int was_empty;
4568
4569 work = os_zalloc(sizeof(*work));
4570 if (work == NULL)
4571 return -1;
4572 wpa_dbg(wpa_s, MSG_DEBUG, "Add radio work '%s'@%p", type, work);
4573 os_get_reltime(&work->time);
4574 work->freq = freq;
4575 work->type = type;
4576 work->wpa_s = wpa_s;
4577 work->cb = cb;
4578 work->ctx = ctx;
4579
e903d32d
KV
4580 if (freq)
4581 work->bands = wpas_freq_to_band(freq);
4582 else if (os_strcmp(type, "scan") == 0 ||
4583 os_strcmp(type, "p2p-scan") == 0)
4584 work->bands = wpas_get_bands(wpa_s,
4585 ((struct wpa_driver_scan_params *)
4586 ctx)->freqs);
4587 else
4588 work->bands = wpas_get_bands(wpa_s, NULL);
4589
b1ae396f
JM
4590 was_empty = dl_list_empty(&wpa_s->radio->work);
4591 if (next)
4592 dl_list_add(&wpa_s->radio->work, &work->list);
4593 else
4594 dl_list_add_tail(&wpa_s->radio->work, &work->list);
4595 if (was_empty) {
4596 wpa_dbg(wpa_s, MSG_DEBUG, "First radio work item in the queue - schedule start immediately");
4597 radio_work_check_next(wpa_s);
e903d32d
KV
4598 } else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_SIMULTANEOUS)
4599 && radio->num_active_works < MAX_ACTIVE_WORKS) {
4600 wpa_dbg(wpa_s, MSG_DEBUG,
4601 "Try to schedule a radio work (num_active_works=%u)",
4602 radio->num_active_works);
4603 radio_work_check_next(wpa_s);
b1ae396f
JM
4604 }
4605
4606 return 0;
4607}
4608
4609
4610/**
4611 * radio_work_done - Indicate that a radio work item has been completed
4612 * @work: Completed work
4613 *
4614 * This function is called once the callback function registered with
4615 * radio_add_work() has completed its work.
4616 */
4617void radio_work_done(struct wpa_radio_work *work)
4618{
4619 struct wpa_supplicant *wpa_s = work->wpa_s;
4620 struct os_reltime now, diff;
1f965e62 4621 unsigned int started = work->started;
b1ae396f
JM
4622
4623 os_get_reltime(&now);
4624 os_reltime_sub(&now, &work->time, &diff);
1f965e62
JM
4625 wpa_dbg(wpa_s, MSG_DEBUG, "Radio work '%s'@%p %s in %ld.%06ld seconds",
4626 work->type, work, started ? "done" : "canceled",
4627 diff.sec, diff.usec);
b1ae396f 4628 radio_work_free(work);
1f965e62
JM
4629 if (started)
4630 radio_work_check_next(wpa_s);
b1ae396f
JM
4631}
4632
4633
a7f5271d
JM
4634struct wpa_radio_work *
4635radio_work_pending(struct wpa_supplicant *wpa_s, const char *type)
f0e30c84
JM
4636{
4637 struct wpa_radio_work *work;
4638 struct wpa_radio *radio = wpa_s->radio;
4639
4640 dl_list_for_each(work, &radio->work, struct wpa_radio_work, list) {
4641 if (work->wpa_s == wpa_s && os_strcmp(work->type, type) == 0)
a7f5271d 4642 return work;
f0e30c84
JM
4643 }
4644
a7f5271d 4645 return NULL;
f0e30c84
JM
4646}
4647
4648
73c00fd7
JM
4649static int wpas_init_driver(struct wpa_supplicant *wpa_s,
4650 struct wpa_interface *iface)
4651{
202dec2a 4652 const char *ifname, *driver, *rn;
73c00fd7
JM
4653
4654 driver = iface->driver;
4655next_driver:
4656 if (wpa_supplicant_set_driver(wpa_s, driver) < 0)
4657 return -1;
4658
4659 wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
4660 if (wpa_s->drv_priv == NULL) {
4661 const char *pos;
4662 pos = driver ? os_strchr(driver, ',') : NULL;
4663 if (pos) {
4664 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
4665 "driver interface - try next driver wrapper");
4666 driver = pos + 1;
4667 goto next_driver;
4668 }
4669 wpa_msg(wpa_s, MSG_ERROR, "Failed to initialize driver "
4670 "interface");
4671 return -1;
4672 }
4673 if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
4674 wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected "
4675 "driver_param '%s'", wpa_s->conf->driver_param);
4676 return -1;
4677 }
4678
4679 ifname = wpa_drv_get_ifname(wpa_s);
4680 if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
4681 wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced "
4682 "interface name with '%s'", ifname);
4683 os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
4684 }
4685
95bf699f 4686 rn = wpa_driver_get_radio_name(wpa_s);
202dec2a
JM
4687 if (rn && rn[0] == '\0')
4688 rn = NULL;
4689
4690 wpa_s->radio = radio_add_interface(wpa_s, rn);
4691 if (wpa_s->radio == NULL)
4692 return -1;
4693
73c00fd7
JM
4694 return 0;
4695}
4696
4697
6fc6879b
JM
4698static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
4699 struct wpa_interface *iface)
4700{
362f781e 4701 struct wpa_driver_capa capa;
6cbdb0c5 4702 int capa_res;
362f781e 4703
6fc6879b
JM
4704 wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
4705 "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
4706 iface->confname ? iface->confname : "N/A",
4707 iface->driver ? iface->driver : "default",
4708 iface->ctrl_interface ? iface->ctrl_interface : "N/A",
4709 iface->bridge_ifname ? iface->bridge_ifname : "N/A");
4710
6fc6879b
JM
4711 if (iface->confname) {
4712#ifdef CONFIG_BACKEND_FILE
4713 wpa_s->confname = os_rel2abs_path(iface->confname);
4714 if (wpa_s->confname == NULL) {
4715 wpa_printf(MSG_ERROR, "Failed to get absolute path "
4716 "for configuration file '%s'.",
4717 iface->confname);
4718 return -1;
4719 }
4720 wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",
4721 iface->confname, wpa_s->confname);
4722#else /* CONFIG_BACKEND_FILE */
4723 wpa_s->confname = os_strdup(iface->confname);
4724#endif /* CONFIG_BACKEND_FILE */
e6304cad 4725 wpa_s->conf = wpa_config_read(wpa_s->confname, NULL);
6fc6879b
JM
4726 if (wpa_s->conf == NULL) {
4727 wpa_printf(MSG_ERROR, "Failed to read or parse "
4728 "configuration '%s'.", wpa_s->confname);
4729 return -1;
4730 }
e6304cad
DS
4731 wpa_s->confanother = os_rel2abs_path(iface->confanother);
4732 wpa_config_read(wpa_s->confanother, wpa_s->conf);
6fc6879b
JM
4733
4734 /*
4735 * Override ctrl_interface and driver_param if set on command
4736 * line.
4737 */
4738 if (iface->ctrl_interface) {
4739 os_free(wpa_s->conf->ctrl_interface);
4740 wpa_s->conf->ctrl_interface =
4741 os_strdup(iface->ctrl_interface);
4742 }
4743
4744 if (iface->driver_param) {
4745 os_free(wpa_s->conf->driver_param);
4746 wpa_s->conf->driver_param =
4747 os_strdup(iface->driver_param);
4748 }
78f79fe5
JM
4749
4750 if (iface->p2p_mgmt && !iface->ctrl_interface) {
4751 os_free(wpa_s->conf->ctrl_interface);
4752 wpa_s->conf->ctrl_interface = NULL;
4753 }
6fc6879b
JM
4754 } else
4755 wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
4756 iface->driver_param);
4757
4758 if (wpa_s->conf == NULL) {
4759 wpa_printf(MSG_ERROR, "\nNo configuration found.");
4760 return -1;
4761 }
4762
4763 if (iface->ifname == NULL) {
4764 wpa_printf(MSG_ERROR, "\nInterface name is required.");
4765 return -1;
4766 }
4767 if (os_strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
4768 wpa_printf(MSG_ERROR, "\nToo long interface name '%s'.",
4769 iface->ifname);
4770 return -1;
4771 }
4772 os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
4773
4774 if (iface->bridge_ifname) {
4775 if (os_strlen(iface->bridge_ifname) >=
4776 sizeof(wpa_s->bridge_ifname)) {
4777 wpa_printf(MSG_ERROR, "\nToo long bridge interface "
4778 "name '%s'.", iface->bridge_ifname);
4779 return -1;
4780 }
4781 os_strlcpy(wpa_s->bridge_ifname, iface->bridge_ifname,
4782 sizeof(wpa_s->bridge_ifname));
4783 }
4784
6fc6879b
JM
4785 /* RSNA Supplicant Key Management - INITIALIZE */
4786 eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
4787 eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
4788
4789 /* Initialize driver interface and register driver event handler before
4790 * L2 receive handler so that association events are processed before
4791 * EAPOL-Key packets if both become available for the same select()
4792 * call. */
73c00fd7 4793 if (wpas_init_driver(wpa_s, iface) < 0)
362f781e
JM
4794 return -1;
4795
6fc6879b
JM
4796 if (wpa_supplicant_init_wpa(wpa_s) < 0)
4797 return -1;
4798
4799 wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
4800 wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
4801 NULL);
4802 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
4803
4804 if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
4805 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
4806 wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
f049052b
BG
4807 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
4808 "dot11RSNAConfigPMKLifetime");
6fc6879b
JM
4809 return -1;
4810 }
4811
4812 if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
4813 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
4814 wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
f049052b 4815 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
6fc6879b
JM
4816 "dot11RSNAConfigPMKReauthThreshold");
4817 return -1;
4818 }
4819
4820 if (wpa_s->conf->dot11RSNAConfigSATimeout &&
4821 wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
4822 wpa_s->conf->dot11RSNAConfigSATimeout)) {
f049052b
BG
4823 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
4824 "dot11RSNAConfigSATimeout");
6fc6879b
JM
4825 return -1;
4826 }
4827
6bf731e8
CL
4828 wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
4829 &wpa_s->hw.num_modes,
4830 &wpa_s->hw.flags);
a1b790eb
JM
4831 if (wpa_s->hw.modes) {
4832 u16 i;
4833
4834 for (i = 0; i < wpa_s->hw.num_modes; i++) {
4835 if (wpa_s->hw.modes[i].vht_capab) {
4836 wpa_s->hw_capab = CAPAB_VHT;
4837 break;
4838 }
4839
4840 if (wpa_s->hw.modes[i].ht_capab &
4841 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)
4842 wpa_s->hw_capab = CAPAB_HT40;
4843 else if (wpa_s->hw.modes[i].ht_capab &&
4844 wpa_s->hw_capab == CAPAB_NO_HT_VHT)
4845 wpa_s->hw_capab = CAPAB_HT;
4846 }
4847 }
6bf731e8 4848
6cbdb0c5
JM
4849 capa_res = wpa_drv_get_capa(wpa_s, &capa);
4850 if (capa_res == 0) {
c58ab8f2 4851 wpa_s->drv_capa_known = 1;
814782b9 4852 wpa_s->drv_flags = capa.flags;
349493bd 4853 wpa_s->drv_enc = capa.enc;
04ee647d 4854 wpa_s->drv_smps_modes = capa.smps_modes;
f936b73c 4855 wpa_s->drv_rrm_flags = capa.rrm_flags;
4f73d88a 4856 wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
814782b9 4857 wpa_s->max_scan_ssids = capa.max_scan_ssids;
cbdf3507 4858 wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
32c02261
AS
4859 wpa_s->max_sched_scan_plans = capa.max_sched_scan_plans;
4860 wpa_s->max_sched_scan_plan_interval =
4861 capa.max_sched_scan_plan_interval;
4862 wpa_s->max_sched_scan_plan_iterations =
4863 capa.max_sched_scan_plan_iterations;
cbdf3507 4864 wpa_s->sched_scan_supported = capa.sched_scan_supported;
b59e6f26 4865 wpa_s->max_match_sets = capa.max_match_sets;
814782b9 4866 wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
c4ea4c5c 4867 wpa_s->max_stations = capa.max_stations;
8cd6b7bc
JB
4868 wpa_s->extended_capa = capa.extended_capa;
4869 wpa_s->extended_capa_mask = capa.extended_capa_mask;
4870 wpa_s->extended_capa_len = capa.extended_capa_len;
4752147d
IP
4871 wpa_s->num_multichan_concurrent =
4872 capa.num_multichan_concurrent;
471cd6e1 4873 wpa_s->wmm_ac_supported = capa.wmm_ac_supported;
56c76fa5
IP
4874
4875 if (capa.mac_addr_rand_scan_supported)
4876 wpa_s->mac_addr_rand_supported |= MAC_ADDR_RAND_SCAN;
4877 if (wpa_s->sched_scan_supported &&
4878 capa.mac_addr_rand_sched_scan_supported)
4879 wpa_s->mac_addr_rand_supported |=
4880 (MAC_ADDR_RAND_SCHED_SCAN | MAC_ADDR_RAND_PNO);
814782b9
JM
4881 }
4882 if (wpa_s->max_remain_on_chan == 0)
4883 wpa_s->max_remain_on_chan = 1000;
4884
c68f6200
AS
4885 /*
4886 * Only take p2p_mgmt parameters when P2P Device is supported.
4887 * Doing it here as it determines whether l2_packet_init() will be done
4888 * during wpa_supplicant_driver_init().
4889 */
4890 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)
4891 wpa_s->p2p_mgmt = iface->p2p_mgmt;
4892 else
4893 iface->p2p_mgmt = 1;
4894
4752147d
IP
4895 if (wpa_s->num_multichan_concurrent == 0)
4896 wpa_s->num_multichan_concurrent = 1;
4897
6fc6879b
JM
4898 if (wpa_supplicant_driver_init(wpa_s) < 0)
4899 return -1;
4900
281ff0aa 4901#ifdef CONFIG_TDLS
1c42b42f
JM
4902 if ((!iface->p2p_mgmt ||
4903 !(wpa_s->drv_flags &
4904 WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
4905 wpa_tdls_init(wpa_s->wpa))
281ff0aa
GP
4906 return -1;
4907#endif /* CONFIG_TDLS */
4908
315ce40a
JM
4909 if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
4910 wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
f049052b 4911 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to set country");
6d158490
LR
4912 return -1;
4913 }
4914
b36a3a65
AN
4915#ifdef CONFIG_FST
4916 if (wpa_s->conf->fst_group_id) {
4917 struct fst_iface_cfg cfg;
4918 struct fst_wpa_obj iface_obj;
4919
4920 fst_wpa_supplicant_fill_iface_obj(wpa_s, &iface_obj);
4921 os_strlcpy(cfg.group_id, wpa_s->conf->fst_group_id,
4922 sizeof(cfg.group_id));
4923 cfg.priority = wpa_s->conf->fst_priority;
4924 cfg.llt = wpa_s->conf->fst_llt;
4925
4926 wpa_s->fst = fst_attach(wpa_s->ifname, wpa_s->own_addr,
4927 &iface_obj, &cfg);
4928 if (!wpa_s->fst) {
4929 wpa_msg(wpa_s, MSG_ERROR,
4930 "FST: Cannot attach iface %s to group %s",
4931 wpa_s->ifname, cfg.group_id);
4932 return -1;
4933 }
4934 }
4935#endif /* CONFIG_FST */
4936
116654ce
JM
4937 if (wpas_wps_init(wpa_s))
4938 return -1;
4939
6fc6879b
JM
4940 if (wpa_supplicant_init_eapol(wpa_s) < 0)
4941 return -1;
4942 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
4943
4944 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
4945 if (wpa_s->ctrl_iface == NULL) {
4946 wpa_printf(MSG_ERROR,
4947 "Failed to initialize control interface '%s'.\n"
4948 "You may have another wpa_supplicant process "
4949 "already running or the file was\n"
4950 "left by an unclean termination of wpa_supplicant "
4951 "in which case you will need\n"
4952 "to manually remove this file before starting "
4953 "wpa_supplicant again.\n",
4954 wpa_s->conf->ctrl_interface);
4955 return -1;
4956 }
4957
04ea7b79
JM
4958 wpa_s->gas = gas_query_init(wpa_s);
4959 if (wpa_s->gas == NULL) {
4960 wpa_printf(MSG_ERROR, "Failed to initialize GAS query");
4961 return -1;
4962 }
4963
c68f6200 4964 if (iface->p2p_mgmt && wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
f049052b 4965 wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
b22128ef
JM
4966 return -1;
4967 }
b22128ef 4968
83922c2d
JM
4969 if (wpa_bss_init(wpa_s) < 0)
4970 return -1;
83922c2d 4971
e4fa8b12
EP
4972 /*
4973 * Set Wake-on-WLAN triggers, if configured.
4974 * Note: We don't restore/remove the triggers on shutdown (it doesn't
4975 * have effect anyway when the interface is down).
4976 */
6cbdb0c5 4977 if (capa_res == 0 && wpas_set_wowlan_triggers(wpa_s, &capa) < 0)
e4fa8b12
EP
4978 return -1;
4979
ec7b97ab
JM
4980#ifdef CONFIG_EAP_PROXY
4981{
4982 size_t len;
07041c6f
NJ
4983 wpa_s->mnc_len = eapol_sm_get_eap_proxy_imsi(wpa_s->eapol, wpa_s->imsi,
4984 &len);
ec7b97ab
JM
4985 if (wpa_s->mnc_len > 0) {
4986 wpa_s->imsi[len] = '\0';
4987 wpa_printf(MSG_DEBUG, "eap_proxy: IMSI %s (MNC length %d)",
4988 wpa_s->imsi, wpa_s->mnc_len);
4989 } else {
4990 wpa_printf(MSG_DEBUG, "eap_proxy: IMSI not available");
4991 }
4992}
4993#endif /* CONFIG_EAP_PROXY */
4994
f64adcd7
JM
4995 if (pcsc_reader_init(wpa_s) < 0)
4996 return -1;
4997
306ae225
JM
4998 if (wpas_init_ext_pw(wpa_s) < 0)
4999 return -1;
5000
b361d580
AK
5001 wpas_rrm_reset(wpa_s);
5002
32c02261
AS
5003 wpas_sched_scan_plans_set(wpa_s, wpa_s->conf->sched_scan_plans);
5004
ca9968a0
JM
5005#ifdef CONFIG_HS20
5006 hs20_init(wpa_s);
5007#endif /* CONFIG_HS20 */
92c6e2e3
DS
5008#ifdef CONFIG_MBO
5009 wpas_mbo_update_non_pref_chan(wpa_s, wpa_s->conf->non_pref_chan);
5010#endif /* CONFIG_MBO */
ca9968a0 5011
cc9985d1 5012 wpa_supplicant_set_default_scan_ies(wpa_s);
5013
6fc6879b
JM
5014 return 0;
5015}
5016
5017
2ee055b3 5018static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
df509539 5019 int notify, int terminate)
6fc6879b 5020{
26fc96e8
JM
5021 struct wpa_global *global = wpa_s->global;
5022 struct wpa_supplicant *iface, *prev;
5023
5024 if (wpa_s == wpa_s->parent)
5025 wpas_p2p_group_remove(wpa_s, "*");
5026
5027 iface = global->ifaces;
5028 while (iface) {
96a26ab7
LD
5029 if (iface->p2pdev == wpa_s)
5030 iface->p2pdev = iface->parent;
26fc96e8
JM
5031 if (iface == wpa_s || iface->parent != wpa_s) {
5032 iface = iface->next;
5033 continue;
5034 }
5035 wpa_printf(MSG_DEBUG,
5036 "Remove remaining child interface %s from parent %s",
5037 iface->ifname, wpa_s->ifname);
5038 prev = iface;
5039 iface = iface->next;
5040 wpa_supplicant_remove_iface(global, prev, terminate);
5041 }
5042
e679f140 5043 wpa_s->disconnected = 1;
6fc6879b
JM
5044 if (wpa_s->drv_priv) {
5045 wpa_supplicant_deauthenticate(wpa_s,
5046 WLAN_REASON_DEAUTH_LEAVING);
5047
6fc6879b
JM
5048 wpa_drv_set_countermeasures(wpa_s, 0);
5049 wpa_clear_keys(wpa_s, NULL);
5050 }
5051
8e56d189 5052 wpa_supplicant_cleanup(wpa_s);
bd10d938 5053 wpas_p2p_deinit_iface(wpa_s);
ab28911d 5054
1f965e62 5055 wpas_ctrl_radio_work_flush(wpa_s);
202dec2a
JM
5056 radio_remove_interface(wpa_s);
5057
b36a3a65
AN
5058#ifdef CONFIG_FST
5059 if (wpa_s->fst) {
5060 fst_detach(wpa_s->fst);
5061 wpa_s->fst = NULL;
5062 }
5063 if (wpa_s->received_mb_ies) {
5064 wpabuf_free(wpa_s->received_mb_ies);
5065 wpa_s->received_mb_ies = NULL;
5066 }
5067#endif /* CONFIG_FST */
5068
6fc6879b
JM
5069 if (wpa_s->drv_priv)
5070 wpa_drv_deinit(wpa_s);
2523ff6e
DS
5071
5072 if (notify)
5073 wpas_notify_iface_removed(wpa_s);
f0811516
DS
5074
5075 if (terminate)
5076 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
5077
5078 if (wpa_s->ctrl_iface) {
5079 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
5080 wpa_s->ctrl_iface = NULL;
5081 }
5082
603a3f34
JL
5083#ifdef CONFIG_MESH
5084 if (wpa_s->ifmsh) {
5085 wpa_supplicant_mesh_iface_deinit(wpa_s, wpa_s->ifmsh);
5086 wpa_s->ifmsh = NULL;
5087 }
5088#endif /* CONFIG_MESH */
5089
f0811516
DS
5090 if (wpa_s->conf != NULL) {
5091 wpa_config_free(wpa_s->conf);
5092 wpa_s->conf = NULL;
5093 }
18e00b5e 5094
a80651d0
KV
5095 os_free(wpa_s->ssids_from_scan_req);
5096
18e00b5e 5097 os_free(wpa_s);
6fc6879b
JM
5098}
5099
5100
2e997eec
RM
5101#ifdef CONFIG_MATCH_IFACE
5102
5103/**
5104 * wpa_supplicant_match_iface - Match an interface description to a name
5105 * @global: Pointer to global data from wpa_supplicant_init()
5106 * @ifname: Name of the interface to match
5107 * Returns: Pointer to the created interface description or %NULL on failure
5108 */
5109struct wpa_interface * wpa_supplicant_match_iface(struct wpa_global *global,
5110 const char *ifname)
5111{
5112 int i;
5113 struct wpa_interface *iface, *miface;
5114
5115 for (i = 0; i < global->params.match_iface_count; i++) {
5116 miface = &global->params.match_ifaces[i];
5117 if (!miface->ifname ||
5118 fnmatch(miface->ifname, ifname, 0) == 0) {
5119 iface = os_zalloc(sizeof(*iface));
5120 if (!iface)
5121 return NULL;
5122 *iface = *miface;
5123 iface->ifname = ifname;
5124 return iface;
5125 }
5126 }
5127
5128 return NULL;
5129}
5130
5131
5132/**
5133 * wpa_supplicant_match_existing - Match existing interfaces
5134 * @global: Pointer to global data from wpa_supplicant_init()
5135 * Returns: 0 on success, -1 on failure
5136 */
5137static int wpa_supplicant_match_existing(struct wpa_global *global)
5138{
5139 struct if_nameindex *ifi, *ifp;
5140 struct wpa_supplicant *wpa_s;
5141 struct wpa_interface *iface;
5142
5143 ifp = if_nameindex();
5144 if (!ifp) {
5145 wpa_printf(MSG_ERROR, "if_nameindex: %s", strerror(errno));
5146 return -1;
5147 }
5148
5149 for (ifi = ifp; ifi->if_name; ifi++) {
5150 wpa_s = wpa_supplicant_get_iface(global, ifi->if_name);
5151 if (wpa_s)
5152 continue;
5153 iface = wpa_supplicant_match_iface(global, ifi->if_name);
5154 if (iface) {
5155 wpa_s = wpa_supplicant_add_iface(global, iface, NULL);
5156 os_free(iface);
5157 if (wpa_s)
5158 wpa_s->matched = 1;
5159 }
5160 }
5161
5162 if_freenameindex(ifp);
5163 return 0;
5164}
5165
5166#endif /* CONFIG_MATCH_IFACE */
5167
5168
6fc6879b
JM
5169/**
5170 * wpa_supplicant_add_iface - Add a new network interface
5171 * @global: Pointer to global data from wpa_supplicant_init()
5172 * @iface: Interface configuration options
1772d348 5173 * @parent: Parent interface or %NULL to assign new interface as parent
6fc6879b
JM
5174 * Returns: Pointer to the created interface or %NULL on failure
5175 *
5176 * This function is used to add new network interfaces for %wpa_supplicant.
5177 * This can be called before wpa_supplicant_run() to add interfaces before the
5178 * main event loop has been started. In addition, new interfaces can be added
5179 * dynamically while %wpa_supplicant is already running. This could happen,
5180 * e.g., when a hotplug network adapter is inserted.
5181 */
5182struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
1772d348
JM
5183 struct wpa_interface *iface,
5184 struct wpa_supplicant *parent)
6fc6879b
JM
5185{
5186 struct wpa_supplicant *wpa_s;
d27df100 5187 struct wpa_interface t_iface;
8e56d189 5188 struct wpa_ssid *ssid;
6fc6879b
JM
5189
5190 if (global == NULL || iface == NULL)
5191 return NULL;
5192
1772d348 5193 wpa_s = wpa_supplicant_alloc(parent);
6fc6879b
JM
5194 if (wpa_s == NULL)
5195 return NULL;
5196
d8222ae3
JM
5197 wpa_s->global = global;
5198
d27df100
JM
5199 t_iface = *iface;
5200 if (global->params.override_driver) {
5201 wpa_printf(MSG_DEBUG, "Override interface parameter: driver "
5202 "('%s' -> '%s')",
5203 iface->driver, global->params.override_driver);
5204 t_iface.driver = global->params.override_driver;
5205 }
5206 if (global->params.override_ctrl_interface) {
5207 wpa_printf(MSG_DEBUG, "Override interface parameter: "
5208 "ctrl_interface ('%s' -> '%s')",
5209 iface->ctrl_interface,
5210 global->params.override_ctrl_interface);
5211 t_iface.ctrl_interface =
5212 global->params.override_ctrl_interface;
5213 }
5214 if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
6fc6879b
JM
5215 wpa_printf(MSG_DEBUG, "Failed to add interface %s",
5216 iface->ifname);
df509539 5217 wpa_supplicant_deinit_iface(wpa_s, 0, 0);
6fc6879b
JM
5218 return NULL;
5219 }
5220
21efc940
TB
5221 if (iface->p2p_mgmt == 0) {
5222 /* Notify the control interfaces about new iface */
5223 if (wpas_notify_iface_added(wpa_s)) {
5224 wpa_supplicant_deinit_iface(wpa_s, 1, 0);
5225 return NULL;
5226 }
1bd3f426 5227
21efc940
TB
5228 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
5229 wpas_notify_network_added(wpa_s, ssid);
5230 }
8e56d189 5231
6fc6879b
JM
5232 wpa_s->next = global->ifaces;
5233 global->ifaces = wpa_s;
5234
f049052b 5235 wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
99218999 5236 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
6fc6879b 5237
c3c4b3ed
JM
5238#ifdef CONFIG_P2P
5239 if (wpa_s->global->p2p == NULL &&
74802c09 5240 !wpa_s->global->p2p_disabled && !wpa_s->conf->p2p_disabled &&
c3c4b3ed 5241 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
f43c1ae7
IP
5242 wpas_p2p_add_p2pdev_interface(
5243 wpa_s, wpa_s->global->params.conf_p2p_dev) < 0) {
c3c4b3ed
JM
5244 wpa_printf(MSG_INFO,
5245 "P2P: Failed to enable P2P Device interface");
5246 /* Try to continue without. P2P will be disabled. */
5247 }
5248#endif /* CONFIG_P2P */
5249
6fc6879b
JM
5250 return wpa_s;
5251}
5252
5253
5254/**
5255 * wpa_supplicant_remove_iface - Remove a network interface
5256 * @global: Pointer to global data from wpa_supplicant_init()
5257 * @wpa_s: Pointer to the network interface to be removed
5258 * Returns: 0 if interface was removed, -1 if interface was not found
5259 *
5260 * This function can be used to dynamically remove network interfaces from
5261 * %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In
5262 * addition, this function is used to remove all remaining interfaces when
5263 * %wpa_supplicant is terminated.
5264 */
5265int wpa_supplicant_remove_iface(struct wpa_global *global,
df509539
DS
5266 struct wpa_supplicant *wpa_s,
5267 int terminate)
6fc6879b
JM
5268{
5269 struct wpa_supplicant *prev;
5b78493f
MH
5270#ifdef CONFIG_MESH
5271 unsigned int mesh_if_created = wpa_s->mesh_if_created;
5272 char *ifname = NULL;
5273#endif /* CONFIG_MESH */
6fc6879b
JM
5274
5275 /* Remove interface from the global list of interfaces */
5276 prev = global->ifaces;
5277 if (prev == wpa_s) {
5278 global->ifaces = wpa_s->next;
5279 } else {
5280 while (prev && prev->next != wpa_s)
5281 prev = prev->next;
5282 if (prev == NULL)
5283 return -1;
5284 prev->next = wpa_s->next;
5285 }
5286
f049052b 5287 wpa_dbg(wpa_s, MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
6fc6879b 5288
5b78493f
MH
5289#ifdef CONFIG_MESH
5290 if (mesh_if_created) {
5291 ifname = os_strdup(wpa_s->ifname);
5292 if (ifname == NULL) {
5293 wpa_dbg(wpa_s, MSG_ERROR,
5294 "mesh: Failed to malloc ifname");
5295 return -1;
5296 }
5297 }
5298#endif /* CONFIG_MESH */
5299
b22128ef
JM
5300 if (global->p2p_group_formation == wpa_s)
5301 global->p2p_group_formation = NULL;
dbca75f8
JM
5302 if (global->p2p_invite_group == wpa_s)
5303 global->p2p_invite_group = NULL;
df509539 5304 wpa_supplicant_deinit_iface(wpa_s, 1, terminate);
6fc6879b 5305
5b78493f
MH
5306#ifdef CONFIG_MESH
5307 if (mesh_if_created) {
5308 wpa_drv_if_remove(global->ifaces, WPA_IF_MESH, ifname);
5309 os_free(ifname);
5310 }
5311#endif /* CONFIG_MESH */
5312
6fc6879b
JM
5313 return 0;
5314}
5315
5316
cf83fb0b
PS
5317/**
5318 * wpa_supplicant_get_eap_mode - Get the current EAP mode
5319 * @wpa_s: Pointer to the network interface
5320 * Returns: Pointer to the eap mode or the string "UNKNOWN" if not found
5321 */
5322const char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s)
5323{
5324 const char *eapol_method;
5325
5326 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) == 0 &&
5327 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
5328 return "NO-EAP";
5329 }
5330
5331 eapol_method = eapol_sm_get_method_name(wpa_s->eapol);
5332 if (eapol_method == NULL)
5333 return "UNKNOWN-EAP";
5334
5335 return eapol_method;
5336}
5337
5338
6fc6879b
JM
5339/**
5340 * wpa_supplicant_get_iface - Get a new network interface
5341 * @global: Pointer to global data from wpa_supplicant_init()
5342 * @ifname: Interface name
5343 * Returns: Pointer to the interface or %NULL if not found
5344 */
5345struct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
5346 const char *ifname)
5347{
5348 struct wpa_supplicant *wpa_s;
5349
5350 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
5351 if (os_strcmp(wpa_s->ifname, ifname) == 0)
5352 return wpa_s;
5353 }
5354 return NULL;
5355}
5356
5357
50b16da1 5358#ifndef CONFIG_NO_WPA_MSG
4f1495ae
BG
5359static const char * wpa_supplicant_msg_ifname_cb(void *ctx)
5360{
5361 struct wpa_supplicant *wpa_s = ctx;
5362 if (wpa_s == NULL)
5363 return NULL;
5364 return wpa_s->ifname;
5365}
50b16da1 5366#endif /* CONFIG_NO_WPA_MSG */
4f1495ae
BG
5367
5368
8c0d0ff2
JM
5369#ifndef WPA_SUPPLICANT_CLEANUP_INTERVAL
5370#define WPA_SUPPLICANT_CLEANUP_INTERVAL 10
5371#endif /* WPA_SUPPLICANT_CLEANUP_INTERVAL */
5372
5373/* Periodic cleanup tasks */
5374static void wpas_periodic(void *eloop_ctx, void *timeout_ctx)
5375{
5376 struct wpa_global *global = eloop_ctx;
5377 struct wpa_supplicant *wpa_s;
5378
5379 eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0,
5380 wpas_periodic, global, NULL);
5381
5382#ifdef CONFIG_P2P
5383 if (global->p2p)
5384 p2p_expire_peers(global->p2p);
5385#endif /* CONFIG_P2P */
5386
3188aaba 5387 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
8c0d0ff2 5388 wpa_bss_flush_by_age(wpa_s, wpa_s->conf->bss_expiration_age);
3188aaba
JM
5389#ifdef CONFIG_AP
5390 ap_periodic(wpa_s);
5391#endif /* CONFIG_AP */
5392 }
8c0d0ff2
JM
5393}
5394
5395
6fc6879b
JM
5396/**
5397 * wpa_supplicant_init - Initialize %wpa_supplicant
5398 * @params: Parameters for %wpa_supplicant
5399 * Returns: Pointer to global %wpa_supplicant data, or %NULL on failure
5400 *
5401 * This function is used to initialize %wpa_supplicant. After successful
5402 * initialization, the returned data pointer can be used to add and remove
5403 * network interfaces, and eventually, to deinitialize %wpa_supplicant.
5404 */
5405struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
5406{
5407 struct wpa_global *global;
ac305589 5408 int ret, i;
6fc6879b
JM
5409
5410 if (params == NULL)
5411 return NULL;
5412
39e7d718
JM
5413#ifdef CONFIG_DRIVER_NDIS
5414 {
5415 void driver_ndis_init_ops(void);
5416 driver_ndis_init_ops();
5417 }
5418#endif /* CONFIG_DRIVER_NDIS */
5419
50b16da1 5420#ifndef CONFIG_NO_WPA_MSG
4f1495ae 5421 wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
50b16da1 5422#endif /* CONFIG_NO_WPA_MSG */
4f1495ae 5423
f4637fe0
JM
5424 if (params->wpa_debug_file_path)
5425 wpa_debug_open_file(params->wpa_debug_file_path);
5426 else
5427 wpa_debug_setup_stdout();
daa70d49
SL
5428 if (params->wpa_debug_syslog)
5429 wpa_debug_open_syslog();
4f68895e
JB
5430 if (params->wpa_debug_tracing) {
5431 ret = wpa_debug_open_linux_tracing();
5432 if (ret) {
5433 wpa_printf(MSG_ERROR,
5434 "Failed to enable trace logging");
5435 return NULL;
5436 }
5437 }
6fc6879b 5438
12760815 5439 ret = eap_register_methods();
6fc6879b
JM
5440 if (ret) {
5441 wpa_printf(MSG_ERROR, "Failed to register EAP methods");
5442 if (ret == -2)
5443 wpa_printf(MSG_ERROR, "Two or more EAP methods used "
5444 "the same EAP type.");
5445 return NULL;
5446 }
5447
5448 global = os_zalloc(sizeof(*global));
5449 if (global == NULL)
5450 return NULL;
b22128ef
JM
5451 dl_list_init(&global->p2p_srv_bonjour);
5452 dl_list_init(&global->p2p_srv_upnp);
6fc6879b
JM
5453 global->params.daemonize = params->daemonize;
5454 global->params.wait_for_monitor = params->wait_for_monitor;
5455 global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
5456 if (params->pid_file)
5457 global->params.pid_file = os_strdup(params->pid_file);
5458 if (params->ctrl_interface)
5459 global->params.ctrl_interface =
5460 os_strdup(params->ctrl_interface);
29257565
JM
5461 if (params->ctrl_interface_group)
5462 global->params.ctrl_interface_group =
5463 os_strdup(params->ctrl_interface_group);
d27df100
JM
5464 if (params->override_driver)
5465 global->params.override_driver =
5466 os_strdup(params->override_driver);
5467 if (params->override_ctrl_interface)
5468 global->params.override_ctrl_interface =
5469 os_strdup(params->override_ctrl_interface);
2e997eec
RM
5470#ifdef CONFIG_MATCH_IFACE
5471 global->params.match_iface_count = params->match_iface_count;
5472 if (params->match_iface_count) {
5473 global->params.match_ifaces =
5474 os_calloc(params->match_iface_count,
5475 sizeof(struct wpa_interface));
5476 os_memcpy(global->params.match_ifaces,
5477 params->match_ifaces,
5478 params->match_iface_count *
5479 sizeof(struct wpa_interface));
5480 }
5481#endif /* CONFIG_MATCH_IFACE */
d4e59795
G
5482#ifdef CONFIG_P2P
5483 if (params->conf_p2p_dev)
5484 global->params.conf_p2p_dev =
5485 os_strdup(params->conf_p2p_dev);
5486#endif /* CONFIG_P2P */
6fc6879b
JM
5487 wpa_debug_level = global->params.wpa_debug_level =
5488 params->wpa_debug_level;
5489 wpa_debug_show_keys = global->params.wpa_debug_show_keys =
5490 params->wpa_debug_show_keys;
5491 wpa_debug_timestamp = global->params.wpa_debug_timestamp =
5492 params->wpa_debug_timestamp;
5493
f19858f5
JM
5494 wpa_printf(MSG_DEBUG, "wpa_supplicant v" VERSION_STR);
5495
0456ea16 5496 if (eloop_init()) {
6fc6879b
JM
5497 wpa_printf(MSG_ERROR, "Failed to initialize event loop");
5498 wpa_supplicant_deinit(global);
5499 return NULL;
5500 }
5501
38e24575 5502 random_init(params->entropy_file);
d47fa330 5503
6fc6879b
JM
5504 global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
5505 if (global->ctrl_iface == NULL) {
5506 wpa_supplicant_deinit(global);
5507 return NULL;
5508 }
5509
dc461de4
WS
5510 if (wpas_notify_supplicant_initialized(global)) {
5511 wpa_supplicant_deinit(global);
5512 return NULL;
6fc6879b
JM
5513 }
5514
c5121837 5515 for (i = 0; wpa_drivers[i]; i++)
ac305589
JM
5516 global->drv_count++;
5517 if (global->drv_count == 0) {
5518 wpa_printf(MSG_ERROR, "No drivers enabled");
5519 wpa_supplicant_deinit(global);
5520 return NULL;
5521 }
faebdeaa 5522 global->drv_priv = os_calloc(global->drv_count, sizeof(void *));
ac305589
JM
5523 if (global->drv_priv == NULL) {
5524 wpa_supplicant_deinit(global);
5525 return NULL;
5526 }
ac305589 5527
9675ce35
JM
5528#ifdef CONFIG_WIFI_DISPLAY
5529 if (wifi_display_init(global) < 0) {
5530 wpa_printf(MSG_ERROR, "Failed to initialize Wi-Fi Display");
5531 wpa_supplicant_deinit(global);
5532 return NULL;
5533 }
5534#endif /* CONFIG_WIFI_DISPLAY */
5535
8c0d0ff2
JM
5536 eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0,
5537 wpas_periodic, global, NULL);
5538
6fc6879b
JM
5539 return global;
5540}
5541
5542
5543/**
5544 * wpa_supplicant_run - Run the %wpa_supplicant main event loop
5545 * @global: Pointer to global data from wpa_supplicant_init()
5546 * Returns: 0 after successful event loop run, -1 on failure
5547 *
5548 * This function starts the main event loop and continues running as long as
5549 * there are any remaining events. In most cases, this function is running as
5550 * long as the %wpa_supplicant process in still in use.
5551 */
5552int wpa_supplicant_run(struct wpa_global *global)
5553{
5554 struct wpa_supplicant *wpa_s;
5555
5556 if (global->params.daemonize &&
2e69bdd1
RM
5557 (wpa_supplicant_daemon(global->params.pid_file) ||
5558 eloop_sock_requeue()))
6fc6879b
JM
5559 return -1;
5560
2e997eec
RM
5561#ifdef CONFIG_MATCH_IFACE
5562 if (wpa_supplicant_match_existing(global))
5563 return -1;
5564#endif
5565
6fc6879b
JM
5566 if (global->params.wait_for_monitor) {
5567 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
ede77701 5568 if (wpa_s->ctrl_iface && !wpa_s->p2p_mgmt)
6fc6879b
JM
5569 wpa_supplicant_ctrl_iface_wait(
5570 wpa_s->ctrl_iface);
5571 }
5572
0456ea16
JM
5573 eloop_register_signal_terminate(wpa_supplicant_terminate, global);
5574 eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
6fc6879b
JM
5575
5576 eloop_run();
5577
5578 return 0;
5579}
5580
5581
5582/**
5583 * wpa_supplicant_deinit - Deinitialize %wpa_supplicant
5584 * @global: Pointer to global data from wpa_supplicant_init()
5585 *
5586 * This function is called to deinitialize %wpa_supplicant and to free all
5587 * allocated resources. Remaining network interfaces will also be removed.
5588 */
5589void wpa_supplicant_deinit(struct wpa_global *global)
5590{
ac305589
JM
5591 int i;
5592
6fc6879b
JM
5593 if (global == NULL)
5594 return;
5595
8c0d0ff2
JM
5596 eloop_cancel_timeout(wpas_periodic, global, NULL);
5597
9675ce35
JM
5598#ifdef CONFIG_WIFI_DISPLAY
5599 wifi_display_deinit(global);
5600#endif /* CONFIG_WIFI_DISPLAY */
b22128ef 5601
6fc6879b 5602 while (global->ifaces)
df509539 5603 wpa_supplicant_remove_iface(global, global->ifaces, 1);
6fc6879b
JM
5604
5605 if (global->ctrl_iface)
5606 wpa_supplicant_global_ctrl_iface_deinit(global->ctrl_iface);
dc461de4
WS
5607
5608 wpas_notify_supplicant_deinitialized(global);
6fc6879b
JM
5609
5610 eap_peer_unregister_methods();
3ec97afe
JM
5611#ifdef CONFIG_AP
5612 eap_server_unregister_methods();
5613#endif /* CONFIG_AP */
6fc6879b 5614
c5121837 5615 for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
ac305589
JM
5616 if (!global->drv_priv[i])
5617 continue;
c5121837 5618 wpa_drivers[i]->global_deinit(global->drv_priv[i]);
ac305589
JM
5619 }
5620 os_free(global->drv_priv);
5621
d47fa330
JM
5622 random_deinit();
5623
6fc6879b
JM
5624 eloop_destroy();
5625
5626 if (global->params.pid_file) {
5627 os_daemonize_terminate(global->params.pid_file);
5628 os_free(global->params.pid_file);
5629 }
5630 os_free(global->params.ctrl_interface);
29257565 5631 os_free(global->params.ctrl_interface_group);
d27df100
JM
5632 os_free(global->params.override_driver);
5633 os_free(global->params.override_ctrl_interface);
2e997eec
RM
5634#ifdef CONFIG_MATCH_IFACE
5635 os_free(global->params.match_ifaces);
5636#endif /* CONFIG_MATCH_IFACE */
d4e59795
G
5637#ifdef CONFIG_P2P
5638 os_free(global->params.conf_p2p_dev);
5639#endif /* CONFIG_P2P */
6fc6879b 5640
af8a827b 5641 os_free(global->p2p_disallow_freq.range);
253f2e37 5642 os_free(global->p2p_go_avoid_freq.range);
01a57fe4 5643 os_free(global->add_psk);
6f3bc72b 5644
6fc6879b 5645 os_free(global);
daa70d49 5646 wpa_debug_close_syslog();
6fc6879b 5647 wpa_debug_close_file();
4f68895e 5648 wpa_debug_close_linux_tracing();
6fc6879b 5649}
611aea7d
JM
5650
5651
5652void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
5653{
849b5dc7
JM
5654 if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
5655 wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
5656 char country[3];
5657 country[0] = wpa_s->conf->country[0];
5658 country[1] = wpa_s->conf->country[1];
5659 country[2] = '\0';
5660 if (wpa_drv_set_country(wpa_s, country) < 0) {
5661 wpa_printf(MSG_ERROR, "Failed to set country code "
5662 "'%s'", country);
5663 }
5664 }
5665
306ae225
JM
5666 if (wpa_s->conf->changed_parameters & CFG_CHANGED_EXT_PW_BACKEND)
5667 wpas_init_ext_pw(wpa_s);
5668
bea48f77
JM
5669 if (wpa_s->conf->changed_parameters & CFG_CHANGED_SCHED_SCAN_PLANS)
5670 wpas_sched_scan_plans_set(wpa_s, wpa_s->conf->sched_scan_plans);
5671
611aea7d
JM
5672#ifdef CONFIG_WPS
5673 wpas_wps_update_config(wpa_s);
5674#endif /* CONFIG_WPS */
b22128ef 5675 wpas_p2p_update_config(wpa_s);
611aea7d
JM
5676 wpa_s->conf->changed_parameters = 0;
5677}
2f9c6aa6
JM
5678
5679
e1117c1c 5680void add_freq(int *freqs, int *num_freqs, int freq)
0fb337c1
JM
5681{
5682 int i;
5683
5684 for (i = 0; i < *num_freqs; i++) {
5685 if (freqs[i] == freq)
5686 return;
5687 }
5688
5689 freqs[*num_freqs] = freq;
5690 (*num_freqs)++;
5691}
5692
5693
5694static int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s)
5695{
5696 struct wpa_bss *bss, *cbss;
5697 const int max_freqs = 10;
5698 int *freqs;
5699 int num_freqs = 0;
5700
faebdeaa 5701 freqs = os_calloc(max_freqs + 1, sizeof(int));
0fb337c1
JM
5702 if (freqs == NULL)
5703 return NULL;
5704
5705 cbss = wpa_s->current_bss;
5706
5707 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
5708 if (bss == cbss)
5709 continue;
5710 if (bss->ssid_len == cbss->ssid_len &&
5711 os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
5712 wpa_blacklist_get(wpa_s, bss->bssid) == NULL) {
5713 add_freq(freqs, &num_freqs, bss->freq);
5714 if (num_freqs == max_freqs)
5715 break;
5716 }
5717 }
5718
5719 if (num_freqs == 0) {
5720 os_free(freqs);
5721 freqs = NULL;
5722 }
5723
5724 return freqs;
5725}
5726
5727
5728void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
5729{
5730 int timeout;
5731 int count;
5732 int *freqs = NULL;
5733
6ac4b15e
JM
5734 wpas_connect_work_done(wpa_s);
5735
5fd9fb27
JM
5736 /*
5737 * Remove possible authentication timeout since the connection failed.
5738 */
5739 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
5740
c2805909
JM
5741 /*
5742 * There is no point in blacklisting the AP if this event is
5743 * generated based on local request to disconnect.
5744 */
5745 if (wpa_s->own_disconnect_req) {
5746 wpa_s->own_disconnect_req = 0;
5747 wpa_dbg(wpa_s, MSG_DEBUG,
5748 "Ignore connection failure due to local request to disconnect");
5749 return;
5750 }
0cdb93fe 5751 if (wpa_s->disconnected) {
0cdb93fe
JM
5752 wpa_dbg(wpa_s, MSG_DEBUG, "Ignore connection failure "
5753 "indication since interface has been put into "
5754 "disconnected state");
5755 return;
5756 }
5757
0fb337c1
JM
5758 /*
5759 * Add the failed BSSID into the blacklist and speed up next scan
5760 * attempt if there could be other APs that could accept association.
5761 * The current blacklist count indicates how many times we have tried
5762 * connecting to this AP and multiple attempts mean that other APs are
5763 * either not available or has already been tried, so that we can start
5764 * increasing the delay here to avoid constant scanning.
5765 */
5766 count = wpa_blacklist_add(wpa_s, bssid);
5767 if (count == 1 && wpa_s->current_bss) {
5768 /*
5769 * This BSS was not in the blacklist before. If there is
5770 * another BSS available for the same ESS, we should try that
5771 * next. Otherwise, we may as well try this one once more
5772 * before allowing other, likely worse, ESSes to be considered.
5773 */
5774 freqs = get_bss_freqs_in_ess(wpa_s);
5775 if (freqs) {
f049052b
BG
5776 wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
5777 "has been seen; try it next");
0fb337c1
JM
5778 wpa_blacklist_add(wpa_s, bssid);
5779 /*
5780 * On the next scan, go through only the known channels
5781 * used in this ESS based on previous scans to speed up
5782 * common load balancing use case.
5783 */
5784 os_free(wpa_s->next_scan_freqs);
5785 wpa_s->next_scan_freqs = freqs;
5786 }
5787 }
5788
f1a52633
JM
5789 /*
5790 * Add previous failure count in case the temporary blacklist was
5791 * cleared due to no other BSSes being available.
5792 */
5793 count += wpa_s->extra_blacklist_count;
5794
dd579704
JM
5795 if (count > 3 && wpa_s->current_ssid) {
5796 wpa_printf(MSG_DEBUG, "Continuous association failures - "
5797 "consider temporary network disabling");
b19c098e 5798 wpas_auth_failed(wpa_s, "CONN_FAILED");
dd579704
JM
5799 }
5800
0fb337c1
JM
5801 switch (count) {
5802 case 1:
5803 timeout = 100;
5804 break;
5805 case 2:
5806 timeout = 500;
5807 break;
5808 case 3:
5809 timeout = 1000;
5810 break;
f1a52633 5811 case 4:
0fb337c1 5812 timeout = 5000;
f1a52633
JM
5813 break;
5814 default:
5815 timeout = 10000;
5816 break;
0fb337c1
JM
5817 }
5818
f1a52633
JM
5819 wpa_dbg(wpa_s, MSG_DEBUG, "Blacklist count %d --> request scan in %d "
5820 "ms", count, timeout);
5821
0fb337c1
JM
5822 /*
5823 * TODO: if more than one possible AP is available in scan results,
5824 * could try the other ones before requesting a new scan.
5825 */
5826 wpa_supplicant_req_scan(wpa_s, timeout / 1000,
5827 1000 * (timeout % 1000));
5828}
22628eca
JM
5829
5830
5831int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
5832{
5833 return wpa_s->conf->ap_scan == 2 ||
5834 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
5835}
d2118814
JM
5836
5837
5838#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
5839int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
5840 struct wpa_ssid *ssid,
5841 const char *field,
5842 const char *value)
5843{
5844#ifdef IEEE8021X_EAPOL
5845 struct eap_peer_config *eap = &ssid->eap;
5846
5847 wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
5848 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
5849 (const u8 *) value, os_strlen(value));
5850
5851 switch (wpa_supplicant_ctrl_req_from_string(field)) {
5852 case WPA_CTRL_REQ_EAP_IDENTITY:
5853 os_free(eap->identity);
5854 eap->identity = (u8 *) os_strdup(value);
5855 eap->identity_len = os_strlen(value);
5856 eap->pending_req_identity = 0;
5857 if (ssid == wpa_s->current_ssid)
5858 wpa_s->reassociate = 1;
5859 break;
5860 case WPA_CTRL_REQ_EAP_PASSWORD:
19c48da0 5861 bin_clear_free(eap->password, eap->password_len);
d2118814
JM
5862 eap->password = (u8 *) os_strdup(value);
5863 eap->password_len = os_strlen(value);
5864 eap->pending_req_password = 0;
5865 if (ssid == wpa_s->current_ssid)
5866 wpa_s->reassociate = 1;
5867 break;
5868 case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
19c48da0 5869 bin_clear_free(eap->new_password, eap->new_password_len);
d2118814
JM
5870 eap->new_password = (u8 *) os_strdup(value);
5871 eap->new_password_len = os_strlen(value);
5872 eap->pending_req_new_password = 0;
5873 if (ssid == wpa_s->current_ssid)
5874 wpa_s->reassociate = 1;
5875 break;
5876 case WPA_CTRL_REQ_EAP_PIN:
19c48da0 5877 str_clear_free(eap->pin);
d2118814
JM
5878 eap->pin = os_strdup(value);
5879 eap->pending_req_pin = 0;
5880 if (ssid == wpa_s->current_ssid)
5881 wpa_s->reassociate = 1;
5882 break;
5883 case WPA_CTRL_REQ_EAP_OTP:
19c48da0 5884 bin_clear_free(eap->otp, eap->otp_len);
d2118814
JM
5885 eap->otp = (u8 *) os_strdup(value);
5886 eap->otp_len = os_strlen(value);
5887 os_free(eap->pending_req_otp);
5888 eap->pending_req_otp = NULL;
5889 eap->pending_req_otp_len = 0;
5890 break;
5891 case WPA_CTRL_REQ_EAP_PASSPHRASE:
19c48da0
JM
5892 str_clear_free(eap->private_key_passwd);
5893 eap->private_key_passwd = os_strdup(value);
d2118814
JM
5894 eap->pending_req_passphrase = 0;
5895 if (ssid == wpa_s->current_ssid)
5896 wpa_s->reassociate = 1;
5897 break;
a5d44ac0 5898 case WPA_CTRL_REQ_SIM:
19c48da0 5899 str_clear_free(eap->external_sim_resp);
a5d44ac0
JM
5900 eap->external_sim_resp = os_strdup(value);
5901 break;
a52410c2
JM
5902 case WPA_CTRL_REQ_PSK_PASSPHRASE:
5903 if (wpa_config_set(ssid, "psk", value, 0) < 0)
5904 return -1;
5905 ssid->mem_only_psk = 1;
5906 if (ssid->passphrase)
5907 wpa_config_update_psk(ssid);
5908 if (wpa_s->wpa_state == WPA_SCANNING && !wpa_s->scanning)
5909 wpa_supplicant_req_scan(wpa_s, 0, 0);
5910 break;
3c108b75
JM
5911 case WPA_CTRL_REQ_EXT_CERT_CHECK:
5912 if (eap->pending_ext_cert_check != PENDING_CHECK)
5913 return -1;
5914 if (os_strcmp(value, "good") == 0)
5915 eap->pending_ext_cert_check = EXT_CERT_CHECK_GOOD;
5916 else if (os_strcmp(value, "bad") == 0)
5917 eap->pending_ext_cert_check = EXT_CERT_CHECK_BAD;
5918 else
5919 return -1;
5920 break;
d2118814
JM
5921 default:
5922 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
5923 return -1;
5924 }
5925
5926 return 0;
5927#else /* IEEE8021X_EAPOL */
5928 wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
5929 return -1;
5930#endif /* IEEE8021X_EAPOL */
5931}
5932#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
349493bd
JM
5933
5934
5935int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
5936{
5937 int i;
5938 unsigned int drv_enc;
5939
44b9ea5b
JM
5940 if (wpa_s->p2p_mgmt)
5941 return 1; /* no normal network profiles on p2p_mgmt interface */
5942
349493bd
JM
5943 if (ssid == NULL)
5944 return 1;
5945
5946 if (ssid->disabled)
5947 return 1;
5948
9feadba1 5949 if (wpa_s->drv_capa_known)
349493bd
JM
5950 drv_enc = wpa_s->drv_enc;
5951 else
5952 drv_enc = (unsigned int) -1;
5953
5954 for (i = 0; i < NUM_WEP_KEYS; i++) {
5955 size_t len = ssid->wep_key_len[i];
5956 if (len == 0)
5957 continue;
5958 if (len == 5 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40))
5959 continue;
5960 if (len == 13 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104))
5961 continue;
5962 if (len == 16 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP128))
5963 continue;
5964 return 1; /* invalid WEP key */
5965 }
5966
9173b16f 5967 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
a52410c2
JM
5968 (!ssid->passphrase || ssid->ssid_len != 0) && !ssid->ext_psk &&
5969 !ssid->mem_only_psk)
2518aad3
JM
5970 return 1;
5971
349493bd
JM
5972 return 0;
5973}
b9cfc09a
JJ
5974
5975
3f56a2b7
JM
5976int wpas_get_ssid_pmf(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
5977{
5978#ifdef CONFIG_IEEE80211W
5979 if (ssid == NULL || ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT) {
5980 if (wpa_s->conf->pmf == MGMT_FRAME_PROTECTION_OPTIONAL &&
5981 !(wpa_s->drv_enc & WPA_DRIVER_CAPA_ENC_BIP)) {
5982 /*
5983 * Driver does not support BIP -- ignore pmf=1 default
5984 * since the connection with PMF would fail and the
5985 * configuration does not require PMF to be enabled.
5986 */
5987 return NO_MGMT_FRAME_PROTECTION;
5988 }
5989
22950049
JM
5990 if (ssid &&
5991 (ssid->key_mgmt &
5992 ~(WPA_KEY_MGMT_NONE | WPA_KEY_MGMT_WPS |
5993 WPA_KEY_MGMT_IEEE8021X_NO_WPA)) == 0) {
5994 /*
5995 * Do not use the default PMF value for non-RSN networks
5996 * since PMF is available only with RSN and pmf=2
5997 * configuration would otherwise prevent connections to
5998 * all open networks.
5999 */
6000 return NO_MGMT_FRAME_PROTECTION;
6001 }
6002
3f56a2b7
JM
6003 return wpa_s->conf->pmf;
6004 }
6005
6006 return ssid->ieee80211w;
6007#else /* CONFIG_IEEE80211W */
6008 return NO_MGMT_FRAME_PROTECTION;
6009#endif /* CONFIG_IEEE80211W */
6010}
6011
6012
b9cfc09a
JJ
6013int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
6014{
6015 if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
6016 return 1;
6017 if (wpa_s->global->conc_pref == WPA_CONC_PREF_STA)
6018 return 0;
6019 return -1;
6020}
00e5e3d5
JM
6021
6022
b19c098e 6023void wpas_auth_failed(struct wpa_supplicant *wpa_s, char *reason)
00e5e3d5
JM
6024{
6025 struct wpa_ssid *ssid = wpa_s->current_ssid;
6026 int dur;
4e1eae1d 6027 struct os_reltime now;
00e5e3d5
JM
6028
6029 if (ssid == NULL) {
6030 wpa_printf(MSG_DEBUG, "Authentication failure but no known "
6031 "SSID block");
6032 return;
6033 }
6034
6035 if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
6036 return;
6037
6038 ssid->auth_failures++;
cbf41ca7
SL
6039
6040#ifdef CONFIG_P2P
6041 if (ssid->p2p_group &&
6042 (wpa_s->p2p_in_provisioning || wpa_s->show_group_started)) {
6043 /*
6044 * Skip the wait time since there is a short timeout on the
6045 * connection to a P2P group.
6046 */
6047 return;
6048 }
6049#endif /* CONFIG_P2P */
6050
00e5e3d5
JM
6051 if (ssid->auth_failures > 50)
6052 dur = 300;
00e5e3d5 6053 else if (ssid->auth_failures > 10)
8a77f1be 6054 dur = 120;
00e5e3d5 6055 else if (ssid->auth_failures > 5)
8a77f1be
JM
6056 dur = 90;
6057 else if (ssid->auth_failures > 3)
6058 dur = 60;
6059 else if (ssid->auth_failures > 2)
00e5e3d5
JM
6060 dur = 30;
6061 else if (ssid->auth_failures > 1)
6062 dur = 20;
6063 else
6064 dur = 10;
6065
8a77f1be
JM
6066 if (ssid->auth_failures > 1 &&
6067 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt))
6068 dur += os_random() % (ssid->auth_failures * 10);
6069
4e1eae1d 6070 os_get_reltime(&now);
00e5e3d5
JM
6071 if (now.sec + dur <= ssid->disabled_until.sec)
6072 return;
6073
6074 ssid->disabled_until.sec = now.sec + dur;
6075
6076 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TEMP_DISABLED
b19c098e 6077 "id=%d ssid=\"%s\" auth_failures=%u duration=%d reason=%s",
00e5e3d5 6078 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
b19c098e 6079 ssid->auth_failures, dur, reason);
00e5e3d5
JM
6080}
6081
6082
6083void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
6084 struct wpa_ssid *ssid, int clear_failures)
6085{
6086 if (ssid == NULL)
6087 return;
6088
6089 if (ssid->disabled_until.sec) {
6090 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REENABLED
6091 "id=%d ssid=\"%s\"",
6092 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
6093 }
6094 ssid->disabled_until.sec = 0;
6095 ssid->disabled_until.usec = 0;
6096 if (clear_failures)
6097 ssid->auth_failures = 0;
6098}
6407f413
JM
6099
6100
6101int disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid)
6102{
6103 size_t i;
6104
6105 if (wpa_s->disallow_aps_bssid == NULL)
6106 return 0;
6107
6108 for (i = 0; i < wpa_s->disallow_aps_bssid_count; i++) {
6109 if (os_memcmp(wpa_s->disallow_aps_bssid + i * ETH_ALEN,
6110 bssid, ETH_ALEN) == 0)
6111 return 1;
6112 }
6113
6114 return 0;
6115}
6116
6117
6118int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
6119 size_t ssid_len)
6120{
6121 size_t i;
6122
6123 if (wpa_s->disallow_aps_ssid == NULL || ssid == NULL)
6124 return 0;
6125
6126 for (i = 0; i < wpa_s->disallow_aps_ssid_count; i++) {
6127 struct wpa_ssid_value *s = &wpa_s->disallow_aps_ssid[i];
6128 if (ssid_len == s->ssid_len &&
6129 os_memcmp(ssid, s->ssid, ssid_len) == 0)
6130 return 1;
6131 }
6132
6133 return 0;
6134}
9796a86c
JM
6135
6136
6137/**
6138 * wpas_request_connection - Request a new connection
6139 * @wpa_s: Pointer to the network interface
6140 *
6141 * This function is used to request a new connection to be found. It will mark
6142 * the interface to allow reassociation and request a new scan to find a
6143 * suitable network to connect to.
6144 */
6145void wpas_request_connection(struct wpa_supplicant *wpa_s)
6146{
6147 wpa_s->normal_scans = 0;
5214f4fa 6148 wpa_s->scan_req = NORMAL_SCAN_REQ;
9796a86c
JM
6149 wpa_supplicant_reinit_autoscan(wpa_s);
6150 wpa_s->extra_blacklist_count = 0;
6151 wpa_s->disconnected = 0;
6152 wpa_s->reassociate = 1;
5e24beae
MH
6153
6154 if (wpa_supplicant_fast_associate(wpa_s) != 1)
6155 wpa_supplicant_req_scan(wpa_s, 0, 0);
0c5f01fd
B
6156 else
6157 wpa_s->reattach = 0;
9796a86c 6158}
36b9883d
DG
6159
6160
5f040be4
RP
6161/**
6162 * wpas_request_disconnection - Request disconnection
6163 * @wpa_s: Pointer to the network interface
6164 *
6165 * This function is used to request disconnection from the currently connected
6166 * network. This will stop any ongoing scans and initiate deauthentication.
6167 */
6168void wpas_request_disconnection(struct wpa_supplicant *wpa_s)
6169{
6170#ifdef CONFIG_SME
6171 wpa_s->sme.prev_bssid_set = 0;
6172#endif /* CONFIG_SME */
6173 wpa_s->reassociate = 0;
6174 wpa_s->disconnected = 1;
6175 wpa_supplicant_cancel_sched_scan(wpa_s);
6176 wpa_supplicant_cancel_scan(wpa_s);
6177 wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
6178 eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL);
6179}
6180
6181
a0c90bb0
IP
6182void dump_freq_data(struct wpa_supplicant *wpa_s, const char *title,
6183 struct wpa_used_freq_data *freqs_data,
6184 unsigned int len)
6185{
6186 unsigned int i;
6187
6188 wpa_dbg(wpa_s, MSG_DEBUG, "Shared frequencies (len=%u): %s",
6189 len, title);
6190 for (i = 0; i < len; i++) {
6191 struct wpa_used_freq_data *cur = &freqs_data[i];
6192 wpa_dbg(wpa_s, MSG_DEBUG, "freq[%u]: %d, flags=0x%X",
6193 i, cur->freq, cur->flags);
6194 }
6195}
6196
6197
53c5dfc2
IP
6198/*
6199 * Find the operating frequencies of any of the virtual interfaces that
a0c90bb0
IP
6200 * are using the same radio as the current interface, and in addition, get
6201 * information about the interface types that are using the frequency.
53c5dfc2 6202 */
a0c90bb0
IP
6203int get_shared_radio_freqs_data(struct wpa_supplicant *wpa_s,
6204 struct wpa_used_freq_data *freqs_data,
6205 unsigned int len)
53c5dfc2 6206{
53c5dfc2
IP
6207 struct wpa_supplicant *ifs;
6208 u8 bssid[ETH_ALEN];
6209 int freq;
6210 unsigned int idx = 0, i;
6211
217cf499
JM
6212 wpa_dbg(wpa_s, MSG_DEBUG,
6213 "Determining shared radio frequencies (max len %u)", len);
a0c90bb0 6214 os_memset(freqs_data, 0, sizeof(struct wpa_used_freq_data) * len);
53c5dfc2 6215
0ad3b9c4
JM
6216 dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
6217 radio_list) {
a0c90bb0
IP
6218 if (idx == len)
6219 break;
6220
53c5dfc2
IP
6221 if (ifs->current_ssid == NULL || ifs->assoc_freq == 0)
6222 continue;
6223
6224 if (ifs->current_ssid->mode == WPAS_MODE_AP ||
241c3333
MH
6225 ifs->current_ssid->mode == WPAS_MODE_P2P_GO ||
6226 ifs->current_ssid->mode == WPAS_MODE_MESH)
53c5dfc2
IP
6227 freq = ifs->current_ssid->frequency;
6228 else if (wpa_drv_get_bssid(ifs, bssid) == 0)
6229 freq = ifs->assoc_freq;
6230 else
6231 continue;
6232
6233 /* Hold only distinct freqs */
6234 for (i = 0; i < idx; i++)
a0c90bb0 6235 if (freqs_data[i].freq == freq)
53c5dfc2
IP
6236 break;
6237
6238 if (i == idx)
a0c90bb0
IP
6239 freqs_data[idx++].freq = freq;
6240
6241 if (ifs->current_ssid->mode == WPAS_MODE_INFRA) {
22264b3c 6242 freqs_data[i].flags |= ifs->current_ssid->p2p_group ?
a0c90bb0
IP
6243 WPA_FREQ_USED_BY_P2P_CLIENT :
6244 WPA_FREQ_USED_BY_INFRA_STATION;
6245 }
53c5dfc2 6246 }
217cf499 6247
a0c90bb0 6248 dump_freq_data(wpa_s, "completed iteration", freqs_data, idx);
53c5dfc2
IP
6249 return idx;
6250}
a0c90bb0
IP
6251
6252
6253/*
6254 * Find the operating frequencies of any of the virtual interfaces that
6255 * are using the same radio as the current interface.
6256 */
6257int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
6258 int *freq_array, unsigned int len)
6259{
6260 struct wpa_used_freq_data *freqs_data;
6261 int num, i;
6262
6263 os_memset(freq_array, 0, sizeof(int) * len);
6264
6265 freqs_data = os_calloc(len, sizeof(struct wpa_used_freq_data));
6266 if (!freqs_data)
6267 return -1;
6268
6269 num = get_shared_radio_freqs_data(wpa_s, freqs_data, len);
6270 for (i = 0; i < num; i++)
6271 freq_array[i] = freqs_data[i].freq;
6272
6273 os_free(freqs_data);
6274
6275 return num;
6276}
b361d580
AK
6277
6278
d89c0701
AK
6279static void wpas_rrm_neighbor_rep_timeout_handler(void *data, void *user_ctx)
6280{
6281 struct rrm_data *rrm = data;
6282
6283 if (!rrm->notify_neighbor_rep) {
6284 wpa_printf(MSG_ERROR,
6285 "RRM: Unexpected neighbor report timeout");
6286 return;
6287 }
6288
6289 wpa_printf(MSG_DEBUG, "RRM: Notifying neighbor report - NONE");
6290 rrm->notify_neighbor_rep(rrm->neighbor_rep_cb_ctx, NULL);
6291
6292 rrm->notify_neighbor_rep = NULL;
6293 rrm->neighbor_rep_cb_ctx = NULL;
6294}
6295
6296
b361d580
AK
6297/*
6298 * wpas_rrm_reset - Clear and reset all RRM data in wpa_supplicant
6299 * @wpa_s: Pointer to wpa_supplicant
6300 */
6301void wpas_rrm_reset(struct wpa_supplicant *wpa_s)
6302{
6303 wpa_s->rrm.rrm_used = 0;
d89c0701
AK
6304
6305 eloop_cancel_timeout(wpas_rrm_neighbor_rep_timeout_handler, &wpa_s->rrm,
6306 NULL);
6307 if (wpa_s->rrm.notify_neighbor_rep)
6308 wpas_rrm_neighbor_rep_timeout_handler(&wpa_s->rrm, NULL);
6309 wpa_s->rrm.next_neighbor_rep_token = 1;
6310}
6311
6312
6313/*
6314 * wpas_rrm_process_neighbor_rep - Handle incoming neighbor report
6315 * @wpa_s: Pointer to wpa_supplicant
6316 * @report: Neighbor report buffer, prefixed by a 1-byte dialog token
6317 * @report_len: Length of neighbor report buffer
6318 */
6319void wpas_rrm_process_neighbor_rep(struct wpa_supplicant *wpa_s,
6320 const u8 *report, size_t report_len)
6321{
6322 struct wpabuf *neighbor_rep;
6323
6324 wpa_hexdump(MSG_DEBUG, "RRM: New Neighbor Report", report, report_len);
6325 if (report_len < 1)
6326 return;
6327
6328 if (report[0] != wpa_s->rrm.next_neighbor_rep_token - 1) {
6329 wpa_printf(MSG_DEBUG,
6330 "RRM: Discarding neighbor report with token %d (expected %d)",
6331 report[0], wpa_s->rrm.next_neighbor_rep_token - 1);
6332 return;
6333 }
6334
6335 eloop_cancel_timeout(wpas_rrm_neighbor_rep_timeout_handler, &wpa_s->rrm,
6336 NULL);
6337
6338 if (!wpa_s->rrm.notify_neighbor_rep) {
6339 wpa_printf(MSG_ERROR, "RRM: Unexpected neighbor report");
6340 return;
6341 }
6342
6343 /* skipping the first byte, which is only an id (dialog token) */
6344 neighbor_rep = wpabuf_alloc(report_len - 1);
6345 if (neighbor_rep == NULL)
6346 return;
6347 wpabuf_put_data(neighbor_rep, report + 1, report_len - 1);
6348 wpa_printf(MSG_DEBUG, "RRM: Notifying neighbor report (token = %d)",
6349 report[0]);
6350 wpa_s->rrm.notify_neighbor_rep(wpa_s->rrm.neighbor_rep_cb_ctx,
6351 neighbor_rep);
6352 wpa_s->rrm.notify_neighbor_rep = NULL;
6353 wpa_s->rrm.neighbor_rep_cb_ctx = NULL;
6354}
6355
6356
b09baf37
JM
6357#if defined(__CYGWIN__) || defined(CONFIG_NATIVE_WINDOWS)
6358/* Workaround different, undefined for Windows, error codes used here */
6359#define ENOTCONN -1
6360#define EOPNOTSUPP -1
6361#define ECANCELED -1
6362#endif
6363
d41a5352
DS
6364/* Measurement Request element + Location Subject + Maximum Age subelement */
6365#define MEASURE_REQUEST_LCI_LEN (3 + 1 + 4)
6366/* Measurement Request element + Location Civic Request */
6367#define MEASURE_REQUEST_CIVIC_LEN (3 + 5)
6368
6369
d89c0701
AK
6370/**
6371 * wpas_rrm_send_neighbor_rep_request - Request a neighbor report from our AP
6372 * @wpa_s: Pointer to wpa_supplicant
4c4b2305
AK
6373 * @ssid: if not null, this is sent in the request. Otherwise, no SSID IE
6374 * is sent in the request.
d41a5352
DS
6375 * @lci: if set, neighbor request will include LCI request
6376 * @civic: if set, neighbor request will include civic location request
d89c0701
AK
6377 * @cb: Callback function to be called once the requested report arrives, or
6378 * timed out after RRM_NEIGHBOR_REPORT_TIMEOUT seconds.
6379 * In the former case, 'neighbor_rep' is a newly allocated wpabuf, and it's
6380 * the requester's responsibility to free it.
6381 * In the latter case NULL will be sent in 'neighbor_rep'.
6382 * @cb_ctx: Context value to send the callback function
6383 * Returns: 0 in case of success, negative error code otherwise
6384 *
6385 * In case there is a previous request which has not been answered yet, the
6386 * new request fails. The caller may retry after RRM_NEIGHBOR_REPORT_TIMEOUT.
6387 * Request must contain a callback function.
d89c0701
AK
6388 */
6389int wpas_rrm_send_neighbor_rep_request(struct wpa_supplicant *wpa_s,
d41a5352
DS
6390 const struct wpa_ssid_value *ssid,
6391 int lci, int civic,
d89c0701
AK
6392 void (*cb)(void *ctx,
6393 struct wpabuf *neighbor_rep),
6394 void *cb_ctx)
6395{
6396 struct wpabuf *buf;
6397 const u8 *rrm_ie;
6398
6399 if (wpa_s->wpa_state != WPA_COMPLETED || wpa_s->current_ssid == NULL) {
6400 wpa_printf(MSG_DEBUG, "RRM: No connection, no RRM.");
6401 return -ENOTCONN;
6402 }
6403
6404 if (!wpa_s->rrm.rrm_used) {
6405 wpa_printf(MSG_DEBUG, "RRM: No RRM in current connection.");
6406 return -EOPNOTSUPP;
6407 }
6408
6409 rrm_ie = wpa_bss_get_ie(wpa_s->current_bss,
6410 WLAN_EID_RRM_ENABLED_CAPABILITIES);
6411 if (!rrm_ie || !(wpa_s->current_bss->caps & IEEE80211_CAP_RRM) ||
6412 !(rrm_ie[2] & WLAN_RRM_CAPS_NEIGHBOR_REPORT)) {
6413 wpa_printf(MSG_DEBUG,
6414 "RRM: No network support for Neighbor Report.");
6415 return -EOPNOTSUPP;
6416 }
6417
6418 if (!cb) {
6419 wpa_printf(MSG_DEBUG,
6420 "RRM: Neighbor Report request must provide a callback.");
6421 return -EINVAL;
6422 }
6423
6424 /* Refuse if there's a live request */
6425 if (wpa_s->rrm.notify_neighbor_rep) {
6426 wpa_printf(MSG_DEBUG,
6427 "RRM: Currently handling previous Neighbor Report.");
6428 return -EBUSY;
6429 }
6430
4c4b2305 6431 /* 3 = action category + action code + dialog token */
d41a5352
DS
6432 buf = wpabuf_alloc(3 + (ssid ? 2 + ssid->ssid_len : 0) +
6433 (lci ? 2 + MEASURE_REQUEST_LCI_LEN : 0) +
6434 (civic ? 2 + MEASURE_REQUEST_CIVIC_LEN : 0));
d89c0701
AK
6435 if (buf == NULL) {
6436 wpa_printf(MSG_DEBUG,
6437 "RRM: Failed to allocate Neighbor Report Request");
6438 return -ENOMEM;
6439 }
6440
6441 wpa_printf(MSG_DEBUG, "RRM: Neighbor report request (for %s), token=%d",
4c4b2305 6442 (ssid ? wpa_ssid_txt(ssid->ssid, ssid->ssid_len) : ""),
d89c0701
AK
6443 wpa_s->rrm.next_neighbor_rep_token);
6444
6445 wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT);
6446 wpabuf_put_u8(buf, WLAN_RRM_NEIGHBOR_REPORT_REQUEST);
6447 wpabuf_put_u8(buf, wpa_s->rrm.next_neighbor_rep_token);
4c4b2305
AK
6448 if (ssid) {
6449 wpabuf_put_u8(buf, WLAN_EID_SSID);
6450 wpabuf_put_u8(buf, ssid->ssid_len);
6451 wpabuf_put_data(buf, ssid->ssid, ssid->ssid_len);
6452 }
d89c0701 6453
d41a5352
DS
6454 if (lci) {
6455 /* IEEE P802.11-REVmc/D5.0 9.4.2.21 */
6456 wpabuf_put_u8(buf, WLAN_EID_MEASURE_REQUEST);
6457 wpabuf_put_u8(buf, MEASURE_REQUEST_LCI_LEN);
6458
6459 /*
6460 * Measurement token; nonzero number that is unique among the
6461 * Measurement Request elements in a particular frame.
6462 */
6463 wpabuf_put_u8(buf, 1); /* Measurement Token */
6464
6465 /*
6466 * Parallel, Enable, Request, and Report bits are 0, Duration is
6467 * reserved.
6468 */
6469 wpabuf_put_u8(buf, 0); /* Measurement Request Mode */
6470 wpabuf_put_u8(buf, MEASURE_TYPE_LCI); /* Measurement Type */
6471
6472 /* IEEE P802.11-REVmc/D5.0 9.4.2.21.10 - LCI request */
6473 /* Location Subject */
6474 wpabuf_put_u8(buf, LOCATION_SUBJECT_REMOTE);
6475
6476 /* Optional Subelements */
6477 /*
6478 * IEEE P802.11-REVmc/D5.0 Figure 9-170
6479 * The Maximum Age subelement is required, otherwise the AP can
6480 * send only data that was determined after receiving the
6481 * request. Setting it here to unlimited age.
6482 */
6483 wpabuf_put_u8(buf, LCI_REQ_SUBELEM_MAX_AGE);
6484 wpabuf_put_u8(buf, 2);
6485 wpabuf_put_le16(buf, 0xffff);
6486 }
6487
6488 if (civic) {
6489 /* IEEE P802.11-REVmc/D5.0 9.4.2.21 */
6490 wpabuf_put_u8(buf, WLAN_EID_MEASURE_REQUEST);
6491 wpabuf_put_u8(buf, MEASURE_REQUEST_CIVIC_LEN);
6492
6493 /*
6494 * Measurement token; nonzero number that is unique among the
6495 * Measurement Request elements in a particular frame.
6496 */
6497 wpabuf_put_u8(buf, 2); /* Measurement Token */
6498
6499 /*
6500 * Parallel, Enable, Request, and Report bits are 0, Duration is
6501 * reserved.
6502 */
6503 wpabuf_put_u8(buf, 0); /* Measurement Request Mode */
6504 /* Measurement Type */
6505 wpabuf_put_u8(buf, MEASURE_TYPE_LOCATION_CIVIC);
6506
6507 /* IEEE P802.11-REVmc/D5.0 9.4.2.21.14:
6508 * Location Civic request */
6509 /* Location Subject */
6510 wpabuf_put_u8(buf, LOCATION_SUBJECT_REMOTE);
6511 wpabuf_put_u8(buf, 0); /* Civic Location Type: IETF RFC 4776 */
6512 /* Location Service Interval Units: Seconds */
6513 wpabuf_put_u8(buf, 0);
6514 /* Location Service Interval: 0 - Only one report is requested
6515 */
6516 wpabuf_put_le16(buf, 0);
6517 /* No optional subelements */
6518 }
6519
d89c0701
AK
6520 wpa_s->rrm.next_neighbor_rep_token++;
6521
6522 if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
6523 wpa_s->own_addr, wpa_s->bssid,
6524 wpabuf_head(buf), wpabuf_len(buf), 0) < 0) {
6525 wpa_printf(MSG_DEBUG,
6526 "RRM: Failed to send Neighbor Report Request");
6527 wpabuf_free(buf);
6528 return -ECANCELED;
6529 }
6530
6531 wpa_s->rrm.neighbor_rep_cb_ctx = cb_ctx;
6532 wpa_s->rrm.notify_neighbor_rep = cb;
6533 eloop_register_timeout(RRM_NEIGHBOR_REPORT_TIMEOUT, 0,
6534 wpas_rrm_neighbor_rep_timeout_handler,
6535 &wpa_s->rrm, NULL);
6536
6537 wpabuf_free(buf);
6538 return 0;
b361d580 6539}
70d1e728
AO
6540
6541
4a742011
DS
6542static struct wpabuf * wpas_rrm_build_lci_report(struct wpa_supplicant *wpa_s,
6543 const u8 *request, size_t len,
6544 struct wpabuf *report)
6545{
6546 u8 token, type, subject;
6547 u16 max_age = 0;
6548 struct os_reltime t, diff;
6549 unsigned long diff_l;
6550 u8 *ptoken;
6551 const u8 *subelem;
6552
6553 if (!wpa_s->lci || len < 3 + 4)
6554 return report;
6555
6556 token = *request++;
6557 /* Measurement request mode isn't used */
6558 request++;
6559 type = *request++;
6560 subject = *request++;
6561
6562 wpa_printf(MSG_DEBUG,
6563 "Measurement request token %u type %u location subject %u",
6564 token, type, subject);
6565
6566 if (type != MEASURE_TYPE_LCI || subject != LOCATION_SUBJECT_REMOTE) {
6567 wpa_printf(MSG_INFO,
6568 "Not building LCI report - bad type or location subject");
6569 return report;
6570 }
6571
6572 /* Subelements are formatted exactly like elements */
6573 subelem = get_ie(request, len, LCI_REQ_SUBELEM_MAX_AGE);
6574 if (subelem && subelem[1] == 2)
6575 max_age = WPA_GET_LE16(subelem + 2);
6576
6577 if (os_get_reltime(&t))
6578 return report;
6579
6580 os_reltime_sub(&t, &wpa_s->lci_time, &diff);
6581 /* LCI age is calculated in 10th of a second units. */
6582 diff_l = diff.sec * 10 + diff.usec / 100000;
6583
6584 if (max_age != 0xffff && max_age < diff_l)
6585 return report;
6586
6587 if (wpabuf_resize(&report, 2 + wpabuf_len(wpa_s->lci)))
6588 return report;
6589
6590 wpabuf_put_u8(report, WLAN_EID_MEASURE_REPORT);
6591 wpabuf_put_u8(report, wpabuf_len(wpa_s->lci));
6592 /* We'll override user's measurement token */
6593 ptoken = wpabuf_put(report, 0);
6594 wpabuf_put_buf(report, wpa_s->lci);
6595 *ptoken = token;
6596
6597 return report;
6598}
6599
6600
6601void wpas_rrm_handle_radio_measurement_request(struct wpa_supplicant *wpa_s,
6602 const u8 *src,
6603 const u8 *frame, size_t len)
6604{
6605 struct wpabuf *buf, *report;
6606 u8 token;
6607 const u8 *ie, *end;
6608
6609 if (wpa_s->wpa_state != WPA_COMPLETED) {
6610 wpa_printf(MSG_INFO,
6611 "RRM: Ignoring radio measurement request: Not associated");
6612 return;
6613 }
6614
6615 if (!wpa_s->rrm.rrm_used) {
6616 wpa_printf(MSG_INFO,
6617 "RRM: Ignoring radio measurement request: Not RRM network");
6618 return;
6619 }
6620
6621 if (len < 3) {
6622 wpa_printf(MSG_INFO,
6623 "RRM: Ignoring too short radio measurement request");
6624 return;
6625 }
6626
6627 end = frame + len;
6628
6629 token = *frame++;
6630
6631 /* Ignore number of repetitions because it's not used in LCI request */
6632 frame += 2;
6633
6634 report = NULL;
6635 while ((ie = get_ie(frame, end - frame, WLAN_EID_MEASURE_REQUEST)) &&
6636 ie[1] >= 3) {
6637 u8 msmt_type;
6638
6639 msmt_type = ie[4];
6640 wpa_printf(MSG_DEBUG, "RRM request %d", msmt_type);
6641
6642 switch (msmt_type) {
6643 case MEASURE_TYPE_LCI:
6644 report = wpas_rrm_build_lci_report(wpa_s, ie + 2, ie[1],
6645 report);
6646 break;
6647 default:
6648 wpa_printf(MSG_INFO,
6649 "RRM: Unsupported radio measurement request %d",
6650 msmt_type);
6651 break;
6652 }
6653
6654 frame = ie + ie[1] + 2;
6655 }
6656
6657 if (!report)
6658 return;
6659
6660 buf = wpabuf_alloc(3 + wpabuf_len(report));
6661 if (!buf) {
6662 wpabuf_free(report);
6663 return;
6664 }
6665
6666 wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT);
6667 wpabuf_put_u8(buf, WLAN_RRM_RADIO_MEASUREMENT_REPORT);
6668 wpabuf_put_u8(buf, token);
6669
6670 wpabuf_put_buf(buf, report);
6671 wpabuf_free(report);
6672
6673 if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, src,
6674 wpa_s->own_addr, wpa_s->bssid,
6675 wpabuf_head(buf), wpabuf_len(buf), 0)) {
6676 wpa_printf(MSG_ERROR,
6677 "RRM: Radio measurement report failed: Sending Action frame failed");
6678 }
6679 wpabuf_free(buf);
6680}
6681
6682
70d1e728
AO
6683void wpas_rrm_handle_link_measurement_request(struct wpa_supplicant *wpa_s,
6684 const u8 *src,
6685 const u8 *frame, size_t len,
6686 int rssi)
6687{
6688 struct wpabuf *buf;
6689 const struct rrm_link_measurement_request *req;
6690 struct rrm_link_measurement_report report;
6691
6692 if (wpa_s->wpa_state != WPA_COMPLETED) {
6693 wpa_printf(MSG_INFO,
6694 "RRM: Ignoring link measurement request. Not associated");
6695 return;
6696 }
6697
6698 if (!wpa_s->rrm.rrm_used) {
6699 wpa_printf(MSG_INFO,
6700 "RRM: Ignoring link measurement request. Not RRM network");
6701 return;
6702 }
6703
6704 if (!(wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_TX_POWER_INSERTION)) {
6705 wpa_printf(MSG_INFO,
6706 "RRM: Measurement report failed. TX power insertion not supported");
6707 return;
6708 }
6709
6710 req = (const struct rrm_link_measurement_request *) frame;
6711 if (len < sizeof(*req)) {
6712 wpa_printf(MSG_INFO,
6713 "RRM: Link measurement report failed. Request too short");
6714 return;
6715 }
6716
6717 os_memset(&report, 0, sizeof(report));
6718 report.tpc.eid = WLAN_EID_TPC_REPORT;
6719 report.tpc.len = 2;
6720 report.rsni = 255; /* 255 indicates that RSNI is not available */
6721 report.dialog_token = req->dialog_token;
6722
6723 /*
6724 * It's possible to estimate RCPI based on RSSI in dBm. This
6725 * calculation will not reflect the correct value for high rates,
6726 * but it's good enough for Action frames which are transmitted
6727 * with up to 24 Mbps rates.
6728 */
6729 if (!rssi)
6730 report.rcpi = 255; /* not available */
6731 else if (rssi < -110)
6732 report.rcpi = 0;
6733 else if (rssi > 0)
6734 report.rcpi = 220;
6735 else
6736 report.rcpi = (rssi + 110) * 2;
6737
6738 /* action_category + action_code */
6739 buf = wpabuf_alloc(2 + sizeof(report));
6740 if (buf == NULL) {
6741 wpa_printf(MSG_ERROR,
6742 "RRM: Link measurement report failed. Buffer allocation failed");
6743 return;
6744 }
6745
6746 wpabuf_put_u8(buf, WLAN_ACTION_RADIO_MEASUREMENT);
6747 wpabuf_put_u8(buf, WLAN_RRM_LINK_MEASUREMENT_REPORT);
6748 wpabuf_put_data(buf, &report, sizeof(report));
6749 wpa_hexdump(MSG_DEBUG, "RRM: Link measurement report:",
6750 wpabuf_head(buf), wpabuf_len(buf));
6751
6752 if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, src,
6753 wpa_s->own_addr, wpa_s->bssid,
6754 wpabuf_head(buf), wpabuf_len(buf), 0)) {
6755 wpa_printf(MSG_ERROR,
6756 "RRM: Link measurement report failed. Send action failed");
6757 }
6758 wpabuf_free(buf);
6759}
af041f99
AA
6760
6761
6762struct wpa_supplicant *
6763wpas_vendor_elem(struct wpa_supplicant *wpa_s, enum wpa_vendor_elem_frame frame)
6764{
6765 switch (frame) {
6766#ifdef CONFIG_P2P
6767 case VENDOR_ELEM_PROBE_REQ_P2P:
6768 case VENDOR_ELEM_PROBE_RESP_P2P:
6769 case VENDOR_ELEM_PROBE_RESP_P2P_GO:
6770 case VENDOR_ELEM_BEACON_P2P_GO:
6771 case VENDOR_ELEM_P2P_PD_REQ:
6772 case VENDOR_ELEM_P2P_PD_RESP:
6773 case VENDOR_ELEM_P2P_GO_NEG_REQ:
6774 case VENDOR_ELEM_P2P_GO_NEG_RESP:
6775 case VENDOR_ELEM_P2P_GO_NEG_CONF:
6776 case VENDOR_ELEM_P2P_INV_REQ:
6777 case VENDOR_ELEM_P2P_INV_RESP:
6778 case VENDOR_ELEM_P2P_ASSOC_REQ:
6779 case VENDOR_ELEM_P2P_ASSOC_RESP:
ba307f85 6780 return wpa_s->p2pdev;
af041f99
AA
6781#endif /* CONFIG_P2P */
6782 default:
6783 return wpa_s;
6784 }
6785}
6786
6787
6788void wpas_vendor_elem_update(struct wpa_supplicant *wpa_s)
6789{
6790 unsigned int i;
6791 char buf[30];
6792
6793 wpa_printf(MSG_DEBUG, "Update vendor elements");
6794
6795 for (i = 0; i < NUM_VENDOR_ELEM_FRAMES; i++) {
6796 if (wpa_s->vendor_elem[i]) {
6797 int res;
6798
6799 res = os_snprintf(buf, sizeof(buf), "frame[%u]", i);
6800 if (!os_snprintf_error(sizeof(buf), res)) {
6801 wpa_hexdump_buf(MSG_DEBUG, buf,
6802 wpa_s->vendor_elem[i]);
6803 }
6804 }
6805 }
6806
6807#ifdef CONFIG_P2P
6808 if (wpa_s->parent == wpa_s &&
6809 wpa_s->global->p2p &&
6810 !wpa_s->global->p2p_disabled)
6811 p2p_set_vendor_elems(wpa_s->global->p2p, wpa_s->vendor_elem);
6812#endif /* CONFIG_P2P */
6813}
6814
6815
6816int wpas_vendor_elem_remove(struct wpa_supplicant *wpa_s, int frame,
6817 const u8 *elem, size_t len)
6818{
6819 u8 *ie, *end;
6820
6821 ie = wpabuf_mhead_u8(wpa_s->vendor_elem[frame]);
6822 end = ie + wpabuf_len(wpa_s->vendor_elem[frame]);
6823
6824 for (; ie + 1 < end; ie += 2 + ie[1]) {
6825 if (ie + len > end)
6826 break;
6827 if (os_memcmp(ie, elem, len) != 0)
6828 continue;
6829
6830 if (wpabuf_len(wpa_s->vendor_elem[frame]) == len) {
6831 wpabuf_free(wpa_s->vendor_elem[frame]);
6832 wpa_s->vendor_elem[frame] = NULL;
6833 } else {
6834 os_memmove(ie, ie + len, end - (ie + len));
6835 wpa_s->vendor_elem[frame]->used -= len;
6836 }
6837 wpas_vendor_elem_update(wpa_s);
6838 return 0;
6839 }
6840
6841 return -1;
6842}
ea69d973
AS
6843
6844
6845struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes,
6846 u16 num_modes, enum hostapd_hw_mode mode)
6847{
6848 u16 i;
6849
6850 for (i = 0; i < num_modes; i++) {
6851 if (modes[i].mode == mode)
6852 return &modes[i];
6853 }
6854
6855 return NULL;
6856}
dd599908
AS
6857
6858
6859static struct
6860wpa_bss_tmp_disallowed * wpas_get_disallowed_bss(struct wpa_supplicant *wpa_s,
6861 const u8 *bssid)
6862{
6863 struct wpa_bss_tmp_disallowed *bss;
6864
6865 dl_list_for_each(bss, &wpa_s->bss_tmp_disallowed,
6866 struct wpa_bss_tmp_disallowed, list) {
6867 if (os_memcmp(bssid, bss->bssid, ETH_ALEN) == 0)
6868 return bss;
6869 }
6870
6871 return NULL;
6872}
6873
6874
6875void wpa_bss_tmp_disallow(struct wpa_supplicant *wpa_s, const u8 *bssid,
6876 unsigned int sec)
6877{
6878 struct wpa_bss_tmp_disallowed *bss;
6879 struct os_reltime until;
6880
6881 os_get_reltime(&until);
6882 until.sec += sec;
6883
6884 bss = wpas_get_disallowed_bss(wpa_s, bssid);
6885 if (bss) {
6886 bss->disallowed_until = until;
6887 return;
6888 }
6889
6890 bss = os_malloc(sizeof(*bss));
6891 if (!bss) {
6892 wpa_printf(MSG_DEBUG,
6893 "Failed to allocate memory for temp disallow BSS");
6894 return;
6895 }
6896
6897 bss->disallowed_until = until;
6898 os_memcpy(bss->bssid, bssid, ETH_ALEN);
6899 dl_list_add(&wpa_s->bss_tmp_disallowed, &bss->list);
6900}
6901
6902
6903int wpa_is_bss_tmp_disallowed(struct wpa_supplicant *wpa_s, const u8 *bssid)
6904{
d010048c 6905 struct wpa_bss_tmp_disallowed *bss = NULL, *tmp, *prev;
dd599908
AS
6906 struct os_reltime now, age;
6907
6908 os_get_reltime(&now);
6909
d010048c
JM
6910 dl_list_for_each_safe(tmp, prev, &wpa_s->bss_tmp_disallowed,
6911 struct wpa_bss_tmp_disallowed, list) {
6912 if (!os_reltime_before(&now, &tmp->disallowed_until)) {
6913 /* This BSS is not disallowed anymore */
6914 dl_list_del(&tmp->list);
6915 os_free(tmp);
6916 continue;
6917 }
6918 if (os_memcmp(bssid, tmp->bssid, ETH_ALEN) == 0) {
6919 bss = tmp;
6920 break;
6921 }
6922 }
dd599908
AS
6923 if (!bss)
6924 return 0;
6925
d010048c
JM
6926 os_reltime_sub(&bss->disallowed_until, &now, &age);
6927 wpa_printf(MSG_DEBUG,
6928 "BSS " MACSTR " disabled for %ld.%0ld seconds",
6929 MAC2STR(bss->bssid), age.sec, age.usec);
6930 return 1;
dd599908 6931}