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