LCOV - code coverage report
Current view: top level - wpa_supplicant - wpa_supplicant.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1426431149 Lines: 2168 2668 81.3 %
Date: 2015-03-15 Functions: 108 112 96.4 %

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

Generated by: LCOV version 1.10