]> git.ipfire.org Git - thirdparty/hostap.git/blame - wpa_supplicant/wpa_supplicant.c
tests: Fix wpas_ctrl_country to match the fixed event data
[thirdparty/hostap.git] / wpa_supplicant / wpa_supplicant.c
CommitLineData
6fc6879b
JM
1/*
2 * WPA Supplicant
b1ae396f 3 * Copyright (c) 2003-2014, 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"
14
15#include "common.h"
d47fa330 16#include "crypto/random.h"
7d232e23 17#include "crypto/sha1.h"
6fc6879b
JM
18#include "eapol_supp/eapol_supp_sm.h"
19#include "eap_peer/eap.h"
ec7b97ab 20#include "eap_peer/eap_proxy.h"
3ec97afe 21#include "eap_server/eap_methods.h"
3acb5005 22#include "rsn_supp/wpa.h"
6fc6879b 23#include "eloop.h"
6fc6879b 24#include "config.h"
306ae225 25#include "utils/ext_password.h"
6fc6879b
JM
26#include "l2_packet/l2_packet.h"
27#include "wpa_supplicant_i.h"
2d5b792d 28#include "driver_i.h"
6fc6879b 29#include "ctrl_iface.h"
6fc6879b 30#include "pcsc_funcs.h"
90973fb2 31#include "common/version.h"
3acb5005
JM
32#include "rsn_supp/preauth.h"
33#include "rsn_supp/pmksa_cache.h"
90973fb2 34#include "common/wpa_ctrl.h"
90973fb2 35#include "common/ieee802_11_defs.h"
72044390 36#include "p2p/p2p.h"
6fc6879b
JM
37#include "blacklist.h"
38#include "wpas_glue.h"
116654ce 39#include "wps_supplicant.h"
11ef8d35 40#include "ibss_rsn.h"
c2a04078 41#include "sme.h"
04ea7b79 42#include "gas_query.h"
1f1b62a0 43#include "ap.h"
b22128ef 44#include "p2p_supplicant.h"
9675ce35 45#include "wifi_display.h"
8bac466b 46#include "notify.h"
60b94c98 47#include "bgscan.h"
7c865c68 48#include "autoscan.h"
83922c2d 49#include "bss.h"
9ba9fa07 50#include "scan.h"
24f6497c 51#include "offchannel.h"
cb418324 52#include "hs20_supplicant.h"
e27d20bb 53#include "wnm_sta.h"
dd10abcc 54#include "wpas_kay.h"
6fc6879b
JM
55
56const char *wpa_supplicant_version =
57"wpa_supplicant v" VERSION_STR "\n"
b1ae396f 58"Copyright (c) 2003-2014, Jouni Malinen <j@w1.fi> and contributors";
6fc6879b
JM
59
60const char *wpa_supplicant_license =
331f89ff
JM
61"This software may be distributed under the terms of the BSD license.\n"
62"See README for more details.\n"
6fc6879b
JM
63#ifdef EAP_TLS_OPENSSL
64"\nThis product includes software developed by the OpenSSL Project\n"
65"for use in the OpenSSL Toolkit (http://www.openssl.org/)\n"
66#endif /* EAP_TLS_OPENSSL */
67;
68
69#ifndef CONFIG_NO_STDOUT_DEBUG
70/* Long text divided into parts in order to fit in C89 strings size limits. */
71const char *wpa_supplicant_full_license1 =
331f89ff 72"";
6fc6879b 73const char *wpa_supplicant_full_license2 =
331f89ff 74"This software may be distributed under the terms of the BSD license.\n"
6fc6879b
JM
75"\n"
76"Redistribution and use in source and binary forms, with or without\n"
77"modification, are permitted provided that the following conditions are\n"
78"met:\n"
79"\n";
80const char *wpa_supplicant_full_license3 =
81"1. Redistributions of source code must retain the above copyright\n"
82" notice, this list of conditions and the following disclaimer.\n"
83"\n"
84"2. Redistributions in binary form must reproduce the above copyright\n"
85" notice, this list of conditions and the following disclaimer in the\n"
86" documentation and/or other materials provided with the distribution.\n"
87"\n";
88const char *wpa_supplicant_full_license4 =
89"3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
90" names of its contributors may be used to endorse or promote products\n"
91" derived from this software without specific prior written permission.\n"
92"\n"
93"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
94"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
95"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
96"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n";
97const char *wpa_supplicant_full_license5 =
98"OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
99"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
100"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
101"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n"
102"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
103"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n"
104"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
105"\n";
106#endif /* CONFIG_NO_STDOUT_DEBUG */
107
6fc6879b 108/* Configure default/group WEP keys for static WEP */
0194fedb 109int wpa_set_wep_keys(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
6fc6879b
JM
110{
111 int i, set = 0;
112
113 for (i = 0; i < NUM_WEP_KEYS; i++) {
114 if (ssid->wep_key_len[i] == 0)
115 continue;
116
117 set = 1;
0382097e 118 wpa_drv_set_key(wpa_s, WPA_ALG_WEP, NULL,
da64c266 119 i, i == ssid->wep_tx_keyidx, NULL, 0,
6fc6879b
JM
120 ssid->wep_key[i], ssid->wep_key_len[i]);
121 }
122
123 return set;
124}
125
126
6ea1f413
JM
127int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s,
128 struct wpa_ssid *ssid)
6fc6879b
JM
129{
130 u8 key[32];
131 size_t keylen;
71934751 132 enum wpa_alg alg;
6fc6879b
JM
133 u8 seq[6] = { 0 };
134
135 /* IBSS/WPA-None uses only one key (Group) for both receiving and
136 * sending unicast and multicast packets. */
137
d7dcba70 138 if (ssid->mode != WPAS_MODE_IBSS) {
f049052b
BG
139 wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid mode %d (not "
140 "IBSS/ad-hoc) for WPA-None", ssid->mode);
6fc6879b
JM
141 return -1;
142 }
143
144 if (!ssid->psk_set) {
f049052b
BG
145 wpa_msg(wpa_s, MSG_INFO, "WPA: No PSK configured for "
146 "WPA-None");
6fc6879b
JM
147 return -1;
148 }
149
150 switch (wpa_s->group_cipher) {
151 case WPA_CIPHER_CCMP:
152 os_memcpy(key, ssid->psk, 16);
153 keylen = 16;
154 alg = WPA_ALG_CCMP;
155 break;
eb7719ff
JM
156 case WPA_CIPHER_GCMP:
157 os_memcpy(key, ssid->psk, 16);
158 keylen = 16;
159 alg = WPA_ALG_GCMP;
160 break;
6fc6879b
JM
161 case WPA_CIPHER_TKIP:
162 /* WPA-None uses the same Michael MIC key for both TX and RX */
163 os_memcpy(key, ssid->psk, 16 + 8);
164 os_memcpy(key + 16 + 8, ssid->psk + 16, 8);
165 keylen = 32;
166 alg = WPA_ALG_TKIP;
167 break;
168 default:
f049052b
BG
169 wpa_msg(wpa_s, MSG_INFO, "WPA: Invalid group cipher %d for "
170 "WPA-None", wpa_s->group_cipher);
6fc6879b
JM
171 return -1;
172 }
173
174 /* TODO: should actually remember the previously used seq#, both for TX
175 * and RX from each STA.. */
176
0382097e 177 return wpa_drv_set_key(wpa_s, alg, NULL, 0, 1, seq, 6, key, keylen);
6fc6879b
JM
178}
179
180
181static void wpa_supplicant_timeout(void *eloop_ctx, void *timeout_ctx)
182{
183 struct wpa_supplicant *wpa_s = eloop_ctx;
184 const u8 *bssid = wpa_s->bssid;
a8e16edc 185 if (is_zero_ether_addr(bssid))
6fc6879b
JM
186 bssid = wpa_s->pending_bssid;
187 wpa_msg(wpa_s, MSG_INFO, "Authentication with " MACSTR " timed out.",
188 MAC2STR(bssid));
189 wpa_blacklist_add(wpa_s, bssid);
190 wpa_sm_notify_disassoc(wpa_s->wpa);
07783eaa 191 wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
6fc6879b 192 wpa_s->reassociate = 1;
48b84f18
BG
193
194 /*
195 * If we timed out, the AP or the local radio may be busy.
196 * So, wait a second until scanning again.
197 */
198 wpa_supplicant_req_scan(wpa_s, 1, 0);
6fc6879b
JM
199}
200
201
202/**
203 * wpa_supplicant_req_auth_timeout - Schedule a timeout for authentication
204 * @wpa_s: Pointer to wpa_supplicant data
205 * @sec: Number of seconds after which to time out authentication
206 * @usec: Number of microseconds after which to time out authentication
207 *
208 * This function is used to schedule a timeout for the current authentication
209 * attempt.
210 */
211void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s,
212 int sec, int usec)
213{
a2a535f8 214 if (wpa_s->conf->ap_scan == 0 &&
c2a04078 215 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED))
6fc6879b
JM
216 return;
217
f049052b 218 wpa_dbg(wpa_s, MSG_DEBUG, "Setting authentication timeout: %d sec "
6fc6879b
JM
219 "%d usec", sec, usec);
220 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
221 eloop_register_timeout(sec, usec, wpa_supplicant_timeout, wpa_s, NULL);
222}
223
224
225/**
226 * wpa_supplicant_cancel_auth_timeout - Cancel authentication timeout
227 * @wpa_s: Pointer to wpa_supplicant data
228 *
229 * This function is used to cancel authentication timeout scheduled with
230 * wpa_supplicant_req_auth_timeout() and it is called when authentication has
231 * been completed.
232 */
233void wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *wpa_s)
234{
f049052b 235 wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling authentication timeout");
6fc6879b
JM
236 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
237 wpa_blacklist_del(wpa_s, wpa_s->bssid);
238}
239
240
241/**
242 * wpa_supplicant_initiate_eapol - Configure EAPOL state machine
243 * @wpa_s: Pointer to wpa_supplicant data
244 *
245 * This function is used to configure EAPOL state machine based on the selected
246 * authentication mode.
247 */
248void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
249{
250#ifdef IEEE8021X_EAPOL
251 struct eapol_config eapol_conf;
252 struct wpa_ssid *ssid = wpa_s->current_ssid;
253
53895c3b 254#ifdef CONFIG_IBSS_RSN
d7dcba70 255 if (ssid->mode == WPAS_MODE_IBSS &&
53895c3b
JM
256 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
257 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
258 /*
259 * RSN IBSS authentication is per-STA and we can disable the
260 * per-BSSID EAPOL authentication.
261 */
262 eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
263 eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
264 eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
265 return;
266 }
267#endif /* CONFIG_IBSS_RSN */
268
0a40ec6a
JM
269 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
270 eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
271
6fc6879b
JM
272 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
273 wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
274 eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
275 else
276 eapol_sm_notify_portControl(wpa_s->eapol, Auto);
277
278 os_memset(&eapol_conf, 0, sizeof(eapol_conf));
279 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
280 eapol_conf.accept_802_1x_keys = 1;
281 eapol_conf.required_keys = 0;
282 if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_UNICAST) {
283 eapol_conf.required_keys |= EAPOL_REQUIRE_KEY_UNICAST;
284 }
285 if (ssid->eapol_flags & EAPOL_FLAG_REQUIRE_KEY_BROADCAST) {
286 eapol_conf.required_keys |=
287 EAPOL_REQUIRE_KEY_BROADCAST;
288 }
289
a2a535f8 290 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED)
6fc6879b 291 eapol_conf.required_keys = 0;
6fc6879b 292 }
a2a535f8 293 eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
6fc6879b 294 eapol_conf.workaround = ssid->eap_workaround;
56586197
JM
295 eapol_conf.eap_disabled =
296 !wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) &&
ad08c363
JM
297 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
298 wpa_s->key_mgmt != WPA_KEY_MGMT_WPS;
a5d44ac0 299 eapol_conf.external_sim = wpa_s->conf->external_sim;
6fc6879b
JM
300 eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
301#endif /* IEEE8021X_EAPOL */
dd10abcc
HW
302
303 ieee802_1x_alloc_kay_sm(wpa_s, ssid);
6fc6879b
JM
304}
305
306
307/**
308 * wpa_supplicant_set_non_wpa_policy - Set WPA parameters to non-WPA mode
309 * @wpa_s: Pointer to wpa_supplicant data
310 * @ssid: Configuration data for the network
311 *
312 * This function is used to configure WPA state machine and related parameters
313 * to a mode where WPA is not enabled. This is called as part of the
314 * authentication configuration when the selected network does not use WPA.
315 */
316void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
317 struct wpa_ssid *ssid)
318{
319 int i;
320
ad08c363
JM
321 if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
322 wpa_s->key_mgmt = WPA_KEY_MGMT_WPS;
323 else if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)
6fc6879b
JM
324 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_NO_WPA;
325 else
326 wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
327 wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
328 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
329 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
330 wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
331 wpa_s->group_cipher = WPA_CIPHER_NONE;
332 wpa_s->mgmt_group_cipher = 0;
333
334 for (i = 0; i < NUM_WEP_KEYS; i++) {
335 if (ssid->wep_key_len[i] > 5) {
336 wpa_s->pairwise_cipher = WPA_CIPHER_WEP104;
337 wpa_s->group_cipher = WPA_CIPHER_WEP104;
338 break;
339 } else if (ssid->wep_key_len[i] > 0) {
340 wpa_s->pairwise_cipher = WPA_CIPHER_WEP40;
341 wpa_s->group_cipher = WPA_CIPHER_WEP40;
342 break;
343 }
344 }
345
346 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED, 0);
347 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
348 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
349 wpa_s->pairwise_cipher);
350 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
351#ifdef CONFIG_IEEE80211W
352 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
353 wpa_s->mgmt_group_cipher);
354#endif /* CONFIG_IEEE80211W */
355
356 pmksa_cache_clear_current(wpa_s->wpa);
357}
358
359
6979582c 360void free_hw_features(struct wpa_supplicant *wpa_s)
6bf731e8
CL
361{
362 int i;
363 if (wpa_s->hw.modes == NULL)
364 return;
365
366 for (i = 0; i < wpa_s->hw.num_modes; i++) {
367 os_free(wpa_s->hw.modes[i].channels);
368 os_free(wpa_s->hw.modes[i].rates);
369 }
370
371 os_free(wpa_s->hw.modes);
372 wpa_s->hw.modes = NULL;
373}
374
375
6fc6879b
JM
376static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
377{
60b94c98 378 bgscan_deinit(wpa_s);
7c865c68 379 autoscan_deinit(wpa_s);
6fc6879b
JM
380 scard_deinit(wpa_s->scard);
381 wpa_s->scard = NULL;
382 wpa_sm_set_scard_ctx(wpa_s->wpa, NULL);
383 eapol_sm_register_scard_ctx(wpa_s->eapol, NULL);
384 l2_packet_deinit(wpa_s->l2);
385 wpa_s->l2 = NULL;
386 if (wpa_s->l2_br) {
387 l2_packet_deinit(wpa_s->l2_br);
388 wpa_s->l2_br = NULL;
389 }
390
6fc6879b 391 if (wpa_s->conf != NULL) {
8e56d189
JM
392 struct wpa_ssid *ssid;
393 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
394 wpas_notify_network_removed(wpa_s, ssid);
6fc6879b
JM
395 }
396
397 os_free(wpa_s->confname);
398 wpa_s->confname = NULL;
399
e6304cad
DS
400 os_free(wpa_s->confanother);
401 wpa_s->confanother = NULL;
402
c16a7590
IP
403#ifdef CONFIG_P2P
404 os_free(wpa_s->conf_p2p_dev);
405 wpa_s->conf_p2p_dev = NULL;
406#endif /* CONFIG_P2P */
407
6fc6879b
JM
408 wpa_sm_set_eapol(wpa_s->wpa, NULL);
409 eapol_sm_deinit(wpa_s->eapol);
410 wpa_s->eapol = NULL;
411
412 rsn_preauth_deinit(wpa_s->wpa);
413
281ff0aa
GP
414#ifdef CONFIG_TDLS
415 wpa_tdls_deinit(wpa_s->wpa);
416#endif /* CONFIG_TDLS */
417
6fc6879b
JM
418 pmksa_candidate_free(wpa_s->wpa);
419 wpa_sm_deinit(wpa_s->wpa);
420 wpa_s->wpa = NULL;
421 wpa_blacklist_clear(wpa_s);
422
83922c2d 423 wpa_bss_deinit(wpa_s);
6fc6879b 424
831770bf 425 wpa_supplicant_cancel_delayed_sched_scan(wpa_s);
6fc6879b
JM
426 wpa_supplicant_cancel_scan(wpa_s);
427 wpa_supplicant_cancel_auth_timeout(wpa_s);
01a17491
JM
428 eloop_cancel_timeout(wpa_supplicant_stop_countermeasures, wpa_s, NULL);
429#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
430 eloop_cancel_timeout(wpa_supplicant_delayed_mic_error_report,
431 wpa_s, NULL);
432#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
6fc6879b 433
116654ce 434 wpas_wps_deinit(wpa_s);
11ef8d35 435
1ff73338
JM
436 wpabuf_free(wpa_s->pending_eapol_rx);
437 wpa_s->pending_eapol_rx = NULL;
438
11ef8d35
JM
439#ifdef CONFIG_IBSS_RSN
440 ibss_rsn_deinit(wpa_s->ibss_rsn);
441 wpa_s->ibss_rsn = NULL;
442#endif /* CONFIG_IBSS_RSN */
c2a04078 443
e29853bb 444 sme_deinit(wpa_s);
2d5b792d
JM
445
446#ifdef CONFIG_AP
447 wpa_supplicant_ap_deinit(wpa_s);
448#endif /* CONFIG_AP */
b22128ef 449
b22128ef 450 wpas_p2p_deinit(wpa_s);
f47d639d 451
24f6497c
JM
452#ifdef CONFIG_OFFCHANNEL
453 offchannel_deinit(wpa_s);
454#endif /* CONFIG_OFFCHANNEL */
455
a4cba8f1
LC
456 wpa_supplicant_cancel_sched_scan(wpa_s);
457
f47d639d
JM
458 os_free(wpa_s->next_scan_freqs);
459 wpa_s->next_scan_freqs = NULL;
fee52342
JM
460
461 os_free(wpa_s->manual_scan_freqs);
462 wpa_s->manual_scan_freqs = NULL;
04ea7b79 463
d3c9c35f
DS
464 os_free(wpa_s->manual_sched_scan_freqs);
465 wpa_s->manual_sched_scan_freqs = NULL;
466
04ea7b79
JM
467 gas_query_deinit(wpa_s->gas);
468 wpa_s->gas = NULL;
6bf731e8
CL
469
470 free_hw_features(wpa_s);
d445a5cd 471
dd10abcc
HW
472 ieee802_1x_dealloc_kay_sm(wpa_s);
473
d445a5cd
JM
474 os_free(wpa_s->bssid_filter);
475 wpa_s->bssid_filter = NULL;
b6668734 476
6407f413
JM
477 os_free(wpa_s->disallow_aps_bssid);
478 wpa_s->disallow_aps_bssid = NULL;
479 os_free(wpa_s->disallow_aps_ssid);
480 wpa_s->disallow_aps_ssid = NULL;
481
b6668734 482 wnm_bss_keep_alive_deinit(wpa_s);
e27d20bb
VK
483#ifdef CONFIG_WNM
484 wnm_deallocate_memory(wpa_s);
485#endif /* CONFIG_WNM */
306ae225
JM
486
487 ext_password_deinit(wpa_s->ext_pw);
488 wpa_s->ext_pw = NULL;
b1f12296
JM
489
490 wpabuf_free(wpa_s->last_gas_resp);
b6a9590b
JM
491 wpa_s->last_gas_resp = NULL;
492 wpabuf_free(wpa_s->prev_gas_resp);
493 wpa_s->prev_gas_resp = NULL;
a297201d
JM
494
495 os_free(wpa_s->last_scan_res);
496 wpa_s->last_scan_res = NULL;
b572df86
JM
497
498#ifdef CONFIG_HS20
fb2ac53d 499 hs20_deinit(wpa_s);
b572df86 500#endif /* CONFIG_HS20 */
6fc6879b
JM
501}
502
503
504/**
505 * wpa_clear_keys - Clear keys configured for the driver
506 * @wpa_s: Pointer to wpa_supplicant data
507 * @addr: Previously used BSSID or %NULL if not available
508 *
509 * This function clears the encryption keys that has been previously configured
510 * for the driver.
511 */
512void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr)
513{
2f30cac3 514 int i, max;
6fc6879b 515
0e27f655 516#ifdef CONFIG_IEEE80211W
2f30cac3
JM
517 max = 6;
518#else /* CONFIG_IEEE80211W */
519 max = 4;
0e27f655 520#endif /* CONFIG_IEEE80211W */
2f30cac3
JM
521
522 /* MLME-DELETEKEYS.request */
523 for (i = 0; i < max; i++) {
524 if (wpa_s->keys_cleared & BIT(i))
525 continue;
526 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, NULL, i, 0, NULL, 0,
527 NULL, 0);
528 }
529 if (!(wpa_s->keys_cleared & BIT(0)) && addr &&
530 !is_zero_ether_addr(addr)) {
6fc6879b
JM
531 wpa_drv_set_key(wpa_s, WPA_ALG_NONE, addr, 0, 0, NULL, 0, NULL,
532 0);
533 /* MLME-SETPROTECTION.request(None) */
534 wpa_drv_mlme_setprotection(
535 wpa_s, addr,
536 MLME_SETPROTECTION_PROTECT_TYPE_NONE,
537 MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
538 }
2f30cac3 539 wpa_s->keys_cleared = (u32) -1;
6fc6879b
JM
540}
541
542
543/**
544 * wpa_supplicant_state_txt - Get the connection state name as a text string
545 * @state: State (wpa_state; WPA_*)
546 * Returns: The state name as a printable text string
547 */
71934751 548const char * wpa_supplicant_state_txt(enum wpa_states state)
6fc6879b
JM
549{
550 switch (state) {
551 case WPA_DISCONNECTED:
552 return "DISCONNECTED";
553 case WPA_INACTIVE:
554 return "INACTIVE";
8401a6b0
JM
555 case WPA_INTERFACE_DISABLED:
556 return "INTERFACE_DISABLED";
6fc6879b
JM
557 case WPA_SCANNING:
558 return "SCANNING";
c2a04078
JM
559 case WPA_AUTHENTICATING:
560 return "AUTHENTICATING";
6fc6879b
JM
561 case WPA_ASSOCIATING:
562 return "ASSOCIATING";
563 case WPA_ASSOCIATED:
564 return "ASSOCIATED";
565 case WPA_4WAY_HANDSHAKE:
566 return "4WAY_HANDSHAKE";
567 case WPA_GROUP_HANDSHAKE:
568 return "GROUP_HANDSHAKE";
569 case WPA_COMPLETED:
570 return "COMPLETED";
571 default:
572 return "UNKNOWN";
573 }
574}
575
576
cfe53c9a
PS
577#ifdef CONFIG_BGSCAN
578
579static void wpa_supplicant_start_bgscan(struct wpa_supplicant *wpa_s)
580{
31392709
HD
581 const char *name;
582
583 if (wpa_s->current_ssid && wpa_s->current_ssid->bgscan)
584 name = wpa_s->current_ssid->bgscan;
585 else
586 name = wpa_s->conf->bgscan;
268043d5 587 if (name == NULL || name[0] == '\0')
31392709 588 return;
0096c427
JM
589 if (wpas_driver_bss_selection(wpa_s))
590 return;
cfe53c9a
PS
591 if (wpa_s->current_ssid == wpa_s->bgscan_ssid)
592 return;
aa109830
DS
593#ifdef CONFIG_P2P
594 if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE)
595 return;
596#endif /* CONFIG_P2P */
cfe53c9a
PS
597
598 bgscan_deinit(wpa_s);
31392709
HD
599 if (wpa_s->current_ssid) {
600 if (bgscan_init(wpa_s, wpa_s->current_ssid, name)) {
cfe53c9a
PS
601 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
602 "bgscan");
603 /*
604 * Live without bgscan; it is only used as a roaming
605 * optimization, so the initial connection is not
606 * affected.
607 */
6409b7a7
YD
608 } else {
609 struct wpa_scan_results *scan_res;
cfe53c9a 610 wpa_s->bgscan_ssid = wpa_s->current_ssid;
6409b7a7
YD
611 scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL,
612 0);
613 if (scan_res) {
614 bgscan_notify_scan(wpa_s, scan_res);
615 wpa_scan_results_free(scan_res);
616 }
617 }
cfe53c9a
PS
618 } else
619 wpa_s->bgscan_ssid = NULL;
620}
621
622
623static void wpa_supplicant_stop_bgscan(struct wpa_supplicant *wpa_s)
624{
625 if (wpa_s->bgscan_ssid != NULL) {
626 bgscan_deinit(wpa_s);
627 wpa_s->bgscan_ssid = NULL;
628 }
629}
630
631#endif /* CONFIG_BGSCAN */
632
633
7c865c68
TB
634static void wpa_supplicant_start_autoscan(struct wpa_supplicant *wpa_s)
635{
99218999 636 if (autoscan_init(wpa_s, 0))
7c865c68
TB
637 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize autoscan");
638}
639
640
641static void wpa_supplicant_stop_autoscan(struct wpa_supplicant *wpa_s)
642{
643 autoscan_deinit(wpa_s);
644}
645
646
c3d12238
JM
647void wpa_supplicant_reinit_autoscan(struct wpa_supplicant *wpa_s)
648{
649 if (wpa_s->wpa_state == WPA_DISCONNECTED ||
650 wpa_s->wpa_state == WPA_SCANNING) {
651 autoscan_deinit(wpa_s);
652 wpa_supplicant_start_autoscan(wpa_s);
653 }
654}
655
656
6fc6879b
JM
657/**
658 * wpa_supplicant_set_state - Set current connection state
659 * @wpa_s: Pointer to wpa_supplicant data
660 * @state: The new connection state
661 *
662 * This function is called whenever the connection state changes, e.g.,
663 * association is completed for WPA/WPA2 4-Way Handshake is started.
664 */
71934751
JM
665void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
666 enum wpa_states state)
6fc6879b 667{
27f43d8d
MH
668 enum wpa_states old_state = wpa_s->wpa_state;
669
f049052b
BG
670 wpa_dbg(wpa_s, MSG_DEBUG, "State: %s -> %s",
671 wpa_supplicant_state_txt(wpa_s->wpa_state),
672 wpa_supplicant_state_txt(state));
6fc6879b 673
5ddd07cb
AS
674 if (state == WPA_INTERFACE_DISABLED) {
675 /* Assure normal scan when interface is restored */
676 wpa_s->normal_scans = 0;
677 }
678
0cf24fda 679 if (state == WPA_COMPLETED) {
6ac4b15e 680 wpas_connect_work_done(wpa_s);
0cf24fda
LC
681 /* Reinitialize normal_scan counter */
682 wpa_s->normal_scans = 0;
683 }
6ac4b15e 684
cb8564b1
DW
685 if (state != WPA_SCANNING)
686 wpa_supplicant_notify_scanning(wpa_s, 0);
687
6fc6879b 688 if (state == WPA_COMPLETED && wpa_s->new_connection) {
6fc6879b 689 struct wpa_ssid *ssid = wpa_s->current_ssid;
7d37a357 690#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
6fc6879b 691 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- Connection to "
1cfc6787
JM
692 MACSTR " completed [id=%d id_str=%s]",
693 MAC2STR(wpa_s->bssid),
6fc6879b
JM
694 ssid ? ssid->id : -1,
695 ssid && ssid->id_str ? ssid->id_str : "");
696#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
00e5e3d5 697 wpas_clear_temp_disabled(wpa_s, ssid, 1);
f1a52633 698 wpa_s->extra_blacklist_count = 0;
6fc6879b 699 wpa_s->new_connection = 0;
6fc6879b 700 wpa_drv_set_operstate(wpa_s, 1);
99ac2913
FF
701#ifndef IEEE8021X_EAPOL
702 wpa_drv_set_supp_port(wpa_s, 1);
703#endif /* IEEE8021X_EAPOL */
17a4734d 704 wpa_s->after_wps = 0;
4d9fb08d 705 wpa_s->known_wps_freq = 0;
b22128ef 706 wpas_p2p_completed(wpa_s);
c3701c66
RM
707
708 sme_sched_obss_scan(wpa_s, 1);
6fc6879b
JM
709 } else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING ||
710 state == WPA_ASSOCIATED) {
711 wpa_s->new_connection = 1;
712 wpa_drv_set_operstate(wpa_s, 0);
99ac2913
FF
713#ifndef IEEE8021X_EAPOL
714 wpa_drv_set_supp_port(wpa_s, 0);
715#endif /* IEEE8021X_EAPOL */
c3701c66 716 sme_sched_obss_scan(wpa_s, 0);
6fc6879b
JM
717 }
718 wpa_s->wpa_state = state;
27f43d8d 719
cfe53c9a
PS
720#ifdef CONFIG_BGSCAN
721 if (state == WPA_COMPLETED)
722 wpa_supplicant_start_bgscan(wpa_s);
37271232 723 else if (state < WPA_ASSOCIATED)
cfe53c9a
PS
724 wpa_supplicant_stop_bgscan(wpa_s);
725#endif /* CONFIG_BGSCAN */
726
7c865c68
TB
727 if (state == WPA_AUTHENTICATING)
728 wpa_supplicant_stop_autoscan(wpa_s);
729
730 if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
731 wpa_supplicant_start_autoscan(wpa_s);
732
5bbf9f10 733 if (wpa_s->wpa_state != old_state) {
27f43d8d 734 wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
5bbf9f10 735
e3bd6e9d
IP
736 /*
737 * Notify the P2P Device interface about a state change in one
738 * of the interfaces.
739 */
740 wpas_p2p_indicate_state_change(wpa_s);
e3bd6e9d 741
5bbf9f10
PS
742 if (wpa_s->wpa_state == WPA_COMPLETED ||
743 old_state == WPA_COMPLETED)
744 wpas_notify_auth_changed(wpa_s);
745 }
6fc6879b
JM
746}
747
748
1a1bf008
JM
749void wpa_supplicant_terminate_proc(struct wpa_global *global)
750{
751 int pending = 0;
752#ifdef CONFIG_WPS
753 struct wpa_supplicant *wpa_s = global->ifaces;
754 while (wpa_s) {
ab41595f 755 struct wpa_supplicant *next = wpa_s->next;
5516ed32
EA
756 if (wpas_wps_terminate_pending(wpa_s) == 1)
757 pending = 1;
20625e97
JM
758#ifdef CONFIG_P2P
759 if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE ||
760 (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group))
761 wpas_p2p_disconnect(wpa_s);
762#endif /* CONFIG_P2P */
ab41595f 763 wpa_s = next;
1a1bf008
JM
764 }
765#endif /* CONFIG_WPS */
766 if (pending)
767 return;
768 eloop_terminate();
769}
770
771
0456ea16 772static void wpa_supplicant_terminate(int sig, void *signal_ctx)
6fc6879b 773{
0456ea16 774 struct wpa_global *global = signal_ctx;
1a1bf008 775 wpa_supplicant_terminate_proc(global);
6fc6879b
JM
776}
777
778
b22128ef 779void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s)
6fc6879b 780{
71934751 781 enum wpa_states old_state = wpa_s->wpa_state;
27f43d8d 782
6fc6879b
JM
783 wpa_s->pairwise_cipher = 0;
784 wpa_s->group_cipher = 0;
785 wpa_s->mgmt_group_cipher = 0;
786 wpa_s->key_mgmt = 0;
8401a6b0 787 if (wpa_s->wpa_state != WPA_INTERFACE_DISABLED)
99218999 788 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
27f43d8d
MH
789
790 if (wpa_s->wpa_state != old_state)
791 wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);
6fc6879b
JM
792}
793
794
795/**
796 * wpa_supplicant_reload_configuration - Reload configuration data
797 * @wpa_s: Pointer to wpa_supplicant data
798 * Returns: 0 on success or -1 if configuration parsing failed
799 *
800 * This function can be used to request that the configuration data is reloaded
801 * (e.g., after configuration file change). This function is reloading
802 * configuration only for one interface, so this may need to be called multiple
803 * times if %wpa_supplicant is controlling multiple interfaces and all
804 * interfaces need reconfiguration.
805 */
806int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
807{
808 struct wpa_config *conf;
809 int reconf_ctrl;
8bac466b
JM
810 int old_ap_scan;
811
6fc6879b
JM
812 if (wpa_s->confname == NULL)
813 return -1;
e6304cad 814 conf = wpa_config_read(wpa_s->confname, NULL);
6fc6879b
JM
815 if (conf == NULL) {
816 wpa_msg(wpa_s, MSG_ERROR, "Failed to parse the configuration "
817 "file '%s' - exiting", wpa_s->confname);
818 return -1;
819 }
e6304cad
DS
820 wpa_config_read(wpa_s->confanother, conf);
821
611aea7d 822 conf->changed_parameters = (unsigned int) -1;
6fc6879b
JM
823
824 reconf_ctrl = !!conf->ctrl_interface != !!wpa_s->conf->ctrl_interface
825 || (conf->ctrl_interface && wpa_s->conf->ctrl_interface &&
826 os_strcmp(conf->ctrl_interface,
827 wpa_s->conf->ctrl_interface) != 0);
828
829 if (reconf_ctrl && wpa_s->ctrl_iface) {
830 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
831 wpa_s->ctrl_iface = NULL;
832 }
833
834 eapol_sm_invalidate_cached_session(wpa_s->eapol);
7b7ce8aa
JM
835 if (wpa_s->current_ssid) {
836 wpa_supplicant_deauthenticate(wpa_s,
837 WLAN_REASON_DEAUTH_LEAVING);
838 }
8bac466b 839
6fc6879b
JM
840 /*
841 * TODO: should notify EAPOL SM about changes in opensc_engine_path,
842 * pkcs11_engine_path, pkcs11_module_path.
843 */
56586197 844 if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
6fc6879b
JM
845 /*
846 * Clear forced success to clear EAP state for next
847 * authentication.
848 */
849 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
850 }
851 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
852 wpa_sm_set_config(wpa_s->wpa, NULL);
d8a790b9 853 wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
6fc6879b
JM
854 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
855 rsn_preauth_deinit(wpa_s->wpa);
8bac466b
JM
856
857 old_ap_scan = wpa_s->conf->ap_scan;
6fc6879b
JM
858 wpa_config_free(wpa_s->conf);
859 wpa_s->conf = conf;
8bac466b
JM
860 if (old_ap_scan != wpa_s->conf->ap_scan)
861 wpas_notify_ap_scan_changed(wpa_s);
862
6fc6879b
JM
863 if (reconf_ctrl)
864 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
865
611aea7d
JM
866 wpa_supplicant_update_config(wpa_s);
867
6fc6879b 868 wpa_supplicant_clear_status(wpa_s);
349493bd 869 if (wpa_supplicant_enabled_networks(wpa_s)) {
43a38635
JM
870 wpa_s->reassociate = 1;
871 wpa_supplicant_req_scan(wpa_s, 0, 0);
872 }
f049052b 873 wpa_dbg(wpa_s, MSG_DEBUG, "Reconfiguration completed");
6fc6879b
JM
874 return 0;
875}
876
877
0456ea16 878static void wpa_supplicant_reconfig(int sig, void *signal_ctx)
6fc6879b 879{
0456ea16 880 struct wpa_global *global = signal_ctx;
6fc6879b 881 struct wpa_supplicant *wpa_s;
6fc6879b 882 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
f049052b
BG
883 wpa_dbg(wpa_s, MSG_DEBUG, "Signal %d received - reconfiguring",
884 sig);
6fc6879b 885 if (wpa_supplicant_reload_configuration(wpa_s) < 0) {
1a1bf008 886 wpa_supplicant_terminate_proc(global);
6fc6879b
JM
887 }
888 }
889}
890
891
6fc6879b
JM
892static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s,
893 struct wpa_ssid *ssid,
894 struct wpa_ie_data *ie)
895{
896 int ret = wpa_sm_parse_own_wpa_ie(wpa_s->wpa, ie);
897 if (ret) {
898 if (ret == -2) {
899 wpa_msg(wpa_s, MSG_INFO, "WPA: Failed to parse WPA IE "
900 "from association info");
901 }
902 return -1;
903 }
904
f049052b
BG
905 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Using WPA IE from AssocReq to set "
906 "cipher suites");
6fc6879b
JM
907 if (!(ie->group_cipher & ssid->group_cipher)) {
908 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled group "
909 "cipher 0x%x (mask 0x%x) - reject",
910 ie->group_cipher, ssid->group_cipher);
911 return -1;
912 }
913 if (!(ie->pairwise_cipher & ssid->pairwise_cipher)) {
914 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled pairwise "
915 "cipher 0x%x (mask 0x%x) - reject",
916 ie->pairwise_cipher, ssid->pairwise_cipher);
917 return -1;
918 }
919 if (!(ie->key_mgmt & ssid->key_mgmt)) {
920 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver used disabled key "
921 "management 0x%x (mask 0x%x) - reject",
922 ie->key_mgmt, ssid->key_mgmt);
923 return -1;
924 }
925
926#ifdef CONFIG_IEEE80211W
0b60b0aa 927 if (!(ie->capabilities & WPA_CAPABILITY_MFPC) &&
62d49803
JM
928 (ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
929 wpa_s->conf->pmf : ssid->ieee80211w) ==
930 MGMT_FRAME_PROTECTION_REQUIRED) {
6fc6879b
JM
931 wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP "
932 "that does not support management frame protection - "
933 "reject");
934 return -1;
935 }
936#endif /* CONFIG_IEEE80211W */
937
938 return 0;
939}
940
941
942/**
943 * wpa_supplicant_set_suites - Set authentication and encryption parameters
944 * @wpa_s: Pointer to wpa_supplicant data
945 * @bss: Scan results for the selected BSS, or %NULL if not available
946 * @ssid: Configuration data for the selected network
947 * @wpa_ie: Buffer for the WPA/RSN IE
948 * @wpa_ie_len: Maximum wpa_ie buffer size on input. This is changed to be the
949 * used buffer length in case the functions returns success.
950 * Returns: 0 on success or -1 on failure
951 *
952 * This function is used to configure authentication and encryption parameters
953 * based on the network configuration and scan result for the selected BSS (if
954 * available).
955 */
956int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
6fa81a3b 957 struct wpa_bss *bss, struct wpa_ssid *ssid,
6fc6879b
JM
958 u8 *wpa_ie, size_t *wpa_ie_len)
959{
960 struct wpa_ie_data ie;
961 int sel, proto;
df0f01d9 962 const u8 *bss_wpa, *bss_rsn, *bss_osen;
6fc6879b
JM
963
964 if (bss) {
6fa81a3b
JM
965 bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
966 bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
df0f01d9 967 bss_osen = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
6fc6879b 968 } else
df0f01d9 969 bss_wpa = bss_rsn = bss_osen = NULL;
6fc6879b
JM
970
971 if (bss_rsn && (ssid->proto & WPA_PROTO_RSN) &&
972 wpa_parse_wpa_ie(bss_rsn, 2 + bss_rsn[1], &ie) == 0 &&
973 (ie.group_cipher & ssid->group_cipher) &&
974 (ie.pairwise_cipher & ssid->pairwise_cipher) &&
975 (ie.key_mgmt & ssid->key_mgmt)) {
f049052b 976 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using IEEE 802.11i/D9.0");
6fc6879b
JM
977 proto = WPA_PROTO_RSN;
978 } else if (bss_wpa && (ssid->proto & WPA_PROTO_WPA) &&
979 wpa_parse_wpa_ie(bss_wpa, 2 +bss_wpa[1], &ie) == 0 &&
980 (ie.group_cipher & ssid->group_cipher) &&
981 (ie.pairwise_cipher & ssid->pairwise_cipher) &&
982 (ie.key_mgmt & ssid->key_mgmt)) {
f049052b 983 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using IEEE 802.11i/D3.0");
6fc6879b 984 proto = WPA_PROTO_WPA;
df0f01d9
JM
985#ifdef CONFIG_HS20
986 } else if (bss_osen && (ssid->proto & WPA_PROTO_OSEN)) {
987 wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: using OSEN");
988 /* TODO: parse OSEN element */
137ff332 989 os_memset(&ie, 0, sizeof(ie));
df0f01d9
JM
990 ie.group_cipher = WPA_CIPHER_CCMP;
991 ie.pairwise_cipher = WPA_CIPHER_CCMP;
992 ie.key_mgmt = WPA_KEY_MGMT_OSEN;
993 proto = WPA_PROTO_OSEN;
994#endif /* CONFIG_HS20 */
6fc6879b
JM
995 } else if (bss) {
996 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select WPA/RSN");
997 return -1;
998 } else {
df0f01d9
JM
999 if (ssid->proto & WPA_PROTO_OSEN)
1000 proto = WPA_PROTO_OSEN;
1001 else if (ssid->proto & WPA_PROTO_RSN)
6fc6879b
JM
1002 proto = WPA_PROTO_RSN;
1003 else
1004 proto = WPA_PROTO_WPA;
1005 if (wpa_supplicant_suites_from_ai(wpa_s, ssid, &ie) < 0) {
1006 os_memset(&ie, 0, sizeof(ie));
1007 ie.group_cipher = ssid->group_cipher;
1008 ie.pairwise_cipher = ssid->pairwise_cipher;
1009 ie.key_mgmt = ssid->key_mgmt;
1010#ifdef CONFIG_IEEE80211W
1011 ie.mgmt_group_cipher =
70f8cc8e 1012 ssid->ieee80211w != NO_MGMT_FRAME_PROTECTION ?
6fc6879b
JM
1013 WPA_CIPHER_AES_128_CMAC : 0;
1014#endif /* CONFIG_IEEE80211W */
f049052b
BG
1015 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Set cipher suites "
1016 "based on configuration");
6fc6879b
JM
1017 } else
1018 proto = ie.proto;
1019 }
1020
f049052b
BG
1021 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected cipher suites: group %d "
1022 "pairwise %d key_mgmt %d proto %d",
1023 ie.group_cipher, ie.pairwise_cipher, ie.key_mgmt, proto);
6fc6879b
JM
1024#ifdef CONFIG_IEEE80211W
1025 if (ssid->ieee80211w) {
f049052b
BG
1026 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected mgmt group cipher %d",
1027 ie.mgmt_group_cipher);
6fc6879b
JM
1028 }
1029#endif /* CONFIG_IEEE80211W */
1030
64fa840a 1031 wpa_s->wpa_proto = proto;
6fc6879b
JM
1032 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, proto);
1033 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED,
df0f01d9 1034 !!(ssid->proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN)));
6fc6879b
JM
1035
1036 if (bss || !wpa_s->ap_ies_from_associnfo) {
1037 if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
1038 bss_wpa ? 2 + bss_wpa[1] : 0) ||
1039 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
1040 bss_rsn ? 2 + bss_rsn[1] : 0))
1041 return -1;
1042 }
1043
1044 sel = ie.group_cipher & ssid->group_cipher;
edbd2a19
JM
1045 wpa_s->group_cipher = wpa_pick_group_cipher(sel);
1046 if (wpa_s->group_cipher < 0) {
f049052b
BG
1047 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select group "
1048 "cipher");
6fc6879b
JM
1049 return -1;
1050 }
edbd2a19
JM
1051 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s",
1052 wpa_cipher_txt(wpa_s->group_cipher));
6fc6879b
JM
1053
1054 sel = ie.pairwise_cipher & ssid->pairwise_cipher;
edbd2a19
JM
1055 wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(sel, 1);
1056 if (wpa_s->pairwise_cipher < 0) {
f049052b
BG
1057 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select pairwise "
1058 "cipher");
6fc6879b
JM
1059 return -1;
1060 }
edbd2a19
JM
1061 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK %s",
1062 wpa_cipher_txt(wpa_s->pairwise_cipher));
6fc6879b
JM
1063
1064 sel = ie.key_mgmt & ssid->key_mgmt;
c10347f2
JM
1065#ifdef CONFIG_SAE
1066 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE))
1067 sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE);
1068#endif /* CONFIG_SAE */
6fc6879b
JM
1069 if (0) {
1070#ifdef CONFIG_IEEE80211R
1071 } else if (sel & WPA_KEY_MGMT_FT_IEEE8021X) {
1072 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
f049052b 1073 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/802.1X");
6fc6879b
JM
1074 } else if (sel & WPA_KEY_MGMT_FT_PSK) {
1075 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_PSK;
f049052b 1076 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT FT/PSK");
6fc6879b 1077#endif /* CONFIG_IEEE80211R */
c10347f2
JM
1078#ifdef CONFIG_SAE
1079 } else if (sel & WPA_KEY_MGMT_SAE) {
1080 wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
1081 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT SAE");
1082 } else if (sel & WPA_KEY_MGMT_FT_SAE) {
1083 wpa_s->key_mgmt = WPA_KEY_MGMT_FT_SAE;
1084 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: using KEY_MGMT FT/SAE");
1085#endif /* CONFIG_SAE */
56586197
JM
1086#ifdef CONFIG_IEEE80211W
1087 } else if (sel & WPA_KEY_MGMT_IEEE8021X_SHA256) {
1088 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256;
f049052b 1089 wpa_dbg(wpa_s, MSG_DEBUG,
56586197
JM
1090 "WPA: using KEY_MGMT 802.1X with SHA256");
1091 } else if (sel & WPA_KEY_MGMT_PSK_SHA256) {
1092 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK_SHA256;
f049052b 1093 wpa_dbg(wpa_s, MSG_DEBUG,
56586197
JM
1094 "WPA: using KEY_MGMT PSK with SHA256");
1095#endif /* CONFIG_IEEE80211W */
6fc6879b
JM
1096 } else if (sel & WPA_KEY_MGMT_IEEE8021X) {
1097 wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
f049052b 1098 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT 802.1X");
6fc6879b
JM
1099 } else if (sel & WPA_KEY_MGMT_PSK) {
1100 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
f049052b 1101 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-PSK");
6fc6879b
JM
1102 } else if (sel & WPA_KEY_MGMT_WPA_NONE) {
1103 wpa_s->key_mgmt = WPA_KEY_MGMT_WPA_NONE;
f049052b 1104 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT WPA-NONE");
df0f01d9
JM
1105#ifdef CONFIG_HS20
1106 } else if (sel & WPA_KEY_MGMT_OSEN) {
1107 wpa_s->key_mgmt = WPA_KEY_MGMT_OSEN;
1108 wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: using KEY_MGMT OSEN");
1109#endif /* CONFIG_HS20 */
6fc6879b 1110 } else {
f049052b
BG
1111 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to select "
1112 "authenticated key management type");
6fc6879b
JM
1113 return -1;
1114 }
1115
1116 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt);
1117 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
1118 wpa_s->pairwise_cipher);
1119 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
1120
1121#ifdef CONFIG_IEEE80211W
1122 sel = ie.mgmt_group_cipher;
62d49803
JM
1123 if ((ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1124 wpa_s->conf->pmf : ssid->ieee80211w) == NO_MGMT_FRAME_PROTECTION ||
0b60b0aa 1125 !(ie.capabilities & WPA_CAPABILITY_MFPC))
6fc6879b
JM
1126 sel = 0;
1127 if (sel & WPA_CIPHER_AES_128_CMAC) {
1128 wpa_s->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
f049052b 1129 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
6fc6879b 1130 "AES-128-CMAC");
8dd9f9cd
JM
1131 } else if (sel & WPA_CIPHER_BIP_GMAC_128) {
1132 wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_GMAC_128;
1133 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1134 "BIP-GMAC-128");
1135 } else if (sel & WPA_CIPHER_BIP_GMAC_256) {
1136 wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_GMAC_256;
1137 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1138 "BIP-GMAC-256");
1139 } else if (sel & WPA_CIPHER_BIP_CMAC_256) {
1140 wpa_s->mgmt_group_cipher = WPA_CIPHER_BIP_CMAC_256;
1141 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
1142 "BIP-CMAC-256");
6fc6879b
JM
1143 } else {
1144 wpa_s->mgmt_group_cipher = 0;
f049052b 1145 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
6fc6879b
JM
1146 }
1147 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
1148 wpa_s->mgmt_group_cipher);
62d49803
JM
1149 wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP,
1150 (ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1151 wpa_s->conf->pmf : ssid->ieee80211w));
6fc6879b
JM
1152#endif /* CONFIG_IEEE80211W */
1153
1154 if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {
f049052b 1155 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to generate WPA IE");
6fc6879b
JM
1156 return -1;
1157 }
1158
0bf927a0 1159 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) {
6fc6879b 1160 wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN);
7d232e23
ZC
1161#ifndef CONFIG_NO_PBKDF2
1162 if (bss && ssid->bssid_set && ssid->ssid_len == 0 &&
1163 ssid->passphrase) {
1164 u8 psk[PMK_LEN];
986de33d
JM
1165 pbkdf2_sha1(ssid->passphrase, bss->ssid, bss->ssid_len,
1166 4096, psk, PMK_LEN);
7d232e23
ZC
1167 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
1168 psk, PMK_LEN);
1169 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
1170 }
1171#endif /* CONFIG_NO_PBKDF2 */
9173b16f
JM
1172#ifdef CONFIG_EXT_PASSWORD
1173 if (ssid->ext_psk) {
1174 struct wpabuf *pw = ext_password_get(wpa_s->ext_pw,
1175 ssid->ext_psk);
1176 char pw_str[64 + 1];
1177 u8 psk[PMK_LEN];
1178
1179 if (pw == NULL) {
1180 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No PSK "
1181 "found from external storage");
1182 return -1;
1183 }
1184
1185 if (wpabuf_len(pw) < 8 || wpabuf_len(pw) > 64) {
1186 wpa_msg(wpa_s, MSG_INFO, "EXT PW: Unexpected "
1187 "PSK length %d in external storage",
1188 (int) wpabuf_len(pw));
1189 ext_password_free(pw);
1190 return -1;
1191 }
1192
1193 os_memcpy(pw_str, wpabuf_head(pw), wpabuf_len(pw));
1194 pw_str[wpabuf_len(pw)] = '\0';
1195
1196#ifndef CONFIG_NO_PBKDF2
1197 if (wpabuf_len(pw) >= 8 && wpabuf_len(pw) < 64 && bss)
1198 {
986de33d
JM
1199 pbkdf2_sha1(pw_str, bss->ssid, bss->ssid_len,
1200 4096, psk, PMK_LEN);
9173b16f
JM
1201 os_memset(pw_str, 0, sizeof(pw_str));
1202 wpa_hexdump_key(MSG_MSGDUMP, "PSK (from "
1203 "external passphrase)",
1204 psk, PMK_LEN);
1205 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
1206 } else
1207#endif /* CONFIG_NO_PBKDF2 */
1208 if (wpabuf_len(pw) == 2 * PMK_LEN) {
1209 if (hexstr2bin(pw_str, psk, PMK_LEN) < 0) {
1210 wpa_msg(wpa_s, MSG_INFO, "EXT PW: "
1211 "Invalid PSK hex string");
1212 os_memset(pw_str, 0, sizeof(pw_str));
1213 ext_password_free(pw);
1214 return -1;
1215 }
1216 wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
1217 } else {
1218 wpa_msg(wpa_s, MSG_INFO, "EXT PW: No suitable "
1219 "PSK available");
1220 os_memset(pw_str, 0, sizeof(pw_str));
1221 ext_password_free(pw);
1222 return -1;
1223 }
1224
1225 os_memset(pw_str, 0, sizeof(pw_str));
1226 ext_password_free(pw);
1227 }
1228#endif /* CONFIG_EXT_PASSWORD */
7d232e23 1229 } else
6fc6879b
JM
1230 wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
1231
1232 return 0;
1233}
1234
1235
8cd6b7bc 1236static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
03e47c9c 1237{
8cd6b7bc 1238 *pos = 0x00;
03e47c9c 1239
8cd6b7bc
JB
1240 switch (idx) {
1241 case 0: /* Bits 0-7 */
1242 break;
1243 case 1: /* Bits 8-15 */
1244 break;
1245 case 2: /* Bits 16-23 */
1246#ifdef CONFIG_WNM
1247 *pos |= 0x02; /* Bit 17 - WNM-Sleep Mode */
1248 *pos |= 0x08; /* Bit 19 - BSS Transition */
1249#endif /* CONFIG_WNM */
1250 break;
1251 case 3: /* Bits 24-31 */
1252#ifdef CONFIG_WNM
1253 *pos |= 0x02; /* Bit 25 - SSID List */
1254#endif /* CONFIG_WNM */
03e47c9c 1255#ifdef CONFIG_INTERWORKING
8cd6b7bc
JB
1256 if (wpa_s->conf->interworking)
1257 *pos |= 0x80; /* Bit 31 - Interworking */
03e47c9c 1258#endif /* CONFIG_INTERWORKING */
8cd6b7bc
JB
1259 break;
1260 case 4: /* Bits 32-39 */
56f5af48 1261#ifdef CONFIG_INTERWORKING
429dd9af
JM
1262 if (wpa_s->drv_flags / WPA_DRIVER_FLAGS_QOS_MAPPING)
1263 *pos |= 0x01; /* Bit 32 - QoS Map */
56f5af48 1264#endif /* CONFIG_INTERWORKING */
8cd6b7bc
JB
1265 break;
1266 case 5: /* Bits 40-47 */
95a3ea94
JM
1267#ifdef CONFIG_HS20
1268 if (wpa_s->conf->hs20)
1269 *pos |= 0x40; /* Bit 46 - WNM-Notification */
1270#endif /* CONFIG_HS20 */
8cd6b7bc
JB
1271 break;
1272 case 6: /* Bits 48-55 */
1273 break;
1274 }
1275}
03e47c9c 1276
03e47c9c 1277
0bbaa9b9 1278int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf, size_t buflen)
8cd6b7bc
JB
1279{
1280 u8 *pos = buf;
95a3ea94 1281 u8 len = 6, i;
8cd6b7bc
JB
1282
1283 if (len < wpa_s->extended_capa_len)
1284 len = wpa_s->extended_capa_len;
0bbaa9b9
JM
1285 if (buflen < (size_t) len + 2) {
1286 wpa_printf(MSG_INFO,
1287 "Not enough room for building extended capabilities element");
1288 return -1;
1289 }
03e47c9c
JM
1290
1291 *pos++ = WLAN_EID_EXT_CAPAB;
8cd6b7bc
JB
1292 *pos++ = len;
1293 for (i = 0; i < len; i++, pos++) {
1294 wpas_ext_capab_byte(wpa_s, pos, i);
1295
1296 if (i < wpa_s->extended_capa_len) {
1297 *pos &= ~wpa_s->extended_capa_mask[i];
1298 *pos |= wpa_s->extended_capa[i];
1299 }
1300 }
03e47c9c 1301
3db5439a
JM
1302 while (len > 0 && buf[1 + len] == 0) {
1303 len--;
1304 buf[1] = len;
1305 }
1306 if (len == 0)
1307 return 0;
1308
1309 return 2 + len;
03e47c9c
JM
1310}
1311
1312
6ac4b15e
JM
1313static int wpas_valid_bss(struct wpa_supplicant *wpa_s,
1314 struct wpa_bss *test_bss)
1315{
1316 struct wpa_bss *bss;
1317
1318 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
1319 if (bss == test_bss)
1320 return 1;
1321 }
1322
1323 return 0;
1324}
1325
1326
1327static int wpas_valid_ssid(struct wpa_supplicant *wpa_s,
1328 struct wpa_ssid *test_ssid)
1329{
1330 struct wpa_ssid *ssid;
1331
1332 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
1333 if (ssid == test_ssid)
1334 return 1;
1335 }
1336
1337 return 0;
1338}
1339
1340
1341int wpas_valid_bss_ssid(struct wpa_supplicant *wpa_s, struct wpa_bss *test_bss,
1342 struct wpa_ssid *test_ssid)
1343{
1344 if (test_bss && !wpas_valid_bss(wpa_s, test_bss))
1345 return 0;
1346
1347 return test_ssid == NULL || wpas_valid_ssid(wpa_s, test_ssid);
1348}
1349
1350
1351void wpas_connect_work_free(struct wpa_connect_work *cwork)
1352{
1353 if (cwork == NULL)
1354 return;
1355 os_free(cwork);
1356}
1357
1358
1359void wpas_connect_work_done(struct wpa_supplicant *wpa_s)
1360{
1361 struct wpa_connect_work *cwork;
1362 struct wpa_radio_work *work = wpa_s->connect_work;
1363
1364 if (!work)
1365 return;
1366
1367 wpa_s->connect_work = NULL;
1368 cwork = work->ctx;
1369 work->ctx = NULL;
1370 wpas_connect_work_free(cwork);
1371 radio_work_done(work);
1372}
1373
1374
1375static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit);
1376
6fc6879b
JM
1377/**
1378 * wpa_supplicant_associate - Request association
1379 * @wpa_s: Pointer to wpa_supplicant data
1380 * @bss: Scan results for the selected BSS, or %NULL if not available
1381 * @ssid: Configuration data for the selected network
1382 *
1383 * This function is used to request %wpa_supplicant to associate with a BSS.
1384 */
1385void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
6fa81a3b 1386 struct wpa_bss *bss, struct wpa_ssid *ssid)
6fc6879b 1387{
6ac4b15e 1388 struct wpa_connect_work *cwork;
6fc6879b 1389
78177a00
JM
1390#ifdef CONFIG_IBSS_RSN
1391 ibss_rsn_deinit(wpa_s->ibss_rsn);
1392 wpa_s->ibss_rsn = NULL;
1393#endif /* CONFIG_IBSS_RSN */
1394
2c5d725c
JM
1395 if (ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO ||
1396 ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
1581b38b
JM
1397#ifdef CONFIG_AP
1398 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP)) {
f049052b
BG
1399 wpa_msg(wpa_s, MSG_INFO, "Driver does not support AP "
1400 "mode");
1581b38b
JM
1401 return;
1402 }
8c981d17
DW
1403 if (wpa_supplicant_create_ap(wpa_s, ssid) < 0) {
1404 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
b2b688d1
VKE
1405 if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
1406 wpas_p2p_ap_setup_failed(wpa_s);
8c981d17
DW
1407 return;
1408 }
8f770587 1409 wpa_s->current_bss = bss;
1581b38b 1410#else /* CONFIG_AP */
f049052b
BG
1411 wpa_msg(wpa_s, MSG_ERROR, "AP mode support not included in "
1412 "the build");
1581b38b
JM
1413#endif /* CONFIG_AP */
1414 return;
1415 }
1416
52c9e6f3 1417#ifdef CONFIG_TDLS
95cb2d88
JM
1418 if (bss)
1419 wpa_tdls_ap_ies(wpa_s->wpa, (const u8 *) (bss + 1),
1420 bss->ie_len);
52c9e6f3
JM
1421#endif /* CONFIG_TDLS */
1422
5cc4d64b
JM
1423 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
1424 ssid->mode == IEEE80211_MODE_INFRA) {
c2a04078
JM
1425 sme_authenticate(wpa_s, bss, ssid);
1426 return;
1427 }
1428
6ac4b15e
JM
1429 if (wpa_s->connect_work) {
1430 wpa_dbg(wpa_s, MSG_DEBUG, "Reject wpa_supplicant_associate() call since connect_work exist");
1431 return;
1432 }
1433
f0e30c84
JM
1434 if (radio_work_pending(wpa_s, "connect")) {
1435 wpa_dbg(wpa_s, MSG_DEBUG, "Reject wpa_supplicant_associate() call since pending work exist");
1436 return;
1437 }
1438
6ac4b15e
JM
1439 cwork = os_zalloc(sizeof(*cwork));
1440 if (cwork == NULL)
1441 return;
1442
1443 cwork->bss = bss;
1444 cwork->ssid = ssid;
1445
1446 if (radio_add_work(wpa_s, bss ? bss->freq : 0, "connect", 1,
1447 wpas_start_assoc_cb, cwork) < 0) {
1448 os_free(cwork);
1449 }
1450}
1451
1452
1453static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
1454{
1455 struct wpa_connect_work *cwork = work->ctx;
1456 struct wpa_bss *bss = cwork->bss;
1457 struct wpa_ssid *ssid = cwork->ssid;
1458 struct wpa_supplicant *wpa_s = work->wpa_s;
1459 u8 wpa_ie[200];
1460 size_t wpa_ie_len;
1461 int use_crypt, ret, i, bssid_changed;
1462 int algs = WPA_AUTH_ALG_OPEN;
1463 unsigned int cipher_pairwise, cipher_group;
1464 struct wpa_driver_associate_params params;
1465 int wep_keys_set = 0;
1466 int assoc_failed = 0;
1467 struct wpa_ssid *old_ssid;
1468#ifdef CONFIG_HT_OVERRIDES
1469 struct ieee80211_ht_capabilities htcaps;
1470 struct ieee80211_ht_capabilities htcaps_mask;
1471#endif /* CONFIG_HT_OVERRIDES */
6aa1cd4e
PS
1472#ifdef CONFIG_VHT_OVERRIDES
1473 struct ieee80211_vht_capabilities vhtcaps;
1474 struct ieee80211_vht_capabilities vhtcaps_mask;
1475#endif /* CONFIG_VHT_OVERRIDES */
6ac4b15e
JM
1476
1477 if (deinit) {
b3253ebb
AO
1478 if (work->started) {
1479 wpa_s->connect_work = NULL;
1480
1481 /* cancel possible auth. timeout */
1482 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s,
1483 NULL);
1484 }
6ac4b15e
JM
1485 wpas_connect_work_free(cwork);
1486 return;
1487 }
1488
1489 wpa_s->connect_work = work;
1490
1491 if (!wpas_valid_bss_ssid(wpa_s, bss, ssid)) {
1492 wpa_dbg(wpa_s, MSG_DEBUG, "BSS/SSID entry for association not valid anymore - drop connection attempt");
1493 wpas_connect_work_done(wpa_s);
1494 return;
1495 }
1496
0c80427d 1497 os_memset(&params, 0, sizeof(params));
6fc6879b 1498 wpa_s->reassociate = 0;
c60ba9f7 1499 wpa_s->eap_expected_failure = 0;
22628eca 1500 if (bss && !wpas_driver_bss_selection(wpa_s)) {
6fc6879b 1501#ifdef CONFIG_IEEE80211R
6fa81a3b 1502 const u8 *ie, *md = NULL;
6fc6879b 1503#endif /* CONFIG_IEEE80211R */
6fc6879b
JM
1504 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
1505 " (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid),
6fa81a3b 1506 wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq);
8bac466b 1507 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
6fc6879b
JM
1508 os_memset(wpa_s->bssid, 0, ETH_ALEN);
1509 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
8bac466b
JM
1510 if (bssid_changed)
1511 wpas_notify_bssid_changed(wpa_s);
6fc6879b 1512#ifdef CONFIG_IEEE80211R
6fa81a3b 1513 ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
6fc6879b
JM
1514 if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
1515 md = ie + 2;
e7846b68 1516 wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
91a05482
JM
1517 if (md) {
1518 /* Prepare for the next transition */
76b7981d 1519 wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
91a05482 1520 }
6fc6879b 1521#endif /* CONFIG_IEEE80211R */
24c23d1b
JM
1522#ifdef CONFIG_WPS
1523 } else if ((ssid->ssid == NULL || ssid->ssid_len == 0) &&
1524 wpa_s->conf->ap_scan == 2 &&
1525 (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
1526 /* Use ap_scan==1 style network selection to find the network
1527 */
4115303b 1528 wpa_s->scan_req = MANUAL_SCAN_REQ;
24c23d1b
JM
1529 wpa_s->reassociate = 1;
1530 wpa_supplicant_req_scan(wpa_s, 0, 0);
1531 return;
1532#endif /* CONFIG_WPS */
6fc6879b
JM
1533 } else {
1534 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
1535 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
1536 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1537 }
a4cba8f1 1538 wpa_supplicant_cancel_sched_scan(wpa_s);
6fc6879b
JM
1539 wpa_supplicant_cancel_scan(wpa_s);
1540
1541 /* Starting new association, so clear the possibly used WPA IE from the
1542 * previous association. */
1543 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
1544
1545#ifdef IEEE8021X_EAPOL
1546 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1547 if (ssid->leap) {
1548 if (ssid->non_leap == 0)
abd9fafa 1549 algs = WPA_AUTH_ALG_LEAP;
6fc6879b 1550 else
abd9fafa 1551 algs |= WPA_AUTH_ALG_LEAP;
6fc6879b
JM
1552 }
1553 }
1554#endif /* IEEE8021X_EAPOL */
f049052b 1555 wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs);
6fc6879b 1556 if (ssid->auth_alg) {
abd9fafa 1557 algs = ssid->auth_alg;
f049052b
BG
1558 wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: "
1559 "0x%x", algs);
6fc6879b 1560 }
6fc6879b 1561
6fa81a3b
JM
1562 if (bss && (wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
1563 wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
0bf927a0 1564 wpa_key_mgmt_wpa(ssid->key_mgmt)) {
6fc6879b 1565 int try_opportunistic;
6e202021
JM
1566 try_opportunistic = (ssid->proactive_key_caching < 0 ?
1567 wpa_s->conf->okc :
1568 ssid->proactive_key_caching) &&
6fc6879b
JM
1569 (ssid->proto & WPA_PROTO_RSN);
1570 if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
b2a12c4f 1571 ssid, try_opportunistic) == 0)
6fc6879b
JM
1572 eapol_sm_notify_pmkid_attempt(wpa_s->eapol, 1);
1573 wpa_ie_len = sizeof(wpa_ie);
1574 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
1575 wpa_ie, &wpa_ie_len)) {
f049052b
BG
1576 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
1577 "key management and encryption suites");
6fc6879b
JM
1578 return;
1579 }
a3f7e518
JM
1580 } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && bss &&
1581 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
1582 /*
1583 * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
1584 * use non-WPA since the scan results did not indicate that the
1585 * AP is using WPA or WPA2.
1586 */
1587 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1588 wpa_ie_len = 0;
1589 wpa_s->wpa_proto = 0;
0bf927a0 1590 } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
6fc6879b
JM
1591 wpa_ie_len = sizeof(wpa_ie);
1592 if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
1593 wpa_ie, &wpa_ie_len)) {
f049052b
BG
1594 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to set WPA "
1595 "key management and encryption suites (no "
1596 "scan results)");
6fc6879b
JM
1597 return;
1598 }
ad08c363
JM
1599#ifdef CONFIG_WPS
1600 } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
b01c18a8
JM
1601 struct wpabuf *wps_ie;
1602 wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
ad08c363
JM
1603 if (wps_ie && wpabuf_len(wps_ie) <= sizeof(wpa_ie)) {
1604 wpa_ie_len = wpabuf_len(wps_ie);
1605 os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
24386985
JM
1606 } else
1607 wpa_ie_len = 0;
ad08c363
JM
1608 wpabuf_free(wps_ie);
1609 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
0c80427d
JM
1610 if (!bss || (bss->caps & IEEE80211_CAP_PRIVACY))
1611 params.wps = WPS_MODE_PRIVACY;
1612 else
1613 params.wps = WPS_MODE_OPEN;
cf546f1a 1614 wpa_s->wpa_proto = 0;
ad08c363 1615#endif /* CONFIG_WPS */
6fc6879b
JM
1616 } else {
1617 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
1618 wpa_ie_len = 0;
cf546f1a 1619 wpa_s->wpa_proto = 0;
6fc6879b
JM
1620 }
1621
5f3a6aa0
JM
1622#ifdef CONFIG_P2P
1623 if (wpa_s->global->p2p) {
1624 u8 *pos;
1625 size_t len;
1626 int res;
5f3a6aa0
JM
1627 pos = wpa_ie + wpa_ie_len;
1628 len = sizeof(wpa_ie) - wpa_ie_len;
b8a8d677
JM
1629 res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
1630 ssid->p2p_group);
5f3a6aa0
JM
1631 if (res >= 0)
1632 wpa_ie_len += res;
1633 }
72044390
JM
1634
1635 wpa_s->cross_connect_disallowed = 0;
1636 if (bss) {
1637 struct wpabuf *p2p;
1638 p2p = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE);
1639 if (p2p) {
1640 wpa_s->cross_connect_disallowed =
1641 p2p_get_cross_connect_disallowed(p2p);
1642 wpabuf_free(p2p);
f049052b
BG
1643 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: WLAN AP %s cross "
1644 "connection",
1645 wpa_s->cross_connect_disallowed ?
1646 "disallows" : "allows");
72044390
JM
1647 }
1648 }
25ef8529
JM
1649
1650 os_memset(wpa_s->p2p_ip_addr_info, 0, sizeof(wpa_s->p2p_ip_addr_info));
5f3a6aa0
JM
1651#endif /* CONFIG_P2P */
1652
cb418324 1653#ifdef CONFIG_HS20
55a2df43 1654 if (is_hs20_network(wpa_s, ssid, bss)) {
cb418324
JM
1655 struct wpabuf *hs20;
1656 hs20 = wpabuf_alloc(20);
1657 if (hs20) {
f9cd147d 1658 int pps_mo_id = hs20_get_pps_mo_id(wpa_s, ssid);
745ef184
JM
1659 size_t len;
1660
f9cd147d 1661 wpas_hs20_add_indication(hs20, pps_mo_id);
745ef184
JM
1662 len = sizeof(wpa_ie) - wpa_ie_len;
1663 if (wpabuf_len(hs20) <= len) {
1664 os_memcpy(wpa_ie + wpa_ie_len,
1665 wpabuf_head(hs20), wpabuf_len(hs20));
1666 wpa_ie_len += wpabuf_len(hs20);
1667 }
cb418324
JM
1668 wpabuf_free(hs20);
1669 }
1670 }
1671#endif /* CONFIG_HS20 */
1672
8b3b803a
AH
1673 /*
1674 * Workaround: Add Extended Capabilities element only if the AP
1675 * included this element in Beacon/Probe Response frames. Some older
1676 * APs seem to have interoperability issues if this element is
1677 * included, so while the standard may require us to include the
1678 * element in all cases, it is justifiable to skip it to avoid
1679 * interoperability issues.
1680 */
1681 if (!bss || wpa_bss_get_ie(bss, WLAN_EID_EXT_CAPAB)) {
0bbaa9b9 1682 u8 ext_capab[18];
8b3b803a 1683 int ext_capab_len;
0bbaa9b9
JM
1684 ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
1685 sizeof(ext_capab));
8b3b803a
AH
1686 if (ext_capab_len > 0) {
1687 u8 *pos = wpa_ie;
1688 if (wpa_ie_len > 0 && pos[0] == WLAN_EID_RSN)
1689 pos += 2 + pos[1];
1690 os_memmove(pos + ext_capab_len, pos,
1691 wpa_ie_len - (pos - wpa_ie));
1692 wpa_ie_len += ext_capab_len;
1693 os_memcpy(pos, ext_capab, ext_capab_len);
1694 }
92cbcf91 1695 }
92cbcf91 1696
6fc6879b
JM
1697 wpa_clear_keys(wpa_s, bss ? bss->bssid : NULL);
1698 use_crypt = 1;
4848a38d
JM
1699 cipher_pairwise = wpa_s->pairwise_cipher;
1700 cipher_group = wpa_s->group_cipher;
6fc6879b
JM
1701 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
1702 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1703 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
1704 use_crypt = 0;
1705 if (wpa_set_wep_keys(wpa_s, ssid)) {
1706 use_crypt = 1;
1707 wep_keys_set = 1;
1708 }
1709 }
ad08c363
JM
1710 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
1711 use_crypt = 0;
6fc6879b
JM
1712
1713#ifdef IEEE8021X_EAPOL
1714 if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
1715 if ((ssid->eapol_flags &
1716 (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
1717 EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) == 0 &&
1718 !wep_keys_set) {
1719 use_crypt = 0;
1720 } else {
1721 /* Assume that dynamic WEP-104 keys will be used and
1722 * set cipher suites in order for drivers to expect
1723 * encryption. */
4848a38d 1724 cipher_pairwise = cipher_group = WPA_CIPHER_WEP104;
6fc6879b
JM
1725 }
1726 }
1727#endif /* IEEE8021X_EAPOL */
1728
1729 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
1730 /* Set the key before (and later after) association */
1731 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
1732 }
1733
6fc6879b 1734 wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
6fc6879b 1735 if (bss) {
6fa81a3b
JM
1736 params.ssid = bss->ssid;
1737 params.ssid_len = bss->ssid_len;
f15854d1
JM
1738 if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) {
1739 wpa_printf(MSG_DEBUG, "Limit connection to BSSID "
1740 MACSTR " freq=%u MHz based on scan results "
1741 "(bssid_set=%d)",
1742 MAC2STR(bss->bssid), bss->freq,
1743 ssid->bssid_set);
22628eca
JM
1744 params.bssid = bss->bssid;
1745 params.freq = bss->freq;
1746 }
7ac7fd43
DS
1747 params.bssid_hint = bss->bssid;
1748 params.freq_hint = bss->freq;
6fc6879b
JM
1749 } else {
1750 params.ssid = ssid->ssid;
1751 params.ssid_len = ssid->ssid_len;
1752 }
9e2af29f
NC
1753
1754 if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&
1755 wpa_s->conf->ap_scan == 2) {
1756 params.bssid = ssid->bssid;
1757 params.fixed_bssid = 1;
1758 }
1759
d7dcba70
JM
1760 if (ssid->mode == WPAS_MODE_IBSS && ssid->frequency > 0 &&
1761 params.freq == 0)
6fc6879b 1762 params.freq = ssid->frequency; /* Initial channel for IBSS */
8f05577d
JM
1763
1764 if (ssid->mode == WPAS_MODE_IBSS) {
1765 if (ssid->beacon_int)
1766 params.beacon_int = ssid->beacon_int;
1767 else
1768 params.beacon_int = wpa_s->conf->beacon_int;
1769 }
1770
6fc6879b
JM
1771 params.wpa_ie = wpa_ie;
1772 params.wpa_ie_len = wpa_ie_len;
1773 params.pairwise_suite = cipher_pairwise;
1774 params.group_suite = cipher_group;
4848a38d 1775 params.key_mgmt_suite = wpa_s->key_mgmt;
64fa840a 1776 params.wpa_proto = wpa_s->wpa_proto;
6fc6879b
JM
1777 params.auth_alg = algs;
1778 params.mode = ssid->mode;
1f6c0ab8 1779 params.bg_scan_period = ssid->bg_scan_period;
6fc6879b
JM
1780 for (i = 0; i < NUM_WEP_KEYS; i++) {
1781 if (ssid->wep_key_len[i])
1782 params.wep_key[i] = ssid->wep_key[i];
1783 params.wep_key_len[i] = ssid->wep_key_len[i];
1784 }
1785 params.wep_tx_keyidx = ssid->wep_tx_keyidx;
1786
c2a04078 1787 if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
4848a38d
JM
1788 (params.key_mgmt_suite == WPA_KEY_MGMT_PSK ||
1789 params.key_mgmt_suite == WPA_KEY_MGMT_FT_PSK)) {
6fc6879b
JM
1790 params.passphrase = ssid->passphrase;
1791 if (ssid->psk_set)
1792 params.psk = ssid->psk;
1793 }
1794
36b15723
JM
1795 params.drop_unencrypted = use_crypt;
1796
6fc6879b 1797#ifdef CONFIG_IEEE80211W
62d49803
JM
1798 params.mgmt_frame_protection =
1799 ssid->ieee80211w == MGMT_FRAME_PROTECTION_DEFAULT ?
1800 wpa_s->conf->pmf : ssid->ieee80211w;
1801 if (params.mgmt_frame_protection != NO_MGMT_FRAME_PROTECTION && bss) {
6fa81a3b 1802 const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
97d3497e
JM
1803 struct wpa_ie_data ie;
1804 if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
1805 ie.capabilities &
1806 (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
f049052b
BG
1807 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Selected AP supports "
1808 "MFP: require MFP");
97d3497e
JM
1809 params.mgmt_frame_protection =
1810 MGMT_FRAME_PROTECTION_REQUIRED;
1811 }
1812 }
6fc6879b
JM
1813#endif /* CONFIG_IEEE80211W */
1814
ffad8858 1815 params.p2p = ssid->p2p_group;
6e3f4b89 1816
eea2fd9e
JM
1817 if (wpa_s->parent->set_sta_uapsd)
1818 params.uapsd = wpa_s->parent->sta_uapsd;
1819 else
1820 params.uapsd = -1;
1821
80e8a5ee
BG
1822#ifdef CONFIG_HT_OVERRIDES
1823 os_memset(&htcaps, 0, sizeof(htcaps));
1824 os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
1825 params.htcaps = (u8 *) &htcaps;
1826 params.htcaps_mask = (u8 *) &htcaps_mask;
1827 wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
1828#endif /* CONFIG_HT_OVERRIDES */
6aa1cd4e
PS
1829#ifdef CONFIG_VHT_OVERRIDES
1830 os_memset(&vhtcaps, 0, sizeof(vhtcaps));
1831 os_memset(&vhtcaps_mask, 0, sizeof(vhtcaps_mask));
1832 params.vhtcaps = &vhtcaps;
1833 params.vhtcaps_mask = &vhtcaps_mask;
1834 wpa_supplicant_apply_vht_overrides(wpa_s, wpa_s->current_ssid, &params);
1835#endif /* CONFIG_VHT_OVERRIDES */
80e8a5ee 1836
8567866d
JJ
1837#ifdef CONFIG_P2P
1838 /*
1839 * If multi-channel concurrency is not supported, check for any
1840 * frequency conflict. In case of any frequency conflict, remove the
1841 * least prioritized connection.
1842 */
1843 if (wpa_s->num_multichan_concurrent < 2) {
d0df6437
IP
1844 int freq, num;
1845 num = get_shared_radio_freqs(wpa_s, &freq, 1);
1846 if (num > 0 && freq > 0 && freq != params.freq) {
1847 wpa_printf(MSG_DEBUG,
1848 "Assoc conflicting freq found (%d != %d)",
8567866d
JJ
1849 freq, params.freq);
1850 if (wpas_p2p_handle_frequency_conflicts(wpa_s,
1851 params.freq,
1852 ssid) < 0)
1853 return;
1854 }
1855 }
1856#endif /* CONFIG_P2P */
1857
17fbb751 1858 ret = wpa_drv_associate(wpa_s, &params);
6fc6879b
JM
1859 if (ret < 0) {
1860 wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
1861 "failed");
871f4dd0
JM
1862 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SANE_ERROR_CODES) {
1863 /*
1864 * The driver is known to mean what is saying, so we
1865 * can stop right here; the association will not
1866 * succeed.
1867 */
1868 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
c1c02342 1869 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
871f4dd0
JM
1870 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1871 return;
1872 }
6fc6879b
JM
1873 /* try to continue anyway; new association will be tried again
1874 * after timeout */
1875 assoc_failed = 1;
1876 }
1877
1878 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
1879 /* Set the key after the association just in case association
1880 * cleared the previously configured key. */
1881 wpa_supplicant_set_wpa_none_key(wpa_s, ssid);
1882 /* No need to timeout authentication since there is no key
1883 * management. */
1884 wpa_supplicant_cancel_auth_timeout(wpa_s);
1885 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
53895c3b 1886#ifdef CONFIG_IBSS_RSN
d7dcba70 1887 } else if (ssid->mode == WPAS_MODE_IBSS &&
53895c3b
JM
1888 wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
1889 wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE) {
1890 /*
1891 * RSN IBSS authentication is per-STA and we can disable the
1892 * per-BSSID authentication.
1893 */
1894 wpa_supplicant_cancel_auth_timeout(wpa_s);
53895c3b 1895#endif /* CONFIG_IBSS_RSN */
6fc6879b
JM
1896 } else {
1897 /* Timeout for IEEE 802.11 authentication and association */
1d3c75b3
DW
1898 int timeout = 60;
1899
1900 if (assoc_failed) {
1901 /* give IBSS a bit more time */
d7dcba70 1902 timeout = ssid->mode == WPAS_MODE_IBSS ? 10 : 5;
1d3c75b3
DW
1903 } else if (wpa_s->conf->ap_scan == 1) {
1904 /* give IBSS a bit more time */
d7dcba70 1905 timeout = ssid->mode == WPAS_MODE_IBSS ? 20 : 10;
1d3c75b3 1906 }
6fc6879b
JM
1907 wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
1908 }
1909
66562e9c
JM
1910 if (wep_keys_set &&
1911 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC)) {
6fc6879b
JM
1912 /* Set static WEP keys again */
1913 wpa_set_wep_keys(wpa_s, ssid);
1914 }
1915
1916 if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
1917 /*
1918 * Do not allow EAP session resumption between different
1919 * network configurations.
1920 */
1921 eapol_sm_invalidate_cached_session(wpa_s->eapol);
1922 }
8bac466b 1923 old_ssid = wpa_s->current_ssid;
6fc6879b 1924 wpa_s->current_ssid = ssid;
8f770587 1925 wpa_s->current_bss = bss;
6fc6879b
JM
1926 wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
1927 wpa_supplicant_initiate_eapol(wpa_s);
8bac466b
JM
1928 if (old_ssid != wpa_s->current_ssid)
1929 wpas_notify_network_changed(wpa_s);
6fc6879b
JM
1930}
1931
1932
09f58c09
JM
1933static void wpa_supplicant_clear_connection(struct wpa_supplicant *wpa_s,
1934 const u8 *addr)
1935{
1936 struct wpa_ssid *old_ssid;
1937
1938 wpa_clear_keys(wpa_s, addr);
09f58c09 1939 old_ssid = wpa_s->current_ssid;
0d30cc24 1940 wpa_supplicant_mark_disassoc(wpa_s);
09f58c09
JM
1941 wpa_sm_set_config(wpa_s->wpa, NULL);
1942 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
1943 if (old_ssid != wpa_s->current_ssid)
1944 wpas_notify_network_changed(wpa_s);
1945 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
1946}
1947
1948
6fc6879b
JM
1949/**
1950 * wpa_supplicant_deauthenticate - Deauthenticate the current connection
1951 * @wpa_s: Pointer to wpa_supplicant data
1952 * @reason_code: IEEE 802.11 reason code for the deauthenticate frame
1953 *
073ab58f 1954 * This function is used to request %wpa_supplicant to deauthenticate from the
6fc6879b
JM
1955 * current AP.
1956 */
1957void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
1958 int reason_code)
1959{
1960 u8 *addr = NULL;
ef48ff94 1961 union wpa_event_data event;
42d23547 1962 int zero_addr = 0;
8bac466b 1963
42d23547
JM
1964 wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
1965 " pending_bssid=" MACSTR " reason=%d state=%s",
1966 MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
1967 reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state));
1968
1969 if (!is_zero_ether_addr(wpa_s->bssid))
1970 addr = wpa_s->bssid;
1971 else if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
1972 (wpa_s->wpa_state == WPA_AUTHENTICATING ||
1973 wpa_s->wpa_state == WPA_ASSOCIATING))
1974 addr = wpa_s->pending_bssid;
1975 else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
1976 /*
1977 * When using driver-based BSS selection, we may not know the
1978 * BSSID with which we are currently trying to associate. We
1979 * need to notify the driver of this disconnection even in such
1980 * a case, so use the all zeros address here.
1981 */
6fc6879b 1982 addr = wpa_s->bssid;
42d23547
JM
1983 zero_addr = 1;
1984 }
1985
7b44ff2c
SD
1986#ifdef CONFIG_TDLS
1987 wpa_tdls_teardown_peers(wpa_s->wpa);
1988#endif /* CONFIG_TDLS */
1989
42d23547
JM
1990 if (addr) {
1991 wpa_drv_deauthenticate(wpa_s, addr, reason_code);
ef48ff94
JM
1992 os_memset(&event, 0, sizeof(event));
1993 event.deauth_info.reason_code = (u16) reason_code;
1994 event.deauth_info.locally_generated = 1;
1995 wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
42d23547
JM
1996 if (zero_addr)
1997 addr = NULL;
6fc6879b 1998 }
09f58c09
JM
1999
2000 wpa_supplicant_clear_connection(wpa_s, addr);
6fc6879b
JM
2001}
2002
dca1a511
DS
2003static void wpa_supplicant_enable_one_network(struct wpa_supplicant *wpa_s,
2004 struct wpa_ssid *ssid)
2005{
2006 if (!ssid || !ssid->disabled || ssid->disabled == 2)
2007 return;
2008
2009 ssid->disabled = 0;
2010 wpas_clear_temp_disabled(wpa_s, ssid, 1);
2011 wpas_notify_network_enabled_changed(wpa_s, ssid);
2012
2013 /*
2014 * Try to reassociate since there is no current configuration and a new
2015 * network was made available.
2016 */
d2592497 2017 if (!wpa_s->current_ssid && !wpa_s->disconnected)
dca1a511
DS
2018 wpa_s->reassociate = 1;
2019}
2020
6fc6879b 2021
86b89452
WS
2022/**
2023 * wpa_supplicant_enable_network - Mark a configured network as enabled
2024 * @wpa_s: wpa_supplicant structure for a network interface
2025 * @ssid: wpa_ssid structure for a configured network or %NULL
2026 *
2027 * Enables the specified network or all networks if no network specified.
2028 */
2029void wpa_supplicant_enable_network(struct wpa_supplicant *wpa_s,
2030 struct wpa_ssid *ssid)
2031{
86b89452 2032 if (ssid == NULL) {
14f79078
JM
2033 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
2034 wpa_supplicant_enable_one_network(wpa_s, ssid);
dca1a511
DS
2035 } else
2036 wpa_supplicant_enable_one_network(wpa_s, ssid);
86b89452 2037
d2592497 2038 if (wpa_s->reassociate && !wpa_s->disconnected) {
dca1a511
DS
2039 if (wpa_s->sched_scanning) {
2040 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to add "
2041 "new network to scan filters");
2042 wpa_supplicant_cancel_sched_scan(wpa_s);
2043 }
86b89452 2044
dad153d1
JM
2045 if (wpa_supplicant_fast_associate(wpa_s) != 1)
2046 wpa_supplicant_req_scan(wpa_s, 0, 0);
86b89452
WS
2047 }
2048}
2049
2050
2051/**
2052 * wpa_supplicant_disable_network - Mark a configured network as disabled
2053 * @wpa_s: wpa_supplicant structure for a network interface
2054 * @ssid: wpa_ssid structure for a configured network or %NULL
2055 *
2056 * Disables the specified network or all networks if no network specified.
2057 */
2058void wpa_supplicant_disable_network(struct wpa_supplicant *wpa_s,
2059 struct wpa_ssid *ssid)
2060{
2061 struct wpa_ssid *other_ssid;
2062 int was_disabled;
2063
2064 if (ssid == NULL) {
725fc39e
DS
2065 if (wpa_s->sched_scanning)
2066 wpa_supplicant_cancel_sched_scan(wpa_s);
2067
4dac0245
JM
2068 for (other_ssid = wpa_s->conf->ssid; other_ssid;
2069 other_ssid = other_ssid->next) {
86b89452 2070 was_disabled = other_ssid->disabled;
4dac0245
JM
2071 if (was_disabled == 2)
2072 continue; /* do not change persistent P2P group
2073 * data */
86b89452
WS
2074
2075 other_ssid->disabled = 1;
2076
2077 if (was_disabled != other_ssid->disabled)
2078 wpas_notify_network_enabled_changed(
2079 wpa_s, other_ssid);
86b89452
WS
2080 }
2081 if (wpa_s->current_ssid)
07783eaa 2082 wpa_supplicant_deauthenticate(
86b89452 2083 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
4dac0245 2084 } else if (ssid->disabled != 2) {
86b89452 2085 if (ssid == wpa_s->current_ssid)
07783eaa 2086 wpa_supplicant_deauthenticate(
86b89452
WS
2087 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
2088
2089 was_disabled = ssid->disabled;
2090
2091 ssid->disabled = 1;
2092
725fc39e 2093 if (was_disabled != ssid->disabled) {
86b89452 2094 wpas_notify_network_enabled_changed(wpa_s, ssid);
725fc39e
DS
2095 if (wpa_s->sched_scanning) {
2096 wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan "
2097 "to remove network from filters");
2098 wpa_supplicant_cancel_sched_scan(wpa_s);
2099 wpa_supplicant_req_scan(wpa_s, 0, 0);
2100 }
2101 }
86b89452
WS
2102 }
2103}
2104
2105
2106/**
2107 * wpa_supplicant_select_network - Attempt association with a network
2108 * @wpa_s: wpa_supplicant structure for a network interface
2109 * @ssid: wpa_ssid structure for a configured network or %NULL for any network
2110 */
2111void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
2112 struct wpa_ssid *ssid)
2113{
2114
2115 struct wpa_ssid *other_ssid;
d93dfbd5 2116 int disconnected = 0;
86b89452 2117
d93dfbd5 2118 if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) {
07783eaa 2119 wpa_supplicant_deauthenticate(
86b89452 2120 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
d93dfbd5
JM
2121 disconnected = 1;
2122 }
86b89452 2123
00e5e3d5
JM
2124 if (ssid)
2125 wpas_clear_temp_disabled(wpa_s, ssid, 1);
2126
86b89452
WS
2127 /*
2128 * Mark all other networks disabled or mark all networks enabled if no
2129 * network specified.
2130 */
4dac0245
JM
2131 for (other_ssid = wpa_s->conf->ssid; other_ssid;
2132 other_ssid = other_ssid->next) {
86b89452 2133 int was_disabled = other_ssid->disabled;
4dac0245
JM
2134 if (was_disabled == 2)
2135 continue; /* do not change persistent P2P group data */
86b89452
WS
2136
2137 other_ssid->disabled = ssid ? (ssid->id != other_ssid->id) : 0;
00e5e3d5
JM
2138 if (was_disabled && !other_ssid->disabled)
2139 wpas_clear_temp_disabled(wpa_s, other_ssid, 0);
86b89452
WS
2140
2141 if (was_disabled != other_ssid->disabled)
2142 wpas_notify_network_enabled_changed(wpa_s, other_ssid);
86b89452 2143 }
2a6f78fb
JJ
2144
2145 if (ssid && ssid == wpa_s->current_ssid && wpa_s->current_ssid) {
2146 /* We are already associated with the selected network */
2147 wpa_printf(MSG_DEBUG, "Already associated with the "
2148 "selected network - do nothing");
2149 return;
2150 }
2151
25a8f9e3 2152 if (ssid) {
96efeeb6 2153 wpa_s->current_ssid = ssid;
25a8f9e3
JM
2154 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
2155 }
7dcdcfd6 2156 wpa_s->connect_without_scan = NULL;
86b89452
WS
2157 wpa_s->disconnected = 0;
2158 wpa_s->reassociate = 1;
cecdddc1
PS
2159
2160 if (wpa_supplicant_fast_associate(wpa_s) != 1)
2161 wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
86b89452 2162
a1641d26
JM
2163 if (ssid)
2164 wpas_notify_network_selected(wpa_s, ssid);
86b89452
WS
2165}
2166
2167
bdec7ee5
MS
2168/**
2169 * wpas_set_pkcs11_engine_and_module_path - Set PKCS #11 engine and module path
2170 * @wpa_s: wpa_supplicant structure for a network interface
2171 * @pkcs11_engine_path: PKCS #11 engine path or NULL
2172 * @pkcs11_module_path: PKCS #11 module path or NULL
2173 * Returns: 0 on success; -1 on failure
2174 *
2175 * Sets the PKCS #11 engine and module path. Both have to be NULL or a valid
2176 * path. If resetting the EAPOL state machine with the new PKCS #11 engine and
2177 * module path fails the paths will be reset to the default value (NULL).
2178 */
2179int wpas_set_pkcs11_engine_and_module_path(struct wpa_supplicant *wpa_s,
2180 const char *pkcs11_engine_path,
2181 const char *pkcs11_module_path)
2182{
2183 char *pkcs11_engine_path_copy = NULL;
2184 char *pkcs11_module_path_copy = NULL;
2185
2186 if (pkcs11_engine_path != NULL) {
2187 pkcs11_engine_path_copy = os_strdup(pkcs11_engine_path);
2188 if (pkcs11_engine_path_copy == NULL)
2189 return -1;
2190 }
2191 if (pkcs11_module_path != NULL) {
2192 pkcs11_module_path_copy = os_strdup(pkcs11_module_path);
04c366cb 2193 if (pkcs11_module_path_copy == NULL) {
bdec7ee5
MS
2194 os_free(pkcs11_engine_path_copy);
2195 return -1;
2196 }
2197 }
2198
2199 os_free(wpa_s->conf->pkcs11_engine_path);
2200 os_free(wpa_s->conf->pkcs11_module_path);
2201 wpa_s->conf->pkcs11_engine_path = pkcs11_engine_path_copy;
2202 wpa_s->conf->pkcs11_module_path = pkcs11_module_path_copy;
2203
2204 wpa_sm_set_eapol(wpa_s->wpa, NULL);
2205 eapol_sm_deinit(wpa_s->eapol);
2206 wpa_s->eapol = NULL;
2207 if (wpa_supplicant_init_eapol(wpa_s)) {
2208 /* Error -> Reset paths to the default value (NULL) once. */
2209 if (pkcs11_engine_path != NULL && pkcs11_module_path != NULL)
2210 wpas_set_pkcs11_engine_and_module_path(wpa_s, NULL,
2211 NULL);
2212
2213 return -1;
2214 }
2215 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
2216
2217 return 0;
2218}
2219
2220
86b89452
WS
2221/**
2222 * wpa_supplicant_set_ap_scan - Set AP scan mode for interface
2223 * @wpa_s: wpa_supplicant structure for a network interface
2224 * @ap_scan: AP scan mode
2225 * Returns: 0 if succeed or -1 if ap_scan has an invalid value
2226 *
2227 */
2228int wpa_supplicant_set_ap_scan(struct wpa_supplicant *wpa_s, int ap_scan)
2229{
2230
2231 int old_ap_scan;
2232
2233 if (ap_scan < 0 || ap_scan > 2)
2234 return -1;
2235
48f8e036
DS
2236#ifdef ANDROID
2237 if (ap_scan == 2 && ap_scan != wpa_s->conf->ap_scan &&
2238 wpa_s->wpa_state >= WPA_ASSOCIATING &&
2239 wpa_s->wpa_state < WPA_COMPLETED) {
2240 wpa_printf(MSG_ERROR, "ap_scan = %d (%d) rejected while "
2241 "associating", wpa_s->conf->ap_scan, ap_scan);
2242 return 0;
2243 }
2244#endif /* ANDROID */
2245
86b89452
WS
2246 old_ap_scan = wpa_s->conf->ap_scan;
2247 wpa_s->conf->ap_scan = ap_scan;
2248
2249 if (old_ap_scan != wpa_s->conf->ap_scan)
2250 wpas_notify_ap_scan_changed(wpa_s);
2251
2252 return 0;
2253}
2254
2255
78633c37
SL
2256/**
2257 * wpa_supplicant_set_bss_expiration_age - Set BSS entry expiration age
2258 * @wpa_s: wpa_supplicant structure for a network interface
2259 * @expire_age: Expiration age in seconds
2260 * Returns: 0 if succeed or -1 if expire_age has an invalid value
2261 *
2262 */
2263int wpa_supplicant_set_bss_expiration_age(struct wpa_supplicant *wpa_s,
2264 unsigned int bss_expire_age)
2265{
2266 if (bss_expire_age < 10) {
2267 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration age %u",
2268 bss_expire_age);
2269 return -1;
2270 }
2271 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration age: %d sec",
2272 bss_expire_age);
2273 wpa_s->conf->bss_expiration_age = bss_expire_age;
2274
2275 return 0;
2276}
2277
2278
2279/**
2280 * wpa_supplicant_set_bss_expiration_count - Set BSS entry expiration scan count
2281 * @wpa_s: wpa_supplicant structure for a network interface
2282 * @expire_count: number of scans after which an unseen BSS is reclaimed
2283 * Returns: 0 if succeed or -1 if expire_count has an invalid value
2284 *
2285 */
2286int wpa_supplicant_set_bss_expiration_count(struct wpa_supplicant *wpa_s,
2287 unsigned int bss_expire_count)
2288{
2289 if (bss_expire_count < 1) {
2290 wpa_msg(wpa_s, MSG_ERROR, "Invalid bss expiration count %u",
2291 bss_expire_count);
2292 return -1;
2293 }
2294 wpa_msg(wpa_s, MSG_DEBUG, "Setting bss expiration scan count: %u",
2295 bss_expire_count);
2296 wpa_s->conf->bss_expiration_scan_count = bss_expire_count;
2297
2298 return 0;
2299}
2300
2301
c6e86b63
MA
2302/**
2303 * wpa_supplicant_set_scan_interval - Set scan interval
2304 * @wpa_s: wpa_supplicant structure for a network interface
2305 * @scan_interval: scan interval in seconds
2306 * Returns: 0 if succeed or -1 if scan_interval has an invalid value
2307 *
2308 */
2309int wpa_supplicant_set_scan_interval(struct wpa_supplicant *wpa_s,
2310 int scan_interval)
2311{
2312 if (scan_interval < 0) {
2313 wpa_msg(wpa_s, MSG_ERROR, "Invalid scan interval %d",
2314 scan_interval);
2315 return -1;
2316 }
2317 wpa_msg(wpa_s, MSG_DEBUG, "Setting scan interval: %d sec",
2318 scan_interval);
9e737f08 2319 wpa_supplicant_update_scan_int(wpa_s, scan_interval);
c6e86b63
MA
2320
2321 return 0;
2322}
2323
2324
86b89452
WS
2325/**
2326 * wpa_supplicant_set_debug_params - Set global debug params
2327 * @global: wpa_global structure
2328 * @debug_level: debug level
2329 * @debug_timestamp: determines if show timestamp in debug data
2330 * @debug_show_keys: determines if show keys in debug data
2331 * Returns: 0 if succeed or -1 if debug_level has wrong value
2332 */
2333int wpa_supplicant_set_debug_params(struct wpa_global *global, int debug_level,
2334 int debug_timestamp, int debug_show_keys)
2335{
2336
2337 int old_level, old_timestamp, old_show_keys;
2338
2339 /* check for allowed debuglevels */
14dc0011
PS
2340 if (debug_level != MSG_EXCESSIVE &&
2341 debug_level != MSG_MSGDUMP &&
86b89452
WS
2342 debug_level != MSG_DEBUG &&
2343 debug_level != MSG_INFO &&
2344 debug_level != MSG_WARNING &&
2345 debug_level != MSG_ERROR)
2346 return -1;
2347
2348 old_level = wpa_debug_level;
2349 old_timestamp = wpa_debug_timestamp;
2350 old_show_keys = wpa_debug_show_keys;
2351
2352 wpa_debug_level = debug_level;
2353 wpa_debug_timestamp = debug_timestamp ? 1 : 0;
2354 wpa_debug_show_keys = debug_show_keys ? 1 : 0;
2355
db9133ac
WS
2356 if (wpa_debug_level != old_level)
2357 wpas_notify_debug_level_changed(global);
2358 if (wpa_debug_timestamp != old_timestamp)
2359 wpas_notify_debug_timestamp_changed(global);
2360 if (wpa_debug_show_keys != old_show_keys)
2361 wpas_notify_debug_show_keys_changed(global);
86b89452
WS
2362
2363 return 0;
2364}
2365
2366
6fc6879b
JM
2367/**
2368 * wpa_supplicant_get_ssid - Get a pointer to the current network structure
2369 * @wpa_s: Pointer to wpa_supplicant data
2370 * Returns: A pointer to the current network structure or %NULL on failure
2371 */
2372struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
2373{
2374 struct wpa_ssid *entry;
2375 u8 ssid[MAX_SSID_LEN];
2376 int res;
2377 size_t ssid_len;
2378 u8 bssid[ETH_ALEN];
2379 int wired;
2380
17fbb751
JM
2381 res = wpa_drv_get_ssid(wpa_s, ssid);
2382 if (res < 0) {
2383 wpa_msg(wpa_s, MSG_WARNING, "Could not read SSID from "
2384 "driver");
2385 return NULL;
6fc6879b 2386 }
17fbb751 2387 ssid_len = res;
6fc6879b 2388
17fbb751 2389 if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
f049052b
BG
2390 wpa_msg(wpa_s, MSG_WARNING, "Could not read BSSID from "
2391 "driver");
6fc6879b
JM
2392 return NULL;
2393 }
2394
c2a04078
JM
2395 wired = wpa_s->conf->ap_scan == 0 &&
2396 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_WIRED);
6fc6879b
JM
2397
2398 entry = wpa_s->conf->ssid;
2399 while (entry) {
349493bd 2400 if (!wpas_network_disabled(wpa_s, entry) &&
6fc6879b
JM
2401 ((ssid_len == entry->ssid_len &&
2402 os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
2403 (!entry->bssid_set ||
2404 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
2405 return entry;
24c23d1b 2406#ifdef CONFIG_WPS
349493bd 2407 if (!wpas_network_disabled(wpa_s, entry) &&
24c23d1b
JM
2408 (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
2409 (entry->ssid == NULL || entry->ssid_len == 0) &&
2410 (!entry->bssid_set ||
2411 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
2412 return entry;
2413#endif /* CONFIG_WPS */
7d232e23 2414
349493bd 2415 if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
7d232e23
ZC
2416 entry->ssid_len == 0 &&
2417 os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
2418 return entry;
2419
6fc6879b
JM
2420 entry = entry->next;
2421 }
2422
2423 return NULL;
2424}
2425
2426
7756114f
JM
2427static int select_driver(struct wpa_supplicant *wpa_s, int i)
2428{
2429 struct wpa_global *global = wpa_s->global;
2430
2431 if (wpa_drivers[i]->global_init && global->drv_priv[i] == NULL) {
2432 global->drv_priv[i] = wpa_drivers[i]->global_init();
2433 if (global->drv_priv[i] == NULL) {
2434 wpa_printf(MSG_ERROR, "Failed to initialize driver "
2435 "'%s'", wpa_drivers[i]->name);
2436 return -1;
2437 }
2438 }
2439
2440 wpa_s->driver = wpa_drivers[i];
2441 wpa_s->global_drv_priv = global->drv_priv[i];
2442
2443 return 0;
2444}
2445
2446
6fc6879b
JM
2447static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
2448 const char *name)
2449{
2450 int i;
362f781e 2451 size_t len;
74b1c84a 2452 const char *pos, *driver = name;
6fc6879b
JM
2453
2454 if (wpa_s == NULL)
2455 return -1;
2456
c5121837 2457 if (wpa_drivers[0] == NULL) {
f049052b
BG
2458 wpa_msg(wpa_s, MSG_ERROR, "No driver interfaces build into "
2459 "wpa_supplicant");
6fc6879b
JM
2460 return -1;
2461 }
2462
2463 if (name == NULL) {
2464 /* default to first driver in the list */
7756114f 2465 return select_driver(wpa_s, 0);
6fc6879b
JM
2466 }
2467
74b1c84a
SO
2468 do {
2469 pos = os_strchr(driver, ',');
2470 if (pos)
2471 len = pos - driver;
2472 else
2473 len = os_strlen(driver);
2474
2475 for (i = 0; wpa_drivers[i]; i++) {
2476 if (os_strlen(wpa_drivers[i]->name) == len &&
2477 os_strncmp(driver, wpa_drivers[i]->name, len) ==
0f4668ce
DW
2478 0) {
2479 /* First driver that succeeds wins */
2480 if (select_driver(wpa_s, i) == 0)
2481 return 0;
2482 }
6fc6879b 2483 }
74b1c84a
SO
2484
2485 driver = pos + 1;
2486 } while (pos);
6fc6879b 2487
f049052b 2488 wpa_msg(wpa_s, MSG_ERROR, "Unsupported driver '%s'", name);
6fc6879b
JM
2489 return -1;
2490}
2491
2492
a8e0505b
JM
2493/**
2494 * wpa_supplicant_rx_eapol - Deliver a received EAPOL frame to wpa_supplicant
2495 * @ctx: Context pointer (wpa_s); this is the ctx variable registered
2496 * with struct wpa_driver_ops::init()
2497 * @src_addr: Source address of the EAPOL frame
2498 * @buf: EAPOL data starting from the EAPOL header (i.e., no Ethernet header)
2499 * @len: Length of the EAPOL data
2500 *
2501 * This function is called for each received EAPOL frame. Most driver
2502 * interfaces rely on more generic OS mechanism for receiving frames through
2503 * l2_packet, but if such a mechanism is not available, the driver wrapper may
2504 * take care of received EAPOL frames and deliver them to the core supplicant
2505 * code by calling this function.
2506 */
6fc6879b
JM
2507void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
2508 const u8 *buf, size_t len)
2509{
2510 struct wpa_supplicant *wpa_s = ctx;
2511
f049052b 2512 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
6fc6879b
JM
2513 wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
2514
db76aa64
JM
2515#ifdef CONFIG_PEERKEY
2516 if (wpa_s->wpa_state > WPA_ASSOCIATED && wpa_s->current_ssid &&
2517 wpa_s->current_ssid->peerkey &&
2518 !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
2519 wpa_sm_rx_eapol_peerkey(wpa_s->wpa, src_addr, buf, len) == 1) {
2520 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: Processed PeerKey EAPOL-Key");
2521 return;
2522 }
2523#endif /* CONFIG_PEERKEY */
2524
3ab35a66
JM
2525 if (wpa_s->wpa_state < WPA_ASSOCIATED ||
2526 (wpa_s->last_eapol_matches_bssid &&
2527#ifdef CONFIG_AP
2528 !wpa_s->ap_iface &&
2529#endif /* CONFIG_AP */
2530 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) != 0)) {
1ff73338
JM
2531 /*
2532 * There is possible race condition between receiving the
2533 * association event and the EAPOL frame since they are coming
2534 * through different paths from the driver. In order to avoid
2535 * issues in trying to process the EAPOL frame before receiving
2536 * association information, lets queue it for processing until
3ab35a66
JM
2537 * the association event is received. This may also be needed in
2538 * driver-based roaming case, so also use src_addr != BSSID as a
2539 * trigger if we have previously confirmed that the
2540 * Authenticator uses BSSID as the src_addr (which is not the
2541 * case with wired IEEE 802.1X).
1ff73338 2542 */
f049052b 2543 wpa_dbg(wpa_s, MSG_DEBUG, "Not associated - Delay processing "
3ab35a66
JM
2544 "of received EAPOL frame (state=%s bssid=" MACSTR ")",
2545 wpa_supplicant_state_txt(wpa_s->wpa_state),
2546 MAC2STR(wpa_s->bssid));
1ff73338
JM
2547 wpabuf_free(wpa_s->pending_eapol_rx);
2548 wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
2549 if (wpa_s->pending_eapol_rx) {
c2be937c 2550 os_get_reltime(&wpa_s->pending_eapol_rx_time);
1ff73338
JM
2551 os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
2552 ETH_ALEN);
2553 }
2554 return;
2555 }
2556
3ab35a66
JM
2557 wpa_s->last_eapol_matches_bssid =
2558 os_memcmp(src_addr, wpa_s->bssid, ETH_ALEN) == 0;
2559
db149ac9
JM
2560#ifdef CONFIG_AP
2561 if (wpa_s->ap_iface) {
2562 wpa_supplicant_ap_rx_eapol(wpa_s, src_addr, buf, len);
2563 return;
2564 }
2565#endif /* CONFIG_AP */
2566
6fc6879b 2567 if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
f049052b
BG
2568 wpa_dbg(wpa_s, MSG_DEBUG, "Ignored received EAPOL frame since "
2569 "no key management is configured");
6fc6879b
JM
2570 return;
2571 }
2572
2573 if (wpa_s->eapol_received == 0 &&
c2a04078 2574 (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) ||
56586197 2575 !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) ||
9c972abb
JM
2576 wpa_s->wpa_state != WPA_COMPLETED) &&
2577 (wpa_s->current_ssid == NULL ||
2578 wpa_s->current_ssid->mode != IEEE80211_MODE_IBSS)) {
6fc6879b
JM
2579 /* Timeout for completing IEEE 802.1X and WPA authentication */
2580 wpa_supplicant_req_auth_timeout(
2581 wpa_s,
56586197 2582 (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
a6f06dab
AT
2583 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
2584 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) ?
6fc6879b
JM
2585 70 : 10, 0);
2586 }
2587 wpa_s->eapol_received++;
2588
2589 if (wpa_s->countermeasures) {
f049052b
BG
2590 wpa_msg(wpa_s, MSG_INFO, "WPA: Countermeasures - dropped "
2591 "EAPOL packet");
6fc6879b
JM
2592 return;
2593 }
2594
8be18440
JM
2595#ifdef CONFIG_IBSS_RSN
2596 if (wpa_s->current_ssid &&
d7dcba70 2597 wpa_s->current_ssid->mode == WPAS_MODE_IBSS) {
8be18440
JM
2598 ibss_rsn_rx_eapol(wpa_s->ibss_rsn, src_addr, buf, len);
2599 return;
2600 }
2601#endif /* CONFIG_IBSS_RSN */
2602
6fc6879b
JM
2603 /* Source address of the incoming EAPOL frame could be compared to the
2604 * current BSSID. However, it is possible that a centralized
2605 * Authenticator could be using another MAC address than the BSSID of
2606 * an AP, so just allow any address to be used for now. The replies are
2607 * still sent to the current BSSID (if available), though. */
2608
2609 os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
56586197 2610 if (!wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) &&
6fc6879b
JM
2611 eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
2612 return;
2613 wpa_drv_poll(wpa_s);
c2a04078 2614 if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE))
6fc6879b 2615 wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
56586197 2616 else if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
6fc6879b
JM
2617 /*
2618 * Set portValid = TRUE here since we are going to skip 4-way
2619 * handshake processing which would normally set portValid. We
2620 * need this to allow the EAPOL state machines to be completed
2621 * without going through EAPOL-Key handshake.
2622 */
2623 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
2624 }
2625}
2626
2627
bfba8deb 2628int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
6fc6879b 2629{
6fc6879b
JM
2630 if (wpa_s->driver->send_eapol) {
2631 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
2632 if (addr)
2633 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
1c42b42f
JM
2634 } else if ((!wpa_s->p2p_mgmt ||
2635 !(wpa_s->drv_flags &
2636 WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
c68f6200 2637 !(wpa_s->drv_flags &
fdadd5fe 2638 WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
bfba8deb 2639 l2_packet_deinit(wpa_s->l2);
6fc6879b
JM
2640 wpa_s->l2 = l2_packet_init(wpa_s->ifname,
2641 wpa_drv_get_mac_addr(wpa_s),
2642 ETH_P_EAPOL,
2643 wpa_supplicant_rx_eapol, wpa_s, 0);
2644 if (wpa_s->l2 == NULL)
2645 return -1;
fdadd5fe
JM
2646 } else {
2647 const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
2648 if (addr)
2649 os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
6fc6879b
JM
2650 }
2651
2652 if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
f049052b 2653 wpa_msg(wpa_s, MSG_ERROR, "Failed to get own L2 address");
6fc6879b
JM
2654 return -1;
2655 }
2656
bfba8deb
JM
2657 return 0;
2658}
2659
2660
25f839c6
JM
2661static void wpa_supplicant_rx_eapol_bridge(void *ctx, const u8 *src_addr,
2662 const u8 *buf, size_t len)
2663{
2664 struct wpa_supplicant *wpa_s = ctx;
2665 const struct l2_ethhdr *eth;
2666
2667 if (len < sizeof(*eth))
2668 return;
2669 eth = (const struct l2_ethhdr *) buf;
2670
2671 if (os_memcmp(eth->h_dest, wpa_s->own_addr, ETH_ALEN) != 0 &&
2672 !(eth->h_dest[0] & 0x01)) {
2673 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
2674 " (bridge - not for this interface - ignore)",
2675 MAC2STR(src_addr), MAC2STR(eth->h_dest));
2676 return;
2677 }
2678
2679 wpa_dbg(wpa_s, MSG_DEBUG, "RX EAPOL from " MACSTR " to " MACSTR
2680 " (bridge)", MAC2STR(src_addr), MAC2STR(eth->h_dest));
2681 wpa_supplicant_rx_eapol(wpa_s, src_addr, buf + sizeof(*eth),
2682 len - sizeof(*eth));
2683}
2684
2685
bfba8deb
JM
2686/**
2687 * wpa_supplicant_driver_init - Initialize driver interface parameters
2688 * @wpa_s: Pointer to wpa_supplicant data
2689 * Returns: 0 on success, -1 on failure
2690 *
2691 * This function is called to initialize driver interface parameters.
2692 * wpa_drv_init() must have been called before this function to initialize the
2693 * driver interface.
2694 */
2695int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
2696{
2697 static int interface_count = 0;
2698
2699 if (wpa_supplicant_update_mac_addr(wpa_s) < 0)
2700 return -1;
2701
c68f6200
AS
2702 wpa_dbg(wpa_s, MSG_DEBUG, "Own MAC address: " MACSTR,
2703 MAC2STR(wpa_s->own_addr));
2704 wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
2705
6fc6879b 2706 if (wpa_s->bridge_ifname[0]) {
f049052b
BG
2707 wpa_dbg(wpa_s, MSG_DEBUG, "Receiving packets from bridge "
2708 "interface '%s'", wpa_s->bridge_ifname);
6fc6879b
JM
2709 wpa_s->l2_br = l2_packet_init(wpa_s->bridge_ifname,
2710 wpa_s->own_addr,
2711 ETH_P_EAPOL,
25f839c6
JM
2712 wpa_supplicant_rx_eapol_bridge,
2713 wpa_s, 1);
6fc6879b 2714 if (wpa_s->l2_br == NULL) {
f049052b
BG
2715 wpa_msg(wpa_s, MSG_ERROR, "Failed to open l2_packet "
2716 "connection for the bridge interface '%s'",
2717 wpa_s->bridge_ifname);
6fc6879b
JM
2718 return -1;
2719 }
2720 }
2721
6fc6879b
JM
2722 wpa_clear_keys(wpa_s, NULL);
2723
2724 /* Make sure that TKIP countermeasures are not left enabled (could
2725 * happen if wpa_supplicant is killed during countermeasures. */
2726 wpa_drv_set_countermeasures(wpa_s, 0);
2727
f049052b 2728 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
6fc6879b
JM
2729 wpa_drv_flush_pmkid(wpa_s);
2730
ba2a573c 2731 wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
b3aa456b
ES
2732 wpa_s->prev_scan_wildcard = 0;
2733
349493bd 2734 if (wpa_supplicant_enabled_networks(wpa_s)) {
a0e9d892
AS
2735 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
2736 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
2737 interface_count = 0;
2738 }
3a94adbf 2739 if (!wpa_s->p2p_mgmt &&
5d0d72a3
BG
2740 wpa_supplicant_delayed_sched_scan(wpa_s,
2741 interface_count % 3,
6a90053c 2742 100000))
5d0d72a3 2743 wpa_supplicant_req_scan(wpa_s, interface_count % 3,
a4cba8f1 2744 100000);
74e259ec
JM
2745 interface_count++;
2746 } else
2747 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
6fc6879b
JM
2748
2749 return 0;
2750}
2751
2752
2753static int wpa_supplicant_daemon(const char *pid_file)
2754{
2755 wpa_printf(MSG_DEBUG, "Daemonize..");
2756 return os_daemonize(pid_file);
2757}
2758
2759
2760static struct wpa_supplicant * wpa_supplicant_alloc(void)
2761{
2762 struct wpa_supplicant *wpa_s;
2763
2764 wpa_s = os_zalloc(sizeof(*wpa_s));
2765 if (wpa_s == NULL)
2766 return NULL;
4115303b 2767 wpa_s->scan_req = INITIAL_SCAN_REQ;
67b9bd08 2768 wpa_s->scan_interval = 5;
c302f207 2769 wpa_s->new_connection = 1;
b22128ef 2770 wpa_s->parent = wpa_s;
cbdf3507 2771 wpa_s->sched_scanning = 0;
6fc6879b
JM
2772
2773 return wpa_s;
2774}
2775
2776
80e8a5ee
BG
2777#ifdef CONFIG_HT_OVERRIDES
2778
2779static int wpa_set_htcap_mcs(struct wpa_supplicant *wpa_s,
2780 struct ieee80211_ht_capabilities *htcaps,
2781 struct ieee80211_ht_capabilities *htcaps_mask,
2782 const char *ht_mcs)
2783{
2784 /* parse ht_mcs into hex array */
2785 int i;
2786 const char *tmp = ht_mcs;
2787 char *end = NULL;
2788
2789 /* If ht_mcs is null, do not set anything */
2790 if (!ht_mcs)
2791 return 0;
2792
2793 /* This is what we are setting in the kernel */
2794 os_memset(&htcaps->supported_mcs_set, 0, IEEE80211_HT_MCS_MASK_LEN);
2795
2796 wpa_msg(wpa_s, MSG_DEBUG, "set_htcap, ht_mcs -:%s:-", ht_mcs);
2797
2798 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
2799 errno = 0;
2800 long v = strtol(tmp, &end, 16);
2801 if (errno == 0) {
2802 wpa_msg(wpa_s, MSG_DEBUG,
2803 "htcap value[%i]: %ld end: %p tmp: %p",
2804 i, v, end, tmp);
2805 if (end == tmp)
2806 break;
2807
2808 htcaps->supported_mcs_set[i] = v;
2809 tmp = end;
2810 } else {
2811 wpa_msg(wpa_s, MSG_ERROR,
2812 "Failed to parse ht-mcs: %s, error: %s\n",
2813 ht_mcs, strerror(errno));
2814 return -1;
2815 }
2816 }
2817
2818 /*
2819 * If we were able to parse any values, then set mask for the MCS set.
2820 */
2821 if (i) {
2822 os_memset(&htcaps_mask->supported_mcs_set, 0xff,
2823 IEEE80211_HT_MCS_MASK_LEN - 1);
2824 /* skip the 3 reserved bits */
2825 htcaps_mask->supported_mcs_set[IEEE80211_HT_MCS_MASK_LEN - 1] =
2826 0x1f;
2827 }
2828
2829 return 0;
2830}
2831
2832
2833static int wpa_disable_max_amsdu(struct wpa_supplicant *wpa_s,
2834 struct ieee80211_ht_capabilities *htcaps,
2835 struct ieee80211_ht_capabilities *htcaps_mask,
2836 int disabled)
2837{
2838 u16 msk;
2839
2840 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_max_amsdu: %d", disabled);
2841
2842 if (disabled == -1)
2843 return 0;
2844
2845 msk = host_to_le16(HT_CAP_INFO_MAX_AMSDU_SIZE);
2846 htcaps_mask->ht_capabilities_info |= msk;
2847 if (disabled)
2848 htcaps->ht_capabilities_info &= msk;
2849 else
2850 htcaps->ht_capabilities_info |= msk;
2851
2852 return 0;
2853}
2854
2855
2856static int wpa_set_ampdu_factor(struct wpa_supplicant *wpa_s,
2857 struct ieee80211_ht_capabilities *htcaps,
2858 struct ieee80211_ht_capabilities *htcaps_mask,
2859 int factor)
2860{
2861 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_factor: %d", factor);
2862
2863 if (factor == -1)
2864 return 0;
2865
2866 if (factor < 0 || factor > 3) {
2867 wpa_msg(wpa_s, MSG_ERROR, "ampdu_factor: %d out of range. "
2868 "Must be 0-3 or -1", factor);
2869 return -EINVAL;
2870 }
2871
2872 htcaps_mask->a_mpdu_params |= 0x3; /* 2 bits for factor */
2873 htcaps->a_mpdu_params &= ~0x3;
2874 htcaps->a_mpdu_params |= factor & 0x3;
2875
2876 return 0;
2877}
2878
2879
2880static int wpa_set_ampdu_density(struct wpa_supplicant *wpa_s,
2881 struct ieee80211_ht_capabilities *htcaps,
2882 struct ieee80211_ht_capabilities *htcaps_mask,
2883 int density)
2884{
2885 wpa_msg(wpa_s, MSG_DEBUG, "set_ampdu_density: %d", density);
2886
2887 if (density == -1)
2888 return 0;
2889
2890 if (density < 0 || density > 7) {
2891 wpa_msg(wpa_s, MSG_ERROR,
2892 "ampdu_density: %d out of range. Must be 0-7 or -1.",
2893 density);
2894 return -EINVAL;
2895 }
2896
2897 htcaps_mask->a_mpdu_params |= 0x1C;
2898 htcaps->a_mpdu_params &= ~(0x1C);
2899 htcaps->a_mpdu_params |= (density << 2) & 0x1C;
2900
2901 return 0;
2902}
2903
2904
2905static int wpa_set_disable_ht40(struct wpa_supplicant *wpa_s,
2906 struct ieee80211_ht_capabilities *htcaps,
2907 struct ieee80211_ht_capabilities *htcaps_mask,
2908 int disabled)
2909{
2910 /* Masking these out disables HT40 */
2911 u16 msk = host_to_le16(HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET |
2912 HT_CAP_INFO_SHORT_GI40MHZ);
2913
2914 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ht40: %d", disabled);
2915
2916 if (disabled)
2917 htcaps->ht_capabilities_info &= ~msk;
2918 else
2919 htcaps->ht_capabilities_info |= msk;
2920
2921 htcaps_mask->ht_capabilities_info |= msk;
2922
2923 return 0;
2924}
2925
2926
a90497f8
BG
2927static int wpa_set_disable_sgi(struct wpa_supplicant *wpa_s,
2928 struct ieee80211_ht_capabilities *htcaps,
2929 struct ieee80211_ht_capabilities *htcaps_mask,
2930 int disabled)
2931{
2932 /* Masking these out disables SGI */
2933 u16 msk = host_to_le16(HT_CAP_INFO_SHORT_GI20MHZ |
2934 HT_CAP_INFO_SHORT_GI40MHZ);
2935
2936 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_sgi: %d", disabled);
2937
2938 if (disabled)
2939 htcaps->ht_capabilities_info &= ~msk;
2940 else
2941 htcaps->ht_capabilities_info |= msk;
2942
2943 htcaps_mask->ht_capabilities_info |= msk;
2944
2945 return 0;
2946}
2947
2948
39a5800f
PK
2949static int wpa_set_disable_ldpc(struct wpa_supplicant *wpa_s,
2950 struct ieee80211_ht_capabilities *htcaps,
2951 struct ieee80211_ht_capabilities *htcaps_mask,
2952 int disabled)
2953{
2954 /* Masking these out disables LDPC */
2955 u16 msk = host_to_le16(HT_CAP_INFO_LDPC_CODING_CAP);
2956
2957 wpa_msg(wpa_s, MSG_DEBUG, "set_disable_ldpc: %d", disabled);
2958
2959 if (disabled)
2960 htcaps->ht_capabilities_info &= ~msk;
2961 else
2962 htcaps->ht_capabilities_info |= msk;
2963
2964 htcaps_mask->ht_capabilities_info |= msk;
2965
2966 return 0;
2967}
2968
2969
80e8a5ee
BG
2970void wpa_supplicant_apply_ht_overrides(
2971 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
2972 struct wpa_driver_associate_params *params)
2973{
2974 struct ieee80211_ht_capabilities *htcaps;
2975 struct ieee80211_ht_capabilities *htcaps_mask;
2976
2977 if (!ssid)
2978 return;
2979
2980 params->disable_ht = ssid->disable_ht;
2981 if (!params->htcaps || !params->htcaps_mask)
2982 return;
2983
2984 htcaps = (struct ieee80211_ht_capabilities *) params->htcaps;
2985 htcaps_mask = (struct ieee80211_ht_capabilities *) params->htcaps_mask;
2986 wpa_set_htcap_mcs(wpa_s, htcaps, htcaps_mask, ssid->ht_mcs);
2987 wpa_disable_max_amsdu(wpa_s, htcaps, htcaps_mask,
2988 ssid->disable_max_amsdu);
2989 wpa_set_ampdu_factor(wpa_s, htcaps, htcaps_mask, ssid->ampdu_factor);
2990 wpa_set_ampdu_density(wpa_s, htcaps, htcaps_mask, ssid->ampdu_density);
2991 wpa_set_disable_ht40(wpa_s, htcaps, htcaps_mask, ssid->disable_ht40);
a90497f8 2992 wpa_set_disable_sgi(wpa_s, htcaps, htcaps_mask, ssid->disable_sgi);
39a5800f 2993 wpa_set_disable_ldpc(wpa_s, htcaps, htcaps_mask, ssid->disable_ldpc);
d41cc8cc
JM
2994
2995 if (ssid->ht40_intolerant) {
2996 u16 bit = host_to_le16(HT_CAP_INFO_40MHZ_INTOLERANT);
2997 htcaps->ht_capabilities_info |= bit;
2998 htcaps_mask->ht_capabilities_info |= bit;
2999 }
80e8a5ee
BG
3000}
3001
3002#endif /* CONFIG_HT_OVERRIDES */
3003
3004
e9ee8dc3
JB
3005#ifdef CONFIG_VHT_OVERRIDES
3006void wpa_supplicant_apply_vht_overrides(
3007 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
3008 struct wpa_driver_associate_params *params)
3009{
3010 struct ieee80211_vht_capabilities *vhtcaps;
3011 struct ieee80211_vht_capabilities *vhtcaps_mask;
4f560cde
EP
3012#ifdef CONFIG_HT_OVERRIDES
3013 int max_ampdu;
3014 const u32 max_ampdu_mask = VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX;
3015#endif /* CONFIG_HT_OVERRIDES */
e9ee8dc3
JB
3016
3017 if (!ssid)
3018 return;
3019
3020 params->disable_vht = ssid->disable_vht;
3021
3022 vhtcaps = (void *) params->vhtcaps;
3023 vhtcaps_mask = (void *) params->vhtcaps_mask;
3024
3025 if (!vhtcaps || !vhtcaps_mask)
3026 return;
3027
3028 vhtcaps->vht_capabilities_info = ssid->vht_capa;
3029 vhtcaps_mask->vht_capabilities_info = ssid->vht_capa_mask;
3030
4f560cde
EP
3031#ifdef CONFIG_HT_OVERRIDES
3032 /* if max ampdu is <= 3, we have to make the HT cap the same */
3033 if (ssid->vht_capa_mask & max_ampdu_mask) {
3034 max_ampdu = (ssid->vht_capa & max_ampdu_mask) >>
3035 find_first_bit(max_ampdu_mask);
3036
3037 max_ampdu = max_ampdu < 3 ? max_ampdu : 3;
3038 wpa_set_ampdu_factor(wpa_s,
3039 (void *) params->htcaps,
3040 (void *) params->htcaps_mask,
3041 max_ampdu);
3042 }
3043#endif /* CONFIG_HT_OVERRIDES */
3044
e9ee8dc3
JB
3045#define OVERRIDE_MCS(i) \
3046 if (ssid->vht_tx_mcs_nss_ ##i >= 0) { \
3047 vhtcaps_mask->vht_supported_mcs_set.tx_map |= \
3048 3 << 2 * (i - 1); \
3049 vhtcaps->vht_supported_mcs_set.tx_map |= \
3050 ssid->vht_tx_mcs_nss_ ##i << 2 * (i - 1); \
3051 } \
3052 if (ssid->vht_rx_mcs_nss_ ##i >= 0) { \
3053 vhtcaps_mask->vht_supported_mcs_set.rx_map |= \
3054 3 << 2 * (i - 1); \
3055 vhtcaps->vht_supported_mcs_set.rx_map |= \
3056 ssid->vht_rx_mcs_nss_ ##i << 2 * (i - 1); \
3057 }
3058
3059 OVERRIDE_MCS(1);
3060 OVERRIDE_MCS(2);
3061 OVERRIDE_MCS(3);
3062 OVERRIDE_MCS(4);
3063 OVERRIDE_MCS(5);
3064 OVERRIDE_MCS(6);
3065 OVERRIDE_MCS(7);
3066 OVERRIDE_MCS(8);
3067}
3068#endif /* CONFIG_VHT_OVERRIDES */
3069
3070
f64adcd7
JM
3071static int pcsc_reader_init(struct wpa_supplicant *wpa_s)
3072{
3073#ifdef PCSC_FUNCS
3074 size_t len;
3075
3076 if (!wpa_s->conf->pcsc_reader)
3077 return 0;
3078
22cf7d73 3079 wpa_s->scard = scard_init(wpa_s->conf->pcsc_reader);
f64adcd7
JM
3080 if (!wpa_s->scard)
3081 return 1;
3082
3083 if (wpa_s->conf->pcsc_pin &&
3084 scard_set_pin(wpa_s->scard, wpa_s->conf->pcsc_pin) < 0) {
3085 scard_deinit(wpa_s->scard);
3086 wpa_s->scard = NULL;
3087 wpa_msg(wpa_s, MSG_ERROR, "PC/SC PIN validation failed");
3088 return -1;
3089 }
3090
3091 len = sizeof(wpa_s->imsi) - 1;
3092 if (scard_get_imsi(wpa_s->scard, wpa_s->imsi, &len)) {
3093 scard_deinit(wpa_s->scard);
3094 wpa_s->scard = NULL;
3095 wpa_msg(wpa_s, MSG_ERROR, "Could not read IMSI");
3096 return -1;
3097 }
3098 wpa_s->imsi[len] = '\0';
3099
3100 wpa_s->mnc_len = scard_get_mnc_len(wpa_s->scard);
3101
3102 wpa_printf(MSG_DEBUG, "SCARD: IMSI %s (MNC length %d)",
3103 wpa_s->imsi, wpa_s->mnc_len);
3104
3105 wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
3106 eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
3107#endif /* PCSC_FUNCS */
3108
3109 return 0;
3110}
3111
3112
306ae225
JM
3113int wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
3114{
3115 char *val, *pos;
3116
3117 ext_password_deinit(wpa_s->ext_pw);
3118 wpa_s->ext_pw = NULL;
3119 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, NULL);
3120
3121 if (!wpa_s->conf->ext_password_backend)
3122 return 0;
3123
3124 val = os_strdup(wpa_s->conf->ext_password_backend);
3125 if (val == NULL)
3126 return -1;
3127 pos = os_strchr(val, ':');
3128 if (pos)
3129 *pos++ = '\0';
3130
3131 wpa_printf(MSG_DEBUG, "EXT PW: Initialize backend '%s'", val);
3132
3133 wpa_s->ext_pw = ext_password_init(val, pos);
3134 os_free(val);
3135 if (wpa_s->ext_pw == NULL) {
3136 wpa_printf(MSG_DEBUG, "EXT PW: Failed to initialize backend");
3137 return -1;
3138 }
3139 eapol_sm_set_ext_pw_ctx(wpa_s->eapol, wpa_s->ext_pw);
3140
3141 return 0;
3142}
3143
3144
e4fa8b12
EP
3145static int wpas_check_wowlan_trigger(const char *start, const char *trigger,
3146 int capa_trigger, u8 *param_trigger)
3147{
3148 if (os_strcmp(start, trigger) != 0)
3149 return 0;
3150 if (!capa_trigger)
3151 return 0;
3152
3153 *param_trigger = 1;
3154 return 1;
3155}
3156
3157
a520bf4a
JM
3158static int wpas_set_wowlan_triggers(struct wpa_supplicant *wpa_s,
3159 struct wpa_driver_capa *capa)
e4fa8b12
EP
3160{
3161 struct wowlan_triggers triggers;
3162 char *start, *end, *buf;
3163 int last, ret;
3164
3165 if (!wpa_s->conf->wowlan_triggers)
3166 return 0;
3167
3168 buf = os_strdup(wpa_s->conf->wowlan_triggers);
3169 if (buf == NULL)
3170 return -1;
3171
3172 os_memset(&triggers, 0, sizeof(triggers));
3173
3174#define CHECK_TRIGGER(trigger) \
3175 wpas_check_wowlan_trigger(start, #trigger, \
3176 capa->wowlan_triggers.trigger, \
3177 &triggers.trigger)
3178
3179 start = buf;
3180 while (*start != '\0') {
3181 while (isblank(*start))
3182 start++;
3183 if (*start == '\0')
3184 break;
3185 end = start;
3186 while (!isblank(*end) && *end != '\0')
3187 end++;
3188 last = *end == '\0';
3189 *end = '\0';
3190
3191 if (!CHECK_TRIGGER(any) &&
3192 !CHECK_TRIGGER(disconnect) &&
3193 !CHECK_TRIGGER(magic_pkt) &&
3194 !CHECK_TRIGGER(gtk_rekey_failure) &&
3195 !CHECK_TRIGGER(eap_identity_req) &&
3196 !CHECK_TRIGGER(four_way_handshake) &&
3197 !CHECK_TRIGGER(rfkill_release)) {
3198 wpa_printf(MSG_DEBUG,
3199 "Unknown/unsupported wowlan trigger '%s'",
3200 start);
3201 ret = -1;
3202 goto out;
3203 }
3204
3205 if (last)
3206 break;
3207 start = end + 1;
3208 }
3209#undef CHECK_TRIGGER
3210
3211 ret = wpa_drv_wowlan(wpa_s, &triggers);
3212out:
3213 os_free(buf);
3214 return ret;
3215}
3216
3217
202dec2a
JM
3218static struct wpa_radio * radio_add_interface(struct wpa_supplicant *wpa_s,
3219 const char *rn)
3220{
3221 struct wpa_supplicant *iface = wpa_s->global->ifaces;
3222 struct wpa_radio *radio;
3223
3224 while (rn && iface) {
3225 radio = iface->radio;
3226 if (radio && os_strcmp(rn, radio->name) == 0) {
3227 wpa_printf(MSG_DEBUG, "Add interface %s to existing radio %s",
3228 wpa_s->ifname, rn);
3229 dl_list_add(&radio->ifaces, &wpa_s->radio_list);
3230 return radio;
3231 }
b154a24e
TB
3232
3233 iface = iface->next;
202dec2a
JM
3234 }
3235
3236 wpa_printf(MSG_DEBUG, "Add interface %s to a new radio %s",
3237 wpa_s->ifname, rn ? rn : "N/A");
3238 radio = os_zalloc(sizeof(*radio));
3239 if (radio == NULL)
3240 return NULL;
3241
3242 if (rn)
3243 os_strlcpy(radio->name, rn, sizeof(radio->name));
3244 dl_list_init(&radio->ifaces);
b1ae396f 3245 dl_list_init(&radio->work);
202dec2a
JM
3246 dl_list_add(&radio->ifaces, &wpa_s->radio_list);
3247
3248 return radio;
3249}
3250
3251
b1ae396f
JM
3252static void radio_work_free(struct wpa_radio_work *work)
3253{
d12a51b5
JM
3254 if (work->wpa_s->scan_work == work) {
3255 /* This should not really happen. */
3256 wpa_dbg(work->wpa_s, MSG_INFO, "Freeing radio work '%s'@%p (started=%d) that is marked as scan_work",
3257 work->type, work, work->started);
3258 work->wpa_s->scan_work = NULL;
3259 }
3260
1b5d4714
JM
3261#ifdef CONFIG_P2P
3262 if (work->wpa_s->p2p_scan_work == work) {
3263 /* This should not really happen. */
3264 wpa_dbg(work->wpa_s, MSG_INFO, "Freeing radio work '%s'@%p (started=%d) that is marked as p2p_scan_work",
3265 work->type, work, work->started);
3266 work->wpa_s->p2p_scan_work = NULL;
3267 }
3268#endif /* CONFIG_P2P */
3269
b1ae396f
JM
3270 dl_list_del(&work->list);
3271 os_free(work);
3272}
3273
3274
3275static void radio_start_next_work(void *eloop_ctx, void *timeout_ctx)
3276{
3277 struct wpa_radio *radio = eloop_ctx;
3278 struct wpa_radio_work *work;
3279 struct os_reltime now, diff;
6428d0a7 3280 struct wpa_supplicant *wpa_s;
b1ae396f
JM
3281
3282 work = dl_list_first(&radio->work, struct wpa_radio_work, list);
3283 if (work == NULL)
3284 return;
3285
3286 if (work->started)
3287 return; /* already started and still in progress */
3288
6428d0a7
JM
3289 wpa_s = dl_list_first(&radio->ifaces, struct wpa_supplicant,
3290 radio_list);
3291 if (wpa_s && wpa_s->external_scan_running) {
3292 wpa_printf(MSG_DEBUG, "Delay radio work start until externally triggered scan completes");
3293 return;
3294 }
3295
b1ae396f
JM
3296 os_get_reltime(&now);
3297 os_reltime_sub(&now, &work->time, &diff);
3298 wpa_dbg(work->wpa_s, MSG_DEBUG, "Starting radio work '%s'@%p after %ld.%06ld second wait",
3299 work->type, work, diff.sec, diff.usec);
3300 work->started = 1;
3301 work->time = now;
3302 work->cb(work, 0);
3303}
3304
3305
b3253ebb
AO
3306/*
3307 * This function removes both started and pending radio works running on
3308 * the provided interface's radio.
3309 * Prior to the removal of the radio work, its callback (cb) is called with
3310 * deinit set to be 1. Each work's callback is responsible for clearing its
3311 * internal data and restoring to a correct state.
3312 * @wpa_s: wpa_supplicant data
3313 * @type: type of works to be removed
3314 * @remove_all: 1 to remove all the works on this radio, 0 to remove only
3315 * this interface's works.
3316 */
3317void radio_remove_works(struct wpa_supplicant *wpa_s,
3318 const char *type, int remove_all)
b1ae396f
JM
3319{
3320 struct wpa_radio_work *work, *tmp;
3321 struct wpa_radio *radio = wpa_s->radio;
3322
3323 dl_list_for_each_safe(work, tmp, &radio->work, struct wpa_radio_work,
3324 list) {
b3253ebb 3325 if (type && os_strcmp(type, work->type) != 0)
b1ae396f 3326 continue;
b3253ebb
AO
3327
3328 /* skip other ifaces' works */
3329 if (!remove_all && work->wpa_s != wpa_s)
b1ae396f 3330 continue;
b3253ebb
AO
3331
3332 wpa_dbg(wpa_s, MSG_DEBUG, "Remove radio work '%s'@%p%s",
3333 work->type, work, work->started ? " (started)" : "");
b1ae396f
JM
3334 work->cb(work, 1);
3335 radio_work_free(work);
3336 }
b3253ebb
AO
3337
3338 /* in case we removed the started work */
3339 radio_work_check_next(wpa_s);
b1ae396f
JM
3340}
3341
3342
202dec2a
JM
3343static void radio_remove_interface(struct wpa_supplicant *wpa_s)
3344{
3345 struct wpa_radio *radio = wpa_s->radio;
3346
3347 if (!radio)
3348 return;
3349
3350 wpa_printf(MSG_DEBUG, "Remove interface %s from radio %s",
3351 wpa_s->ifname, radio->name);
3352 dl_list_del(&wpa_s->radio_list);
c46235aa
AO
3353 radio_remove_works(wpa_s, NULL, 0);
3354 wpa_s->radio = NULL;
3355 if (!dl_list_empty(&radio->ifaces))
202dec2a
JM
3356 return; /* Interfaces remain for this radio */
3357
3358 wpa_printf(MSG_DEBUG, "Remove radio %s", radio->name);
b1ae396f 3359 eloop_cancel_timeout(radio_start_next_work, radio, NULL);
202dec2a
JM
3360 os_free(radio);
3361}
3362
3363
6428d0a7 3364void radio_work_check_next(struct wpa_supplicant *wpa_s)
b1ae396f
JM
3365{
3366 struct wpa_radio *radio = wpa_s->radio;
3367
3368 if (dl_list_empty(&radio->work))
3369 return;
3370 eloop_cancel_timeout(radio_start_next_work, radio, NULL);
3371 eloop_register_timeout(0, 0, radio_start_next_work, radio, NULL);
3372}
3373
3374
3375/**
3376 * radio_add_work - Add a radio work item
3377 * @wpa_s: Pointer to wpa_supplicant data
3378 * @freq: Frequency of the offchannel operation in MHz or 0
3379 * @type: Unique identifier for each type of work
3380 * @next: Force as the next work to be executed
3381 * @cb: Callback function for indicating when radio is available
3382 * @ctx: Context pointer for the work (work->ctx in cb())
3383 * Returns: 0 on success, -1 on failure
3384 *
3385 * This function is used to request time for an operation that requires
3386 * exclusive radio control. Once the radio is available, the registered callback
3387 * function will be called. radio_work_done() must be called once the exclusive
3388 * radio operation has been completed, so that the radio is freed for other
3389 * operations. The special case of deinit=1 is used to free the context data
3390 * during interface removal. That does not allow the callback function to start
3391 * the radio operation, i.e., it must free any resources allocated for the radio
3392 * work and return.
3393 *
3394 * The @freq parameter can be used to indicate a single channel on which the
3395 * offchannel operation will occur. This may allow multiple radio work
3396 * operations to be performed in parallel if they apply for the same channel.
3397 * Setting this to 0 indicates that the work item may use multiple channels or
3398 * requires exclusive control of the radio.
3399 */
3400int radio_add_work(struct wpa_supplicant *wpa_s, unsigned int freq,
3401 const char *type, int next,
3402 void (*cb)(struct wpa_radio_work *work, int deinit),
3403 void *ctx)
3404{
3405 struct wpa_radio_work *work;
3406 int was_empty;
3407
3408 work = os_zalloc(sizeof(*work));
3409 if (work == NULL)
3410 return -1;
3411 wpa_dbg(wpa_s, MSG_DEBUG, "Add radio work '%s'@%p", type, work);
3412 os_get_reltime(&work->time);
3413 work->freq = freq;
3414 work->type = type;
3415 work->wpa_s = wpa_s;
3416 work->cb = cb;
3417 work->ctx = ctx;
3418
3419 was_empty = dl_list_empty(&wpa_s->radio->work);
3420 if (next)
3421 dl_list_add(&wpa_s->radio->work, &work->list);
3422 else
3423 dl_list_add_tail(&wpa_s->radio->work, &work->list);
3424 if (was_empty) {
3425 wpa_dbg(wpa_s, MSG_DEBUG, "First radio work item in the queue - schedule start immediately");
3426 radio_work_check_next(wpa_s);
3427 }
3428
3429 return 0;
3430}
3431
3432
3433/**
3434 * radio_work_done - Indicate that a radio work item has been completed
3435 * @work: Completed work
3436 *
3437 * This function is called once the callback function registered with
3438 * radio_add_work() has completed its work.
3439 */
3440void radio_work_done(struct wpa_radio_work *work)
3441{
3442 struct wpa_supplicant *wpa_s = work->wpa_s;
3443 struct os_reltime now, diff;
1f965e62 3444 unsigned int started = work->started;
b1ae396f
JM
3445
3446 os_get_reltime(&now);
3447 os_reltime_sub(&now, &work->time, &diff);
1f965e62
JM
3448 wpa_dbg(wpa_s, MSG_DEBUG, "Radio work '%s'@%p %s in %ld.%06ld seconds",
3449 work->type, work, started ? "done" : "canceled",
3450 diff.sec, diff.usec);
b1ae396f 3451 radio_work_free(work);
1f965e62
JM
3452 if (started)
3453 radio_work_check_next(wpa_s);
b1ae396f
JM
3454}
3455
3456
f0e30c84
JM
3457int radio_work_pending(struct wpa_supplicant *wpa_s, const char *type)
3458{
3459 struct wpa_radio_work *work;
3460 struct wpa_radio *radio = wpa_s->radio;
3461
3462 dl_list_for_each(work, &radio->work, struct wpa_radio_work, list) {
3463 if (work->wpa_s == wpa_s && os_strcmp(work->type, type) == 0)
3464 return 1;
3465 }
3466
3467 return 0;
3468}
3469
3470
73c00fd7
JM
3471static int wpas_init_driver(struct wpa_supplicant *wpa_s,
3472 struct wpa_interface *iface)
3473{
202dec2a 3474 const char *ifname, *driver, *rn;
73c00fd7
JM
3475
3476 driver = iface->driver;
3477next_driver:
3478 if (wpa_supplicant_set_driver(wpa_s, driver) < 0)
3479 return -1;
3480
3481 wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
3482 if (wpa_s->drv_priv == NULL) {
3483 const char *pos;
3484 pos = driver ? os_strchr(driver, ',') : NULL;
3485 if (pos) {
3486 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to initialize "
3487 "driver interface - try next driver wrapper");
3488 driver = pos + 1;
3489 goto next_driver;
3490 }
3491 wpa_msg(wpa_s, MSG_ERROR, "Failed to initialize driver "
3492 "interface");
3493 return -1;
3494 }
3495 if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
3496 wpa_msg(wpa_s, MSG_ERROR, "Driver interface rejected "
3497 "driver_param '%s'", wpa_s->conf->driver_param);
3498 return -1;
3499 }
3500
3501 ifname = wpa_drv_get_ifname(wpa_s);
3502 if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
3503 wpa_dbg(wpa_s, MSG_DEBUG, "Driver interface replaced "
3504 "interface name with '%s'", ifname);
3505 os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
3506 }
3507
95bf699f 3508 rn = wpa_driver_get_radio_name(wpa_s);
202dec2a
JM
3509 if (rn && rn[0] == '\0')
3510 rn = NULL;
3511
3512 wpa_s->radio = radio_add_interface(wpa_s, rn);
3513 if (wpa_s->radio == NULL)
3514 return -1;
3515
73c00fd7
JM
3516 return 0;
3517}
3518
3519
6fc6879b
JM
3520static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
3521 struct wpa_interface *iface)
3522{
362f781e
JM
3523 struct wpa_driver_capa capa;
3524
6fc6879b
JM
3525 wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
3526 "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
3527 iface->confname ? iface->confname : "N/A",
3528 iface->driver ? iface->driver : "default",
3529 iface->ctrl_interface ? iface->ctrl_interface : "N/A",
3530 iface->bridge_ifname ? iface->bridge_ifname : "N/A");
3531
6fc6879b
JM
3532 if (iface->confname) {
3533#ifdef CONFIG_BACKEND_FILE
3534 wpa_s->confname = os_rel2abs_path(iface->confname);
3535 if (wpa_s->confname == NULL) {
3536 wpa_printf(MSG_ERROR, "Failed to get absolute path "
3537 "for configuration file '%s'.",
3538 iface->confname);
3539 return -1;
3540 }
3541 wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",
3542 iface->confname, wpa_s->confname);
3543#else /* CONFIG_BACKEND_FILE */
3544 wpa_s->confname = os_strdup(iface->confname);
3545#endif /* CONFIG_BACKEND_FILE */
e6304cad 3546 wpa_s->conf = wpa_config_read(wpa_s->confname, NULL);
6fc6879b
JM
3547 if (wpa_s->conf == NULL) {
3548 wpa_printf(MSG_ERROR, "Failed to read or parse "
3549 "configuration '%s'.", wpa_s->confname);
3550 return -1;
3551 }
e6304cad
DS
3552 wpa_s->confanother = os_rel2abs_path(iface->confanother);
3553 wpa_config_read(wpa_s->confanother, wpa_s->conf);
6fc6879b 3554
c16a7590
IP
3555#ifdef CONFIG_P2P
3556 wpa_s->conf_p2p_dev = os_rel2abs_path(iface->conf_p2p_dev);
3557 wpa_config_read(wpa_s->conf_p2p_dev, wpa_s->conf);
3558#endif /* CONFIG_P2P */
3559
6fc6879b
JM
3560 /*
3561 * Override ctrl_interface and driver_param if set on command
3562 * line.
3563 */
3564 if (iface->ctrl_interface) {
3565 os_free(wpa_s->conf->ctrl_interface);
3566 wpa_s->conf->ctrl_interface =
3567 os_strdup(iface->ctrl_interface);
3568 }
3569
3570 if (iface->driver_param) {
3571 os_free(wpa_s->conf->driver_param);
3572 wpa_s->conf->driver_param =
3573 os_strdup(iface->driver_param);
3574 }
78f79fe5
JM
3575
3576 if (iface->p2p_mgmt && !iface->ctrl_interface) {
3577 os_free(wpa_s->conf->ctrl_interface);
3578 wpa_s->conf->ctrl_interface = NULL;
3579 }
6fc6879b
JM
3580 } else
3581 wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
3582 iface->driver_param);
3583
3584 if (wpa_s->conf == NULL) {
3585 wpa_printf(MSG_ERROR, "\nNo configuration found.");
3586 return -1;
3587 }
3588
3589 if (iface->ifname == NULL) {
3590 wpa_printf(MSG_ERROR, "\nInterface name is required.");
3591 return -1;
3592 }
3593 if (os_strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
3594 wpa_printf(MSG_ERROR, "\nToo long interface name '%s'.",
3595 iface->ifname);
3596 return -1;
3597 }
3598 os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
3599
3600 if (iface->bridge_ifname) {
3601 if (os_strlen(iface->bridge_ifname) >=
3602 sizeof(wpa_s->bridge_ifname)) {
3603 wpa_printf(MSG_ERROR, "\nToo long bridge interface "
3604 "name '%s'.", iface->bridge_ifname);
3605 return -1;
3606 }
3607 os_strlcpy(wpa_s->bridge_ifname, iface->bridge_ifname,
3608 sizeof(wpa_s->bridge_ifname));
3609 }
3610
6fc6879b
JM
3611 /* RSNA Supplicant Key Management - INITIALIZE */
3612 eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
3613 eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
3614
3615 /* Initialize driver interface and register driver event handler before
3616 * L2 receive handler so that association events are processed before
3617 * EAPOL-Key packets if both become available for the same select()
3618 * call. */
73c00fd7 3619 if (wpas_init_driver(wpa_s, iface) < 0)
362f781e
JM
3620 return -1;
3621
6fc6879b
JM
3622 if (wpa_supplicant_init_wpa(wpa_s) < 0)
3623 return -1;
3624
3625 wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
3626 wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
3627 NULL);
3628 wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
3629
3630 if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
3631 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
3632 wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
f049052b
BG
3633 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
3634 "dot11RSNAConfigPMKLifetime");
6fc6879b
JM
3635 return -1;
3636 }
3637
3638 if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
3639 wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
3640 wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
f049052b 3641 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
6fc6879b
JM
3642 "dot11RSNAConfigPMKReauthThreshold");
3643 return -1;
3644 }
3645
3646 if (wpa_s->conf->dot11RSNAConfigSATimeout &&
3647 wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
3648 wpa_s->conf->dot11RSNAConfigSATimeout)) {
f049052b
BG
3649 wpa_msg(wpa_s, MSG_ERROR, "Invalid WPA parameter value for "
3650 "dot11RSNAConfigSATimeout");
6fc6879b
JM
3651 return -1;
3652 }
3653
6bf731e8
CL
3654 wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s,
3655 &wpa_s->hw.num_modes,
3656 &wpa_s->hw.flags);
3657
814782b9 3658 if (wpa_drv_get_capa(wpa_s, &capa) == 0) {
c58ab8f2 3659 wpa_s->drv_capa_known = 1;
814782b9 3660 wpa_s->drv_flags = capa.flags;
349493bd 3661 wpa_s->drv_enc = capa.enc;
4f73d88a 3662 wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
814782b9 3663 wpa_s->max_scan_ssids = capa.max_scan_ssids;
cbdf3507
LC
3664 wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
3665 wpa_s->sched_scan_supported = capa.sched_scan_supported;
b59e6f26 3666 wpa_s->max_match_sets = capa.max_match_sets;
814782b9 3667 wpa_s->max_remain_on_chan = capa.max_remain_on_chan;
c4ea4c5c 3668 wpa_s->max_stations = capa.max_stations;
8cd6b7bc
JB
3669 wpa_s->extended_capa = capa.extended_capa;
3670 wpa_s->extended_capa_mask = capa.extended_capa_mask;
3671 wpa_s->extended_capa_len = capa.extended_capa_len;
4752147d
IP
3672 wpa_s->num_multichan_concurrent =
3673 capa.num_multichan_concurrent;
814782b9
JM
3674 }
3675 if (wpa_s->max_remain_on_chan == 0)
3676 wpa_s->max_remain_on_chan = 1000;
3677
c68f6200
AS
3678 /*
3679 * Only take p2p_mgmt parameters when P2P Device is supported.
3680 * Doing it here as it determines whether l2_packet_init() will be done
3681 * during wpa_supplicant_driver_init().
3682 */
3683 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)
3684 wpa_s->p2p_mgmt = iface->p2p_mgmt;
3685 else
3686 iface->p2p_mgmt = 1;
3687
4752147d
IP
3688 if (wpa_s->num_multichan_concurrent == 0)
3689 wpa_s->num_multichan_concurrent = 1;
3690
6fc6879b
JM
3691 if (wpa_supplicant_driver_init(wpa_s) < 0)
3692 return -1;
3693
281ff0aa 3694#ifdef CONFIG_TDLS
1c42b42f
JM
3695 if ((!iface->p2p_mgmt ||
3696 !(wpa_s->drv_flags &
3697 WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
3698 wpa_tdls_init(wpa_s->wpa))
281ff0aa
GP
3699 return -1;
3700#endif /* CONFIG_TDLS */
3701
315ce40a
JM
3702 if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
3703 wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
f049052b 3704 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to set country");
6d158490
LR
3705 return -1;
3706 }
3707
116654ce
JM
3708 if (wpas_wps_init(wpa_s))
3709 return -1;
3710
6fc6879b
JM
3711 if (wpa_supplicant_init_eapol(wpa_s) < 0)
3712 return -1;
3713 wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
3714
3715 wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
3716 if (wpa_s->ctrl_iface == NULL) {
3717 wpa_printf(MSG_ERROR,
3718 "Failed to initialize control interface '%s'.\n"
3719 "You may have another wpa_supplicant process "
3720 "already running or the file was\n"
3721 "left by an unclean termination of wpa_supplicant "
3722 "in which case you will need\n"
3723 "to manually remove this file before starting "
3724 "wpa_supplicant again.\n",
3725 wpa_s->conf->ctrl_interface);
3726 return -1;
3727 }
3728
04ea7b79
JM
3729 wpa_s->gas = gas_query_init(wpa_s);
3730 if (wpa_s->gas == NULL) {
3731 wpa_printf(MSG_ERROR, "Failed to initialize GAS query");
3732 return -1;
3733 }
3734
c68f6200 3735 if (iface->p2p_mgmt && wpas_p2p_init(wpa_s->global, wpa_s) < 0) {
f049052b 3736 wpa_msg(wpa_s, MSG_ERROR, "Failed to init P2P");
b22128ef
JM
3737 return -1;
3738 }
b22128ef 3739
83922c2d
JM
3740 if (wpa_bss_init(wpa_s) < 0)
3741 return -1;
83922c2d 3742
e4fa8b12
EP
3743 /*
3744 * Set Wake-on-WLAN triggers, if configured.
3745 * Note: We don't restore/remove the triggers on shutdown (it doesn't
3746 * have effect anyway when the interface is down).
3747 */
3748 if (wpas_set_wowlan_triggers(wpa_s, &capa) < 0)
3749 return -1;
3750
ec7b97ab
JM
3751#ifdef CONFIG_EAP_PROXY
3752{
3753 size_t len;
07041c6f
NJ
3754 wpa_s->mnc_len = eapol_sm_get_eap_proxy_imsi(wpa_s->eapol, wpa_s->imsi,
3755 &len);
ec7b97ab
JM
3756 if (wpa_s->mnc_len > 0) {
3757 wpa_s->imsi[len] = '\0';
3758 wpa_printf(MSG_DEBUG, "eap_proxy: IMSI %s (MNC length %d)",
3759 wpa_s->imsi, wpa_s->mnc_len);
3760 } else {
3761 wpa_printf(MSG_DEBUG, "eap_proxy: IMSI not available");
3762 }
3763}
3764#endif /* CONFIG_EAP_PROXY */
3765
f64adcd7
JM
3766 if (pcsc_reader_init(wpa_s) < 0)
3767 return -1;
3768
306ae225
JM
3769 if (wpas_init_ext_pw(wpa_s) < 0)
3770 return -1;
3771
6fc6879b
JM
3772 return 0;
3773}
3774
3775
2ee055b3 3776static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
df509539 3777 int notify, int terminate)
6fc6879b 3778{
e679f140 3779 wpa_s->disconnected = 1;
6fc6879b
JM
3780 if (wpa_s->drv_priv) {
3781 wpa_supplicant_deauthenticate(wpa_s,
3782 WLAN_REASON_DEAUTH_LEAVING);
3783
6fc6879b
JM
3784 wpa_drv_set_countermeasures(wpa_s, 0);
3785 wpa_clear_keys(wpa_s, NULL);
3786 }
3787
8e56d189 3788 wpa_supplicant_cleanup(wpa_s);
bd10d938 3789 wpas_p2p_deinit_iface(wpa_s);
ab28911d 3790
1f965e62 3791 wpas_ctrl_radio_work_flush(wpa_s);
202dec2a
JM
3792 radio_remove_interface(wpa_s);
3793
6fc6879b
JM
3794 if (wpa_s->drv_priv)
3795 wpa_drv_deinit(wpa_s);
2523ff6e
DS
3796
3797 if (notify)
3798 wpas_notify_iface_removed(wpa_s);
f0811516
DS
3799
3800 if (terminate)
3801 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
3802
3803 if (wpa_s->ctrl_iface) {
3804 wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
3805 wpa_s->ctrl_iface = NULL;
3806 }
3807
3808 if (wpa_s->conf != NULL) {
3809 wpa_config_free(wpa_s->conf);
3810 wpa_s->conf = NULL;
3811 }
18e00b5e
JM
3812
3813 os_free(wpa_s);
6fc6879b
JM
3814}
3815
3816
3817/**
3818 * wpa_supplicant_add_iface - Add a new network interface
3819 * @global: Pointer to global data from wpa_supplicant_init()
3820 * @iface: Interface configuration options
3821 * Returns: Pointer to the created interface or %NULL on failure
3822 *
3823 * This function is used to add new network interfaces for %wpa_supplicant.
3824 * This can be called before wpa_supplicant_run() to add interfaces before the
3825 * main event loop has been started. In addition, new interfaces can be added
3826 * dynamically while %wpa_supplicant is already running. This could happen,
3827 * e.g., when a hotplug network adapter is inserted.
3828 */
3829struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
3830 struct wpa_interface *iface)
3831{
3832 struct wpa_supplicant *wpa_s;
d27df100 3833 struct wpa_interface t_iface;
8e56d189 3834 struct wpa_ssid *ssid;
6fc6879b
JM
3835
3836 if (global == NULL || iface == NULL)
3837 return NULL;
3838
3839 wpa_s = wpa_supplicant_alloc();
3840 if (wpa_s == NULL)
3841 return NULL;
3842
d8222ae3
JM
3843 wpa_s->global = global;
3844
d27df100
JM
3845 t_iface = *iface;
3846 if (global->params.override_driver) {
3847 wpa_printf(MSG_DEBUG, "Override interface parameter: driver "
3848 "('%s' -> '%s')",
3849 iface->driver, global->params.override_driver);
3850 t_iface.driver = global->params.override_driver;
3851 }
3852 if (global->params.override_ctrl_interface) {
3853 wpa_printf(MSG_DEBUG, "Override interface parameter: "
3854 "ctrl_interface ('%s' -> '%s')",
3855 iface->ctrl_interface,
3856 global->params.override_ctrl_interface);
3857 t_iface.ctrl_interface =
3858 global->params.override_ctrl_interface;
3859 }
3860 if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
6fc6879b
JM
3861 wpa_printf(MSG_DEBUG, "Failed to add interface %s",
3862 iface->ifname);
df509539 3863 wpa_supplicant_deinit_iface(wpa_s, 0, 0);
6fc6879b
JM
3864 return NULL;
3865 }
3866
dc461de4
WS
3867 /* Notify the control interfaces about new iface */
3868 if (wpas_notify_iface_added(wpa_s)) {
df509539 3869 wpa_supplicant_deinit_iface(wpa_s, 1, 0);
6fc6879b
JM
3870 return NULL;
3871 }
1bd3f426 3872
8e56d189
JM
3873 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
3874 wpas_notify_network_added(wpa_s, ssid);
3875
6fc6879b
JM
3876 wpa_s->next = global->ifaces;
3877 global->ifaces = wpa_s;
3878
f049052b 3879 wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
99218999 3880 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
6fc6879b
JM
3881
3882 return wpa_s;
3883}
3884
3885
3886/**
3887 * wpa_supplicant_remove_iface - Remove a network interface
3888 * @global: Pointer to global data from wpa_supplicant_init()
3889 * @wpa_s: Pointer to the network interface to be removed
3890 * Returns: 0 if interface was removed, -1 if interface was not found
3891 *
3892 * This function can be used to dynamically remove network interfaces from
3893 * %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In
3894 * addition, this function is used to remove all remaining interfaces when
3895 * %wpa_supplicant is terminated.
3896 */
3897int wpa_supplicant_remove_iface(struct wpa_global *global,
df509539
DS
3898 struct wpa_supplicant *wpa_s,
3899 int terminate)
6fc6879b
JM
3900{
3901 struct wpa_supplicant *prev;
3902
3903 /* Remove interface from the global list of interfaces */
3904 prev = global->ifaces;
3905 if (prev == wpa_s) {
3906 global->ifaces = wpa_s->next;
3907 } else {
3908 while (prev && prev->next != wpa_s)
3909 prev = prev->next;
3910 if (prev == NULL)
3911 return -1;
3912 prev->next = wpa_s->next;
3913 }
3914
f049052b 3915 wpa_dbg(wpa_s, MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
6fc6879b 3916
b22128ef
JM
3917 if (global->p2p_group_formation == wpa_s)
3918 global->p2p_group_formation = NULL;
dbca75f8
JM
3919 if (global->p2p_invite_group == wpa_s)
3920 global->p2p_invite_group = NULL;
df509539 3921 wpa_supplicant_deinit_iface(wpa_s, 1, terminate);
6fc6879b
JM
3922
3923 return 0;
3924}
3925
3926
cf83fb0b
PS
3927/**
3928 * wpa_supplicant_get_eap_mode - Get the current EAP mode
3929 * @wpa_s: Pointer to the network interface
3930 * Returns: Pointer to the eap mode or the string "UNKNOWN" if not found
3931 */
3932const char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s)
3933{
3934 const char *eapol_method;
3935
3936 if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) == 0 &&
3937 wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
3938 return "NO-EAP";
3939 }
3940
3941 eapol_method = eapol_sm_get_method_name(wpa_s->eapol);
3942 if (eapol_method == NULL)
3943 return "UNKNOWN-EAP";
3944
3945 return eapol_method;
3946}
3947
3948
6fc6879b
JM
3949/**
3950 * wpa_supplicant_get_iface - Get a new network interface
3951 * @global: Pointer to global data from wpa_supplicant_init()
3952 * @ifname: Interface name
3953 * Returns: Pointer to the interface or %NULL if not found
3954 */
3955struct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
3956 const char *ifname)
3957{
3958 struct wpa_supplicant *wpa_s;
3959
3960 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
3961 if (os_strcmp(wpa_s->ifname, ifname) == 0)
3962 return wpa_s;
3963 }
3964 return NULL;
3965}
3966
3967
50b16da1 3968#ifndef CONFIG_NO_WPA_MSG
4f1495ae
BG
3969static const char * wpa_supplicant_msg_ifname_cb(void *ctx)
3970{
3971 struct wpa_supplicant *wpa_s = ctx;
3972 if (wpa_s == NULL)
3973 return NULL;
3974 return wpa_s->ifname;
3975}
50b16da1 3976#endif /* CONFIG_NO_WPA_MSG */
4f1495ae
BG
3977
3978
6fc6879b
JM
3979/**
3980 * wpa_supplicant_init - Initialize %wpa_supplicant
3981 * @params: Parameters for %wpa_supplicant
3982 * Returns: Pointer to global %wpa_supplicant data, or %NULL on failure
3983 *
3984 * This function is used to initialize %wpa_supplicant. After successful
3985 * initialization, the returned data pointer can be used to add and remove
3986 * network interfaces, and eventually, to deinitialize %wpa_supplicant.
3987 */
3988struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
3989{
3990 struct wpa_global *global;
ac305589 3991 int ret, i;
6fc6879b
JM
3992
3993 if (params == NULL)
3994 return NULL;
3995
39e7d718
JM
3996#ifdef CONFIG_DRIVER_NDIS
3997 {
3998 void driver_ndis_init_ops(void);
3999 driver_ndis_init_ops();
4000 }
4001#endif /* CONFIG_DRIVER_NDIS */
4002
50b16da1 4003#ifndef CONFIG_NO_WPA_MSG
4f1495ae 4004 wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
50b16da1 4005#endif /* CONFIG_NO_WPA_MSG */
4f1495ae 4006
6fc6879b 4007 wpa_debug_open_file(params->wpa_debug_file_path);
daa70d49
SL
4008 if (params->wpa_debug_syslog)
4009 wpa_debug_open_syslog();
4f68895e
JB
4010 if (params->wpa_debug_tracing) {
4011 ret = wpa_debug_open_linux_tracing();
4012 if (ret) {
4013 wpa_printf(MSG_ERROR,
4014 "Failed to enable trace logging");
4015 return NULL;
4016 }
4017 }
6fc6879b 4018
12760815 4019 ret = eap_register_methods();
6fc6879b
JM
4020 if (ret) {
4021 wpa_printf(MSG_ERROR, "Failed to register EAP methods");
4022 if (ret == -2)
4023 wpa_printf(MSG_ERROR, "Two or more EAP methods used "
4024 "the same EAP type.");
4025 return NULL;
4026 }
4027
4028 global = os_zalloc(sizeof(*global));
4029 if (global == NULL)
4030 return NULL;
b22128ef
JM
4031 dl_list_init(&global->p2p_srv_bonjour);
4032 dl_list_init(&global->p2p_srv_upnp);
6fc6879b
JM
4033 global->params.daemonize = params->daemonize;
4034 global->params.wait_for_monitor = params->wait_for_monitor;
4035 global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
4036 if (params->pid_file)
4037 global->params.pid_file = os_strdup(params->pid_file);
4038 if (params->ctrl_interface)
4039 global->params.ctrl_interface =
4040 os_strdup(params->ctrl_interface);
29257565
JM
4041 if (params->ctrl_interface_group)
4042 global->params.ctrl_interface_group =
4043 os_strdup(params->ctrl_interface_group);
d27df100
JM
4044 if (params->override_driver)
4045 global->params.override_driver =
4046 os_strdup(params->override_driver);
4047 if (params->override_ctrl_interface)
4048 global->params.override_ctrl_interface =
4049 os_strdup(params->override_ctrl_interface);
6fc6879b
JM
4050 wpa_debug_level = global->params.wpa_debug_level =
4051 params->wpa_debug_level;
4052 wpa_debug_show_keys = global->params.wpa_debug_show_keys =
4053 params->wpa_debug_show_keys;
4054 wpa_debug_timestamp = global->params.wpa_debug_timestamp =
4055 params->wpa_debug_timestamp;
4056
f19858f5
JM
4057 wpa_printf(MSG_DEBUG, "wpa_supplicant v" VERSION_STR);
4058
0456ea16 4059 if (eloop_init()) {
6fc6879b
JM
4060 wpa_printf(MSG_ERROR, "Failed to initialize event loop");
4061 wpa_supplicant_deinit(global);
4062 return NULL;
4063 }
4064
38e24575 4065 random_init(params->entropy_file);
d47fa330 4066
6fc6879b
JM
4067 global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
4068 if (global->ctrl_iface == NULL) {
4069 wpa_supplicant_deinit(global);
4070 return NULL;
4071 }
4072
dc461de4
WS
4073 if (wpas_notify_supplicant_initialized(global)) {
4074 wpa_supplicant_deinit(global);
4075 return NULL;
6fc6879b
JM
4076 }
4077
c5121837 4078 for (i = 0; wpa_drivers[i]; i++)
ac305589
JM
4079 global->drv_count++;
4080 if (global->drv_count == 0) {
4081 wpa_printf(MSG_ERROR, "No drivers enabled");
4082 wpa_supplicant_deinit(global);
4083 return NULL;
4084 }
4085 global->drv_priv = os_zalloc(global->drv_count * sizeof(void *));
4086 if (global->drv_priv == NULL) {
4087 wpa_supplicant_deinit(global);
4088 return NULL;
4089 }
ac305589 4090
9675ce35
JM
4091#ifdef CONFIG_WIFI_DISPLAY
4092 if (wifi_display_init(global) < 0) {
4093 wpa_printf(MSG_ERROR, "Failed to initialize Wi-Fi Display");
4094 wpa_supplicant_deinit(global);
4095 return NULL;
4096 }
4097#endif /* CONFIG_WIFI_DISPLAY */
4098
6fc6879b
JM
4099 return global;
4100}
4101
4102
4103/**
4104 * wpa_supplicant_run - Run the %wpa_supplicant main event loop
4105 * @global: Pointer to global data from wpa_supplicant_init()
4106 * Returns: 0 after successful event loop run, -1 on failure
4107 *
4108 * This function starts the main event loop and continues running as long as
4109 * there are any remaining events. In most cases, this function is running as
4110 * long as the %wpa_supplicant process in still in use.
4111 */
4112int wpa_supplicant_run(struct wpa_global *global)
4113{
4114 struct wpa_supplicant *wpa_s;
4115
4116 if (global->params.daemonize &&
4117 wpa_supplicant_daemon(global->params.pid_file))
4118 return -1;
4119
4120 if (global->params.wait_for_monitor) {
4121 for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
4122 if (wpa_s->ctrl_iface)
4123 wpa_supplicant_ctrl_iface_wait(
4124 wpa_s->ctrl_iface);
4125 }
4126
0456ea16
JM
4127 eloop_register_signal_terminate(wpa_supplicant_terminate, global);
4128 eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
6fc6879b
JM
4129
4130 eloop_run();
4131
4132 return 0;
4133}
4134
4135
4136/**
4137 * wpa_supplicant_deinit - Deinitialize %wpa_supplicant
4138 * @global: Pointer to global data from wpa_supplicant_init()
4139 *
4140 * This function is called to deinitialize %wpa_supplicant and to free all
4141 * allocated resources. Remaining network interfaces will also be removed.
4142 */
4143void wpa_supplicant_deinit(struct wpa_global *global)
4144{
ac305589
JM
4145 int i;
4146
6fc6879b
JM
4147 if (global == NULL)
4148 return;
4149
9675ce35
JM
4150#ifdef CONFIG_WIFI_DISPLAY
4151 wifi_display_deinit(global);
4152#endif /* CONFIG_WIFI_DISPLAY */
b22128ef 4153
6fc6879b 4154 while (global->ifaces)
df509539 4155 wpa_supplicant_remove_iface(global, global->ifaces, 1);
6fc6879b
JM
4156
4157 if (global->ctrl_iface)
4158 wpa_supplicant_global_ctrl_iface_deinit(global->ctrl_iface);
dc461de4
WS
4159
4160 wpas_notify_supplicant_deinitialized(global);
6fc6879b
JM
4161
4162 eap_peer_unregister_methods();
3ec97afe
JM
4163#ifdef CONFIG_AP
4164 eap_server_unregister_methods();
4165#endif /* CONFIG_AP */
6fc6879b 4166
c5121837 4167 for (i = 0; wpa_drivers[i] && global->drv_priv; i++) {
ac305589
JM
4168 if (!global->drv_priv[i])
4169 continue;
c5121837 4170 wpa_drivers[i]->global_deinit(global->drv_priv[i]);
ac305589
JM
4171 }
4172 os_free(global->drv_priv);
4173
d47fa330
JM
4174 random_deinit();
4175
6fc6879b
JM
4176 eloop_destroy();
4177
4178 if (global->params.pid_file) {
4179 os_daemonize_terminate(global->params.pid_file);
4180 os_free(global->params.pid_file);
4181 }
4182 os_free(global->params.ctrl_interface);
29257565 4183 os_free(global->params.ctrl_interface_group);
d27df100
JM
4184 os_free(global->params.override_driver);
4185 os_free(global->params.override_ctrl_interface);
6fc6879b 4186
af8a827b 4187 os_free(global->p2p_disallow_freq.range);
253f2e37 4188 os_free(global->p2p_go_avoid_freq.range);
01a57fe4 4189 os_free(global->add_psk);
6f3bc72b 4190
6fc6879b 4191 os_free(global);
daa70d49 4192 wpa_debug_close_syslog();
6fc6879b 4193 wpa_debug_close_file();
4f68895e 4194 wpa_debug_close_linux_tracing();
6fc6879b 4195}
611aea7d
JM
4196
4197
4198void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s)
4199{
849b5dc7
JM
4200 if ((wpa_s->conf->changed_parameters & CFG_CHANGED_COUNTRY) &&
4201 wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
4202 char country[3];
4203 country[0] = wpa_s->conf->country[0];
4204 country[1] = wpa_s->conf->country[1];
4205 country[2] = '\0';
4206 if (wpa_drv_set_country(wpa_s, country) < 0) {
4207 wpa_printf(MSG_ERROR, "Failed to set country code "
4208 "'%s'", country);
4209 }
4210 }
4211
306ae225
JM
4212 if (wpa_s->conf->changed_parameters & CFG_CHANGED_EXT_PW_BACKEND)
4213 wpas_init_ext_pw(wpa_s);
4214
611aea7d
JM
4215#ifdef CONFIG_WPS
4216 wpas_wps_update_config(wpa_s);
4217#endif /* CONFIG_WPS */
b22128ef 4218 wpas_p2p_update_config(wpa_s);
611aea7d
JM
4219 wpa_s->conf->changed_parameters = 0;
4220}
2f9c6aa6
JM
4221
4222
0fb337c1
JM
4223static void add_freq(int *freqs, int *num_freqs, int freq)
4224{
4225 int i;
4226
4227 for (i = 0; i < *num_freqs; i++) {
4228 if (freqs[i] == freq)
4229 return;
4230 }
4231
4232 freqs[*num_freqs] = freq;
4233 (*num_freqs)++;
4234}
4235
4236
4237static int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s)
4238{
4239 struct wpa_bss *bss, *cbss;
4240 const int max_freqs = 10;
4241 int *freqs;
4242 int num_freqs = 0;
4243
4244 freqs = os_zalloc(sizeof(int) * (max_freqs + 1));
4245 if (freqs == NULL)
4246 return NULL;
4247
4248 cbss = wpa_s->current_bss;
4249
4250 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
4251 if (bss == cbss)
4252 continue;
4253 if (bss->ssid_len == cbss->ssid_len &&
4254 os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
4255 wpa_blacklist_get(wpa_s, bss->bssid) == NULL) {
4256 add_freq(freqs, &num_freqs, bss->freq);
4257 if (num_freqs == max_freqs)
4258 break;
4259 }
4260 }
4261
4262 if (num_freqs == 0) {
4263 os_free(freqs);
4264 freqs = NULL;
4265 }
4266
4267 return freqs;
4268}
4269
4270
4271void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
4272{
4273 int timeout;
4274 int count;
4275 int *freqs = NULL;
4276
6ac4b15e
JM
4277 wpas_connect_work_done(wpa_s);
4278
5fd9fb27
JM
4279 /*
4280 * Remove possible authentication timeout since the connection failed.
4281 */
4282 eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL);
4283
0cdb93fe
JM
4284 if (wpa_s->disconnected) {
4285 /*
4286 * There is no point in blacklisting the AP if this event is
4287 * generated based on local request to disconnect.
4288 */
4289 wpa_dbg(wpa_s, MSG_DEBUG, "Ignore connection failure "
4290 "indication since interface has been put into "
4291 "disconnected state");
4292 return;
4293 }
4294
0fb337c1
JM
4295 /*
4296 * Add the failed BSSID into the blacklist and speed up next scan
4297 * attempt if there could be other APs that could accept association.
4298 * The current blacklist count indicates how many times we have tried
4299 * connecting to this AP and multiple attempts mean that other APs are
4300 * either not available or has already been tried, so that we can start
4301 * increasing the delay here to avoid constant scanning.
4302 */
4303 count = wpa_blacklist_add(wpa_s, bssid);
4304 if (count == 1 && wpa_s->current_bss) {
4305 /*
4306 * This BSS was not in the blacklist before. If there is
4307 * another BSS available for the same ESS, we should try that
4308 * next. Otherwise, we may as well try this one once more
4309 * before allowing other, likely worse, ESSes to be considered.
4310 */
4311 freqs = get_bss_freqs_in_ess(wpa_s);
4312 if (freqs) {
f049052b
BG
4313 wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS "
4314 "has been seen; try it next");
0fb337c1
JM
4315 wpa_blacklist_add(wpa_s, bssid);
4316 /*
4317 * On the next scan, go through only the known channels
4318 * used in this ESS based on previous scans to speed up
4319 * common load balancing use case.
4320 */
4321 os_free(wpa_s->next_scan_freqs);
4322 wpa_s->next_scan_freqs = freqs;
4323 }
4324 }
4325
f1a52633
JM
4326 /*
4327 * Add previous failure count in case the temporary blacklist was
4328 * cleared due to no other BSSes being available.
4329 */
4330 count += wpa_s->extra_blacklist_count;
4331
dd579704
JM
4332 if (count > 3 && wpa_s->current_ssid) {
4333 wpa_printf(MSG_DEBUG, "Continuous association failures - "
4334 "consider temporary network disabling");
b19c098e 4335 wpas_auth_failed(wpa_s, "CONN_FAILED");
dd579704
JM
4336 }
4337
0fb337c1
JM
4338 switch (count) {
4339 case 1:
4340 timeout = 100;
4341 break;
4342 case 2:
4343 timeout = 500;
4344 break;
4345 case 3:
4346 timeout = 1000;
4347 break;
f1a52633 4348 case 4:
0fb337c1 4349 timeout = 5000;
f1a52633
JM
4350 break;
4351 default:
4352 timeout = 10000;
4353 break;
0fb337c1
JM
4354 }
4355
f1a52633
JM
4356 wpa_dbg(wpa_s, MSG_DEBUG, "Blacklist count %d --> request scan in %d "
4357 "ms", count, timeout);
4358
0fb337c1
JM
4359 /*
4360 * TODO: if more than one possible AP is available in scan results,
4361 * could try the other ones before requesting a new scan.
4362 */
4363 wpa_supplicant_req_scan(wpa_s, timeout / 1000,
4364 1000 * (timeout % 1000));
4365}
22628eca
JM
4366
4367
4368int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s)
4369{
4370 return wpa_s->conf->ap_scan == 2 ||
4371 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION);
4372}
d2118814
JM
4373
4374
4375#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
4376int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
4377 struct wpa_ssid *ssid,
4378 const char *field,
4379 const char *value)
4380{
4381#ifdef IEEE8021X_EAPOL
4382 struct eap_peer_config *eap = &ssid->eap;
4383
4384 wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
4385 wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
4386 (const u8 *) value, os_strlen(value));
4387
4388 switch (wpa_supplicant_ctrl_req_from_string(field)) {
4389 case WPA_CTRL_REQ_EAP_IDENTITY:
4390 os_free(eap->identity);
4391 eap->identity = (u8 *) os_strdup(value);
4392 eap->identity_len = os_strlen(value);
4393 eap->pending_req_identity = 0;
4394 if (ssid == wpa_s->current_ssid)
4395 wpa_s->reassociate = 1;
4396 break;
4397 case WPA_CTRL_REQ_EAP_PASSWORD:
19c48da0 4398 bin_clear_free(eap->password, eap->password_len);
d2118814
JM
4399 eap->password = (u8 *) os_strdup(value);
4400 eap->password_len = os_strlen(value);
4401 eap->pending_req_password = 0;
4402 if (ssid == wpa_s->current_ssid)
4403 wpa_s->reassociate = 1;
4404 break;
4405 case WPA_CTRL_REQ_EAP_NEW_PASSWORD:
19c48da0 4406 bin_clear_free(eap->new_password, eap->new_password_len);
d2118814
JM
4407 eap->new_password = (u8 *) os_strdup(value);
4408 eap->new_password_len = os_strlen(value);
4409 eap->pending_req_new_password = 0;
4410 if (ssid == wpa_s->current_ssid)
4411 wpa_s->reassociate = 1;
4412 break;
4413 case WPA_CTRL_REQ_EAP_PIN:
19c48da0 4414 str_clear_free(eap->pin);
d2118814
JM
4415 eap->pin = os_strdup(value);
4416 eap->pending_req_pin = 0;
4417 if (ssid == wpa_s->current_ssid)
4418 wpa_s->reassociate = 1;
4419 break;
4420 case WPA_CTRL_REQ_EAP_OTP:
19c48da0 4421 bin_clear_free(eap->otp, eap->otp_len);
d2118814
JM
4422 eap->otp = (u8 *) os_strdup(value);
4423 eap->otp_len = os_strlen(value);
4424 os_free(eap->pending_req_otp);
4425 eap->pending_req_otp = NULL;
4426 eap->pending_req_otp_len = 0;
4427 break;
4428 case WPA_CTRL_REQ_EAP_PASSPHRASE:
19c48da0
JM
4429 str_clear_free(eap->private_key_passwd);
4430 eap->private_key_passwd = os_strdup(value);
d2118814
JM
4431 eap->pending_req_passphrase = 0;
4432 if (ssid == wpa_s->current_ssid)
4433 wpa_s->reassociate = 1;
4434 break;
a5d44ac0 4435 case WPA_CTRL_REQ_SIM:
19c48da0 4436 str_clear_free(eap->external_sim_resp);
a5d44ac0
JM
4437 eap->external_sim_resp = os_strdup(value);
4438 break;
d2118814
JM
4439 default:
4440 wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
4441 return -1;
4442 }
4443
4444 return 0;
4445#else /* IEEE8021X_EAPOL */
4446 wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
4447 return -1;
4448#endif /* IEEE8021X_EAPOL */
4449}
4450#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
349493bd
JM
4451
4452
4453int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
4454{
4455 int i;
4456 unsigned int drv_enc;
4457
4458 if (ssid == NULL)
4459 return 1;
4460
4461 if (ssid->disabled)
4462 return 1;
4463
4464 if (wpa_s && wpa_s->drv_capa_known)
4465 drv_enc = wpa_s->drv_enc;
4466 else
4467 drv_enc = (unsigned int) -1;
4468
4469 for (i = 0; i < NUM_WEP_KEYS; i++) {
4470 size_t len = ssid->wep_key_len[i];
4471 if (len == 0)
4472 continue;
4473 if (len == 5 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40))
4474 continue;
4475 if (len == 13 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104))
4476 continue;
4477 if (len == 16 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP128))
4478 continue;
4479 return 1; /* invalid WEP key */
4480 }
4481
9173b16f 4482 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
759ff2f0 4483 (!ssid->passphrase || ssid->ssid_len != 0) && !ssid->ext_psk)
2518aad3
JM
4484 return 1;
4485
349493bd
JM
4486 return 0;
4487}
b9cfc09a
JJ
4488
4489
4490int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s)
4491{
4492 if (wpa_s->global->conc_pref == WPA_CONC_PREF_P2P)
4493 return 1;
4494 if (wpa_s->global->conc_pref == WPA_CONC_PREF_STA)
4495 return 0;
4496 return -1;
4497}
00e5e3d5
JM
4498
4499
b19c098e 4500void wpas_auth_failed(struct wpa_supplicant *wpa_s, char *reason)
00e5e3d5
JM
4501{
4502 struct wpa_ssid *ssid = wpa_s->current_ssid;
4503 int dur;
4e1eae1d 4504 struct os_reltime now;
00e5e3d5
JM
4505
4506 if (ssid == NULL) {
4507 wpa_printf(MSG_DEBUG, "Authentication failure but no known "
4508 "SSID block");
4509 return;
4510 }
4511
4512 if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
4513 return;
4514
4515 ssid->auth_failures++;
cbf41ca7
SL
4516
4517#ifdef CONFIG_P2P
4518 if (ssid->p2p_group &&
4519 (wpa_s->p2p_in_provisioning || wpa_s->show_group_started)) {
4520 /*
4521 * Skip the wait time since there is a short timeout on the
4522 * connection to a P2P group.
4523 */
4524 return;
4525 }
4526#endif /* CONFIG_P2P */
4527
00e5e3d5
JM
4528 if (ssid->auth_failures > 50)
4529 dur = 300;
00e5e3d5 4530 else if (ssid->auth_failures > 10)
8a77f1be 4531 dur = 120;
00e5e3d5 4532 else if (ssid->auth_failures > 5)
8a77f1be
JM
4533 dur = 90;
4534 else if (ssid->auth_failures > 3)
4535 dur = 60;
4536 else if (ssid->auth_failures > 2)
00e5e3d5
JM
4537 dur = 30;
4538 else if (ssid->auth_failures > 1)
4539 dur = 20;
4540 else
4541 dur = 10;
4542
8a77f1be
JM
4543 if (ssid->auth_failures > 1 &&
4544 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt))
4545 dur += os_random() % (ssid->auth_failures * 10);
4546
4e1eae1d 4547 os_get_reltime(&now);
00e5e3d5
JM
4548 if (now.sec + dur <= ssid->disabled_until.sec)
4549 return;
4550
4551 ssid->disabled_until.sec = now.sec + dur;
4552
4553 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_TEMP_DISABLED
b19c098e 4554 "id=%d ssid=\"%s\" auth_failures=%u duration=%d reason=%s",
00e5e3d5 4555 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len),
b19c098e 4556 ssid->auth_failures, dur, reason);
00e5e3d5
JM
4557}
4558
4559
4560void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s,
4561 struct wpa_ssid *ssid, int clear_failures)
4562{
4563 if (ssid == NULL)
4564 return;
4565
4566 if (ssid->disabled_until.sec) {
4567 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REENABLED
4568 "id=%d ssid=\"%s\"",
4569 ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
4570 }
4571 ssid->disabled_until.sec = 0;
4572 ssid->disabled_until.usec = 0;
4573 if (clear_failures)
4574 ssid->auth_failures = 0;
4575}
6407f413
JM
4576
4577
4578int disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid)
4579{
4580 size_t i;
4581
4582 if (wpa_s->disallow_aps_bssid == NULL)
4583 return 0;
4584
4585 for (i = 0; i < wpa_s->disallow_aps_bssid_count; i++) {
4586 if (os_memcmp(wpa_s->disallow_aps_bssid + i * ETH_ALEN,
4587 bssid, ETH_ALEN) == 0)
4588 return 1;
4589 }
4590
4591 return 0;
4592}
4593
4594
4595int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
4596 size_t ssid_len)
4597{
4598 size_t i;
4599
4600 if (wpa_s->disallow_aps_ssid == NULL || ssid == NULL)
4601 return 0;
4602
4603 for (i = 0; i < wpa_s->disallow_aps_ssid_count; i++) {
4604 struct wpa_ssid_value *s = &wpa_s->disallow_aps_ssid[i];
4605 if (ssid_len == s->ssid_len &&
4606 os_memcmp(ssid, s->ssid, ssid_len) == 0)
4607 return 1;
4608 }
4609
4610 return 0;
4611}
9796a86c
JM
4612
4613
4614/**
4615 * wpas_request_connection - Request a new connection
4616 * @wpa_s: Pointer to the network interface
4617 *
4618 * This function is used to request a new connection to be found. It will mark
4619 * the interface to allow reassociation and request a new scan to find a
4620 * suitable network to connect to.
4621 */
4622void wpas_request_connection(struct wpa_supplicant *wpa_s)
4623{
4624 wpa_s->normal_scans = 0;
4625 wpa_supplicant_reinit_autoscan(wpa_s);
4626 wpa_s->extra_blacklist_count = 0;
4627 wpa_s->disconnected = 0;
4628 wpa_s->reassociate = 1;
5e24beae
MH
4629
4630 if (wpa_supplicant_fast_associate(wpa_s) != 1)
4631 wpa_supplicant_req_scan(wpa_s, 0, 0);
9796a86c 4632}
36b9883d
DG
4633
4634
a0c90bb0
IP
4635void dump_freq_data(struct wpa_supplicant *wpa_s, const char *title,
4636 struct wpa_used_freq_data *freqs_data,
4637 unsigned int len)
4638{
4639 unsigned int i;
4640
4641 wpa_dbg(wpa_s, MSG_DEBUG, "Shared frequencies (len=%u): %s",
4642 len, title);
4643 for (i = 0; i < len; i++) {
4644 struct wpa_used_freq_data *cur = &freqs_data[i];
4645 wpa_dbg(wpa_s, MSG_DEBUG, "freq[%u]: %d, flags=0x%X",
4646 i, cur->freq, cur->flags);
4647 }
4648}
4649
4650
53c5dfc2
IP
4651/*
4652 * Find the operating frequencies of any of the virtual interfaces that
a0c90bb0
IP
4653 * are using the same radio as the current interface, and in addition, get
4654 * information about the interface types that are using the frequency.
53c5dfc2 4655 */
a0c90bb0
IP
4656int get_shared_radio_freqs_data(struct wpa_supplicant *wpa_s,
4657 struct wpa_used_freq_data *freqs_data,
4658 unsigned int len)
53c5dfc2 4659{
53c5dfc2
IP
4660 struct wpa_supplicant *ifs;
4661 u8 bssid[ETH_ALEN];
4662 int freq;
4663 unsigned int idx = 0, i;
4664
217cf499
JM
4665 wpa_dbg(wpa_s, MSG_DEBUG,
4666 "Determining shared radio frequencies (max len %u)", len);
a0c90bb0 4667 os_memset(freqs_data, 0, sizeof(struct wpa_used_freq_data) * len);
53c5dfc2 4668
0ad3b9c4
JM
4669 dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
4670 radio_list) {
a0c90bb0
IP
4671 if (idx == len)
4672 break;
4673
53c5dfc2
IP
4674 if (ifs->current_ssid == NULL || ifs->assoc_freq == 0)
4675 continue;
4676
4677 if (ifs->current_ssid->mode == WPAS_MODE_AP ||
4678 ifs->current_ssid->mode == WPAS_MODE_P2P_GO)
4679 freq = ifs->current_ssid->frequency;
4680 else if (wpa_drv_get_bssid(ifs, bssid) == 0)
4681 freq = ifs->assoc_freq;
4682 else
4683 continue;
4684
4685 /* Hold only distinct freqs */
4686 for (i = 0; i < idx; i++)
a0c90bb0 4687 if (freqs_data[i].freq == freq)
53c5dfc2
IP
4688 break;
4689
4690 if (i == idx)
a0c90bb0
IP
4691 freqs_data[idx++].freq = freq;
4692
4693 if (ifs->current_ssid->mode == WPAS_MODE_INFRA) {
4694 freqs_data[i].flags = ifs->current_ssid->p2p_group ?
4695 WPA_FREQ_USED_BY_P2P_CLIENT :
4696 WPA_FREQ_USED_BY_INFRA_STATION;
4697 }
53c5dfc2 4698 }
217cf499 4699
a0c90bb0 4700 dump_freq_data(wpa_s, "completed iteration", freqs_data, idx);
53c5dfc2
IP
4701 return idx;
4702}
a0c90bb0
IP
4703
4704
4705/*
4706 * Find the operating frequencies of any of the virtual interfaces that
4707 * are using the same radio as the current interface.
4708 */
4709int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
4710 int *freq_array, unsigned int len)
4711{
4712 struct wpa_used_freq_data *freqs_data;
4713 int num, i;
4714
4715 os_memset(freq_array, 0, sizeof(int) * len);
4716
4717 freqs_data = os_calloc(len, sizeof(struct wpa_used_freq_data));
4718 if (!freqs_data)
4719 return -1;
4720
4721 num = get_shared_radio_freqs_data(wpa_s, freqs_data, len);
4722 for (i = 0; i < num; i++)
4723 freq_array[i] = freqs_data[i].freq;
4724
4725 os_free(freqs_data);
4726
4727 return num;
4728}