LCOV - code coverage report
Current view: top level - wpa_supplicant - events.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1426431149 Lines: 1299 1669 77.8 %
Date: 2015-03-15 Functions: 56 63 88.9 %

          Line data    Source code
       1             : /*
       2             :  * WPA Supplicant - Driver event processing
       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             : 
       9             : #include "includes.h"
      10             : 
      11             : #include "common.h"
      12             : #include "eapol_supp/eapol_supp_sm.h"
      13             : #include "rsn_supp/wpa.h"
      14             : #include "eloop.h"
      15             : #include "config.h"
      16             : #include "l2_packet/l2_packet.h"
      17             : #include "wpa_supplicant_i.h"
      18             : #include "driver_i.h"
      19             : #include "pcsc_funcs.h"
      20             : #include "rsn_supp/preauth.h"
      21             : #include "rsn_supp/pmksa_cache.h"
      22             : #include "common/wpa_ctrl.h"
      23             : #include "eap_peer/eap.h"
      24             : #include "ap/hostapd.h"
      25             : #include "p2p/p2p.h"
      26             : #include "wnm_sta.h"
      27             : #include "notify.h"
      28             : #include "common/ieee802_11_defs.h"
      29             : #include "common/ieee802_11_common.h"
      30             : #include "crypto/random.h"
      31             : #include "blacklist.h"
      32             : #include "wpas_glue.h"
      33             : #include "wps_supplicant.h"
      34             : #include "ibss_rsn.h"
      35             : #include "sme.h"
      36             : #include "gas_query.h"
      37             : #include "p2p_supplicant.h"
      38             : #include "bgscan.h"
      39             : #include "autoscan.h"
      40             : #include "ap.h"
      41             : #include "bss.h"
      42             : #include "scan.h"
      43             : #include "offchannel.h"
      44             : #include "interworking.h"
      45             : #include "mesh.h"
      46             : #include "mesh_mpm.h"
      47             : #include "wmm_ac.h"
      48             : 
      49             : 
      50             : #ifndef CONFIG_NO_SCAN_PROCESSING
      51             : static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
      52             :                                               int new_scan, int own_request);
      53             : #endif /* CONFIG_NO_SCAN_PROCESSING */
      54             : 
      55             : 
      56        3167 : static int wpas_temp_disabled(struct wpa_supplicant *wpa_s,
      57             :                               struct wpa_ssid *ssid)
      58             : {
      59             :         struct os_reltime now;
      60             : 
      61        3167 :         if (ssid == NULL || ssid->disabled_until.sec == 0)
      62        3156 :                 return 0;
      63             : 
      64          11 :         os_get_reltime(&now);
      65          11 :         if (ssid->disabled_until.sec > now.sec)
      66          11 :                 return ssid->disabled_until.sec - now.sec;
      67             : 
      68           0 :         wpas_clear_temp_disabled(wpa_s, ssid, 0);
      69             : 
      70           0 :         return 0;
      71             : }
      72             : 
      73             : 
      74        2582 : static struct wpa_bss * wpa_supplicant_get_new_bss(
      75             :         struct wpa_supplicant *wpa_s, const u8 *bssid)
      76             : {
      77        2582 :         struct wpa_bss *bss = NULL;
      78        2582 :         struct wpa_ssid *ssid = wpa_s->current_ssid;
      79             : 
      80        2582 :         if (ssid->ssid_len > 0)
      81        2469 :                 bss = wpa_bss_get(wpa_s, bssid, ssid->ssid, ssid->ssid_len);
      82        2582 :         if (!bss)
      83         128 :                 bss = wpa_bss_get_bssid(wpa_s, bssid);
      84             : 
      85        2582 :         return bss;
      86             : }
      87             : 
      88             : 
      89        2567 : static void wpa_supplicant_update_current_bss(struct wpa_supplicant *wpa_s)
      90             : {
      91        2567 :         struct wpa_bss *bss = wpa_supplicant_get_new_bss(wpa_s, wpa_s->bssid);
      92             : 
      93        2567 :         if (!bss) {
      94          15 :                 wpa_supplicant_update_scan_results(wpa_s);
      95             : 
      96             :                 /* Get the BSS from the new scan results */
      97          15 :                 bss = wpa_supplicant_get_new_bss(wpa_s, wpa_s->bssid);
      98             :         }
      99             : 
     100        2567 :         if (bss)
     101        2567 :                 wpa_s->current_bss = bss;
     102        2567 : }
     103             : 
     104             : 
     105        2570 : static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
     106             : {
     107             :         struct wpa_ssid *ssid, *old_ssid;
     108             :         int res;
     109             : 
     110        2570 :         if (wpa_s->conf->ap_scan == 1 && wpa_s->current_ssid) {
     111        2551 :                 wpa_supplicant_update_current_bss(wpa_s);
     112        2551 :                 return 0;
     113             :         }
     114             : 
     115          19 :         wpa_dbg(wpa_s, MSG_DEBUG, "Select network based on association "
     116             :                 "information");
     117          19 :         ssid = wpa_supplicant_get_ssid(wpa_s);
     118          19 :         if (ssid == NULL) {
     119           2 :                 wpa_msg(wpa_s, MSG_INFO,
     120             :                         "No network configuration found for the current AP");
     121           2 :                 return -1;
     122             :         }
     123             : 
     124          17 :         if (wpas_network_disabled(wpa_s, ssid)) {
     125           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Selected network is disabled");
     126           0 :                 return -1;
     127             :         }
     128             : 
     129          33 :         if (disallowed_bssid(wpa_s, wpa_s->bssid) ||
     130          16 :             disallowed_ssid(wpa_s, ssid->ssid, ssid->ssid_len)) {
     131           1 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Selected BSS is disallowed");
     132           1 :                 return -1;
     133             :         }
     134             : 
     135          16 :         res = wpas_temp_disabled(wpa_s, ssid);
     136          16 :         if (res > 0) {
     137           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Selected network is temporarily "
     138             :                         "disabled for %d second(s)", res);
     139           0 :                 return -1;
     140             :         }
     141             : 
     142          16 :         wpa_dbg(wpa_s, MSG_DEBUG, "Network configuration found for the "
     143             :                 "current AP");
     144          16 :         if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
     145             :                 u8 wpa_ie[80];
     146           8 :                 size_t wpa_ie_len = sizeof(wpa_ie);
     147           8 :                 if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
     148             :                                               wpa_ie, &wpa_ie_len) < 0)
     149           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "Could not set WPA suites");
     150             :         } else {
     151           8 :                 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
     152             :         }
     153             : 
     154          16 :         if (wpa_s->current_ssid && wpa_s->current_ssid != ssid)
     155           0 :                 eapol_sm_invalidate_cached_session(wpa_s->eapol);
     156          16 :         old_ssid = wpa_s->current_ssid;
     157          16 :         wpa_s->current_ssid = ssid;
     158             : 
     159          16 :         wpa_supplicant_update_current_bss(wpa_s);
     160             : 
     161          16 :         wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
     162          16 :         wpa_supplicant_initiate_eapol(wpa_s);
     163          16 :         if (old_ssid != wpa_s->current_ssid)
     164           9 :                 wpas_notify_network_changed(wpa_s);
     165             : 
     166          16 :         return 0;
     167             : }
     168             : 
     169             : 
     170        3341 : void wpa_supplicant_stop_countermeasures(void *eloop_ctx, void *sock_ctx)
     171             : {
     172        3341 :         struct wpa_supplicant *wpa_s = eloop_ctx;
     173             : 
     174        3341 :         if (wpa_s->countermeasures) {
     175           1 :                 wpa_s->countermeasures = 0;
     176           1 :                 wpa_drv_set_countermeasures(wpa_s, 0);
     177           1 :                 wpa_msg(wpa_s, MSG_INFO, "WPA: TKIP countermeasures stopped");
     178             : 
     179             :                 /*
     180             :                  * It is possible that the device is sched scanning, which means
     181             :                  * that a connection attempt will be done only when we receive
     182             :                  * scan results. However, in this case, it would be preferable
     183             :                  * to scan and connect immediately, so cancel the sched_scan and
     184             :                  * issue a regular scan flow.
     185             :                  */
     186           1 :                 wpa_supplicant_cancel_sched_scan(wpa_s);
     187           1 :                 wpa_supplicant_req_scan(wpa_s, 0, 0);
     188             :         }
     189        3341 : }
     190             : 
     191             : 
     192        5018 : void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
     193             : {
     194             :         int bssid_changed;
     195             : 
     196        5018 :         wnm_bss_keep_alive_deinit(wpa_s);
     197             : 
     198             : #ifdef CONFIG_IBSS_RSN
     199        5018 :         ibss_rsn_deinit(wpa_s->ibss_rsn);
     200        5018 :         wpa_s->ibss_rsn = NULL;
     201             : #endif /* CONFIG_IBSS_RSN */
     202             : 
     203             : #ifdef CONFIG_AP
     204        5018 :         wpa_supplicant_ap_deinit(wpa_s);
     205             : #endif /* CONFIG_AP */
     206             : 
     207        5018 :         if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
     208        5055 :                 return;
     209             : 
     210        4981 :         wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
     211        4981 :         bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
     212        4981 :         os_memset(wpa_s->bssid, 0, ETH_ALEN);
     213        4981 :         os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
     214        4981 :         sme_clear_on_disassoc(wpa_s);
     215             : #ifdef CONFIG_P2P
     216        4981 :         os_memset(wpa_s->go_dev_addr, 0, ETH_ALEN);
     217             : #endif /* CONFIG_P2P */
     218        4981 :         wpa_s->current_bss = NULL;
     219        4981 :         wpa_s->assoc_freq = 0;
     220             : 
     221        4981 :         if (bssid_changed)
     222        2383 :                 wpas_notify_bssid_changed(wpa_s);
     223             : 
     224        4981 :         eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
     225        4981 :         eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
     226        4981 :         if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt))
     227         784 :                 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
     228        4981 :         wpa_s->ap_ies_from_associnfo = 0;
     229        4981 :         wpa_s->current_ssid = NULL;
     230        4981 :         eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
     231        4981 :         wpa_s->key_mgmt = 0;
     232             : 
     233        4981 :         wpas_rrm_reset(wpa_s);
     234             : }
     235             : 
     236             : 
     237           0 : static void wpa_find_assoc_pmkid(struct wpa_supplicant *wpa_s)
     238             : {
     239             :         struct wpa_ie_data ie;
     240           0 :         int pmksa_set = -1;
     241             :         size_t i;
     242             : 
     243           0 :         if (wpa_sm_parse_own_wpa_ie(wpa_s->wpa, &ie) < 0 ||
     244           0 :             ie.pmkid == NULL)
     245           0 :                 return;
     246             : 
     247           0 :         for (i = 0; i < ie.num_pmkid; i++) {
     248           0 :                 pmksa_set = pmksa_cache_set_current(wpa_s->wpa,
     249           0 :                                                     ie.pmkid + i * PMKID_LEN,
     250             :                                                     NULL, NULL, 0);
     251           0 :                 if (pmksa_set == 0) {
     252           0 :                         eapol_sm_notify_pmkid_attempt(wpa_s->eapol);
     253           0 :                         break;
     254             :                 }
     255             :         }
     256             : 
     257           0 :         wpa_dbg(wpa_s, MSG_DEBUG, "RSN: PMKID from assoc IE %sfound from "
     258             :                 "PMKSA cache", pmksa_set == 0 ? "" : "not ");
     259             : }
     260             : 
     261             : 
     262           0 : static void wpa_supplicant_event_pmkid_candidate(struct wpa_supplicant *wpa_s,
     263             :                                                  union wpa_event_data *data)
     264             : {
     265           0 :         if (data == NULL) {
     266           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "RSN: No data in PMKID candidate "
     267             :                         "event");
     268           0 :                 return;
     269             :         }
     270           0 :         wpa_dbg(wpa_s, MSG_DEBUG, "RSN: PMKID candidate event - bssid=" MACSTR
     271             :                 " index=%d preauth=%d",
     272             :                 MAC2STR(data->pmkid_candidate.bssid),
     273             :                 data->pmkid_candidate.index,
     274             :                 data->pmkid_candidate.preauth);
     275             : 
     276           0 :         pmksa_candidate_add(wpa_s->wpa, data->pmkid_candidate.bssid,
     277             :                             data->pmkid_candidate.index,
     278             :                             data->pmkid_candidate.preauth);
     279             : }
     280             : 
     281             : 
     282        4998 : static int wpa_supplicant_dynamic_keys(struct wpa_supplicant *wpa_s)
     283             : {
     284        9338 :         if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
     285        4340 :             wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
     286         663 :                 return 0;
     287             : 
     288             : #ifdef IEEE8021X_EAPOL
     289        4355 :         if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
     290          40 :             wpa_s->current_ssid &&
     291          20 :             !(wpa_s->current_ssid->eapol_flags &
     292             :               (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
     293             :                EAPOL_FLAG_REQUIRE_KEY_BROADCAST))) {
     294             :                 /* IEEE 802.1X, but not using dynamic WEP keys (i.e., either
     295             :                  * plaintext or static WEP keys). */
     296          16 :                 return 0;
     297             :         }
     298             : #endif /* IEEE8021X_EAPOL */
     299             : 
     300        4319 :         return 1;
     301             : }
     302             : 
     303             : 
     304             : /**
     305             :  * wpa_supplicant_scard_init - Initialize SIM/USIM access with PC/SC
     306             :  * @wpa_s: pointer to wpa_supplicant data
     307             :  * @ssid: Configuration data for the network
     308             :  * Returns: 0 on success, -1 on failure
     309             :  *
     310             :  * This function is called when starting authentication with a network that is
     311             :  * configured to use PC/SC for SIM/USIM access (EAP-SIM or EAP-AKA).
     312             :  */
     313        5099 : int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
     314             :                               struct wpa_ssid *ssid)
     315             : {
     316             : #ifdef IEEE8021X_EAPOL
     317             : #ifdef PCSC_FUNCS
     318             :         int aka = 0, sim = 0;
     319             : 
     320             :         if ((ssid != NULL && ssid->eap.pcsc == NULL) ||
     321             :             wpa_s->scard != NULL || wpa_s->conf->external_sim)
     322             :                 return 0;
     323             : 
     324             :         if (ssid == NULL || ssid->eap.eap_methods == NULL) {
     325             :                 sim = 1;
     326             :                 aka = 1;
     327             :         } else {
     328             :                 struct eap_method_type *eap = ssid->eap.eap_methods;
     329             :                 while (eap->vendor != EAP_VENDOR_IETF ||
     330             :                        eap->method != EAP_TYPE_NONE) {
     331             :                         if (eap->vendor == EAP_VENDOR_IETF) {
     332             :                                 if (eap->method == EAP_TYPE_SIM)
     333             :                                         sim = 1;
     334             :                                 else if (eap->method == EAP_TYPE_AKA ||
     335             :                                          eap->method == EAP_TYPE_AKA_PRIME)
     336             :                                         aka = 1;
     337             :                         }
     338             :                         eap++;
     339             :                 }
     340             :         }
     341             : 
     342             :         if (eap_peer_get_eap_method(EAP_VENDOR_IETF, EAP_TYPE_SIM) == NULL)
     343             :                 sim = 0;
     344             :         if (eap_peer_get_eap_method(EAP_VENDOR_IETF, EAP_TYPE_AKA) == NULL &&
     345             :             eap_peer_get_eap_method(EAP_VENDOR_IETF, EAP_TYPE_AKA_PRIME) ==
     346             :             NULL)
     347             :                 aka = 0;
     348             : 
     349             :         if (!sim && !aka) {
     350             :                 wpa_dbg(wpa_s, MSG_DEBUG, "Selected network is configured to "
     351             :                         "use SIM, but neither EAP-SIM nor EAP-AKA are "
     352             :                         "enabled");
     353             :                 return 0;
     354             :         }
     355             : 
     356             :         wpa_dbg(wpa_s, MSG_DEBUG, "Selected network is configured to use SIM "
     357             :                 "(sim=%d aka=%d) - initialize PCSC", sim, aka);
     358             : 
     359             :         wpa_s->scard = scard_init(wpa_s->conf->pcsc_reader);
     360             :         if (wpa_s->scard == NULL) {
     361             :                 wpa_msg(wpa_s, MSG_WARNING, "Failed to initialize SIM "
     362             :                         "(pcsc-lite)");
     363             :                 return -1;
     364             :         }
     365             :         wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
     366             :         eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
     367             : #endif /* PCSC_FUNCS */
     368             : #endif /* IEEE8021X_EAPOL */
     369             : 
     370        5099 :         return 0;
     371             : }
     372             : 
     373             : 
     374             : #ifndef CONFIG_NO_SCAN_PROCESSING
     375             : 
     376        2626 : static int has_wep_key(struct wpa_ssid *ssid)
     377             : {
     378             :         int i;
     379             : 
     380       13030 :         for (i = 0; i < NUM_WEP_KEYS; i++) {
     381       10429 :                 if (ssid->wep_key_len[i])
     382          25 :                         return 1;
     383             :         }
     384             : 
     385        2601 :         return 0;
     386             : }
     387             : 
     388             : 
     389        2639 : static int wpa_supplicant_match_privacy(struct wpa_bss *bss,
     390             :                                         struct wpa_ssid *ssid)
     391             : {
     392        2639 :         int privacy = 0;
     393             : 
     394        2639 :         if (ssid->mixed_cell)
     395           0 :                 return 1;
     396             : 
     397             : #ifdef CONFIG_WPS
     398        2639 :         if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
     399         294 :                 return 1;
     400             : #endif /* CONFIG_WPS */
     401             : 
     402        2345 :         if (has_wep_key(ssid))
     403          25 :                 privacy = 1;
     404             : 
     405             : #ifdef IEEE8021X_EAPOL
     406        2355 :         if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) &&
     407          10 :             ssid->eapol_flags & (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
     408             :                                  EAPOL_FLAG_REQUIRE_KEY_BROADCAST))
     409           2 :                 privacy = 1;
     410             : #endif /* IEEE8021X_EAPOL */
     411             : 
     412        2345 :         if (wpa_key_mgmt_wpa(ssid->key_mgmt))
     413        1959 :                 privacy = 1;
     414             : 
     415        2345 :         if (ssid->key_mgmt & WPA_KEY_MGMT_OSEN)
     416           2 :                 privacy = 1;
     417             : 
     418        2345 :         if (bss->caps & IEEE80211_CAP_PRIVACY)
     419        1989 :                 return privacy;
     420         356 :         return !privacy;
     421             : }
     422             : 
     423             : 
     424        2737 : static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s,
     425             :                                          struct wpa_ssid *ssid,
     426             :                                          struct wpa_bss *bss)
     427             : {
     428             :         struct wpa_ie_data ie;
     429        2737 :         int proto_match = 0;
     430             :         const u8 *rsn_ie, *wpa_ie;
     431             :         int ret;
     432             :         int wep_ok;
     433             : 
     434        2737 :         ret = wpas_wps_ssid_bss_match(wpa_s, ssid, bss);
     435        2737 :         if (ret >= 0)
     436         324 :                 return ret;
     437             : 
     438             :         /* Allow TSN if local configuration accepts WEP use without WPA/WPA2 */
     439        2833 :         wep_ok = !wpa_key_mgmt_wpa(ssid->key_mgmt) &&
     440         760 :                 (((ssid->key_mgmt & WPA_KEY_MGMT_NONE) &&
     441         736 :                   ssid->wep_key_len[ssid->wep_tx_keyidx] > 0) ||
     442         362 :                  (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA));
     443             : 
     444        2413 :         rsn_ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
     445        2413 :         while ((ssid->proto & WPA_PROTO_RSN) && rsn_ie) {
     446        1940 :                 proto_match++;
     447             : 
     448        1940 :                 if (wpa_parse_wpa_ie(rsn_ie, 2 + rsn_ie[1], &ie)) {
     449           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip RSN IE - parse "
     450             :                                 "failed");
     451           0 :                         break;
     452             :                 }
     453             : 
     454        1940 :                 if (wep_ok &&
     455           0 :                     (ie.group_cipher & (WPA_CIPHER_WEP40 | WPA_CIPHER_WEP104)))
     456             :                 {
     457           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   selected based on TSN "
     458             :                                 "in RSN IE");
     459           0 :                         return 1;
     460             :                 }
     461             : 
     462        1940 :                 if (!(ie.proto & ssid->proto)) {
     463           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip RSN IE - proto "
     464             :                                 "mismatch");
     465           0 :                         break;
     466             :                 }
     467             : 
     468        1940 :                 if (!(ie.pairwise_cipher & ssid->pairwise_cipher)) {
     469           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip RSN IE - PTK "
     470             :                                 "cipher mismatch");
     471           0 :                         break;
     472             :                 }
     473             : 
     474        1940 :                 if (!(ie.group_cipher & ssid->group_cipher)) {
     475           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip RSN IE - GTK "
     476             :                                 "cipher mismatch");
     477           0 :                         break;
     478             :                 }
     479             : 
     480        1940 :                 if (!(ie.key_mgmt & ssid->key_mgmt)) {
     481           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip RSN IE - key mgmt "
     482             :                                 "mismatch");
     483           0 :                         break;
     484             :                 }
     485             : 
     486             : #ifdef CONFIG_IEEE80211W
     487        3738 :                 if (!(ie.capabilities & WPA_CAPABILITY_MFPC) &&
     488        1798 :                     wpas_get_ssid_pmf(wpa_s, ssid) ==
     489             :                     MGMT_FRAME_PROTECTION_REQUIRED) {
     490           2 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip RSN IE - no mgmt "
     491             :                                 "frame protection");
     492           2 :                         break;
     493             :                 }
     494             : #endif /* CONFIG_IEEE80211W */
     495             : 
     496        1938 :                 wpa_dbg(wpa_s, MSG_DEBUG, "   selected based on RSN IE");
     497        1938 :                 return 1;
     498             :         }
     499             : 
     500         475 :         wpa_ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
     501         475 :         while ((ssid->proto & WPA_PROTO_WPA) && wpa_ie) {
     502          21 :                 proto_match++;
     503             : 
     504          21 :                 if (wpa_parse_wpa_ie(wpa_ie, 2 + wpa_ie[1], &ie)) {
     505           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip WPA IE - parse "
     506             :                                 "failed");
     507           0 :                         break;
     508             :                 }
     509             : 
     510          21 :                 if (wep_ok &&
     511           0 :                     (ie.group_cipher & (WPA_CIPHER_WEP40 | WPA_CIPHER_WEP104)))
     512             :                 {
     513           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   selected based on TSN "
     514             :                                 "in WPA IE");
     515           0 :                         return 1;
     516             :                 }
     517             : 
     518          21 :                 if (!(ie.proto & ssid->proto)) {
     519           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip WPA IE - proto "
     520             :                                 "mismatch");
     521           0 :                         break;
     522             :                 }
     523             : 
     524          21 :                 if (!(ie.pairwise_cipher & ssid->pairwise_cipher)) {
     525           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip WPA IE - PTK "
     526             :                                 "cipher mismatch");
     527           0 :                         break;
     528             :                 }
     529             : 
     530          21 :                 if (!(ie.group_cipher & ssid->group_cipher)) {
     531           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip WPA IE - GTK "
     532             :                                 "cipher mismatch");
     533           0 :                         break;
     534             :                 }
     535             : 
     536          21 :                 if (!(ie.key_mgmt & ssid->key_mgmt)) {
     537           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip WPA IE - key mgmt "
     538             :                                 "mismatch");
     539           0 :                         break;
     540             :                 }
     541             : 
     542          21 :                 wpa_dbg(wpa_s, MSG_DEBUG, "   selected based on WPA IE");
     543          21 :                 return 1;
     544             :         }
     545             : 
     546         454 :         if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && !wpa_ie &&
     547             :             !rsn_ie) {
     548          10 :                 wpa_dbg(wpa_s, MSG_DEBUG, "   allow for non-WPA IEEE 802.1X");
     549          10 :                 return 1;
     550             :         }
     551             : 
     552         885 :         if ((ssid->proto & (WPA_PROTO_WPA | WPA_PROTO_RSN)) &&
     553         509 :             wpa_key_mgmt_wpa(ssid->key_mgmt) && proto_match == 0) {
     554          66 :                 wpa_dbg(wpa_s, MSG_DEBUG, "   skip - no WPA/RSN proto match");
     555          66 :                 return 0;
     556             :         }
     557             : 
     558         380 :         if ((ssid->key_mgmt & WPA_KEY_MGMT_OSEN) &&
     559           2 :             wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE)) {
     560           2 :                 wpa_dbg(wpa_s, MSG_DEBUG, "   allow in OSEN");
     561           2 :                 return 1;
     562             :         }
     563             : 
     564         376 :         if (!wpa_key_mgmt_wpa(ssid->key_mgmt)) {
     565         374 :                 wpa_dbg(wpa_s, MSG_DEBUG, "   allow in non-WPA/WPA2");
     566         374 :                 return 1;
     567             :         }
     568             : 
     569           2 :         wpa_dbg(wpa_s, MSG_DEBUG, "   reject due to mismatch with "
     570             :                 "WPA/WPA2");
     571             : 
     572           2 :         return 0;
     573             : }
     574             : 
     575             : 
     576        2634 : static int freq_allowed(int *freqs, int freq)
     577             : {
     578             :         int i;
     579             : 
     580        2634 :         if (freqs == NULL)
     581        2634 :                 return 1;
     582             : 
     583           0 :         for (i = 0; freqs[i]; i++)
     584           0 :                 if (freqs[i] == freq)
     585           0 :                         return 1;
     586           0 :         return 0;
     587             : }
     588             : 
     589             : 
     590        2634 : static int rate_match(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
     591             : {
     592        2634 :         const struct hostapd_hw_modes *mode = NULL, *modes;
     593        2634 :         const u8 scan_ie[2] = { WLAN_EID_SUPP_RATES, WLAN_EID_EXT_SUPP_RATES };
     594             :         const u8 *rate_ie;
     595             :         int i, j, k;
     596             : 
     597        2634 :         if (bss->freq == 0)
     598           0 :                 return 1; /* Cannot do matching without knowing band */
     599             : 
     600        2634 :         modes = wpa_s->hw.modes;
     601        2634 :         if (modes == NULL) {
     602             :                 /*
     603             :                  * The driver does not provide any additional information
     604             :                  * about the utilized hardware, so allow the connection attempt
     605             :                  * to continue.
     606             :                  */
     607          14 :                 return 1;
     608             :         }
     609             : 
     610       10480 :         for (i = 0; i < wpa_s->hw.num_modes; i++) {
     611       75485 :                 for (j = 0; j < modes[i].num_channels; j++) {
     612       72813 :                         int freq = modes[i].channels[j].freq;
     613       72813 :                         if (freq == bss->freq) {
     614        7756 :                                 if (mode &&
     615        2568 :                                     mode->mode == HOSTAPD_MODE_IEEE80211G)
     616        2568 :                                         break; /* do not allow 802.11b replace
     617             :                                                 * 802.11g */
     618        2620 :                                 mode = &modes[i];
     619        2620 :                                 break;
     620             :                         }
     621             :                 }
     622             :         }
     623             : 
     624        2620 :         if (mode == NULL)
     625           0 :                 return 0;
     626             : 
     627        7860 :         for (i = 0; i < (int) sizeof(scan_ie); i++) {
     628        5240 :                 rate_ie = wpa_bss_get_ie(bss, scan_ie[i]);
     629        5240 :                 if (rate_ie == NULL)
     630         604 :                         continue;
     631             : 
     632       33632 :                 for (j = 2; j < rate_ie[1] + 2; j++) {
     633       28996 :                         int flagged = !!(rate_ie[j] & 0x80);
     634       28996 :                         int r = (rate_ie[j] & 0x7f) * 5;
     635             : 
     636             :                         /*
     637             :                          * IEEE Std 802.11n-2009 7.3.2.2:
     638             :                          * The new BSS Membership selector value is encoded
     639             :                          * like a legacy basic rate, but it is not a rate and
     640             :                          * only indicates if the BSS members are required to
     641             :                          * support the mandatory features of Clause 20 [HT PHY]
     642             :                          * in order to join the BSS.
     643             :                          */
     644       28996 :                         if (flagged && ((rate_ie[j] & 0x7f) ==
     645             :                                         BSS_MEMBERSHIP_SELECTOR_HT_PHY)) {
     646           7 :                                 if (!ht_supported(mode)) {
     647           0 :                                         wpa_dbg(wpa_s, MSG_DEBUG,
     648             :                                                 "   hardware does not support "
     649             :                                                 "HT PHY");
     650           0 :                                         return 0;
     651             :                                 }
     652           7 :                                 continue;
     653             :                         }
     654             : 
     655             :                         /* There's also a VHT selector for 802.11ac */
     656       28989 :                         if (flagged && ((rate_ie[j] & 0x7f) ==
     657             :                                         BSS_MEMBERSHIP_SELECTOR_VHT_PHY)) {
     658           3 :                                 if (!vht_supported(mode)) {
     659           0 :                                         wpa_dbg(wpa_s, MSG_DEBUG,
     660             :                                                 "   hardware does not support "
     661             :                                                 "VHT PHY");
     662           0 :                                         return 0;
     663             :                                 }
     664           3 :                                 continue;
     665             :                         }
     666             : 
     667       28986 :                         if (!flagged)
     668       19116 :                                 continue;
     669             : 
     670             :                         /* check for legacy basic rates */
     671       32160 :                         for (k = 0; k < mode->num_rates; k++) {
     672       32160 :                                 if (mode->rates[k] == r)
     673        9870 :                                         break;
     674             :                         }
     675        9870 :                         if (k == mode->num_rates) {
     676             :                                 /*
     677             :                                  * IEEE Std 802.11-2007 7.3.2.2 demands that in
     678             :                                  * order to join a BSS all required rates
     679             :                                  * have to be supported by the hardware.
     680             :                                  */
     681           0 :                                 wpa_dbg(wpa_s, MSG_DEBUG,
     682             :                                         "   hardware does not support required rate %d.%d Mbps (freq=%d mode==%d num_rates=%d)",
     683             :                                         r / 10, r % 10,
     684             :                                         bss->freq, mode->mode, mode->num_rates);
     685           0 :                                 return 0;
     686             :                         }
     687             :                 }
     688             :         }
     689             : 
     690        2620 :         return 1;
     691             : }
     692             : 
     693             : 
     694             : /*
     695             :  * Test whether BSS is in an ESS.
     696             :  * This is done differently in DMG (60 GHz) and non-DMG bands
     697             :  */
     698        2636 : static int bss_is_ess(struct wpa_bss *bss)
     699             : {
     700        2636 :         if (bss_is_dmg(bss)) {
     701           0 :                 return (bss->caps & IEEE80211_CAP_DMG_MASK) ==
     702             :                         IEEE80211_CAP_DMG_AP;
     703             :         }
     704             : 
     705        2636 :         return ((bss->caps & (IEEE80211_CAP_ESS | IEEE80211_CAP_IBSS)) ==
     706             :                 IEEE80211_CAP_ESS);
     707             : }
     708             : 
     709             : 
     710          17 : static int match_mac_mask(const u8 *addr_a, const u8 *addr_b, const u8 *mask)
     711             : {
     712             :         size_t i;
     713             : 
     714          55 :         for (i = 0; i < ETH_ALEN; i++) {
     715          52 :                 if ((addr_a[i] & mask[i]) != (addr_b[i] & mask[i]))
     716          14 :                         return 0;
     717             :         }
     718           3 :         return 1;
     719             : }
     720             : 
     721             : 
     722          12 : static int addr_in_list(const u8 *addr, const u8 *list, size_t num)
     723             : {
     724             :         size_t i;
     725             : 
     726          26 :         for (i = 0; i < num; i++) {
     727          17 :                 const u8 *a = list + i * ETH_ALEN * 2;
     728          17 :                 const u8 *m = a + ETH_ALEN;
     729             : 
     730          17 :                 if (match_mac_mask(a, addr, m))
     731           3 :                         return 1;
     732             :         }
     733           9 :         return 0;
     734             : }
     735             : 
     736             : 
     737        3357 : static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
     738             :                                             int i, struct wpa_bss *bss,
     739             :                                             struct wpa_ssid *group,
     740             :                                             int only_first_ssid)
     741             : {
     742             :         u8 wpa_ie_len, rsn_ie_len;
     743             :         int wpa;
     744             :         struct wpa_blacklist *e;
     745             :         const u8 *ie;
     746             :         struct wpa_ssid *ssid;
     747             :         int osen;
     748             : 
     749        3357 :         ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
     750        3357 :         wpa_ie_len = ie ? ie[1] : 0;
     751             : 
     752        3357 :         ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
     753        3357 :         rsn_ie_len = ie ? ie[1] : 0;
     754             : 
     755        3357 :         ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE);
     756        3357 :         osen = ie != NULL;
     757             : 
     758        3357 :         wpa_dbg(wpa_s, MSG_DEBUG, "%d: " MACSTR " ssid='%s' "
     759             :                 "wpa_ie_len=%u rsn_ie_len=%u caps=0x%x level=%d%s%s%s",
     760             :                 i, MAC2STR(bss->bssid), wpa_ssid_txt(bss->ssid, bss->ssid_len),
     761             :                 wpa_ie_len, rsn_ie_len, bss->caps, bss->level,
     762             :                 wpa_bss_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE) ? " wps" : "",
     763             :                 (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) ||
     764             :                  wpa_bss_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE)) ?
     765             :                 " p2p" : "",
     766             :                 osen ? " osen=1" : "");
     767             : 
     768        3357 :         e = wpa_blacklist_get(wpa_s, bss->bssid);
     769        3357 :         if (e) {
     770         193 :                 int limit = 1;
     771         193 :                 if (wpa_supplicant_enabled_networks(wpa_s) == 1) {
     772             :                         /*
     773             :                          * When only a single network is enabled, we can
     774             :                          * trigger blacklisting on the first failure. This
     775             :                          * should not be done with multiple enabled networks to
     776             :                          * avoid getting forced to move into a worse ESS on
     777             :                          * single error if there are no other BSSes of the
     778             :                          * current ESS.
     779             :                          */
     780         193 :                         limit = 0;
     781             :                 }
     782         193 :                 if (e->count > limit) {
     783         193 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip - blacklisted "
     784             :                                 "(count=%d limit=%d)", e->count, limit);
     785         193 :                         return NULL;
     786             :                 }
     787             :         }
     788             : 
     789        3164 :         if (bss->ssid_len == 0) {
     790          16 :                 wpa_dbg(wpa_s, MSG_DEBUG, "   skip - SSID not known");
     791          16 :                 return NULL;
     792             :         }
     793             : 
     794        3148 :         if (disallowed_bssid(wpa_s, bss->bssid)) {
     795           1 :                 wpa_dbg(wpa_s, MSG_DEBUG, "   skip - BSSID disallowed");
     796           1 :                 return NULL;
     797             :         }
     798             : 
     799        3147 :         if (disallowed_ssid(wpa_s, bss->ssid, bss->ssid_len)) {
     800           2 :                 wpa_dbg(wpa_s, MSG_DEBUG, "   skip - SSID disallowed");
     801           2 :                 return NULL;
     802             :         }
     803             : 
     804        3145 :         wpa = wpa_ie_len > 0 || rsn_ie_len > 0;
     805             : 
     806        5535 :         for (ssid = group; ssid; ssid = only_first_ssid ? NULL : ssid->pnext) {
     807        5024 :                 int check_ssid = wpa ? 1 : (ssid->ssid_len != 0);
     808             :                 int res;
     809             : 
     810        5024 :                 if (wpas_network_disabled(wpa_s, ssid)) {
     811        1877 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip - disabled");
     812        1877 :                         continue;
     813             :                 }
     814             : 
     815        3147 :                 res = wpas_temp_disabled(wpa_s, ssid);
     816        3147 :                 if (res > 0) {
     817          10 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip - disabled "
     818             :                                 "temporarily for %d second(s)", res);
     819          10 :                         continue;
     820             :                 }
     821             : 
     822             : #ifdef CONFIG_WPS
     823        3137 :                 if ((ssid->key_mgmt & WPA_KEY_MGMT_WPS) && e && e->count > 0) {
     824           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip - blacklisted "
     825             :                                 "(WPS)");
     826           0 :                         continue;
     827             :                 }
     828             : 
     829        3250 :                 if (wpa && ssid->ssid_len == 0 &&
     830         113 :                     wpas_wps_ssid_wildcard_ok(wpa_s, ssid, bss))
     831         108 :                         check_ssid = 0;
     832             : 
     833        3137 :                 if (!wpa && (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
     834             :                         /* Only allow wildcard SSID match if an AP
     835             :                          * advertises active WPS operation that matches
     836             :                          * with our mode. */
     837          47 :                         check_ssid = 1;
     838          89 :                         if (ssid->ssid_len == 0 &&
     839          42 :                             wpas_wps_ssid_wildcard_ok(wpa_s, ssid, bss))
     840          14 :                                 check_ssid = 0;
     841             :                 }
     842             : #endif /* CONFIG_WPS */
     843             : 
     844        3237 :                 if (ssid->bssid_set && ssid->ssid_len == 0 &&
     845         100 :                     os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) == 0)
     846         100 :                         check_ssid = 0;
     847             : 
     848        6152 :                 if (check_ssid &&
     849        5838 :                     (bss->ssid_len != ssid->ssid_len ||
     850        2823 :                      os_memcmp(bss->ssid, ssid->ssid, bss->ssid_len) != 0)) {
     851         389 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip - SSID mismatch");
     852         389 :                         continue;
     853             :                 }
     854             : 
     855        3378 :                 if (ssid->bssid_set &&
     856         630 :                     os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0) {
     857           5 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip - BSSID mismatch");
     858           5 :                         continue;
     859             :                 }
     860             : 
     861             :                 /* check blacklist */
     862        2746 :                 if (ssid->num_bssid_blacklist &&
     863           3 :                     addr_in_list(bss->bssid, ssid->bssid_blacklist,
     864             :                                  ssid->num_bssid_blacklist)) {
     865           0 :                         wpa_dbg(wpa_s, MSG_DEBUG,
     866             :                                 "   skip - BSSID blacklisted");
     867           0 :                         continue;
     868             :                 }
     869             : 
     870             :                 /* if there is a whitelist, only accept those APs */
     871        2752 :                 if (ssid->num_bssid_whitelist &&
     872           9 :                     !addr_in_list(bss->bssid, ssid->bssid_whitelist,
     873             :                                   ssid->num_bssid_whitelist)) {
     874           6 :                         wpa_dbg(wpa_s, MSG_DEBUG,
     875             :                                 "   skip - BSSID not in whitelist");
     876           6 :                         continue;
     877             :                 }
     878             : 
     879        2737 :                 if (!wpa_supplicant_ssid_bss_match(wpa_s, ssid, bss))
     880          98 :                         continue;
     881             : 
     882        3035 :                 if (!osen && !wpa &&
     883         421 :                     !(ssid->key_mgmt & WPA_KEY_MGMT_NONE) &&
     884          35 :                     !(ssid->key_mgmt & WPA_KEY_MGMT_WPS) &&
     885          10 :                     !(ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)) {
     886           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip - non-WPA network "
     887             :                                 "not allowed");
     888           0 :                         continue;
     889             :                 }
     890             : 
     891        2920 :                 if (wpa && !wpa_key_mgmt_wpa(ssid->key_mgmt) &&
     892         281 :                     has_wep_key(ssid)) {
     893           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip - ignore WPA/WPA2 AP for WEP network block");
     894           0 :                         continue;
     895             :                 }
     896             : 
     897        2639 :                 if ((ssid->key_mgmt & WPA_KEY_MGMT_OSEN) && !osen) {
     898           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip - non-OSEN network "
     899             :                                 "not allowed");
     900           0 :                         continue;
     901             :                 }
     902             : 
     903        2639 :                 if (!wpa_supplicant_match_privacy(bss, ssid)) {
     904           3 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip - privacy "
     905             :                                 "mismatch");
     906           3 :                         continue;
     907             :                 }
     908             : 
     909        2636 :                 if (!bss_is_ess(bss)) {
     910           2 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip - not ESS network");
     911           2 :                         continue;
     912             :                 }
     913             : 
     914        2634 :                 if (!freq_allowed(ssid->freq_list, bss->freq)) {
     915           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip - frequency not "
     916             :                                 "allowed");
     917           0 :                         continue;
     918             :                 }
     919             : 
     920        2634 :                 if (!rate_match(wpa_s, bss)) {
     921           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip - rate sets do "
     922             :                                 "not match");
     923           0 :                         continue;
     924             :                 }
     925             : 
     926             : #ifdef CONFIG_P2P
     927        3174 :                 if (ssid->p2p_group &&
     928         540 :                     !wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) &&
     929           0 :                     !wpa_bss_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE)) {
     930           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "   skip - no P2P IE seen");
     931           0 :                         continue;
     932             :                 }
     933             : 
     934        2634 :                 if (!is_zero_ether_addr(ssid->go_p2p_dev_addr)) {
     935             :                         struct wpabuf *p2p_ie;
     936             :                         u8 dev_addr[ETH_ALEN];
     937             : 
     938          45 :                         ie = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE);
     939          45 :                         if (ie == NULL) {
     940           0 :                                 wpa_dbg(wpa_s, MSG_DEBUG, "   skip - no P2P element");
     941           0 :                                 continue;
     942             :                         }
     943          45 :                         p2p_ie = wpa_bss_get_vendor_ie_multi(
     944             :                                 bss, P2P_IE_VENDOR_TYPE);
     945          45 :                         if (p2p_ie == NULL) {
     946           0 :                                 wpa_dbg(wpa_s, MSG_DEBUG, "   skip - could not fetch P2P element");
     947           0 :                                 continue;
     948             :                         }
     949             : 
     950          45 :                         if (p2p_parse_dev_addr_in_p2p_ie(p2p_ie, dev_addr) < 0
     951          45 :                             || os_memcmp(dev_addr, ssid->go_p2p_dev_addr,
     952             :                                          ETH_ALEN) != 0) {
     953           0 :                                 wpa_dbg(wpa_s, MSG_DEBUG, "   skip - no matching GO P2P Device Address in P2P element");
     954           0 :                                 wpabuf_free(p2p_ie);
     955           0 :                                 continue;
     956             :                         }
     957          45 :                         wpabuf_free(p2p_ie);
     958             :                 }
     959             : 
     960             :                 /*
     961             :                  * TODO: skip the AP if its P2P IE has Group Formation
     962             :                  * bit set in the P2P Group Capability Bitmap and we
     963             :                  * are not in Group Formation with that device.
     964             :                  */
     965             : #endif /* CONFIG_P2P */
     966             : 
     967             :                 /* Matching configuration found */
     968        2634 :                 return ssid;
     969             :         }
     970             : 
     971             :         /* No matching configuration found */
     972         511 :         return NULL;
     973             : }
     974             : 
     975             : 
     976             : static struct wpa_bss *
     977        3015 : wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s,
     978             :                           struct wpa_ssid *group,
     979             :                           struct wpa_ssid **selected_ssid,
     980             :                           int only_first_ssid)
     981             : {
     982             :         unsigned int i;
     983             : 
     984        3015 :         if (only_first_ssid)
     985          96 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Try to find BSS matching pre-selected network id=%d",
     986             :                         group->id);
     987             :         else
     988        2919 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Selecting BSS from priority group %d",
     989             :                         group->priority);
     990             : 
     991        7476 :         for (i = 0; i < wpa_s->last_scan_res_used; i++) {
     992        3357 :                 struct wpa_bss *bss = wpa_s->last_scan_res[i];
     993        3357 :                 *selected_ssid = wpa_scan_res_match(wpa_s, i, bss, group,
     994             :                                                     only_first_ssid);
     995        3357 :                 if (!*selected_ssid)
     996         723 :                         continue;
     997        2634 :                 wpa_dbg(wpa_s, MSG_DEBUG, "   selected BSS " MACSTR
     998             :                         " ssid='%s'",
     999             :                         MAC2STR(bss->bssid),
    1000             :                         wpa_ssid_txt(bss->ssid, bss->ssid_len));
    1001        2634 :                 return bss;
    1002             :         }
    1003             : 
    1004         381 :         return NULL;
    1005             : }
    1006             : 
    1007             : 
    1008        3070 : struct wpa_bss * wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s,
    1009             :                                              struct wpa_ssid **selected_ssid)
    1010             : {
    1011        3070 :         struct wpa_bss *selected = NULL;
    1012             :         int prio;
    1013        3070 :         struct wpa_ssid *next_ssid = NULL;
    1014             : 
    1015        6130 :         if (wpa_s->last_scan_res == NULL ||
    1016        3060 :             wpa_s->last_scan_res_used == 0)
    1017         168 :                 return NULL; /* no scan results from last update */
    1018             : 
    1019        2902 :         if (wpa_s->next_ssid) {
    1020             :                 struct wpa_ssid *ssid;
    1021             : 
    1022             :                 /* check that next_ssid is still valid */
    1023         101 :                 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
    1024         101 :                         if (ssid == wpa_s->next_ssid)
    1025          91 :                                 break;
    1026             :                 }
    1027          91 :                 next_ssid = ssid;
    1028          91 :                 wpa_s->next_ssid = NULL;
    1029             :         }
    1030             : 
    1031        8616 :         while (selected == NULL) {
    1032        3455 :                 for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
    1033        3107 :                         if (next_ssid && next_ssid->priority ==
    1034          98 :                             wpa_s->conf->pssid[prio]->priority) {
    1035          96 :                                 selected = wpa_supplicant_select_bss(
    1036             :                                         wpa_s, next_ssid, selected_ssid, 1);
    1037          96 :                                 if (selected)
    1038          90 :                                         break;
    1039             :                         }
    1040        2919 :                         selected = wpa_supplicant_select_bss(
    1041        2919 :                                 wpa_s, wpa_s->conf->pssid[prio],
    1042             :                                 selected_ssid, 0);
    1043        2919 :                         if (selected)
    1044        2544 :                                 break;
    1045             :                 }
    1046             : 
    1047        3259 :                 if (selected == NULL && wpa_s->blacklist &&
    1048         179 :                     !wpa_s->countermeasures) {
    1049         178 :                         wpa_dbg(wpa_s, MSG_DEBUG, "No APs found - clear "
    1050             :                                 "blacklist and try again");
    1051         178 :                         wpa_blacklist_clear(wpa_s);
    1052         178 :                         wpa_s->blacklist_cleared++;
    1053        2902 :                 } else if (selected == NULL)
    1054         268 :                         break;
    1055             :         }
    1056             : 
    1057        2902 :         return selected;
    1058             : }
    1059             : 
    1060             : 
    1061         327 : static void wpa_supplicant_req_new_scan(struct wpa_supplicant *wpa_s,
    1062             :                                         int timeout_sec, int timeout_usec)
    1063             : {
    1064         327 :         if (!wpa_supplicant_enabled_networks(wpa_s)) {
    1065             :                 /*
    1066             :                  * No networks are enabled; short-circuit request so
    1067             :                  * we don't wait timeout seconds before transitioning
    1068             :                  * to INACTIVE state.
    1069             :                  */
    1070         119 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Short-circuit new scan request "
    1071             :                         "since there are no enabled networks");
    1072         119 :                 wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
    1073         446 :                 return;
    1074             :         }
    1075             : 
    1076         208 :         wpa_s->scan_for_connection = 1;
    1077         208 :         wpa_supplicant_req_scan(wpa_s, timeout_sec, timeout_usec);
    1078             : }
    1079             : 
    1080             : 
    1081        2506 : int wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
    1082             :                            struct wpa_bss *selected,
    1083             :                            struct wpa_ssid *ssid)
    1084             : {
    1085        2506 :         if (wpas_wps_scan_pbc_overlap(wpa_s, selected, ssid)) {
    1086           3 :                 wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP
    1087             :                         "PBC session overlap");
    1088             : #ifdef CONFIG_P2P
    1089           5 :                 if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT ||
    1090           2 :                     wpa_s->p2p_in_provisioning) {
    1091           2 :                         eloop_register_timeout(0, 0, wpas_p2p_pbc_overlap_cb,
    1092             :                                                wpa_s, NULL);
    1093           2 :                         return -1;
    1094             :                 }
    1095             : #endif /* CONFIG_P2P */
    1096             : 
    1097             : #ifdef CONFIG_WPS
    1098           1 :                 wpas_wps_cancel(wpa_s);
    1099             : #endif /* CONFIG_WPS */
    1100           1 :                 return -1;
    1101             :         }
    1102             : 
    1103       47557 :         wpa_msg(wpa_s, MSG_DEBUG,
    1104             :                 "Considering connect request: reassociate: %d  selected: "
    1105             :                 MACSTR "  bssid: " MACSTR "  pending: " MACSTR
    1106             :                 "  wpa_state: %s  ssid=%p  current_ssid=%p",
    1107       15018 :                 wpa_s->reassociate, MAC2STR(selected->bssid),
    1108       30036 :                 MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
    1109             :                 wpa_supplicant_state_txt(wpa_s->wpa_state),
    1110             :                 ssid, wpa_s->current_ssid);
    1111             : 
    1112             :         /*
    1113             :          * Do not trigger new association unless the BSSID has changed or if
    1114             :          * reassociation is requested. If we are in process of associating with
    1115             :          * the selected BSSID, do not trigger new attempt.
    1116             :          */
    1117        2605 :         if (wpa_s->reassociate ||
    1118         204 :             (os_memcmp(selected->bssid, wpa_s->bssid, ETH_ALEN) != 0 &&
    1119         204 :              ((wpa_s->wpa_state != WPA_ASSOCIATING &&
    1120         103 :                wpa_s->wpa_state != WPA_AUTHENTICATING) ||
    1121           2 :               (!is_zero_ether_addr(wpa_s->pending_bssid) &&
    1122           1 :                os_memcmp(selected->bssid, wpa_s->pending_bssid, ETH_ALEN) !=
    1123           1 :                0) ||
    1124           1 :               (is_zero_ether_addr(wpa_s->pending_bssid) &&
    1125           0 :                ssid != wpa_s->current_ssid)))) {
    1126        2502 :                 if (wpa_supplicant_scard_init(wpa_s, ssid)) {
    1127           0 :                         wpa_supplicant_req_new_scan(wpa_s, 10, 0);
    1128           0 :                         return 0;
    1129             :                 }
    1130       15012 :                 wpa_msg(wpa_s, MSG_DEBUG, "Request association with " MACSTR,
    1131       15012 :                         MAC2STR(selected->bssid));
    1132        2502 :                 wpa_supplicant_associate(wpa_s, selected, ssid);
    1133             :         } else {
    1134           1 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Already associated or trying to "
    1135             :                         "connect with the selected AP");
    1136             :         }
    1137             : 
    1138        2503 :         return 0;
    1139             : }
    1140             : 
    1141             : 
    1142             : static struct wpa_ssid *
    1143         421 : wpa_supplicant_pick_new_network(struct wpa_supplicant *wpa_s)
    1144             : {
    1145             :         int prio;
    1146             :         struct wpa_ssid *ssid;
    1147             : 
    1148         686 :         for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
    1149         591 :                 for (ssid = wpa_s->conf->pssid[prio]; ssid; ssid = ssid->pnext)
    1150             :                 {
    1151         326 :                         if (wpas_network_disabled(wpa_s, ssid))
    1152          28 :                                 continue;
    1153         581 :                         if (ssid->mode == IEEE80211_MODE_IBSS ||
    1154         551 :                             ssid->mode == IEEE80211_MODE_AP ||
    1155         268 :                             ssid->mode == IEEE80211_MODE_MESH)
    1156          30 :                                 return ssid;
    1157             :                 }
    1158             :         }
    1159         391 :         return NULL;
    1160             : }
    1161             : 
    1162             : 
    1163             : /* TODO: move the rsn_preauth_scan_result*() to be called from notify.c based
    1164             :  * on BSS added and BSS changed events */
    1165        1177 : static void wpa_supplicant_rsn_preauth_scan_results(
    1166             :         struct wpa_supplicant *wpa_s)
    1167             : {
    1168             :         struct wpa_bss *bss;
    1169             : 
    1170        1177 :         if (rsn_preauth_scan_results(wpa_s->wpa) < 0)
    1171        2181 :                 return;
    1172             : 
    1173         397 :         dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
    1174             :                 const u8 *ssid, *rsn;
    1175             : 
    1176         224 :                 ssid = wpa_bss_get_ie(bss, WLAN_EID_SSID);
    1177         224 :                 if (ssid == NULL)
    1178           0 :                         continue;
    1179             : 
    1180         224 :                 rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
    1181         224 :                 if (rsn == NULL)
    1182          70 :                         continue;
    1183             : 
    1184         154 :                 rsn_preauth_scan_result(wpa_s->wpa, bss->bssid, ssid, rsn);
    1185             :         }
    1186             : 
    1187             : }
    1188             : 
    1189             : 
    1190        2393 : static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s,
    1191             :                                        struct wpa_bss *selected,
    1192             :                                        struct wpa_ssid *ssid)
    1193             : {
    1194        2393 :         struct wpa_bss *current_bss = NULL;
    1195             :         int min_diff;
    1196             : 
    1197        2393 :         if (wpa_s->reassociate)
    1198        2251 :                 return 1; /* explicit request to reassociate */
    1199         142 :         if (wpa_s->wpa_state < WPA_ASSOCIATED)
    1200          97 :                 return 1; /* we are not associated; continue */
    1201          45 :         if (wpa_s->current_ssid == NULL)
    1202           0 :                 return 1; /* unknown current SSID */
    1203          45 :         if (wpa_s->current_ssid != ssid)
    1204           0 :                 return 1; /* different network block */
    1205             : 
    1206          45 :         if (wpas_driver_bss_selection(wpa_s))
    1207           0 :                 return 0; /* Driver-based roaming */
    1208             : 
    1209          45 :         if (wpa_s->current_ssid->ssid)
    1210          90 :                 current_bss = wpa_bss_get(wpa_s, wpa_s->bssid,
    1211          45 :                                           wpa_s->current_ssid->ssid,
    1212          45 :                                           wpa_s->current_ssid->ssid_len);
    1213          45 :         if (!current_bss)
    1214           0 :                 current_bss = wpa_bss_get_bssid(wpa_s, wpa_s->bssid);
    1215             : 
    1216          45 :         if (!current_bss)
    1217           0 :                 return 1; /* current BSS not seen in scan results */
    1218             : 
    1219          45 :         if (current_bss == selected)
    1220          33 :                 return 0;
    1221             : 
    1222          12 :         if (selected->last_update_idx > current_bss->last_update_idx)
    1223           0 :                 return 1; /* current BSS not seen in the last scan */
    1224             : 
    1225             : #ifndef CONFIG_NO_ROAMING
    1226          12 :         wpa_dbg(wpa_s, MSG_DEBUG, "Considering within-ESS reassociation");
    1227          12 :         wpa_dbg(wpa_s, MSG_DEBUG, "Current BSS: " MACSTR
    1228             :                 " level=%d snr=%d est_throughput=%u",
    1229             :                 MAC2STR(current_bss->bssid), current_bss->level,
    1230             :                 current_bss->snr, current_bss->est_throughput);
    1231          12 :         wpa_dbg(wpa_s, MSG_DEBUG, "Selected BSS: " MACSTR
    1232             :                 " level=%d snr=%d est_throughput=%u",
    1233             :                 MAC2STR(selected->bssid), selected->level,
    1234             :                 selected->snr, selected->est_throughput);
    1235             : 
    1236          12 :         if (wpa_s->current_ssid->bssid_set &&
    1237           0 :             os_memcmp(selected->bssid, wpa_s->current_ssid->bssid, ETH_ALEN) ==
    1238             :             0) {
    1239           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Allow reassociation - selected BSS "
    1240             :                         "has preferred BSSID");
    1241           0 :                 return 1;
    1242             :         }
    1243             : 
    1244          12 :         if (selected->est_throughput > current_bss->est_throughput + 5000) {
    1245           1 :                 wpa_dbg(wpa_s, MSG_DEBUG,
    1246             :                         "Allow reassociation - selected BSS has better estimated throughput");
    1247           1 :                 return 1;
    1248             :         }
    1249             : 
    1250          11 :         if (current_bss->level < 0 && current_bss->level > selected->level) {
    1251           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Skip roam - Current BSS has better "
    1252             :                         "signal level");
    1253           0 :                 return 0;
    1254             :         }
    1255             : 
    1256          11 :         min_diff = 2;
    1257          11 :         if (current_bss->level < 0) {
    1258          11 :                 if (current_bss->level < -85)
    1259           0 :                         min_diff = 1;
    1260          11 :                 else if (current_bss->level < -80)
    1261           0 :                         min_diff = 2;
    1262          11 :                 else if (current_bss->level < -75)
    1263           0 :                         min_diff = 3;
    1264          11 :                 else if (current_bss->level < -70)
    1265           0 :                         min_diff = 4;
    1266             :                 else
    1267          11 :                         min_diff = 5;
    1268             :         }
    1269          11 :         if (abs(current_bss->level - selected->level) < min_diff) {
    1270          11 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Skip roam - too small difference "
    1271             :                         "in signal level");
    1272          11 :                 return 0;
    1273             :         }
    1274             : 
    1275           0 :         return 1;
    1276             : #else /* CONFIG_NO_ROAMING */
    1277             :         return 0;
    1278             : #endif /* CONFIG_NO_ROAMING */
    1279             : }
    1280             : 
    1281             : 
    1282             : /* Return != 0 if no scan results could be fetched or if scan results should not
    1283             :  * be shared with other virtual interfaces. */
    1284        2884 : static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
    1285             :                                               union wpa_event_data *data,
    1286             :                                               int own_request)
    1287             : {
    1288        2884 :         struct wpa_scan_results *scan_res = NULL;
    1289        2884 :         int ret = 0;
    1290        2884 :         int ap = 0;
    1291             : #ifndef CONFIG_NO_RANDOM_POOL
    1292             :         size_t i, num;
    1293             : #endif /* CONFIG_NO_RANDOM_POOL */
    1294             : 
    1295             : #ifdef CONFIG_AP
    1296        2884 :         if (wpa_s->ap_iface)
    1297           1 :                 ap = 1;
    1298             : #endif /* CONFIG_AP */
    1299             : 
    1300        2884 :         wpa_supplicant_notify_scanning(wpa_s, 0);
    1301             : 
    1302        2884 :         scan_res = wpa_supplicant_get_scan_results(wpa_s,
    1303             :                                                    data ? &data->scan_info :
    1304             :                                                    NULL, 1);
    1305        2884 :         if (scan_res == NULL) {
    1306           0 :                 if (wpa_s->conf->ap_scan == 2 || ap ||
    1307           0 :                     wpa_s->scan_res_handler == scan_only_handler)
    1308           0 :                         return -1;
    1309           0 :                 if (!own_request)
    1310           0 :                         return -1;
    1311           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to get scan results - try "
    1312             :                         "scanning again");
    1313           0 :                 wpa_supplicant_req_new_scan(wpa_s, 1, 0);
    1314           0 :                 ret = -1;
    1315           0 :                 goto scan_work_done;
    1316             :         }
    1317             : 
    1318             : #ifndef CONFIG_NO_RANDOM_POOL
    1319             :         num = scan_res->num;
    1320             :         if (num > 10)
    1321             :                 num = 10;
    1322             :         for (i = 0; i < num; i++) {
    1323             :                 u8 buf[5];
    1324             :                 struct wpa_scan_res *res = scan_res->res[i];
    1325             :                 buf[0] = res->bssid[5];
    1326             :                 buf[1] = res->qual & 0xff;
    1327             :                 buf[2] = res->noise & 0xff;
    1328             :                 buf[3] = res->level & 0xff;
    1329             :                 buf[4] = res->tsf & 0xff;
    1330             :                 random_add_randomness(buf, sizeof(buf));
    1331             :         }
    1332             : #endif /* CONFIG_NO_RANDOM_POOL */
    1333             : 
    1334        4140 :         if (own_request && wpa_s->scan_res_handler &&
    1335        1256 :             (wpa_s->own_scan_running || !wpa_s->radio->external_scan_running)) {
    1336             :                 void (*scan_res_handler)(struct wpa_supplicant *wpa_s,
    1337             :                                          struct wpa_scan_results *scan_res);
    1338             : 
    1339        1256 :                 scan_res_handler = wpa_s->scan_res_handler;
    1340        1256 :                 wpa_s->scan_res_handler = NULL;
    1341        1256 :                 scan_res_handler(wpa_s, scan_res);
    1342        1256 :                 ret = -2;
    1343        1256 :                 goto scan_work_done;
    1344             :         }
    1345             : 
    1346        1628 :         if (ap) {
    1347           1 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Ignore scan results in AP mode");
    1348             : #ifdef CONFIG_AP
    1349           1 :                 if (wpa_s->ap_iface->scan_cb)
    1350           1 :                         wpa_s->ap_iface->scan_cb(wpa_s->ap_iface);
    1351             : #endif /* CONFIG_AP */
    1352           1 :                 goto scan_work_done;
    1353             :         }
    1354             : 
    1355        1627 :         wpa_dbg(wpa_s, MSG_DEBUG, "New scan results available (own=%u ext=%u)",
    1356             :                 wpa_s->own_scan_running, wpa_s->radio->external_scan_running);
    1357        1627 :         if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
    1358          13 :             wpa_s->manual_scan_use_id && wpa_s->own_scan_running) {
    1359          12 :                 wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS "id=%u",
    1360             :                              wpa_s->manual_scan_id);
    1361          12 :                 wpa_s->manual_scan_use_id = 0;
    1362             :         } else {
    1363        1615 :                 wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS);
    1364             :         }
    1365        1627 :         wpas_notify_scan_results(wpa_s);
    1366             : 
    1367        1627 :         wpas_notify_scan_done(wpa_s, 1);
    1368             : 
    1369        1627 :         if (!wpa_s->own_scan_running && wpa_s->radio->external_scan_running) {
    1370          12 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Do not use results from externally requested scan operation for network selection");
    1371          12 :                 wpa_scan_results_free(scan_res);
    1372          12 :                 return 0;
    1373             :         }
    1374             : 
    1375        1615 :         if (wnm_scan_process(wpa_s, 1) > 0)
    1376           0 :                 goto scan_work_done;
    1377             : 
    1378        1615 :         if (sme_proc_obss_scan(wpa_s) > 0)
    1379           4 :                 goto scan_work_done;
    1380             : 
    1381        1611 :         if ((wpa_s->conf->ap_scan == 2 && !wpas_wps_searching(wpa_s)))
    1382           0 :                 goto scan_work_done;
    1383             : 
    1384        1611 :         if (autoscan_notify_scan(wpa_s, scan_res))
    1385           0 :                 goto scan_work_done;
    1386             : 
    1387        1611 :         if (wpa_s->disconnected) {
    1388          65 :                 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
    1389          65 :                 goto scan_work_done;
    1390             :         }
    1391             : 
    1392        3091 :         if (!wpas_driver_bss_selection(wpa_s) &&
    1393        1545 :             bgscan_notify_scan(wpa_s, scan_res) == 1)
    1394           0 :                 goto scan_work_done;
    1395             : 
    1396        1546 :         wpas_wps_update_ap_info(wpa_s, scan_res);
    1397             : 
    1398        1546 :         wpa_scan_results_free(scan_res);
    1399             : 
    1400        1546 :         if (wpa_s->scan_work) {
    1401        1520 :                 struct wpa_radio_work *work = wpa_s->scan_work;
    1402        1520 :                 wpa_s->scan_work = NULL;
    1403        1520 :                 radio_work_done(work);
    1404             :         }
    1405             : 
    1406        1546 :         return wpas_select_network_from_last_scan(wpa_s, 1, own_request);
    1407             : 
    1408             : scan_work_done:
    1409        1326 :         wpa_scan_results_free(scan_res);
    1410        1326 :         if (wpa_s->scan_work) {
    1411         205 :                 struct wpa_radio_work *work = wpa_s->scan_work;
    1412         205 :                 wpa_s->scan_work = NULL;
    1413         205 :                 radio_work_done(work);
    1414             :         }
    1415        1326 :         return ret;
    1416             : }
    1417             : 
    1418             : 
    1419        2818 : static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
    1420             :                                               int new_scan, int own_request)
    1421             : {
    1422             :         struct wpa_bss *selected;
    1423        2818 :         struct wpa_ssid *ssid = NULL;
    1424             : 
    1425        2818 :         if (wpa_s->p2p_mgmt)
    1426           1 :                 return 0; /* no normal connection on p2p_mgmt interface */
    1427             : 
    1428        2817 :         selected = wpa_supplicant_pick_network(wpa_s, &ssid);
    1429             : 
    1430        2817 :         if (selected) {
    1431             :                 int skip;
    1432        2393 :                 skip = !wpa_supplicant_need_to_roam(wpa_s, selected, ssid);
    1433        2393 :                 if (skip) {
    1434          44 :                         if (new_scan)
    1435          44 :                                 wpa_supplicant_rsn_preauth_scan_results(wpa_s);
    1436          44 :                         return 0;
    1437             :                 }
    1438             : 
    1439        2349 :                 if (wpa_supplicant_connect(wpa_s, selected, ssid) < 0) {
    1440           3 :                         wpa_dbg(wpa_s, MSG_DEBUG, "Connect failed");
    1441           3 :                         return -1;
    1442             :                 }
    1443        2346 :                 if (new_scan)
    1444        1103 :                         wpa_supplicant_rsn_preauth_scan_results(wpa_s);
    1445             :                 /*
    1446             :                  * Do not notify other virtual radios of scan results since we do not
    1447             :                  * want them to start other associations at the same time.
    1448             :                  */
    1449        2346 :                 return 1;
    1450             :         } else {
    1451             : #ifdef CONFIG_MESH
    1452         424 :                 if (wpa_s->ifmsh) {
    1453           3 :                         wpa_msg(wpa_s, MSG_INFO,
    1454             :                                 "Avoiding join because we already joined a mesh group");
    1455           3 :                         return 0;
    1456             :                 }
    1457             : #endif /* CONFIG_MESH */
    1458         421 :                 wpa_dbg(wpa_s, MSG_DEBUG, "No suitable network found");
    1459         421 :                 ssid = wpa_supplicant_pick_new_network(wpa_s);
    1460         421 :                 if (ssid) {
    1461          30 :                         wpa_dbg(wpa_s, MSG_DEBUG, "Setup a new network");
    1462          30 :                         wpa_supplicant_associate(wpa_s, NULL, ssid);
    1463          30 :                         if (new_scan)
    1464          30 :                                 wpa_supplicant_rsn_preauth_scan_results(wpa_s);
    1465         391 :                 } else if (own_request) {
    1466             :                         /*
    1467             :                          * No SSID found. If SCAN results are as a result of
    1468             :                          * own scan request and not due to a scan request on
    1469             :                          * another shared interface, try another scan.
    1470             :                          */
    1471         378 :                         int timeout_sec = wpa_s->scan_interval;
    1472         378 :                         int timeout_usec = 0;
    1473             : #ifdef CONFIG_P2P
    1474             :                         int res;
    1475             : 
    1476         378 :                         res = wpas_p2p_scan_no_go_seen(wpa_s);
    1477         378 :                         if (res == 2)
    1478           1 :                                 return 2;
    1479         377 :                         if (res == 1)
    1480           0 :                                 return 0;
    1481             : 
    1482         684 :                         if (wpa_s->p2p_in_provisioning ||
    1483         612 :                             wpa_s->show_group_started ||
    1484         305 :                             wpa_s->p2p_in_invitation) {
    1485             :                                 /*
    1486             :                                  * Use shorter wait during P2P Provisioning
    1487             :                                  * state and during P2P join-a-group operation
    1488             :                                  * to speed up group formation.
    1489             :                                  */
    1490          72 :                                 timeout_sec = 0;
    1491          72 :                                 timeout_usec = 250000;
    1492          72 :                                 wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
    1493             :                                                             timeout_usec);
    1494          72 :                                 return 0;
    1495             :                         }
    1496             : #endif /* CONFIG_P2P */
    1497             : #ifdef CONFIG_INTERWORKING
    1498         355 :                         if (wpa_s->conf->auto_interworking &&
    1499         100 :                             wpa_s->conf->interworking &&
    1500          50 :                             wpa_s->conf->cred) {
    1501          50 :                                 wpa_dbg(wpa_s, MSG_DEBUG, "Interworking: "
    1502             :                                         "start ANQP fetch since no matching "
    1503             :                                         "networks found");
    1504          50 :                                 wpa_s->network_select = 1;
    1505          50 :                                 wpa_s->auto_network_select = 1;
    1506          50 :                                 interworking_start_fetch_anqp(wpa_s);
    1507          50 :                                 return 1;
    1508             :                         }
    1509             : #endif /* CONFIG_INTERWORKING */
    1510             : #ifdef CONFIG_WPS
    1511         255 :                         if (wpa_s->after_wps > 0 || wpas_wps_searching(wpa_s)) {
    1512          51 :                                 wpa_dbg(wpa_s, MSG_DEBUG, "Use shorter wait during WPS processing");
    1513          51 :                                 timeout_sec = 0;
    1514          51 :                                 timeout_usec = 500000;
    1515          51 :                                 wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
    1516             :                                                             timeout_usec);
    1517          51 :                                 return 0;
    1518             :                         }
    1519             : #endif /* CONFIG_WPS */
    1520         204 :                         if (wpa_supplicant_req_sched_scan(wpa_s))
    1521         204 :                                 wpa_supplicant_req_new_scan(wpa_s, timeout_sec,
    1522             :                                                             timeout_usec);
    1523             :                 }
    1524             :         }
    1525         247 :         return 0;
    1526             : }
    1527             : 
    1528             : 
    1529        2869 : static int wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
    1530             :                                              union wpa_event_data *data)
    1531             : {
    1532             :         struct wpa_supplicant *ifs;
    1533             :         int res;
    1534             : 
    1535        2869 :         res = _wpa_supplicant_event_scan_results(wpa_s, data, 1);
    1536        2869 :         if (res == 2) {
    1537             :                 /*
    1538             :                  * Interface may have been removed, so must not dereference
    1539             :                  * wpa_s after this.
    1540             :                  */
    1541           1 :                 return 1;
    1542             :         }
    1543        2868 :         if (res != 0) {
    1544             :                 /*
    1545             :                  * If no scan results could be fetched, then no need to
    1546             :                  * notify those interfaces that did not actually request
    1547             :                  * this scan. Similarly, if scan results started a new operation on this
    1548             :                  * interface, do not notify other interfaces to avoid concurrent
    1549             :                  * operations during a connection attempt.
    1550             :                  */
    1551        2387 :                 return 0;
    1552             :         }
    1553             : 
    1554             :         /*
    1555             :          * Check other interfaces to see if they share the same radio. If
    1556             :          * so, they get updated with this same scan info.
    1557             :          */
    1558         977 :         dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
    1559             :                          radio_list) {
    1560         496 :                 if (ifs != wpa_s) {
    1561          15 :                         wpa_printf(MSG_DEBUG, "%s: Updating scan results from "
    1562          15 :                                    "sibling", ifs->ifname);
    1563          15 :                         _wpa_supplicant_event_scan_results(ifs, data, 0);
    1564             :                 }
    1565             :         }
    1566             : 
    1567         481 :         return 0;
    1568             : }
    1569             : 
    1570             : #endif /* CONFIG_NO_SCAN_PROCESSING */
    1571             : 
    1572             : 
    1573        2050 : int wpa_supplicant_fast_associate(struct wpa_supplicant *wpa_s)
    1574             : {
    1575             : #ifdef CONFIG_NO_SCAN_PROCESSING
    1576             :         return -1;
    1577             : #else /* CONFIG_NO_SCAN_PROCESSING */
    1578             :         struct os_reltime now;
    1579             : 
    1580        2050 :         if (wpa_s->last_scan_res_used <= 0)
    1581         745 :                 return -1;
    1582             : 
    1583        1305 :         os_get_reltime(&now);
    1584        1305 :         if (os_reltime_expired(&now, &wpa_s->last_scan, 5)) {
    1585          33 :                 wpa_printf(MSG_DEBUG, "Fast associate: Old scan results");
    1586          33 :                 return -1;
    1587             :         }
    1588             : 
    1589        1272 :         return wpas_select_network_from_last_scan(wpa_s, 0, 1);
    1590             : #endif /* CONFIG_NO_SCAN_PROCESSING */
    1591             : }
    1592             : 
    1593             : #ifdef CONFIG_WNM
    1594             : 
    1595          22 : static void wnm_bss_keep_alive(void *eloop_ctx, void *sock_ctx)
    1596             : {
    1597          22 :         struct wpa_supplicant *wpa_s = eloop_ctx;
    1598             : 
    1599          22 :         if (wpa_s->wpa_state < WPA_ASSOCIATED)
    1600          22 :                 return;
    1601             : 
    1602          22 :         if (!wpa_s->no_keep_alive) {
    1603          18 :                 wpa_printf(MSG_DEBUG, "WNM: Send keep-alive to AP " MACSTR,
    1604          18 :                            MAC2STR(wpa_s->bssid));
    1605             :                 /* TODO: could skip this if normal data traffic has been sent */
    1606             :                 /* TODO: Consider using some more appropriate data frame for
    1607             :                  * this */
    1608           3 :                 if (wpa_s->l2)
    1609           3 :                         l2_packet_send(wpa_s->l2, wpa_s->bssid, 0x0800,
    1610             :                                        (u8 *) "", 0);
    1611             :         }
    1612             : 
    1613             : #ifdef CONFIG_SME
    1614          22 :         if (wpa_s->sme.bss_max_idle_period) {
    1615             :                 unsigned int msec;
    1616          22 :                 msec = wpa_s->sme.bss_max_idle_period * 1024; /* times 1000 */
    1617          22 :                 if (msec > 100)
    1618          22 :                         msec -= 100;
    1619          22 :                 eloop_register_timeout(msec / 1000, msec % 1000 * 1000,
    1620             :                                        wnm_bss_keep_alive, wpa_s, NULL);
    1621             :         }
    1622             : #endif /* CONFIG_SME */
    1623             : }
    1624             : 
    1625             : 
    1626        2551 : static void wnm_process_assoc_resp(struct wpa_supplicant *wpa_s,
    1627             :                                    const u8 *ies, size_t ies_len)
    1628             : {
    1629             :         struct ieee802_11_elems elems;
    1630             : 
    1631        2551 :         if (ies == NULL)
    1632           0 :                 return;
    1633             : 
    1634        2551 :         if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed)
    1635           0 :                 return;
    1636             : 
    1637             : #ifdef CONFIG_SME
    1638        2551 :         if (elems.bss_max_idle_period) {
    1639             :                 unsigned int msec;
    1640        2551 :                 wpa_s->sme.bss_max_idle_period =
    1641        2551 :                         WPA_GET_LE16(elems.bss_max_idle_period);
    1642        5102 :                 wpa_printf(MSG_DEBUG, "WNM: BSS Max Idle Period: %u (* 1000 "
    1643        2551 :                            "TU)%s", wpa_s->sme.bss_max_idle_period,
    1644        2551 :                            (elems.bss_max_idle_period[2] & 0x01) ?
    1645             :                            " (protected keep-live required)" : "");
    1646        2551 :                 if (wpa_s->sme.bss_max_idle_period == 0)
    1647           0 :                         wpa_s->sme.bss_max_idle_period = 1;
    1648        2551 :                 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) {
    1649        2519 :                         eloop_cancel_timeout(wnm_bss_keep_alive, wpa_s, NULL);
    1650             :                          /* msec times 1000 */
    1651        2519 :                         msec = wpa_s->sme.bss_max_idle_period * 1024;
    1652        2519 :                         if (msec > 100)
    1653        2519 :                                 msec -= 100;
    1654        2519 :                         eloop_register_timeout(msec / 1000, msec % 1000 * 1000,
    1655             :                                                wnm_bss_keep_alive, wpa_s,
    1656             :                                                NULL);
    1657             :                 }
    1658             :         }
    1659             : #endif /* CONFIG_SME */
    1660             : }
    1661             : 
    1662             : #endif /* CONFIG_WNM */
    1663             : 
    1664             : 
    1665        5306 : void wnm_bss_keep_alive_deinit(struct wpa_supplicant *wpa_s)
    1666             : {
    1667             : #ifdef CONFIG_WNM
    1668        5306 :         eloop_cancel_timeout(wnm_bss_keep_alive, wpa_s, NULL);
    1669             : #endif /* CONFIG_WNM */
    1670        5306 : }
    1671             : 
    1672             : 
    1673             : #ifdef CONFIG_INTERWORKING
    1674             : 
    1675           2 : static int wpas_qos_map_set(struct wpa_supplicant *wpa_s, const u8 *qos_map,
    1676             :                             size_t len)
    1677             : {
    1678             :         int res;
    1679             : 
    1680           2 :         wpa_hexdump(MSG_DEBUG, "Interworking: QoS Map Set", qos_map, len);
    1681           2 :         res = wpa_drv_set_qos_map(wpa_s, qos_map, len);
    1682           2 :         if (res) {
    1683           0 :                 wpa_printf(MSG_DEBUG, "Interworking: Failed to configure QoS Map Set to the driver");
    1684             :         }
    1685             : 
    1686           2 :         return res;
    1687             : }
    1688             : 
    1689             : 
    1690        2551 : static void interworking_process_assoc_resp(struct wpa_supplicant *wpa_s,
    1691             :                                             const u8 *ies, size_t ies_len)
    1692             : {
    1693             :         struct ieee802_11_elems elems;
    1694             : 
    1695        2551 :         if (ies == NULL)
    1696           0 :                 return;
    1697             : 
    1698        2551 :         if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed)
    1699           0 :                 return;
    1700             : 
    1701        2551 :         if (elems.qos_map_set) {
    1702           1 :                 wpas_qos_map_set(wpa_s, elems.qos_map_set,
    1703           1 :                                  elems.qos_map_set_len);
    1704             :         }
    1705             : }
    1706             : 
    1707             : #endif /* CONFIG_INTERWORKING */
    1708             : 
    1709             : 
    1710        2552 : static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
    1711             :                                           union wpa_event_data *data)
    1712             : {
    1713        2552 :         int l, len, found = 0, wpa_found, rsn_found;
    1714             :         const u8 *p;
    1715             : #ifdef CONFIG_IEEE80211R
    1716             :         u8 bssid[ETH_ALEN];
    1717             : #endif /* CONFIG_IEEE80211R */
    1718             : 
    1719        2552 :         wpa_dbg(wpa_s, MSG_DEBUG, "Association info event");
    1720        2552 :         if (data->assoc_info.req_ies)
    1721           0 :                 wpa_hexdump(MSG_DEBUG, "req_ies", data->assoc_info.req_ies,
    1722             :                             data->assoc_info.req_ies_len);
    1723        2552 :         if (data->assoc_info.resp_ies) {
    1724        2551 :                 wpa_hexdump(MSG_DEBUG, "resp_ies", data->assoc_info.resp_ies,
    1725             :                             data->assoc_info.resp_ies_len);
    1726             : #ifdef CONFIG_TDLS
    1727        2551 :                 wpa_tdls_assoc_resp_ies(wpa_s->wpa, data->assoc_info.resp_ies,
    1728             :                                         data->assoc_info.resp_ies_len);
    1729             : #endif /* CONFIG_TDLS */
    1730             : #ifdef CONFIG_WNM
    1731        2551 :                 wnm_process_assoc_resp(wpa_s, data->assoc_info.resp_ies,
    1732             :                                        data->assoc_info.resp_ies_len);
    1733             : #endif /* CONFIG_WNM */
    1734             : #ifdef CONFIG_INTERWORKING
    1735        2551 :                 interworking_process_assoc_resp(wpa_s, data->assoc_info.resp_ies,
    1736             :                                                 data->assoc_info.resp_ies_len);
    1737             : #endif /* CONFIG_INTERWORKING */
    1738             :         }
    1739        2552 :         if (data->assoc_info.beacon_ies)
    1740           0 :                 wpa_hexdump(MSG_DEBUG, "beacon_ies",
    1741           0 :                             data->assoc_info.beacon_ies,
    1742             :                             data->assoc_info.beacon_ies_len);
    1743        2552 :         if (data->assoc_info.freq)
    1744        2534 :                 wpa_dbg(wpa_s, MSG_DEBUG, "freq=%u MHz",
    1745             :                         data->assoc_info.freq);
    1746             : 
    1747        2552 :         p = data->assoc_info.req_ies;
    1748        2552 :         l = data->assoc_info.req_ies_len;
    1749             : 
    1750             :         /* Go through the IEs and make a copy of the WPA/RSN IE, if present. */
    1751        5104 :         while (p && l >= 2) {
    1752           0 :                 len = p[1] + 2;
    1753           0 :                 if (len > l) {
    1754           0 :                         wpa_hexdump(MSG_DEBUG, "Truncated IE in assoc_info",
    1755             :                                     p, l);
    1756           0 :                         break;
    1757             :                 }
    1758           0 :                 if ((p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
    1759           0 :                      (os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0)) ||
    1760           0 :                     (p[0] == WLAN_EID_RSN && p[1] >= 2)) {
    1761           0 :                         if (wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, p, len))
    1762           0 :                                 break;
    1763           0 :                         found = 1;
    1764           0 :                         wpa_find_assoc_pmkid(wpa_s);
    1765           0 :                         break;
    1766             :                 }
    1767           0 :                 l -= len;
    1768           0 :                 p += len;
    1769             :         }
    1770        2552 :         if (!found && data->assoc_info.req_ies)
    1771           0 :                 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
    1772             : 
    1773             : #ifdef CONFIG_IEEE80211R
    1774             : #ifdef CONFIG_SME
    1775        2552 :         if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FT) {
    1776         442 :                 if (wpa_drv_get_bssid(wpa_s, bssid) < 0 ||
    1777         221 :                     wpa_ft_validate_reassoc_resp(wpa_s->wpa,
    1778             :                                                  data->assoc_info.resp_ies,
    1779             :                                                  data->assoc_info.resp_ies_len,
    1780             :                                                  bssid) < 0) {
    1781           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "FT: Validation of "
    1782             :                                 "Reassociation Response failed");
    1783           0 :                         wpa_supplicant_deauthenticate(
    1784             :                                 wpa_s, WLAN_REASON_INVALID_IE);
    1785           0 :                         return -1;
    1786             :                 }
    1787             :         }
    1788             : 
    1789        2552 :         p = data->assoc_info.resp_ies;
    1790        2552 :         l = data->assoc_info.resp_ies_len;
    1791             : 
    1792             : #ifdef CONFIG_WPS_STRICT
    1793             :         if (p && wpa_s->current_ssid &&
    1794             :             wpa_s->current_ssid->key_mgmt == WPA_KEY_MGMT_WPS) {
    1795             :                 struct wpabuf *wps;
    1796             :                 wps = ieee802_11_vendor_ie_concat(p, l, WPS_IE_VENDOR_TYPE);
    1797             :                 if (wps == NULL) {
    1798             :                         wpa_msg(wpa_s, MSG_INFO, "WPS-STRICT: AP did not "
    1799             :                                 "include WPS IE in (Re)Association Response");
    1800             :                         return -1;
    1801             :                 }
    1802             : 
    1803             :                 if (wps_validate_assoc_resp(wps) < 0) {
    1804             :                         wpabuf_free(wps);
    1805             :                         wpa_supplicant_deauthenticate(
    1806             :                                 wpa_s, WLAN_REASON_INVALID_IE);
    1807             :                         return -1;
    1808             :                 }
    1809             :                 wpabuf_free(wps);
    1810             :         }
    1811             : #endif /* CONFIG_WPS_STRICT */
    1812             : 
    1813             :         /* Go through the IEs and make a copy of the MDIE, if present. */
    1814       22170 :         while (p && l >= 2) {
    1815       17312 :                 len = p[1] + 2;
    1816       17312 :                 if (len > l) {
    1817           0 :                         wpa_hexdump(MSG_DEBUG, "Truncated IE in assoc_info",
    1818             :                                     p, l);
    1819           0 :                         break;
    1820             :                 }
    1821       17558 :                 if (p[0] == WLAN_EID_MOBILITY_DOMAIN &&
    1822         246 :                     p[1] >= MOBILITY_DOMAIN_ID_LEN) {
    1823         246 :                         wpa_s->sme.ft_used = 1;
    1824         246 :                         os_memcpy(wpa_s->sme.mobility_domain, p + 2,
    1825             :                                   MOBILITY_DOMAIN_ID_LEN);
    1826         246 :                         break;
    1827             :                 }
    1828       17066 :                 l -= len;
    1829       17066 :                 p += len;
    1830             :         }
    1831             : #endif /* CONFIG_SME */
    1832             : 
    1833             :         /* Process FT when SME is in the driver */
    1834        2584 :         if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
    1835          32 :             wpa_ft_is_completed(wpa_s->wpa)) {
    1836           0 :                 if (wpa_drv_get_bssid(wpa_s, bssid) < 0 ||
    1837           0 :                     wpa_ft_validate_reassoc_resp(wpa_s->wpa,
    1838             :                                                  data->assoc_info.resp_ies,
    1839             :                                                  data->assoc_info.resp_ies_len,
    1840             :                                                  bssid) < 0) {
    1841           0 :                         wpa_dbg(wpa_s, MSG_DEBUG, "FT: Validation of "
    1842             :                                 "Reassociation Response failed");
    1843           0 :                         wpa_supplicant_deauthenticate(
    1844             :                                 wpa_s, WLAN_REASON_INVALID_IE);
    1845           0 :                         return -1;
    1846             :                 }
    1847           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "FT: Reassociation Response done");
    1848             :         }
    1849             : 
    1850        2552 :         wpa_sm_set_ft_params(wpa_s->wpa, data->assoc_info.resp_ies,
    1851             :                              data->assoc_info.resp_ies_len);
    1852             : #endif /* CONFIG_IEEE80211R */
    1853             : 
    1854             :         /* WPA/RSN IE from Beacon/ProbeResp */
    1855        2552 :         p = data->assoc_info.beacon_ies;
    1856        2552 :         l = data->assoc_info.beacon_ies_len;
    1857             : 
    1858             :         /* Go through the IEs and make a copy of the WPA/RSN IEs, if present.
    1859             :          */
    1860        2552 :         wpa_found = rsn_found = 0;
    1861        5104 :         while (p && l >= 2) {
    1862           0 :                 len = p[1] + 2;
    1863           0 :                 if (len > l) {
    1864           0 :                         wpa_hexdump(MSG_DEBUG, "Truncated IE in beacon_ies",
    1865             :                                     p, l);
    1866           0 :                         break;
    1867             :                 }
    1868           0 :                 if (!wpa_found &&
    1869           0 :                     p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 &&
    1870           0 :                     os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0) {
    1871           0 :                         wpa_found = 1;
    1872           0 :                         wpa_sm_set_ap_wpa_ie(wpa_s->wpa, p, len);
    1873             :                 }
    1874             : 
    1875           0 :                 if (!rsn_found &&
    1876           0 :                     p[0] == WLAN_EID_RSN && p[1] >= 2) {
    1877           0 :                         rsn_found = 1;
    1878           0 :                         wpa_sm_set_ap_rsn_ie(wpa_s->wpa, p, len);
    1879             :                 }
    1880             : 
    1881           0 :                 l -= len;
    1882           0 :                 p += len;
    1883             :         }
    1884             : 
    1885        2552 :         if (!wpa_found && data->assoc_info.beacon_ies)
    1886           0 :                 wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
    1887        2552 :         if (!rsn_found && data->assoc_info.beacon_ies)
    1888           0 :                 wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
    1889        2552 :         if (wpa_found || rsn_found)
    1890           0 :                 wpa_s->ap_ies_from_associnfo = 1;
    1891             : 
    1892        2854 :         if (wpa_s->assoc_freq && data->assoc_info.freq &&
    1893         302 :             wpa_s->assoc_freq != data->assoc_info.freq) {
    1894           1 :                 wpa_printf(MSG_DEBUG, "Operating frequency changed from "
    1895             :                            "%u to %u MHz",
    1896             :                            wpa_s->assoc_freq, data->assoc_info.freq);
    1897           1 :                 wpa_supplicant_update_scan_results(wpa_s);
    1898             :         }
    1899             : 
    1900        2552 :         wpa_s->assoc_freq = data->assoc_info.freq;
    1901             : 
    1902        2552 :         return 0;
    1903             : }
    1904             : 
    1905             : 
    1906           0 : static int wpa_supplicant_assoc_update_ie(struct wpa_supplicant *wpa_s)
    1907             : {
    1908           0 :         const u8 *bss_wpa = NULL, *bss_rsn = NULL;
    1909             : 
    1910           0 :         if (!wpa_s->current_bss || !wpa_s->current_ssid)
    1911           0 :                 return -1;
    1912             : 
    1913           0 :         if (!wpa_key_mgmt_wpa_any(wpa_s->current_ssid->key_mgmt))
    1914           0 :                 return 0;
    1915             : 
    1916           0 :         bss_wpa = wpa_bss_get_vendor_ie(wpa_s->current_bss,
    1917             :                                         WPA_IE_VENDOR_TYPE);
    1918           0 :         bss_rsn = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_RSN);
    1919             : 
    1920           0 :         if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa,
    1921           0 :                                  bss_wpa ? 2 + bss_wpa[1] : 0) ||
    1922           0 :             wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn,
    1923           0 :                                  bss_rsn ? 2 + bss_rsn[1] : 0))
    1924           0 :                 return -1;
    1925             : 
    1926           0 :         return 0;
    1927             : }
    1928             : 
    1929             : 
    1930        2571 : static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
    1931             :                                        union wpa_event_data *data)
    1932             : {
    1933             :         u8 bssid[ETH_ALEN];
    1934             :         int ft_completed;
    1935             : 
    1936             : #ifdef CONFIG_AP
    1937        2571 :         if (wpa_s->ap_iface) {
    1938           0 :                 if (!data)
    1939           3 :                         return;
    1940           0 :                 hostapd_notif_assoc(wpa_s->ap_iface->bss[0],
    1941             :                                     data->assoc_info.addr,
    1942             :                                     data->assoc_info.req_ies,
    1943             :                                     data->assoc_info.req_ies_len,
    1944             :                                     data->assoc_info.reassoc);
    1945           0 :                 return;
    1946             :         }
    1947             : #endif /* CONFIG_AP */
    1948             : 
    1949        2571 :         ft_completed = wpa_ft_is_completed(wpa_s->wpa);
    1950        2571 :         if (data && wpa_supplicant_event_associnfo(wpa_s, data) < 0)
    1951           0 :                 return;
    1952             : 
    1953        2571 :         if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
    1954           0 :                 wpa_dbg(wpa_s, MSG_ERROR, "Failed to get BSSID");
    1955           0 :                 wpa_supplicant_deauthenticate(
    1956             :                         wpa_s, WLAN_REASON_DEAUTH_LEAVING);
    1957           0 :                 return;
    1958             :         }
    1959             : 
    1960        2571 :         wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED);
    1961        2571 :         if (os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0) {
    1962        2570 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Associated to a new BSS: BSSID="
    1963             :                         MACSTR, MAC2STR(bssid));
    1964             :                 random_add_randomness(bssid, ETH_ALEN);
    1965        2570 :                 os_memcpy(wpa_s->bssid, bssid, ETH_ALEN);
    1966        2570 :                 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
    1967        2570 :                 wpas_notify_bssid_changed(wpa_s);
    1968             : 
    1969        2570 :                 if (wpa_supplicant_dynamic_keys(wpa_s) && !ft_completed) {
    1970        2002 :                         wpa_clear_keys(wpa_s, bssid);
    1971             :                 }
    1972        2570 :                 if (wpa_supplicant_select_config(wpa_s) < 0) {
    1973           3 :                         wpa_supplicant_deauthenticate(
    1974             :                                 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
    1975           3 :                         return;
    1976             :                 }
    1977             : 
    1978        5125 :                 if (wpa_s->conf->ap_scan == 1 &&
    1979        2558 :                     wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION) {
    1980           0 :                         if (wpa_supplicant_assoc_update_ie(wpa_s) < 0)
    1981           0 :                                 wpa_msg(wpa_s, MSG_WARNING,
    1982             :                                         "WPA/RSN IEs not updated");
    1983             :                 }
    1984             :         }
    1985             : 
    1986             : #ifdef CONFIG_SME
    1987        2568 :         os_memcpy(wpa_s->sme.prev_bssid, bssid, ETH_ALEN);
    1988        2568 :         wpa_s->sme.prev_bssid_set = 1;
    1989        2568 :         wpa_s->sme.last_unprot_disconnect.sec = 0;
    1990             : #endif /* CONFIG_SME */
    1991             : 
    1992        2568 :         wpa_msg(wpa_s, MSG_INFO, "Associated with " MACSTR, MAC2STR(bssid));
    1993        2568 :         if (wpa_s->current_ssid) {
    1994             :                 /* When using scanning (ap_scan=1), SIM PC/SC interface can be
    1995             :                  * initialized before association, but for other modes,
    1996             :                  * initialize PC/SC here, if the current configuration needs
    1997             :                  * smartcard or SIM/USIM. */
    1998        2568 :                 wpa_supplicant_scard_init(wpa_s, wpa_s->current_ssid);
    1999             :         }
    2000        2568 :         wpa_sm_notify_assoc(wpa_s->wpa, bssid);
    2001        2568 :         if (wpa_s->l2)
    2002        2568 :                 l2_packet_notify_auth_start(wpa_s->l2);
    2003             : 
    2004             :         /*
    2005             :          * Set portEnabled first to FALSE in order to get EAP state machine out
    2006             :          * of the SUCCESS state and eapSuccess cleared. Without this, EAPOL PAE
    2007             :          * state machine may transit to AUTHENTICATING state based on obsolete
    2008             :          * eapSuccess and then trigger BE_AUTH to SUCCESS and PAE to
    2009             :          * AUTHENTICATED without ever giving chance to EAP state machine to
    2010             :          * reset the state.
    2011             :          */
    2012        2568 :         if (!ft_completed) {
    2013        2347 :                 eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
    2014        2347 :                 eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
    2015             :         }
    2016        2568 :         if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || ft_completed)
    2017         919 :                 eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
    2018             :         /* 802.1X::portControl = Auto */
    2019        2568 :         eapol_sm_notify_portEnabled(wpa_s->eapol, TRUE);
    2020        2568 :         wpa_s->eapol_received = 0;
    2021        4798 :         if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
    2022        4455 :             wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE ||
    2023        4450 :             (wpa_s->current_ssid &&
    2024        2225 :              wpa_s->current_ssid->mode == IEEE80211_MODE_IBSS)) {
    2025         698 :                 if (wpa_s->current_ssid &&
    2026         354 :                     wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE &&
    2027           5 :                     (wpa_s->drv_flags &
    2028             :                      WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE)) {
    2029             :                         /*
    2030             :                          * Set the key after having received joined-IBSS event
    2031             :                          * from the driver.
    2032             :                          */
    2033           5 :                         wpa_supplicant_set_wpa_none_key(wpa_s,
    2034             :                                                         wpa_s->current_ssid);
    2035             :                 }
    2036         349 :                 wpa_supplicant_cancel_auth_timeout(wpa_s);
    2037         349 :                 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
    2038        2219 :         } else if (!ft_completed) {
    2039             :                 /* Timeout for receiving the first EAPOL packet */
    2040        1998 :                 wpa_supplicant_req_auth_timeout(wpa_s, 10, 0);
    2041             :         }
    2042        2568 :         wpa_supplicant_cancel_scan(wpa_s);
    2043             : 
    2044        2568 :         if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
    2045           0 :             wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
    2046             :                 /*
    2047             :                  * We are done; the driver will take care of RSN 4-way
    2048             :                  * handshake.
    2049             :                  */
    2050           0 :                 wpa_supplicant_cancel_auth_timeout(wpa_s);
    2051           0 :                 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
    2052           0 :                 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
    2053           0 :                 eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
    2054        2568 :         } else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) &&
    2055           0 :                    wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) {
    2056             :                 /*
    2057             :                  * The driver will take care of RSN 4-way handshake, so we need
    2058             :                  * to allow EAPOL supplicant to complete its work without
    2059             :                  * waiting for WPA supplicant.
    2060             :                  */
    2061           0 :                 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
    2062        2568 :         } else if (ft_completed) {
    2063             :                 /*
    2064             :                  * FT protocol completed - make sure EAPOL state machine ends
    2065             :                  * up in authenticated.
    2066             :                  */
    2067         221 :                 wpa_supplicant_cancel_auth_timeout(wpa_s);
    2068         221 :                 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
    2069         221 :                 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
    2070         221 :                 eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
    2071             :         }
    2072             : 
    2073        2568 :         wpa_s->last_eapol_matches_bssid = 0;
    2074             : 
    2075        2568 :         if (wpa_s->pending_eapol_rx) {
    2076             :                 struct os_reltime now, age;
    2077           2 :                 os_get_reltime(&now);
    2078           2 :                 os_reltime_sub(&now, &wpa_s->pending_eapol_rx_time, &age);
    2079           3 :                 if (age.sec == 0 && age.usec < 100000 &&
    2080           1 :                     os_memcmp(wpa_s->pending_eapol_rx_src, bssid, ETH_ALEN) ==
    2081             :                     0) {
    2082           1 :                         wpa_dbg(wpa_s, MSG_DEBUG, "Process pending EAPOL "
    2083             :                                 "frame that was received just before "
    2084             :                                 "association notification");
    2085           2 :                         wpa_supplicant_rx_eapol(
    2086           1 :                                 wpa_s, wpa_s->pending_eapol_rx_src,
    2087           1 :                                 wpabuf_head(wpa_s->pending_eapol_rx),
    2088           1 :                                 wpabuf_len(wpa_s->pending_eapol_rx));
    2089             :                 }
    2090           2 :                 wpabuf_free(wpa_s->pending_eapol_rx);
    2091           2 :                 wpa_s->pending_eapol_rx = NULL;
    2092             :         }
    2093             : 
    2094        4798 :         if ((wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
    2095        2578 :              wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) &&
    2096         696 :             wpa_s->current_ssid &&
    2097         348 :             (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE)) {
    2098             :                 /* Set static WEP keys again */
    2099         341 :                 wpa_set_wep_keys(wpa_s, wpa_s->current_ssid);
    2100             :         }
    2101             : 
    2102             : #ifdef CONFIG_IBSS_RSN
    2103        5136 :         if (wpa_s->current_ssid &&
    2104        2586 :             wpa_s->current_ssid->mode == WPAS_MODE_IBSS &&
    2105          29 :             wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
    2106          17 :             wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE &&
    2107           6 :             wpa_s->ibss_rsn == NULL) {
    2108           6 :                 wpa_s->ibss_rsn = ibss_rsn_init(wpa_s);
    2109           6 :                 if (!wpa_s->ibss_rsn) {
    2110           0 :                         wpa_msg(wpa_s, MSG_INFO, "Failed to init IBSS RSN");
    2111           0 :                         wpa_supplicant_deauthenticate(
    2112             :                                 wpa_s, WLAN_REASON_DEAUTH_LEAVING);
    2113           0 :                         return;
    2114             :                 }
    2115             : 
    2116           6 :                 ibss_rsn_set_psk(wpa_s->ibss_rsn, wpa_s->current_ssid->psk);
    2117             :         }
    2118             : #endif /* CONFIG_IBSS_RSN */
    2119             : 
    2120        2568 :         wpas_wps_notify_assoc(wpa_s, bssid);
    2121             : 
    2122        2568 :         if (data) {
    2123        2536 :                 wmm_ac_notify_assoc(wpa_s, data->assoc_info.resp_ies,
    2124             :                                     data->assoc_info.resp_ies_len,
    2125        2536 :                                     &data->assoc_info.wmm_params);
    2126             : 
    2127        2536 :                 if (wpa_s->reassoc_same_bss)
    2128          48 :                         wmm_ac_restore_tspecs(wpa_s);
    2129             :         }
    2130             : }
    2131             : 
    2132             : 
    2133          42 : static int disconnect_reason_recoverable(u16 reason_code)
    2134             : {
    2135          82 :         return reason_code == WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY ||
    2136          82 :                 reason_code == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA ||
    2137             :                 reason_code == WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA;
    2138             : }
    2139             : 
    2140             : 
    2141        2455 : static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
    2142             :                                           u16 reason_code,
    2143             :                                           int locally_generated)
    2144             : {
    2145             :         const u8 *bssid;
    2146             : 
    2147        2455 :         if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
    2148             :                 /*
    2149             :                  * At least Host AP driver and a Prism3 card seemed to be
    2150             :                  * generating streams of disconnected events when configuring
    2151             :                  * IBSS for WPA-None. Ignore them for now.
    2152             :                  */
    2153        2460 :                 return;
    2154             :         }
    2155             : 
    2156        2450 :         bssid = wpa_s->bssid;
    2157        2450 :         if (is_zero_ether_addr(bssid))
    2158          85 :                 bssid = wpa_s->pending_bssid;
    2159             : 
    2160        2518 :         if (!is_zero_ether_addr(bssid) ||
    2161          68 :             wpa_s->wpa_state >= WPA_AUTHENTICATING) {
    2162       16674 :                 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR
    2163             :                         " reason=%d%s",
    2164       14292 :                         MAC2STR(bssid), reason_code,
    2165             :                         locally_generated ? " locally_generated=1" : "");
    2166             :         }
    2167             : }
    2168             : 
    2169             : 
    2170        2429 : static int could_be_psk_mismatch(struct wpa_supplicant *wpa_s, u16 reason_code,
    2171             :                                  int locally_generated)
    2172             : {
    2173        2444 :         if (wpa_s->wpa_state != WPA_4WAY_HANDSHAKE ||
    2174          15 :             !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt))
    2175        2416 :                 return 0; /* Not in 4-way handshake with PSK */
    2176             : 
    2177             :         /*
    2178             :          * It looks like connection was lost while trying to go through PSK
    2179             :          * 4-way handshake. Filter out known disconnection cases that are caused
    2180             :          * by something else than PSK mismatch to avoid confusing reports.
    2181             :          */
    2182             : 
    2183          13 :         if (locally_generated) {
    2184          10 :                 if (reason_code == WLAN_REASON_IE_IN_4WAY_DIFFERS)
    2185           2 :                         return 0;
    2186             :         }
    2187             : 
    2188          11 :         return 1;
    2189             : }
    2190             : 
    2191             : 
    2192        2434 : static void wpa_supplicant_event_disassoc_finish(struct wpa_supplicant *wpa_s,
    2193             :                                                  u16 reason_code,
    2194             :                                                  int locally_generated)
    2195             : {
    2196             :         const u8 *bssid;
    2197             :         int authenticating;
    2198             :         u8 prev_pending_bssid[ETH_ALEN];
    2199        2434 :         struct wpa_bss *fast_reconnect = NULL;
    2200        2434 :         struct wpa_ssid *fast_reconnect_ssid = NULL;
    2201             :         struct wpa_ssid *last_ssid;
    2202             : 
    2203        2434 :         authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING;
    2204        2434 :         os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN);
    2205             : 
    2206        2434 :         if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
    2207             :                 /*
    2208             :                  * At least Host AP driver and a Prism3 card seemed to be
    2209             :                  * generating streams of disconnected events when configuring
    2210             :                  * IBSS for WPA-None. Ignore them for now.
    2211             :                  */
    2212           5 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Disconnect event - ignore in "
    2213             :                         "IBSS/WPA-None mode");
    2214           5 :                 return;
    2215             :         }
    2216             : 
    2217        2429 :         if (could_be_psk_mismatch(wpa_s, reason_code, locally_generated)) {
    2218          11 :                 wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - "
    2219             :                         "pre-shared key may be incorrect");
    2220          11 :                 if (wpas_p2p_4way_hs_failed(wpa_s) > 0)
    2221           1 :                         return; /* P2P group removed */
    2222          10 :                 wpas_auth_failed(wpa_s, "WRONG_KEY");
    2223             :         }
    2224        4205 :         if (!wpa_s->disconnected &&
    2225        1779 :             (!wpa_s->auto_reconnect_disabled ||
    2226           3 :              wpa_s->key_mgmt == WPA_KEY_MGMT_WPS ||
    2227           1 :              wpas_wps_searching(wpa_s))) {
    2228        1777 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Auto connect enabled: try to "
    2229             :                         "reconnect (wps=%d/%d wpa_state=%d)",
    2230             :                         wpa_s->key_mgmt == WPA_KEY_MGMT_WPS,
    2231             :                         wpas_wps_searching(wpa_s),
    2232             :                         wpa_s->wpa_state);
    2233        4568 :                 if (wpa_s->wpa_state == WPA_COMPLETED &&
    2234        2028 :                     wpa_s->current_ssid &&
    2235        2016 :                     wpa_s->current_ssid->mode == WPAS_MODE_INFRA &&
    2236          42 :                     !locally_generated &&
    2237          42 :                     disconnect_reason_recoverable(reason_code)) {
    2238             :                         /*
    2239             :                          * It looks like the AP has dropped association with
    2240             :                          * us, but could allow us to get back in. Try to
    2241             :                          * reconnect to the same BSS without full scan to save
    2242             :                          * time for some common cases.
    2243             :                          */
    2244           4 :                         fast_reconnect = wpa_s->current_bss;
    2245           4 :                         fast_reconnect_ssid = wpa_s->current_ssid;
    2246        1773 :                 } else if (wpa_s->wpa_state >= WPA_ASSOCIATING)
    2247        1723 :                         wpa_supplicant_req_scan(wpa_s, 0, 100000);
    2248             :                 else
    2249          50 :                         wpa_dbg(wpa_s, MSG_DEBUG, "Do not request new "
    2250             :                                 "immediate scan");
    2251             :         } else {
    2252         651 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Auto connect disabled: do not "
    2253             :                         "try to re-connect");
    2254         651 :                 wpa_s->reassociate = 0;
    2255         651 :                 wpa_s->disconnected = 1;
    2256         651 :                 wpa_supplicant_cancel_sched_scan(wpa_s);
    2257             :         }
    2258        2428 :         bssid = wpa_s->bssid;
    2259        2428 :         if (is_zero_ether_addr(bssid))
    2260         175 :                 bssid = wpa_s->pending_bssid;
    2261        2428 :         if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
    2262        2265 :                 wpas_connection_failed(wpa_s, bssid);
    2263        2428 :         wpa_sm_notify_disassoc(wpa_s->wpa);
    2264        2428 :         if (locally_generated)
    2265        2145 :                 wpa_s->disconnect_reason = -reason_code;
    2266             :         else
    2267         283 :                 wpa_s->disconnect_reason = reason_code;
    2268        2428 :         wpas_notify_disconnect_reason(wpa_s);
    2269        2428 :         if (wpa_supplicant_dynamic_keys(wpa_s)) {
    2270        2096 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Disconnect event - remove keys");
    2271        2096 :                 wpa_clear_keys(wpa_s, wpa_s->bssid);
    2272             :         }
    2273        2428 :         last_ssid = wpa_s->current_ssid;
    2274        2428 :         wpa_supplicant_mark_disassoc(wpa_s);
    2275             : 
    2276        2428 :         if (authenticating && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) {
    2277          11 :                 sme_disassoc_while_authenticating(wpa_s, prev_pending_bssid);
    2278          11 :                 wpa_s->current_ssid = last_ssid;
    2279             :         }
    2280             : 
    2281        2432 :         if (fast_reconnect &&
    2282           8 :             !wpas_network_disabled(wpa_s, fast_reconnect_ssid) &&
    2283           8 :             !disallowed_bssid(wpa_s, fast_reconnect->bssid) &&
    2284           4 :             !disallowed_ssid(wpa_s, fast_reconnect->ssid,
    2285           4 :                              fast_reconnect->ssid_len) &&
    2286           4 :             !wpas_temp_disabled(wpa_s, fast_reconnect_ssid)) {
    2287             : #ifndef CONFIG_NO_SCAN_PROCESSING
    2288           3 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Try to reconnect to the same BSS");
    2289           6 :                 if (wpa_supplicant_connect(wpa_s, fast_reconnect,
    2290             :                                            fast_reconnect_ssid) < 0) {
    2291             :                         /* Recover through full scan */
    2292           0 :                         wpa_supplicant_req_scan(wpa_s, 0, 100000);
    2293             :                 }
    2294             : #endif /* CONFIG_NO_SCAN_PROCESSING */
    2295        2425 :         } else if (fast_reconnect) {
    2296             :                 /*
    2297             :                  * Could not reconnect to the same BSS due to network being
    2298             :                  * disabled. Use a new scan to match the alternative behavior
    2299             :                  * above, i.e., to continue automatic reconnection attempt in a
    2300             :                  * way that enforces disabled network rules.
    2301             :                  */
    2302           1 :                 wpa_supplicant_req_scan(wpa_s, 0, 100000);
    2303             :         }
    2304             : }
    2305             : 
    2306             : 
    2307             : #ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
    2308             : void wpa_supplicant_delayed_mic_error_report(void *eloop_ctx, void *sock_ctx)
    2309             : {
    2310             :         struct wpa_supplicant *wpa_s = eloop_ctx;
    2311             : 
    2312             :         if (!wpa_s->pending_mic_error_report)
    2313             :                 return;
    2314             : 
    2315             :         wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Sending pending MIC error report");
    2316             :         wpa_sm_key_request(wpa_s->wpa, 1, wpa_s->pending_mic_error_pairwise);
    2317             :         wpa_s->pending_mic_error_report = 0;
    2318             : }
    2319             : #endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
    2320             : 
    2321             : 
    2322             : static void
    2323           4 : wpa_supplicant_event_michael_mic_failure(struct wpa_supplicant *wpa_s,
    2324             :                                          union wpa_event_data *data)
    2325             : {
    2326             :         int pairwise;
    2327             :         struct os_reltime t;
    2328             : 
    2329           4 :         wpa_msg(wpa_s, MSG_WARNING, "Michael MIC failure detected");
    2330           4 :         pairwise = (data && data->michael_mic_failure.unicast);
    2331           4 :         os_get_reltime(&t);
    2332           6 :         if ((wpa_s->last_michael_mic_error.sec &&
    2333           4 :              !os_reltime_expired(&t, &wpa_s->last_michael_mic_error, 60)) ||
    2334           2 :             wpa_s->pending_mic_error_report) {
    2335           2 :                 if (wpa_s->pending_mic_error_report) {
    2336             :                         /*
    2337             :                          * Send the pending MIC error report immediately since
    2338             :                          * we are going to start countermeasures and AP better
    2339             :                          * do the same.
    2340             :                          */
    2341           0 :                         wpa_sm_key_request(wpa_s->wpa, 1,
    2342             :                                            wpa_s->pending_mic_error_pairwise);
    2343             :                 }
    2344             : 
    2345             :                 /* Send the new MIC error report immediately since we are going
    2346             :                  * to start countermeasures and AP better do the same.
    2347             :                  */
    2348           2 :                 wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
    2349             : 
    2350             :                 /* initialize countermeasures */
    2351           2 :                 wpa_s->countermeasures = 1;
    2352             : 
    2353           2 :                 wpa_blacklist_add(wpa_s, wpa_s->bssid);
    2354             : 
    2355           2 :                 wpa_msg(wpa_s, MSG_WARNING, "TKIP countermeasures started");
    2356             : 
    2357             :                 /*
    2358             :                  * Need to wait for completion of request frame. We do not get
    2359             :                  * any callback for the message completion, so just wait a
    2360             :                  * short while and hope for the best. */
    2361           2 :                 os_sleep(0, 10000);
    2362             : 
    2363           2 :                 wpa_drv_set_countermeasures(wpa_s, 1);
    2364           2 :                 wpa_supplicant_deauthenticate(wpa_s,
    2365             :                                               WLAN_REASON_MICHAEL_MIC_FAILURE);
    2366           2 :                 eloop_cancel_timeout(wpa_supplicant_stop_countermeasures,
    2367             :                                      wpa_s, NULL);
    2368           2 :                 eloop_register_timeout(60, 0,
    2369             :                                        wpa_supplicant_stop_countermeasures,
    2370             :                                        wpa_s, NULL);
    2371             :                 /* TODO: mark the AP rejected for 60 second. STA is
    2372             :                  * allowed to associate with another AP.. */
    2373             :         } else {
    2374             : #ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
    2375             :                 if (wpa_s->mic_errors_seen) {
    2376             :                         /*
    2377             :                          * Reduce the effectiveness of Michael MIC error
    2378             :                          * reports as a means for attacking against TKIP if
    2379             :                          * more than one MIC failure is noticed with the same
    2380             :                          * PTK. We delay the transmission of the reports by a
    2381             :                          * random time between 0 and 60 seconds in order to
    2382             :                          * force the attacker wait 60 seconds before getting
    2383             :                          * the information on whether a frame resulted in a MIC
    2384             :                          * failure.
    2385             :                          */
    2386             :                         u8 rval[4];
    2387             :                         int sec;
    2388             : 
    2389             :                         if (os_get_random(rval, sizeof(rval)) < 0)
    2390             :                                 sec = os_random() % 60;
    2391             :                         else
    2392             :                                 sec = WPA_GET_BE32(rval) % 60;
    2393             :                         wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Delay MIC error "
    2394             :                                 "report %d seconds", sec);
    2395             :                         wpa_s->pending_mic_error_report = 1;
    2396             :                         wpa_s->pending_mic_error_pairwise = pairwise;
    2397             :                         eloop_cancel_timeout(
    2398             :                                 wpa_supplicant_delayed_mic_error_report,
    2399             :                                 wpa_s, NULL);
    2400             :                         eloop_register_timeout(
    2401             :                                 sec, os_random() % 1000000,
    2402             :                                 wpa_supplicant_delayed_mic_error_report,
    2403             :                                 wpa_s, NULL);
    2404             :                 } else {
    2405             :                         wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
    2406             :                 }
    2407             : #else /* CONFIG_DELAYED_MIC_ERROR_REPORT */
    2408           2 :                 wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
    2409             : #endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
    2410             :         }
    2411           4 :         wpa_s->last_michael_mic_error = t;
    2412           4 :         wpa_s->mic_errors_seen++;
    2413           4 : }
    2414             : 
    2415             : 
    2416             : #ifdef CONFIG_TERMINATE_ONLASTIF
    2417             : static int any_interfaces(struct wpa_supplicant *head)
    2418             : {
    2419             :         struct wpa_supplicant *wpa_s;
    2420             : 
    2421             :         for (wpa_s = head; wpa_s != NULL; wpa_s = wpa_s->next)
    2422             :                 if (!wpa_s->interface_removed)
    2423             :                         return 1;
    2424             :         return 0;
    2425             : }
    2426             : #endif /* CONFIG_TERMINATE_ONLASTIF */
    2427             : 
    2428             : 
    2429             : static void
    2430          27 : wpa_supplicant_event_interface_status(struct wpa_supplicant *wpa_s,
    2431             :                                       union wpa_event_data *data)
    2432             : {
    2433          27 :         if (os_strcmp(wpa_s->ifname, data->interface_status.ifname) != 0)
    2434          38 :                 return;
    2435             : 
    2436          16 :         switch (data->interface_status.ievent) {
    2437             :         case EVENT_INTERFACE_ADDED:
    2438           0 :                 if (!wpa_s->interface_removed)
    2439           0 :                         break;
    2440           0 :                 wpa_s->interface_removed = 0;
    2441           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Configured interface was added");
    2442           0 :                 if (wpa_supplicant_driver_init(wpa_s) < 0) {
    2443           0 :                         wpa_msg(wpa_s, MSG_INFO, "Failed to initialize the "
    2444             :                                 "driver after interface was added");
    2445             :                 }
    2446           0 :                 break;
    2447             :         case EVENT_INTERFACE_REMOVED:
    2448          16 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Configured interface was removed");
    2449          16 :                 wpa_s->interface_removed = 1;
    2450          16 :                 wpa_supplicant_mark_disassoc(wpa_s);
    2451          16 :                 wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
    2452          16 :                 l2_packet_deinit(wpa_s->l2);
    2453          16 :                 wpa_s->l2 = NULL;
    2454             : #ifdef CONFIG_TERMINATE_ONLASTIF
    2455             :                 /* check if last interface */
    2456             :                 if (!any_interfaces(wpa_s->global->ifaces))
    2457             :                         eloop_terminate();
    2458             : #endif /* CONFIG_TERMINATE_ONLASTIF */
    2459          16 :                 break;
    2460             :         }
    2461             : }
    2462             : 
    2463             : 
    2464             : #ifdef CONFIG_PEERKEY
    2465             : static void
    2466           0 : wpa_supplicant_event_stkstart(struct wpa_supplicant *wpa_s,
    2467             :                               union wpa_event_data *data)
    2468             : {
    2469           0 :         if (data == NULL)
    2470           0 :                 return;
    2471           0 :         wpa_sm_stkstart(wpa_s->wpa, data->stkstart.peer);
    2472             : }
    2473             : #endif /* CONFIG_PEERKEY */
    2474             : 
    2475             : 
    2476             : #ifdef CONFIG_TDLS
    2477           0 : static void wpa_supplicant_event_tdls(struct wpa_supplicant *wpa_s,
    2478             :                                       union wpa_event_data *data)
    2479             : {
    2480           0 :         if (data == NULL)
    2481           0 :                 return;
    2482           0 :         switch (data->tdls.oper) {
    2483             :         case TDLS_REQUEST_SETUP:
    2484           0 :                 wpa_tdls_remove(wpa_s->wpa, data->tdls.peer);
    2485           0 :                 if (wpa_tdls_is_external_setup(wpa_s->wpa))
    2486           0 :                         wpa_tdls_start(wpa_s->wpa, data->tdls.peer);
    2487             :                 else
    2488           0 :                         wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, data->tdls.peer);
    2489           0 :                 break;
    2490             :         case TDLS_REQUEST_TEARDOWN:
    2491           0 :                 if (wpa_tdls_is_external_setup(wpa_s->wpa))
    2492           0 :                         wpa_tdls_teardown_link(wpa_s->wpa, data->tdls.peer,
    2493           0 :                                                data->tdls.reason_code);
    2494             :                 else
    2495           0 :                         wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN,
    2496           0 :                                           data->tdls.peer);
    2497           0 :                 break;
    2498             :         case TDLS_REQUEST_DISCOVER:
    2499           0 :                         wpa_tdls_send_discovery_request(wpa_s->wpa,
    2500           0 :                                                         data->tdls.peer);
    2501           0 :                 break;
    2502             :         }
    2503             : }
    2504             : #endif /* CONFIG_TDLS */
    2505             : 
    2506             : 
    2507             : #ifdef CONFIG_WNM
    2508           0 : static void wpa_supplicant_event_wnm(struct wpa_supplicant *wpa_s,
    2509             :                                      union wpa_event_data *data)
    2510             : {
    2511           0 :         if (data == NULL)
    2512           0 :                 return;
    2513           0 :         switch (data->wnm.oper) {
    2514             :         case WNM_OPER_SLEEP:
    2515           0 :                 wpa_printf(MSG_DEBUG, "Start sending WNM-Sleep Request "
    2516             :                            "(action=%d, intval=%d)",
    2517           0 :                            data->wnm.sleep_action, data->wnm.sleep_intval);
    2518           0 :                 ieee802_11_send_wnmsleep_req(wpa_s, data->wnm.sleep_action,
    2519           0 :                                              data->wnm.sleep_intval, NULL);
    2520           0 :                 break;
    2521             :         }
    2522             : }
    2523             : #endif /* CONFIG_WNM */
    2524             : 
    2525             : 
    2526             : #ifdef CONFIG_IEEE80211R
    2527             : static void
    2528         113 : wpa_supplicant_event_ft_response(struct wpa_supplicant *wpa_s,
    2529             :                                  union wpa_event_data *data)
    2530             : {
    2531         113 :         if (data == NULL)
    2532         113 :                 return;
    2533             : 
    2534         226 :         if (wpa_ft_process_response(wpa_s->wpa, data->ft_ies.ies,
    2535             :                                     data->ft_ies.ies_len,
    2536             :                                     data->ft_ies.ft_action,
    2537         113 :                                     data->ft_ies.target_ap,
    2538             :                                     data->ft_ies.ric_ies,
    2539             :                                     data->ft_ies.ric_ies_len) < 0) {
    2540             :                 /* TODO: prevent MLME/driver from trying to associate? */
    2541             :         }
    2542             : }
    2543             : #endif /* CONFIG_IEEE80211R */
    2544             : 
    2545             : 
    2546             : #ifdef CONFIG_IBSS_RSN
    2547          25 : static void wpa_supplicant_event_ibss_rsn_start(struct wpa_supplicant *wpa_s,
    2548             :                                                 union wpa_event_data *data)
    2549             : {
    2550             :         struct wpa_ssid *ssid;
    2551          25 :         if (wpa_s->wpa_state < WPA_ASSOCIATED)
    2552           0 :                 return;
    2553          25 :         if (data == NULL)
    2554           0 :                 return;
    2555          25 :         ssid = wpa_s->current_ssid;
    2556          25 :         if (ssid == NULL)
    2557           0 :                 return;
    2558          25 :         if (ssid->mode != WPAS_MODE_IBSS || !wpa_key_mgmt_wpa(ssid->key_mgmt))
    2559          13 :                 return;
    2560             : 
    2561          12 :         ibss_rsn_start(wpa_s->ibss_rsn, data->ibss_rsn_start.peer);
    2562             : }
    2563             : 
    2564             : 
    2565          20 : static void wpa_supplicant_event_ibss_auth(struct wpa_supplicant *wpa_s,
    2566             :                                            union wpa_event_data *data)
    2567             : {
    2568          20 :         struct wpa_ssid *ssid = wpa_s->current_ssid;
    2569             : 
    2570          20 :         if (ssid == NULL)
    2571           0 :                 return;
    2572             : 
    2573             :         /* check if the ssid is correctly configured as IBSS/RSN */
    2574          20 :         if (ssid->mode != WPAS_MODE_IBSS || !wpa_key_mgmt_wpa(ssid->key_mgmt))
    2575           0 :                 return;
    2576             : 
    2577          20 :         ibss_rsn_handle_auth(wpa_s->ibss_rsn, data->rx_mgmt.frame,
    2578             :                              data->rx_mgmt.frame_len);
    2579             : }
    2580             : #endif /* CONFIG_IBSS_RSN */
    2581             : 
    2582             : 
    2583             : #ifdef CONFIG_IEEE80211R
    2584         123 : static void ft_rx_action(struct wpa_supplicant *wpa_s, const u8 *data,
    2585             :                          size_t len)
    2586             : {
    2587             :         const u8 *sta_addr, *target_ap_addr;
    2588             :         u16 status;
    2589             : 
    2590         123 :         wpa_hexdump(MSG_MSGDUMP, "FT: RX Action", data, len);
    2591         123 :         if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME))
    2592           0 :                 return; /* only SME case supported for now */
    2593         123 :         if (len < 1 + 2 * ETH_ALEN + 2)
    2594           0 :                 return;
    2595         123 :         if (data[0] != 2)
    2596           0 :                 return; /* Only FT Action Response is supported for now */
    2597         123 :         sta_addr = data + 1;
    2598         123 :         target_ap_addr = data + 1 + ETH_ALEN;
    2599         123 :         status = WPA_GET_LE16(data + 1 + 2 * ETH_ALEN);
    2600         123 :         wpa_dbg(wpa_s, MSG_DEBUG, "FT: Received FT Action Response: STA "
    2601             :                 MACSTR " TargetAP " MACSTR " status %u",
    2602             :                 MAC2STR(sta_addr), MAC2STR(target_ap_addr), status);
    2603             : 
    2604         123 :         if (os_memcmp(sta_addr, wpa_s->own_addr, ETH_ALEN) != 0) {
    2605           1 :                 wpa_dbg(wpa_s, MSG_DEBUG, "FT: Foreign STA Address " MACSTR
    2606             :                         " in FT Action Response", MAC2STR(sta_addr));
    2607           1 :                 return;
    2608             :         }
    2609             : 
    2610         122 :         if (status) {
    2611           2 :                 wpa_dbg(wpa_s, MSG_DEBUG, "FT: FT Action Response indicates "
    2612             :                         "failure (status code %d)", status);
    2613             :                 /* TODO: report error to FT code(?) */
    2614           2 :                 return;
    2615             :         }
    2616             : 
    2617         120 :         if (wpa_ft_process_response(wpa_s->wpa, data + 1 + 2 * ETH_ALEN + 2,
    2618             :                                     len - (1 + 2 * ETH_ALEN + 2), 1,
    2619             :                                     target_ap_addr, NULL, 0) < 0)
    2620          12 :                 return;
    2621             : 
    2622             : #ifdef CONFIG_SME
    2623             :         {
    2624             :                 struct wpa_bss *bss;
    2625         108 :                 bss = wpa_bss_get_bssid(wpa_s, target_ap_addr);
    2626         108 :                 if (bss)
    2627         108 :                         wpa_s->sme.freq = bss->freq;
    2628         108 :                 wpa_s->sme.auth_alg = WPA_AUTH_ALG_FT;
    2629         108 :                 sme_associate(wpa_s, WPAS_MODE_INFRA, target_ap_addr,
    2630             :                               WLAN_AUTH_FT);
    2631             :         }
    2632             : #endif /* CONFIG_SME */
    2633             : }
    2634             : #endif /* CONFIG_IEEE80211R */
    2635             : 
    2636             : 
    2637          19 : static void wpa_supplicant_event_unprot_deauth(struct wpa_supplicant *wpa_s,
    2638             :                                                struct unprot_deauth *e)
    2639             : {
    2640             : #ifdef CONFIG_IEEE80211W
    2641         247 :         wpa_printf(MSG_DEBUG, "Unprotected Deauthentication frame "
    2642             :                    "dropped: " MACSTR " -> " MACSTR
    2643             :                    " (reason code %u)",
    2644         247 :                    MAC2STR(e->sa), MAC2STR(e->da), e->reason_code);
    2645          19 :         sme_event_unprot_disconnect(wpa_s, e->sa, e->da, e->reason_code);
    2646             : #endif /* CONFIG_IEEE80211W */
    2647          19 : }
    2648             : 
    2649             : 
    2650          19 : static void wpa_supplicant_event_unprot_disassoc(struct wpa_supplicant *wpa_s,
    2651             :                                                  struct unprot_disassoc *e)
    2652             : {
    2653             : #ifdef CONFIG_IEEE80211W
    2654         247 :         wpa_printf(MSG_DEBUG, "Unprotected Disassociation frame "
    2655             :                    "dropped: " MACSTR " -> " MACSTR
    2656             :                    " (reason code %u)",
    2657         247 :                    MAC2STR(e->sa), MAC2STR(e->da), e->reason_code);
    2658          19 :         sme_event_unprot_disconnect(wpa_s, e->sa, e->da, e->reason_code);
    2659             : #endif /* CONFIG_IEEE80211W */
    2660          19 : }
    2661             : 
    2662             : 
    2663        2557 : static void wpas_event_disconnect(struct wpa_supplicant *wpa_s, const u8 *addr,
    2664             :                                   u16 reason_code, int locally_generated,
    2665             :                                   const u8 *ie, size_t ie_len, int deauth)
    2666             : {
    2667             : #ifdef CONFIG_AP
    2668        2557 :         if (wpa_s->ap_iface && addr) {
    2669           0 :                 hostapd_notif_disassoc(wpa_s->ap_iface->bss[0], addr);
    2670           0 :                 return;
    2671             :         }
    2672             : 
    2673        2557 :         if (wpa_s->ap_iface) {
    2674         112 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Ignore deauth event in AP mode");
    2675         112 :                 return;
    2676             :         }
    2677             : #endif /* CONFIG_AP */
    2678             : 
    2679        2445 :         if (!locally_generated)
    2680         294 :                 wpa_s->own_disconnect_req = 0;
    2681             : 
    2682        2445 :         wpa_supplicant_event_disassoc(wpa_s, reason_code, locally_generated);
    2683             : 
    2684        4800 :         if (((reason_code == WLAN_REASON_IEEE_802_1X_AUTH_FAILED ||
    2685        3806 :               ((wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
    2686        2363 :                 (wpa_s->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)) &&
    2687        1154 :                eapol_sm_failed(wpa_s->eapol))) &&
    2688         242 :              !wpa_s->eap_expected_failure))
    2689         238 :                 wpas_auth_failed(wpa_s, "AUTH_FAILED");
    2690             : 
    2691             : #ifdef CONFIG_P2P
    2692        2445 :         if (deauth && reason_code > 0) {
    2693        2432 :                 if (wpas_p2p_deauth_notif(wpa_s, addr, reason_code, ie, ie_len,
    2694             :                                           locally_generated) > 0) {
    2695             :                         /*
    2696             :                          * The interface was removed, so cannot continue
    2697             :                          * processing any additional operations after this.
    2698             :                          */
    2699          11 :                         return;
    2700             :                 }
    2701             :         }
    2702             : #endif /* CONFIG_P2P */
    2703             : 
    2704        2434 :         wpa_supplicant_event_disassoc_finish(wpa_s, reason_code,
    2705             :                                              locally_generated);
    2706             : }
    2707             : 
    2708             : 
    2709          13 : static void wpas_event_disassoc(struct wpa_supplicant *wpa_s,
    2710             :                                 struct disassoc_info *info)
    2711             : {
    2712          13 :         u16 reason_code = 0;
    2713          13 :         int locally_generated = 0;
    2714          13 :         const u8 *addr = NULL;
    2715          13 :         const u8 *ie = NULL;
    2716          13 :         size_t ie_len = 0;
    2717             : 
    2718          13 :         wpa_dbg(wpa_s, MSG_DEBUG, "Disassociation notification");
    2719             : 
    2720          13 :         if (info) {
    2721           5 :                 addr = info->addr;
    2722           5 :                 ie = info->ie;
    2723           5 :                 ie_len = info->ie_len;
    2724           5 :                 reason_code = info->reason_code;
    2725           5 :                 locally_generated = info->locally_generated;
    2726           5 :                 wpa_dbg(wpa_s, MSG_DEBUG, " * reason %u%s", reason_code,
    2727             :                         locally_generated ? " (locally generated)" : "");
    2728           5 :                 if (addr)
    2729           5 :                         wpa_dbg(wpa_s, MSG_DEBUG, " * address " MACSTR,
    2730             :                                 MAC2STR(addr));
    2731           5 :                 wpa_hexdump(MSG_DEBUG, "Disassociation frame IE(s)",
    2732             :                             ie, ie_len);
    2733             :         }
    2734             : 
    2735             : #ifdef CONFIG_AP
    2736          13 :         if (wpa_s->ap_iface && info && info->addr) {
    2737           0 :                 hostapd_notif_disassoc(wpa_s->ap_iface->bss[0], info->addr);
    2738           0 :                 return;
    2739             :         }
    2740             : 
    2741          13 :         if (wpa_s->ap_iface) {
    2742           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Ignore disassoc event in AP mode");
    2743           0 :                 return;
    2744             :         }
    2745             : #endif /* CONFIG_AP */
    2746             : 
    2747             : #ifdef CONFIG_P2P
    2748          13 :         if (info) {
    2749           5 :                 wpas_p2p_disassoc_notif(
    2750             :                         wpa_s, info->addr, reason_code, info->ie, info->ie_len,
    2751             :                         locally_generated);
    2752             :         }
    2753             : #endif /* CONFIG_P2P */
    2754             : 
    2755          13 :         if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
    2756           5 :                 sme_event_disassoc(wpa_s, info);
    2757             : 
    2758          13 :         wpas_event_disconnect(wpa_s, addr, reason_code, locally_generated,
    2759             :                               ie, ie_len, 0);
    2760             : }
    2761             : 
    2762             : 
    2763        2544 : static void wpas_event_deauth(struct wpa_supplicant *wpa_s,
    2764             :                               struct deauth_info *info)
    2765             : {
    2766        2544 :         u16 reason_code = 0;
    2767        2544 :         int locally_generated = 0;
    2768        2544 :         const u8 *addr = NULL;
    2769        2544 :         const u8 *ie = NULL;
    2770        2544 :         size_t ie_len = 0;
    2771             : 
    2772        2544 :         wpa_dbg(wpa_s, MSG_DEBUG, "Deauthentication notification");
    2773             : 
    2774        2544 :         if (info) {
    2775        2544 :                 addr = info->addr;
    2776        2544 :                 ie = info->ie;
    2777        2544 :                 ie_len = info->ie_len;
    2778        2544 :                 reason_code = info->reason_code;
    2779        2544 :                 locally_generated = info->locally_generated;
    2780        2544 :                 wpa_dbg(wpa_s, MSG_DEBUG, " * reason %u%s",
    2781             :                         reason_code,
    2782             :                         locally_generated ? " (locally generated)" : "");
    2783        2544 :                 if (addr) {
    2784         299 :                         wpa_dbg(wpa_s, MSG_DEBUG, " * address " MACSTR,
    2785             :                                 MAC2STR(addr));
    2786             :                 }
    2787        2544 :                 wpa_hexdump(MSG_DEBUG, "Deauthentication frame IE(s)",
    2788             :                             ie, ie_len);
    2789             :         }
    2790             : 
    2791        2544 :         wpa_reset_ft_completed(wpa_s->wpa);
    2792             : 
    2793        2544 :         wpas_event_disconnect(wpa_s, addr, reason_code,
    2794             :                               locally_generated, ie, ie_len, 1);
    2795        2544 : }
    2796             : 
    2797             : 
    2798        7305 : static const char * reg_init_str(enum reg_change_initiator init)
    2799             : {
    2800        7305 :         switch (init) {
    2801             :         case REGDOM_SET_BY_CORE:
    2802        6968 :                 return "CORE";
    2803             :         case REGDOM_SET_BY_USER:
    2804         298 :                 return "USER";
    2805             :         case REGDOM_SET_BY_DRIVER:
    2806           0 :                 return "DRIVER";
    2807             :         case REGDOM_SET_BY_COUNTRY_IE:
    2808          21 :                 return "COUNTRY_IE";
    2809             :         case REGDOM_BEACON_HINT:
    2810          18 :                 return "BEACON_HINT";
    2811             :         }
    2812           0 :         return "?";
    2813             : }
    2814             : 
    2815             : 
    2816        7305 : static const char * reg_type_str(enum reg_type type)
    2817             : {
    2818        7305 :         switch (type) {
    2819             :         case REGDOM_TYPE_UNKNOWN:
    2820          18 :                 return "UNKNOWN";
    2821             :         case REGDOM_TYPE_COUNTRY:
    2822         319 :                 return "COUNTRY";
    2823             :         case REGDOM_TYPE_WORLD:
    2824        6968 :                 return "WORLD";
    2825             :         case REGDOM_TYPE_CUSTOM_WORLD:
    2826           0 :                 return "CUSTOM_WORLD";
    2827             :         case REGDOM_TYPE_INTERSECTION:
    2828           0 :                 return "INTERSECTION";
    2829             :         }
    2830           0 :         return "?";
    2831             : }
    2832             : 
    2833             : 
    2834        7305 : static void wpa_supplicant_update_channel_list(
    2835             :         struct wpa_supplicant *wpa_s, struct channel_list_changed *info)
    2836             : {
    2837             :         struct wpa_supplicant *ifs;
    2838             : 
    2839       14610 :         wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REGDOM_CHANGE "init=%s type=%s%s%s",
    2840             :                 reg_init_str(info->initiator), reg_type_str(info->type),
    2841        7305 :                 info->alpha2[0] ? " alpha2=" : "",
    2842        7305 :                 info->alpha2[0] ? info->alpha2 : "");
    2843             : 
    2844        7305 :         if (wpa_s->drv_priv == NULL)
    2845        7305 :                 return; /* Ignore event during drv initialization */
    2846             : 
    2847        7305 :         free_hw_features(wpa_s);
    2848        7305 :         wpa_s->hw.modes = wpa_drv_get_hw_feature_data(
    2849             :                 wpa_s, &wpa_s->hw.num_modes, &wpa_s->hw.flags);
    2850             : 
    2851        7305 :         wpas_p2p_update_channel_list(wpa_s);
    2852             : 
    2853             :         /*
    2854             :          * Check other interfaces to see if they share the same radio. If
    2855             :          * so, they get updated with this same hw mode info.
    2856             :          */
    2857       14654 :         dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
    2858             :                          radio_list) {
    2859        7349 :                 if (ifs != wpa_s) {
    2860          44 :                         wpa_printf(MSG_DEBUG, "%s: Updating hw mode",
    2861          44 :                                    ifs->ifname);
    2862          44 :                         free_hw_features(ifs);
    2863          44 :                         ifs->hw.modes = wpa_drv_get_hw_feature_data(
    2864             :                                 ifs, &ifs->hw.num_modes, &ifs->hw.flags);
    2865             :                 }
    2866             :         }
    2867             : }
    2868             : 
    2869             : 
    2870        1538 : static void wpas_event_rx_mgmt_action(struct wpa_supplicant *wpa_s,
    2871             :                                       const u8 *frame, size_t len, int freq,
    2872             :                                       int rssi)
    2873             : {
    2874             :         const struct ieee80211_mgmt *mgmt;
    2875             :         const u8 *payload;
    2876             :         size_t plen;
    2877             :         u8 category;
    2878             : 
    2879        1538 :         if (len < IEEE80211_HDRLEN + 2)
    2880           0 :                 return;
    2881             : 
    2882        1538 :         mgmt = (const struct ieee80211_mgmt *) frame;
    2883        1538 :         payload = frame + IEEE80211_HDRLEN;
    2884        1538 :         category = *payload++;
    2885        1538 :         plen = len - IEEE80211_HDRLEN - 1;
    2886             : 
    2887        1538 :         wpa_dbg(wpa_s, MSG_DEBUG, "Received Action frame: SA=" MACSTR
    2888             :                 " Category=%u DataLen=%d freq=%d MHz",
    2889             :                 MAC2STR(mgmt->sa), category, (int) plen, freq);
    2890             : 
    2891        1538 :         if (category == WLAN_ACTION_WMM) {
    2892          15 :                 wmm_ac_rx_action(wpa_s, mgmt->da, mgmt->sa, payload, plen);
    2893          15 :                 return;
    2894             :         }
    2895             : 
    2896             : #ifdef CONFIG_IEEE80211R
    2897        1523 :         if (category == WLAN_ACTION_FT) {
    2898         123 :                 ft_rx_action(wpa_s, payload, plen);
    2899         123 :                 return;
    2900             :         }
    2901             : #endif /* CONFIG_IEEE80211R */
    2902             : 
    2903             : #ifdef CONFIG_IEEE80211W
    2904             : #ifdef CONFIG_SME
    2905        1400 :         if (category == WLAN_ACTION_SA_QUERY) {
    2906           3 :                 sme_sa_query_rx(wpa_s, mgmt->sa, payload, plen);
    2907           3 :                 return;
    2908             :         }
    2909             : #endif /* CONFIG_SME */
    2910             : #endif /* CONFIG_IEEE80211W */
    2911             : 
    2912             : #ifdef CONFIG_WNM
    2913        1397 :         if (mgmt->u.action.category == WLAN_ACTION_WNM) {
    2914          43 :                 ieee802_11_rx_wnm_action(wpa_s, mgmt, len);
    2915          43 :                 return;
    2916             :         }
    2917             : #endif /* CONFIG_WNM */
    2918             : 
    2919             : #ifdef CONFIG_GAS
    2920        1472 :         if ((mgmt->u.action.category == WLAN_ACTION_PUBLIC ||
    2921        1355 :              mgmt->u.action.category == WLAN_ACTION_PROTECTED_DUAL) &&
    2922        1237 :             gas_query_rx(wpa_s->gas, mgmt->da, mgmt->sa, mgmt->bssid,
    2923        1237 :                          mgmt->u.action.category,
    2924             :                          payload, plen, freq) == 0)
    2925         397 :                 return;
    2926             : #endif /* CONFIG_GAS */
    2927             : 
    2928             : #ifdef CONFIG_TDLS
    2929        1779 :         if (category == WLAN_ACTION_PUBLIC && plen >= 4 &&
    2930         822 :             payload[0] == WLAN_TDLS_DISCOVERY_RESPONSE) {
    2931           2 :                 wpa_dbg(wpa_s, MSG_DEBUG,
    2932             :                         "TDLS: Received Discovery Response from " MACSTR,
    2933             :                         MAC2STR(mgmt->sa));
    2934           2 :                 return;
    2935             :         }
    2936             : #endif /* CONFIG_TDLS */
    2937             : 
    2938             : #ifdef CONFIG_INTERWORKING
    2939         956 :         if (category == WLAN_ACTION_QOS && plen >= 1 &&
    2940           1 :             payload[0] == QOS_QOS_MAP_CONFIG) {
    2941           1 :                 const u8 *pos = payload + 1;
    2942           1 :                 size_t qlen = plen - 1;
    2943           1 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Interworking: Received QoS Map Configure frame from "
    2944             :                         MACSTR, MAC2STR(mgmt->sa));
    2945           1 :                 if (os_memcmp(mgmt->sa, wpa_s->bssid, ETH_ALEN) == 0 &&
    2946           2 :                     qlen > 2 && pos[0] == WLAN_EID_QOS_MAP_SET &&
    2947           2 :                     pos[1] <= qlen - 2 && pos[1] >= 16)
    2948           1 :                         wpas_qos_map_set(wpa_s, pos + 2, pos[1]);
    2949           1 :                 return;
    2950             :         }
    2951             : #endif /* CONFIG_INTERWORKING */
    2952             : 
    2953         954 :         if (category == WLAN_ACTION_RADIO_MEASUREMENT &&
    2954           0 :             payload[0] == WLAN_RRM_NEIGHBOR_REPORT_RESPONSE) {
    2955           0 :                 wpas_rrm_process_neighbor_rep(wpa_s, payload + 1, plen - 1);
    2956           0 :                 return;
    2957             :         }
    2958             : 
    2959         954 :         if (category == WLAN_ACTION_RADIO_MEASUREMENT &&
    2960           0 :             payload[0] == WLAN_RRM_LINK_MEASUREMENT_REQUEST) {
    2961           0 :                 wpas_rrm_handle_link_measurement_request(wpa_s, mgmt->sa,
    2962             :                                                          payload + 1, plen - 1,
    2963             :                                                          rssi);
    2964           0 :                 return;
    2965             :         }
    2966             : 
    2967         954 :         wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
    2968             :                            category, payload, plen, freq);
    2969         954 :         if (wpa_s->ifmsh)
    2970         111 :                 mesh_mpm_action_rx(wpa_s, mgmt, len);
    2971             : }
    2972             : 
    2973             : 
    2974           4 : static void wpa_supplicant_notify_avoid_freq(struct wpa_supplicant *wpa_s,
    2975             :                                              union wpa_event_data *event)
    2976             : {
    2977             : #ifdef CONFIG_P2P
    2978             :         struct wpa_supplicant *ifs;
    2979             : #endif /* CONFIG_P2P */
    2980             :         struct wpa_freq_range_list *list;
    2981           4 :         char *str = NULL;
    2982             : 
    2983           4 :         list = &event->freq_range;
    2984             : 
    2985           4 :         if (list->num)
    2986           2 :                 str = freq_range_list_str(list);
    2987           4 :         wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_AVOID_FREQ "ranges=%s",
    2988             :                 str ? str : "");
    2989             : 
    2990             : #ifdef CONFIG_P2P
    2991           4 :         if (freq_range_list_parse(&wpa_s->global->p2p_go_avoid_freq, str)) {
    2992           0 :                 wpa_dbg(wpa_s, MSG_ERROR, "%s: Failed to parse freq range",
    2993             :                         __func__);
    2994             :         } else {
    2995           4 :                 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Update channel list based on frequency avoid event");
    2996           4 :                 wpas_p2p_update_channel_list(wpa_s);
    2997             :         }
    2998             : 
    2999           8 :         for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
    3000             :                 int freq;
    3001           7 :                 if (!ifs->current_ssid ||
    3002           6 :                     !ifs->current_ssid->p2p_group ||
    3003           3 :                     (ifs->current_ssid->mode != WPAS_MODE_P2P_GO &&
    3004           0 :                      ifs->current_ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION))
    3005           1 :                         continue;
    3006             : 
    3007           3 :                 freq = ifs->current_ssid->frequency;
    3008           3 :                 if (!freq_range_list_includes(list, freq)) {
    3009           2 :                         wpa_dbg(ifs, MSG_DEBUG, "P2P GO operating frequency %d MHz in safe range",
    3010             :                                 freq);
    3011           2 :                         continue;
    3012             :                 }
    3013             : 
    3014           1 :                 wpa_dbg(ifs, MSG_DEBUG, "P2P GO operating in unsafe frequency %d MHz",
    3015             :                         freq);
    3016             :                 /* TODO: Consider using CSA or removing the group within
    3017             :                  * wpa_supplicant */
    3018           1 :                 wpa_msg(ifs, MSG_INFO, P2P_EVENT_REMOVE_AND_REFORM_GROUP);
    3019             :         }
    3020             : #endif /* CONFIG_P2P */
    3021             : 
    3022           4 :         os_free(str);
    3023           4 : }
    3024             : 
    3025             : 
    3026           0 : static void wpa_supplicant_event_assoc_auth(struct wpa_supplicant *wpa_s,
    3027             :                                             union wpa_event_data *data)
    3028             : {
    3029           0 :         wpa_dbg(wpa_s, MSG_DEBUG,
    3030             :                 "Connection authorized by device, previous state %d",
    3031             :                 wpa_s->wpa_state);
    3032           0 :         if (wpa_s->wpa_state == WPA_ASSOCIATED) {
    3033           0 :                 wpa_supplicant_cancel_auth_timeout(wpa_s);
    3034           0 :                 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
    3035           0 :                 eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
    3036           0 :                 eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
    3037             :         }
    3038           0 :         wpa_sm_set_rx_replay_ctr(wpa_s->wpa, data->assoc_info.key_replay_ctr);
    3039           0 :         wpa_sm_set_ptk_kck_kek(wpa_s->wpa, data->assoc_info.ptk_kck,
    3040             :                                data->assoc_info.ptk_kck_len,
    3041             :                                data->assoc_info.ptk_kek,
    3042             :                                data->assoc_info.ptk_kek_len);
    3043           0 : }
    3044             : 
    3045             : 
    3046       33726 : void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
    3047             :                           union wpa_event_data *data)
    3048             : {
    3049       33726 :         struct wpa_supplicant *wpa_s = ctx;
    3050             : 
    3051       33726 :         if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED &&
    3052          36 :             event != EVENT_INTERFACE_ENABLED &&
    3053          20 :             event != EVENT_INTERFACE_STATUS &&
    3054             :             event != EVENT_SCHED_SCAN_STOPPED) {
    3055          20 :                 wpa_dbg(wpa_s, MSG_DEBUG,
    3056             :                         "Ignore event %s (%d) while interface is disabled",
    3057             :                         event_to_string(event), event);
    3058       33746 :                 return;
    3059             :         }
    3060             : 
    3061             : #ifndef CONFIG_NO_STDOUT_DEBUG
    3062             : {
    3063       33706 :         int level = MSG_DEBUG;
    3064             : 
    3065       33706 :         if (event == EVENT_RX_MGMT && data->rx_mgmt.frame_len >= 24) {
    3066             :                 const struct ieee80211_hdr *hdr;
    3067             :                 u16 fc;
    3068        4707 :                 hdr = (const struct ieee80211_hdr *) data->rx_mgmt.frame;
    3069        4707 :                 fc = le_to_host16(hdr->frame_control);
    3070        9414 :                 if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
    3071        4707 :                     WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON)
    3072         357 :                         level = MSG_EXCESSIVE;
    3073             :         }
    3074             : 
    3075       33706 :         wpa_dbg(wpa_s, level, "Event %s (%d) received",
    3076             :                 event_to_string(event), event);
    3077             : }
    3078             : #endif /* CONFIG_NO_STDOUT_DEBUG */
    3079             : 
    3080       33706 :         switch (event) {
    3081             :         case EVENT_AUTH:
    3082        2474 :                 sme_event_auth(wpa_s, data);
    3083        2474 :                 break;
    3084             :         case EVENT_ASSOC:
    3085        2571 :                 wpa_supplicant_event_assoc(wpa_s, data);
    3086        2571 :                 if (data && data->assoc_info.authorized)
    3087           0 :                         wpa_supplicant_event_assoc_auth(wpa_s, data);
    3088        2571 :                 break;
    3089             :         case EVENT_DISASSOC:
    3090          13 :                 wpas_event_disassoc(wpa_s,
    3091             :                                     data ? &data->disassoc_info : NULL);
    3092          13 :                 break;
    3093             :         case EVENT_DEAUTH:
    3094        2544 :                 wpas_event_deauth(wpa_s,
    3095             :                                   data ? &data->deauth_info : NULL);
    3096        2544 :                 break;
    3097             :         case EVENT_MICHAEL_MIC_FAILURE:
    3098           4 :                 wpa_supplicant_event_michael_mic_failure(wpa_s, data);
    3099           4 :                 break;
    3100             : #ifndef CONFIG_NO_SCAN_PROCESSING
    3101             :         case EVENT_SCAN_STARTED:
    3102        2858 :                 os_get_reltime(&wpa_s->scan_start_time);
    3103        2858 :                 if (wpa_s->own_scan_requested) {
    3104             :                         struct os_reltime diff;
    3105             : 
    3106        2845 :                         os_reltime_sub(&wpa_s->scan_start_time,
    3107             :                                        &wpa_s->scan_trigger_time, &diff);
    3108        2845 :                         wpa_dbg(wpa_s, MSG_DEBUG, "Own scan request started a scan in %ld.%06ld seconds",
    3109             :                                 diff.sec, diff.usec);
    3110        2845 :                         wpa_s->own_scan_requested = 0;
    3111        2845 :                         wpa_s->own_scan_running = 1;
    3112        2845 :                         if (wpa_s->last_scan_req == MANUAL_SCAN_REQ &&
    3113             :                             wpa_s->manual_scan_use_id) {
    3114          15 :                                 wpa_msg_ctrl(wpa_s, MSG_INFO,
    3115             :                                              WPA_EVENT_SCAN_STARTED "id=%u",
    3116             :                                              wpa_s->manual_scan_id);
    3117             :                         } else {
    3118        2830 :                                 wpa_msg_ctrl(wpa_s, MSG_INFO,
    3119             :                                              WPA_EVENT_SCAN_STARTED);
    3120             :                         }
    3121             :                 } else {
    3122          13 :                         wpa_dbg(wpa_s, MSG_DEBUG, "External program started a scan");
    3123          13 :                         wpa_s->radio->external_scan_running = 1;
    3124          13 :                         wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_STARTED);
    3125             :                 }
    3126        2858 :                 break;
    3127             :         case EVENT_SCAN_RESULTS:
    3128        2869 :                 if (os_reltime_initialized(&wpa_s->scan_start_time)) {
    3129             :                         struct os_reltime now, diff;
    3130        2854 :                         os_get_reltime(&now);
    3131        2854 :                         os_reltime_sub(&now, &wpa_s->scan_start_time, &diff);
    3132        2854 :                         wpa_s->scan_start_time.sec = 0;
    3133        2854 :                         wpa_s->scan_start_time.usec = 0;
    3134        2854 :                         wpa_dbg(wpa_s, MSG_DEBUG, "Scan completed in %ld.%06ld seconds",
    3135             :                                 diff.sec, diff.usec);
    3136             :                 }
    3137        2869 :                 if (wpa_supplicant_event_scan_results(wpa_s, data))
    3138           1 :                         break; /* interface may have been removed */
    3139        2868 :                 wpa_s->own_scan_running = 0;
    3140        2868 :                 wpa_s->radio->external_scan_running = 0;
    3141        2868 :                 radio_work_check_next(wpa_s);
    3142        2868 :                 break;
    3143             : #endif /* CONFIG_NO_SCAN_PROCESSING */
    3144             :         case EVENT_ASSOCINFO:
    3145          14 :                 wpa_supplicant_event_associnfo(wpa_s, data);
    3146          14 :                 break;
    3147             :         case EVENT_INTERFACE_STATUS:
    3148          27 :                 wpa_supplicant_event_interface_status(wpa_s, data);
    3149          27 :                 break;
    3150             :         case EVENT_PMKID_CANDIDATE:
    3151           0 :                 wpa_supplicant_event_pmkid_candidate(wpa_s, data);
    3152           0 :                 break;
    3153             : #ifdef CONFIG_PEERKEY
    3154             :         case EVENT_STKSTART:
    3155           0 :                 wpa_supplicant_event_stkstart(wpa_s, data);
    3156           0 :                 break;
    3157             : #endif /* CONFIG_PEERKEY */
    3158             : #ifdef CONFIG_TDLS
    3159             :         case EVENT_TDLS:
    3160           0 :                 wpa_supplicant_event_tdls(wpa_s, data);
    3161           0 :                 break;
    3162             : #endif /* CONFIG_TDLS */
    3163             : #ifdef CONFIG_WNM
    3164             :         case EVENT_WNM:
    3165           0 :                 wpa_supplicant_event_wnm(wpa_s, data);
    3166           0 :                 break;
    3167             : #endif /* CONFIG_WNM */
    3168             : #ifdef CONFIG_IEEE80211R
    3169             :         case EVENT_FT_RESPONSE:
    3170         113 :                 wpa_supplicant_event_ft_response(wpa_s, data);
    3171         113 :                 break;
    3172             : #endif /* CONFIG_IEEE80211R */
    3173             : #ifdef CONFIG_IBSS_RSN
    3174             :         case EVENT_IBSS_RSN_START:
    3175          25 :                 wpa_supplicant_event_ibss_rsn_start(wpa_s, data);
    3176          25 :                 break;
    3177             : #endif /* CONFIG_IBSS_RSN */
    3178             :         case EVENT_ASSOC_REJECT:
    3179          13 :                 if (data->assoc_reject.bssid)
    3180          70 :                         wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_ASSOC_REJECT
    3181             :                                 "bssid=" MACSTR       " status_code=%u",
    3182          60 :                                 MAC2STR(data->assoc_reject.bssid),
    3183          10 :                                 data->assoc_reject.status_code);
    3184             :                 else
    3185           3 :                         wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_ASSOC_REJECT
    3186             :                                 "status_code=%u",
    3187           3 :                                 data->assoc_reject.status_code);
    3188          13 :                 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
    3189           7 :                         sme_event_assoc_reject(wpa_s, data);
    3190             :                 else {
    3191           6 :                         const u8 *bssid = data->assoc_reject.bssid;
    3192           6 :                         if (bssid == NULL || is_zero_ether_addr(bssid))
    3193           3 :                                 bssid = wpa_s->pending_bssid;
    3194           6 :                         wpas_connection_failed(wpa_s, bssid);
    3195           6 :                         wpa_supplicant_mark_disassoc(wpa_s);
    3196             :                 }
    3197          13 :                 break;
    3198             :         case EVENT_AUTH_TIMED_OUT:
    3199             :                 /* It is possible to get this event from earlier connection */
    3200          34 :                 if (wpa_s->current_ssid &&
    3201          17 :                     wpa_s->current_ssid->mode == WPAS_MODE_MESH) {
    3202           0 :                         wpa_dbg(wpa_s, MSG_DEBUG,
    3203             :                                 "Ignore AUTH_TIMED_OUT in mesh configuration");
    3204           0 :                         break;
    3205             :                 }
    3206          17 :                 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
    3207          16 :                         sme_event_auth_timed_out(wpa_s, data);
    3208          17 :                 break;
    3209             :         case EVENT_ASSOC_TIMED_OUT:
    3210             :                 /* It is possible to get this event from earlier connection */
    3211           2 :                 if (wpa_s->current_ssid &&
    3212           1 :                     wpa_s->current_ssid->mode == WPAS_MODE_MESH) {
    3213           0 :                         wpa_dbg(wpa_s, MSG_DEBUG,
    3214             :                                 "Ignore ASSOC_TIMED_OUT in mesh configuration");
    3215           0 :                         break;
    3216             :                 }
    3217           1 :                 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
    3218           1 :                         sme_event_assoc_timed_out(wpa_s, data);
    3219           1 :                 break;
    3220             :         case EVENT_TX_STATUS:
    3221        3213 :                 wpa_dbg(wpa_s, MSG_DEBUG, "EVENT_TX_STATUS dst=" MACSTR
    3222             :                         " type=%d stype=%d",
    3223             :                         MAC2STR(data->tx_status.dst),
    3224             :                         data->tx_status.type, data->tx_status.stype);
    3225             : #ifdef CONFIG_AP
    3226        3213 :                 if (wpa_s->ap_iface == NULL) {
    3227             : #ifdef CONFIG_OFFCHANNEL
    3228        3704 :                         if (data->tx_status.type == WLAN_FC_TYPE_MGMT &&
    3229        1852 :                             data->tx_status.stype == WLAN_FC_STYPE_ACTION)
    3230        1851 :                                 offchannel_send_action_tx_status(
    3231             :                                         wpa_s, data->tx_status.dst,
    3232             :                                         data->tx_status.data,
    3233             :                                         data->tx_status.data_len,
    3234        1851 :                                         data->tx_status.ack ?
    3235             :                                         OFFCHANNEL_SEND_ACTION_SUCCESS :
    3236             :                                         OFFCHANNEL_SEND_ACTION_NO_ACK);
    3237             : #endif /* CONFIG_OFFCHANNEL */
    3238        1852 :                         break;
    3239             :                 }
    3240             : #endif /* CONFIG_AP */
    3241             : #ifdef CONFIG_OFFCHANNEL
    3242        1361 :                 wpa_dbg(wpa_s, MSG_DEBUG, "EVENT_TX_STATUS pending_dst="
    3243             :                         MACSTR, MAC2STR(wpa_s->parent->pending_action_dst));
    3244             :                 /*
    3245             :                  * Catch TX status events for Action frames we sent via group
    3246             :                  * interface in GO mode.
    3247             :                  */
    3248        2712 :                 if (data->tx_status.type == WLAN_FC_TYPE_MGMT &&
    3249        1442 :                     data->tx_status.stype == WLAN_FC_STYPE_ACTION &&
    3250          91 :                     os_memcmp(wpa_s->parent->pending_action_dst,
    3251             :                               data->tx_status.dst, ETH_ALEN) == 0) {
    3252          83 :                         offchannel_send_action_tx_status(
    3253             :                                 wpa_s->parent, data->tx_status.dst,
    3254             :                                 data->tx_status.data,
    3255             :                                 data->tx_status.data_len,
    3256          83 :                                 data->tx_status.ack ?
    3257             :                                 OFFCHANNEL_SEND_ACTION_SUCCESS :
    3258             :                                 OFFCHANNEL_SEND_ACTION_NO_ACK);
    3259          83 :                         break;
    3260             :                 }
    3261             : #endif /* CONFIG_OFFCHANNEL */
    3262             : #ifdef CONFIG_AP
    3263        1278 :                 switch (data->tx_status.type) {
    3264             :                 case WLAN_FC_TYPE_MGMT:
    3265        2536 :                         ap_mgmt_tx_cb(wpa_s, data->tx_status.data,
    3266             :                                       data->tx_status.data_len,
    3267        1268 :                                       data->tx_status.stype,
    3268             :                                       data->tx_status.ack);
    3269        1268 :                         break;
    3270             :                 case WLAN_FC_TYPE_DATA:
    3271          10 :                         ap_tx_status(wpa_s, data->tx_status.dst,
    3272             :                                      data->tx_status.data,
    3273             :                                      data->tx_status.data_len,
    3274             :                                      data->tx_status.ack);
    3275          10 :                         break;
    3276             :                 }
    3277             : #endif /* CONFIG_AP */
    3278        1278 :                 break;
    3279             : #ifdef CONFIG_AP
    3280             :         case EVENT_EAPOL_TX_STATUS:
    3281        3300 :                 ap_eapol_tx_status(wpa_s, data->eapol_tx_status.dst,
    3282             :                                    data->eapol_tx_status.data,
    3283        1650 :                                    data->eapol_tx_status.data_len,
    3284             :                                    data->eapol_tx_status.ack);
    3285        1650 :                 break;
    3286             :         case EVENT_DRIVER_CLIENT_POLL_OK:
    3287           0 :                 ap_client_poll_ok(wpa_s, data->client_poll.addr);
    3288           0 :                 break;
    3289             :         case EVENT_RX_FROM_UNKNOWN:
    3290           0 :                 if (wpa_s->ap_iface == NULL)
    3291           0 :                         break;
    3292           0 :                 ap_rx_from_unknown_sta(wpa_s, data->rx_from_unknown.addr,
    3293             :                                        data->rx_from_unknown.wds);
    3294           0 :                 break;
    3295             :         case EVENT_CH_SWITCH:
    3296          15 :                 if (!data)
    3297           0 :                         break;
    3298          15 :                 if (!wpa_s->ap_iface) {
    3299          14 :                         wpa_dbg(wpa_s, MSG_DEBUG, "AP: Ignore channel switch "
    3300             :                                 "event in non-AP mode");
    3301          14 :                         break;
    3302             :                 }
    3303             : 
    3304           2 :                 wpas_ap_ch_switch(wpa_s, data->ch_switch.freq,
    3305             :                                   data->ch_switch.ht_enabled,
    3306             :                                   data->ch_switch.ch_offset,
    3307           1 :                                   data->ch_switch.ch_width,
    3308             :                                   data->ch_switch.cf1,
    3309             :                                   data->ch_switch.cf2);
    3310           1 :                 break;
    3311             : #ifdef NEED_AP_MLME
    3312             :         case EVENT_DFS_RADAR_DETECTED:
    3313          21 :                 if (data)
    3314          21 :                         wpas_event_dfs_radar_detected(wpa_s, &data->dfs_event);
    3315          21 :                 break;
    3316             :         case EVENT_DFS_CAC_STARTED:
    3317           0 :                 if (data)
    3318           0 :                         wpas_event_dfs_cac_started(wpa_s, &data->dfs_event);
    3319           0 :                 break;
    3320             :         case EVENT_DFS_CAC_FINISHED:
    3321           1 :                 if (data)
    3322           1 :                         wpas_event_dfs_cac_finished(wpa_s, &data->dfs_event);
    3323           1 :                 break;
    3324             :         case EVENT_DFS_CAC_ABORTED:
    3325           0 :                 if (data)
    3326           0 :                         wpas_event_dfs_cac_aborted(wpa_s, &data->dfs_event);
    3327           0 :                 break;
    3328             :         case EVENT_DFS_NOP_FINISHED:
    3329           0 :                 if (data)
    3330           0 :                         wpas_event_dfs_cac_nop_finished(wpa_s,
    3331             :                                                         &data->dfs_event);
    3332           0 :                 break;
    3333             : #endif /* NEED_AP_MLME */
    3334             : #endif /* CONFIG_AP */
    3335             :         case EVENT_RX_MGMT: {
    3336             :                 u16 fc, stype;
    3337             :                 const struct ieee80211_mgmt *mgmt;
    3338             : 
    3339             : #ifdef CONFIG_TESTING_OPTIONS
    3340        4707 :                 if (wpa_s->ext_mgmt_frame_handling) {
    3341          56 :                         struct rx_mgmt *rx = &data->rx_mgmt;
    3342          56 :                         size_t hex_len = 2 * rx->frame_len + 1;
    3343          56 :                         char *hex = os_malloc(hex_len);
    3344          56 :                         if (hex) {
    3345          56 :                                 wpa_snprintf_hex(hex, hex_len,
    3346             :                                                  rx->frame, rx->frame_len);
    3347          56 :                                 wpa_msg(wpa_s, MSG_INFO, "MGMT-RX freq=%d datarate=%u ssi_signal=%d %s",
    3348             :                                         rx->freq, rx->datarate, rx->ssi_signal,
    3349             :                                         hex);
    3350          56 :                                 os_free(hex);
    3351             :                         }
    3352          56 :                         break;
    3353             :                 }
    3354             : #endif /* CONFIG_TESTING_OPTIONS */
    3355             : 
    3356        4651 :                 mgmt = (const struct ieee80211_mgmt *)
    3357             :                         data->rx_mgmt.frame;
    3358        4651 :                 fc = le_to_host16(mgmt->frame_control);
    3359        4651 :                 stype = WLAN_FC_GET_STYPE(fc);
    3360             : 
    3361             : #ifdef CONFIG_AP
    3362        4651 :                 if (wpa_s->ap_iface == NULL) {
    3363             : #endif /* CONFIG_AP */
    3364             : #ifdef CONFIG_P2P
    3365        3478 :                         if (stype == WLAN_FC_STYPE_PROBE_REQ &&
    3366         725 :                             data->rx_mgmt.frame_len > 24) {
    3367         725 :                                 const u8 *src = mgmt->sa;
    3368         725 :                                 const u8 *ie = mgmt->u.probe_req.variable;
    3369        1450 :                                 size_t ie_len = data->rx_mgmt.frame_len -
    3370         725 :                                         (mgmt->u.probe_req.variable -
    3371         725 :                                          data->rx_mgmt.frame);
    3372        1450 :                                 wpas_p2p_probe_req_rx(
    3373         725 :                                         wpa_s, src, mgmt->da,
    3374         725 :                                         mgmt->bssid, ie, ie_len,
    3375             :                                         data->rx_mgmt.ssi_signal);
    3376         725 :                                 break;
    3377             :                         }
    3378             : #endif /* CONFIG_P2P */
    3379             : #ifdef CONFIG_IBSS_RSN
    3380        2872 :                         if (wpa_s->current_ssid &&
    3381         864 :                             wpa_s->current_ssid->mode == WPAS_MODE_IBSS &&
    3382          20 :                             stype == WLAN_FC_STYPE_AUTH &&
    3383          20 :                             data->rx_mgmt.frame_len >= 30) {
    3384          20 :                                 wpa_supplicant_event_ibss_auth(wpa_s, data);
    3385          20 :                                 break;
    3386             :                         }
    3387             : #endif /* CONFIG_IBSS_RSN */
    3388             : 
    3389        2008 :                         if (stype == WLAN_FC_STYPE_ACTION) {
    3390        1538 :                                 wpas_event_rx_mgmt_action(
    3391             :                                         wpa_s, data->rx_mgmt.frame,
    3392             :                                         data->rx_mgmt.frame_len,
    3393             :                                         data->rx_mgmt.freq,
    3394             :                                         data->rx_mgmt.ssi_signal);
    3395        1538 :                                 break;
    3396             :                         }
    3397             : 
    3398         470 :                         if (wpa_s->ifmsh) {
    3399         461 :                                 mesh_mpm_mgmt_rx(wpa_s, &data->rx_mgmt);
    3400         461 :                                 break;
    3401             :                         }
    3402             : 
    3403           9 :                         wpa_dbg(wpa_s, MSG_DEBUG, "AP: ignore received "
    3404             :                                 "management frame in non-AP mode");
    3405           9 :                         break;
    3406             : #ifdef CONFIG_AP
    3407             :                 }
    3408             : 
    3409        2298 :                 if (stype == WLAN_FC_STYPE_PROBE_REQ &&
    3410         400 :                     data->rx_mgmt.frame_len > 24) {
    3411         400 :                         const u8 *ie = mgmt->u.probe_req.variable;
    3412         800 :                         size_t ie_len = data->rx_mgmt.frame_len -
    3413         400 :                                 (mgmt->u.probe_req.variable -
    3414         400 :                                  data->rx_mgmt.frame);
    3415             : 
    3416         800 :                         wpas_notify_preq(wpa_s, mgmt->sa, mgmt->da,
    3417         400 :                                          mgmt->bssid, ie, ie_len,
    3418         400 :                                          data->rx_mgmt.ssi_signal);
    3419             :                 }
    3420             : 
    3421        1898 :                 ap_mgmt_rx(wpa_s, &data->rx_mgmt);
    3422             : #endif /* CONFIG_AP */
    3423        1898 :                 break;
    3424             :                 }
    3425             :         case EVENT_RX_PROBE_REQ:
    3426           0 :                 if (data->rx_probe_req.sa == NULL ||
    3427           0 :                     data->rx_probe_req.ie == NULL)
    3428             :                         break;
    3429             : #ifdef CONFIG_AP
    3430           0 :                 if (wpa_s->ap_iface) {
    3431           0 :                         hostapd_probe_req_rx(wpa_s->ap_iface->bss[0],
    3432             :                                              data->rx_probe_req.sa,
    3433             :                                              data->rx_probe_req.da,
    3434             :                                              data->rx_probe_req.bssid,
    3435             :                                              data->rx_probe_req.ie,
    3436             :                                              data->rx_probe_req.ie_len,
    3437             :                                              data->rx_probe_req.ssi_signal);
    3438           0 :                         break;
    3439             :                 }
    3440             : #endif /* CONFIG_AP */
    3441           0 :                 wpas_p2p_probe_req_rx(wpa_s, data->rx_probe_req.sa,
    3442             :                                       data->rx_probe_req.da,
    3443             :                                       data->rx_probe_req.bssid,
    3444             :                                       data->rx_probe_req.ie,
    3445             :                                       data->rx_probe_req.ie_len,
    3446             :                                       data->rx_probe_req.ssi_signal);
    3447           0 :                 break;
    3448             :         case EVENT_REMAIN_ON_CHANNEL:
    3449             : #ifdef CONFIG_OFFCHANNEL
    3450        1595 :                 offchannel_remain_on_channel_cb(
    3451             :                         wpa_s, data->remain_on_channel.freq,
    3452             :                         data->remain_on_channel.duration);
    3453             : #endif /* CONFIG_OFFCHANNEL */
    3454        1595 :                 wpas_p2p_remain_on_channel_cb(
    3455             :                         wpa_s, data->remain_on_channel.freq,
    3456             :                         data->remain_on_channel.duration);
    3457        1595 :                 break;
    3458             :         case EVENT_CANCEL_REMAIN_ON_CHANNEL:
    3459             : #ifdef CONFIG_OFFCHANNEL
    3460        1508 :                 offchannel_cancel_remain_on_channel_cb(
    3461             :                         wpa_s, data->remain_on_channel.freq);
    3462             : #endif /* CONFIG_OFFCHANNEL */
    3463        1508 :                 wpas_p2p_cancel_remain_on_channel_cb(
    3464             :                         wpa_s, data->remain_on_channel.freq);
    3465        1508 :                 break;
    3466             :         case EVENT_EAPOL_RX:
    3467           0 :                 wpa_supplicant_rx_eapol(wpa_s, data->eapol_rx.src,
    3468             :                                         data->eapol_rx.data,
    3469             :                                         data->eapol_rx.data_len);
    3470           0 :                 break;
    3471             :         case EVENT_SIGNAL_CHANGE:
    3472           5 :                 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SIGNAL_CHANGE
    3473             :                         "above=%d signal=%d noise=%d txrate=%d",
    3474             :                         data->signal_change.above_threshold,
    3475             :                         data->signal_change.current_signal,
    3476             :                         data->signal_change.current_noise,
    3477             :                         data->signal_change.current_txrate);
    3478           5 :                 wpa_bss_update_level(wpa_s->current_bss,
    3479             :                                      data->signal_change.current_signal);
    3480           5 :                 bgscan_notify_signal_change(
    3481             :                         wpa_s, data->signal_change.above_threshold,
    3482             :                         data->signal_change.current_signal,
    3483             :                         data->signal_change.current_noise,
    3484             :                         data->signal_change.current_txrate);
    3485           5 :                 break;
    3486             :         case EVENT_INTERFACE_ENABLED:
    3487          13 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Interface was enabled");
    3488          13 :                 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
    3489          11 :                         wpa_supplicant_update_mac_addr(wpa_s);
    3490          11 :                         if (wpa_s->p2p_mgmt) {
    3491           0 :                                 wpa_supplicant_set_state(wpa_s,
    3492             :                                                          WPA_DISCONNECTED);
    3493           0 :                                 break;
    3494             :                         }
    3495             : 
    3496             : #ifdef CONFIG_AP
    3497          11 :                         if (!wpa_s->ap_iface) {
    3498          11 :                                 wpa_supplicant_set_state(wpa_s,
    3499             :                                                          WPA_DISCONNECTED);
    3500          11 :                                 wpa_s->scan_req = NORMAL_SCAN_REQ;
    3501          11 :                                 wpa_supplicant_req_scan(wpa_s, 0, 0);
    3502             :                         } else
    3503           0 :                                 wpa_supplicant_set_state(wpa_s,
    3504             :                                                          WPA_COMPLETED);
    3505             : #else /* CONFIG_AP */
    3506             :                         wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
    3507             :                         wpa_supplicant_req_scan(wpa_s, 0, 0);
    3508             : #endif /* CONFIG_AP */
    3509             :                 }
    3510          13 :                 break;
    3511             :         case EVENT_INTERFACE_DISABLED:
    3512          29 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Interface was disabled");
    3513             : #ifdef CONFIG_P2P
    3514          56 :                 if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO ||
    3515          39 :                     (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group &&
    3516           2 :                      wpa_s->current_ssid->mode == WPAS_MODE_P2P_GO)) {
    3517             :                         /*
    3518             :                          * Mark interface disabled if this happens to end up not
    3519             :                          * being removed as a separate P2P group interface.
    3520             :                          */
    3521           2 :                         wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
    3522             :                         /*
    3523             :                          * The interface was externally disabled. Remove
    3524             :                          * it assuming an external entity will start a
    3525             :                          * new session if needed.
    3526             :                          */
    3527           4 :                         if (wpa_s->current_ssid &&
    3528           2 :                             wpa_s->current_ssid->p2p_group)
    3529           2 :                                 wpas_p2p_interface_unavailable(wpa_s);
    3530             :                         else
    3531           0 :                                 wpas_p2p_disconnect(wpa_s);
    3532             :                         /*
    3533             :                          * wpa_s instance may have been freed, so must not use
    3534             :                          * it here anymore.
    3535             :                          */
    3536           2 :                         break;
    3537             :                 }
    3538          28 :                 if (wpa_s->p2p_scan_work && wpa_s->global->p2p &&
    3539           1 :                     p2p_in_progress(wpa_s->global->p2p) > 1) {
    3540             :                         /* This radio work will be cancelled, so clear P2P
    3541             :                          * state as well.
    3542             :                          */
    3543           1 :                         p2p_stop_find(wpa_s->global->p2p);
    3544             :                 }
    3545             : #endif /* CONFIG_P2P */
    3546             : 
    3547          27 :                 if (wpa_s->wpa_state >= WPA_AUTHENTICATING) {
    3548             :                         /*
    3549             :                          * Indicate disconnection to keep ctrl_iface events
    3550             :                          * consistent.
    3551             :                          */
    3552          10 :                         wpa_supplicant_event_disassoc(
    3553             :                                 wpa_s, WLAN_REASON_DEAUTH_LEAVING, 1);
    3554             :                 }
    3555          27 :                 wpa_supplicant_mark_disassoc(wpa_s);
    3556          27 :                 radio_remove_works(wpa_s, NULL, 0);
    3557             : 
    3558          27 :                 wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED);
    3559          27 :                 break;
    3560             :         case EVENT_CHANNEL_LIST_CHANGED:
    3561        7305 :                 wpa_supplicant_update_channel_list(
    3562             :                         wpa_s, &data->channel_list_changed);
    3563        7305 :                 break;
    3564             :         case EVENT_INTERFACE_UNAVAILABLE:
    3565           3 :                 wpas_p2p_interface_unavailable(wpa_s);
    3566           3 :                 break;
    3567             :         case EVENT_BEST_CHANNEL:
    3568           0 :                 wpa_dbg(wpa_s, MSG_DEBUG, "Best channel event received "
    3569             :                         "(%d %d %d)",
    3570             :                         data->best_chan.freq_24, data->best_chan.freq_5,
    3571             :                         data->best_chan.freq_overall);
    3572           0 :                 wpa_s->best_24_freq = data->best_chan.freq_24;
    3573           0 :                 wpa_s->best_5_freq = data->best_chan.freq_5;
    3574           0 :                 wpa_s->best_overall_freq = data->best_chan.freq_overall;
    3575           0 :                 wpas_p2p_update_best_channels(wpa_s, data->best_chan.freq_24,
    3576             :                                               data->best_chan.freq_5,
    3577             :                                               data->best_chan.freq_overall);
    3578           0 :                 break;
    3579             :         case EVENT_UNPROT_DEAUTH:
    3580          19 :                 wpa_supplicant_event_unprot_deauth(wpa_s,
    3581             :                                                    &data->unprot_deauth);
    3582          19 :                 break;
    3583             :         case EVENT_UNPROT_DISASSOC:
    3584          19 :                 wpa_supplicant_event_unprot_disassoc(wpa_s,
    3585             :                                                      &data->unprot_disassoc);
    3586          19 :                 break;
    3587             :         case EVENT_STATION_LOW_ACK:
    3588             : #ifdef CONFIG_AP
    3589           0 :                 if (wpa_s->ap_iface && data)
    3590           0 :                         hostapd_event_sta_low_ack(wpa_s->ap_iface->bss[0],
    3591           0 :                                                   data->low_ack.addr);
    3592             : #endif /* CONFIG_AP */
    3593             : #ifdef CONFIG_TDLS
    3594           0 :                 if (data)
    3595           0 :                         wpa_tdls_disable_unreachable_link(wpa_s->wpa,
    3596           0 :                                                           data->low_ack.addr);
    3597             : #endif /* CONFIG_TDLS */
    3598           0 :                 break;
    3599             :         case EVENT_IBSS_PEER_LOST:
    3600             : #ifdef CONFIG_IBSS_RSN
    3601           2 :                 ibss_rsn_stop(wpa_s->ibss_rsn, data->ibss_peer_lost.peer);
    3602             : #endif /* CONFIG_IBSS_RSN */
    3603           2 :                 break;
    3604             :         case EVENT_DRIVER_GTK_REKEY:
    3605           0 :                 if (os_memcmp(data->driver_gtk_rekey.bssid,
    3606             :                               wpa_s->bssid, ETH_ALEN))
    3607           0 :                         break;
    3608           0 :                 if (!wpa_s->wpa)
    3609           0 :                         break;
    3610           0 :                 wpa_sm_update_replay_ctr(wpa_s->wpa,
    3611             :                                          data->driver_gtk_rekey.replay_ctr);
    3612           0 :                 break;
    3613             :         case EVENT_SCHED_SCAN_STOPPED:
    3614           0 :                 wpa_s->pno = 0;
    3615           0 :                 wpa_s->sched_scanning = 0;
    3616           0 :                 wpa_supplicant_notify_scanning(wpa_s, 0);
    3617             : 
    3618           0 :                 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
    3619           0 :                         break;
    3620             : 
    3621             :                 /*
    3622             :                  * Start a new sched scan to continue searching for more SSIDs
    3623             :                  * either if timed out or PNO schedule scan is pending.
    3624             :                  */
    3625           0 :                 if (wpa_s->sched_scan_timed_out) {
    3626           0 :                         wpa_supplicant_req_sched_scan(wpa_s);
    3627           0 :                 } else if (wpa_s->pno_sched_pending) {
    3628           0 :                         wpa_s->pno_sched_pending = 0;
    3629           0 :                         wpas_start_pno(wpa_s);
    3630             :                 }
    3631             : 
    3632           0 :                 break;
    3633             :         case EVENT_WPS_BUTTON_PUSHED:
    3634             : #ifdef CONFIG_WPS
    3635           0 :                 wpas_wps_start_pbc(wpa_s, NULL, 0);
    3636             : #endif /* CONFIG_WPS */
    3637           0 :                 break;
    3638             :         case EVENT_AVOID_FREQUENCIES:
    3639           4 :                 wpa_supplicant_notify_avoid_freq(wpa_s, data);
    3640           4 :                 break;
    3641             :         case EVENT_CONNECT_FAILED_REASON:
    3642             : #ifdef CONFIG_AP
    3643           0 :                 if (!wpa_s->ap_iface || !data)
    3644             :                         break;
    3645           0 :                 hostapd_event_connect_failed_reason(
    3646           0 :                         wpa_s->ap_iface->bss[0],
    3647           0 :                         data->connect_failed_reason.addr,
    3648           0 :                         data->connect_failed_reason.code);
    3649             : #endif /* CONFIG_AP */
    3650           0 :                 break;
    3651             :         case EVENT_NEW_PEER_CANDIDATE:
    3652             : #ifdef CONFIG_MESH
    3653          54 :                 if (!wpa_s->ifmsh || !data)
    3654             :                         break;
    3655          54 :                 wpa_mesh_notify_peer(wpa_s, data->mesh_peer.peer,
    3656             :                                      data->mesh_peer.ies,
    3657             :                                      data->mesh_peer.ie_len);
    3658             : #endif /* CONFIG_MESH */
    3659          54 :                 break;
    3660             :         default:
    3661           0 :                 wpa_msg(wpa_s, MSG_INFO, "Unknown event %d", event);
    3662           0 :                 break;
    3663             :         }
    3664             : }

Generated by: LCOV version 1.10