1 1.1 christos /* 2 1.1 christos * WPA Supplicant - Driver event processing 3 1.9 christos * Copyright (c) 2003-2019, Jouni Malinen <j (at) w1.fi> 4 1.1 christos * 5 1.2 joerg * This software may be distributed under the terms of the BSD license. 6 1.2 joerg * See README for more details. 7 1.1 christos */ 8 1.1 christos 9 1.1 christos #include "includes.h" 10 1.1 christos 11 1.1 christos #include "common.h" 12 1.1 christos #include "eapol_supp/eapol_supp_sm.h" 13 1.1 christos #include "rsn_supp/wpa.h" 14 1.1 christos #include "eloop.h" 15 1.1 christos #include "config.h" 16 1.1 christos #include "l2_packet/l2_packet.h" 17 1.1 christos #include "wpa_supplicant_i.h" 18 1.1 christos #include "driver_i.h" 19 1.1 christos #include "pcsc_funcs.h" 20 1.1 christos #include "rsn_supp/preauth.h" 21 1.1 christos #include "rsn_supp/pmksa_cache.h" 22 1.1 christos #include "common/wpa_ctrl.h" 23 1.1 christos #include "eap_peer/eap.h" 24 1.1 christos #include "ap/hostapd.h" 25 1.10 christos #include "ap/sta_info.h" 26 1.2 joerg #include "p2p/p2p.h" 27 1.6 christos #include "fst/fst.h" 28 1.2 joerg #include "wnm_sta.h" 29 1.1 christos #include "notify.h" 30 1.1 christos #include "common/ieee802_11_defs.h" 31 1.2 joerg #include "common/ieee802_11_common.h" 32 1.7 christos #include "common/gas_server.h" 33 1.9 christos #include "common/dpp.h" 34 1.10 christos #include "common/ptksa_cache.h" 35 1.2 joerg #include "crypto/random.h" 36 1.10 christos #include "bssid_ignore.h" 37 1.1 christos #include "wpas_glue.h" 38 1.1 christos #include "wps_supplicant.h" 39 1.1 christos #include "ibss_rsn.h" 40 1.1 christos #include "sme.h" 41 1.2 joerg #include "gas_query.h" 42 1.2 joerg #include "p2p_supplicant.h" 43 1.1 christos #include "bgscan.h" 44 1.2 joerg #include "autoscan.h" 45 1.1 christos #include "ap.h" 46 1.1 christos #include "bss.h" 47 1.1 christos #include "scan.h" 48 1.2 joerg #include "offchannel.h" 49 1.2 joerg #include "interworking.h" 50 1.3 christos #include "mesh.h" 51 1.3 christos #include "mesh_mpm.h" 52 1.3 christos #include "wmm_ac.h" 53 1.10 christos #include "nan_usd.h" 54 1.7 christos #include "dpp_supplicant.h" 55 1.7 christos 56 1.7 christos 57 1.7 christos #define MAX_OWE_TRANSITION_BSS_SELECT_COUNT 5 58 1.2 joerg 59 1.2 joerg 60 1.2 joerg #ifndef CONFIG_NO_SCAN_PROCESSING 61 1.2 joerg static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s, 62 1.10 christos int new_scan, int own_request, 63 1.10 christos bool trigger_6ghz_scan, 64 1.10 christos union wpa_event_data *data); 65 1.2 joerg #endif /* CONFIG_NO_SCAN_PROCESSING */ 66 1.2 joerg 67 1.2 joerg 68 1.7 christos int wpas_temp_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) 69 1.2 joerg { 70 1.2 joerg struct os_reltime now; 71 1.2 joerg 72 1.2 joerg if (ssid == NULL || ssid->disabled_until.sec == 0) 73 1.2 joerg return 0; 74 1.2 joerg 75 1.2 joerg os_get_reltime(&now); 76 1.2 joerg if (ssid->disabled_until.sec > now.sec) 77 1.2 joerg return ssid->disabled_until.sec - now.sec; 78 1.2 joerg 79 1.2 joerg wpas_clear_temp_disabled(wpa_s, ssid, 0); 80 1.2 joerg 81 1.2 joerg return 0; 82 1.2 joerg } 83 1.2 joerg 84 1.2 joerg 85 1.6 christos #ifndef CONFIG_NO_SCAN_PROCESSING 86 1.6 christos /** 87 1.6 christos * wpas_reenabled_network_time - Time until first network is re-enabled 88 1.6 christos * @wpa_s: Pointer to wpa_supplicant data 89 1.6 christos * Returns: If all enabled networks are temporarily disabled, returns the time 90 1.6 christos * (in sec) until the first network is re-enabled. Otherwise returns 0. 91 1.6 christos * 92 1.6 christos * This function is used in case all enabled networks are temporarily disabled, 93 1.6 christos * in which case it returns the time (in sec) that the first network will be 94 1.6 christos * re-enabled. The function assumes that at least one network is enabled. 95 1.6 christos */ 96 1.6 christos static int wpas_reenabled_network_time(struct wpa_supplicant *wpa_s) 97 1.6 christos { 98 1.6 christos struct wpa_ssid *ssid; 99 1.6 christos int disabled_for, res = 0; 100 1.6 christos 101 1.6 christos #ifdef CONFIG_INTERWORKING 102 1.6 christos if (wpa_s->conf->auto_interworking && wpa_s->conf->interworking && 103 1.6 christos wpa_s->conf->cred) 104 1.6 christos return 0; 105 1.6 christos #endif /* CONFIG_INTERWORKING */ 106 1.6 christos 107 1.6 christos for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { 108 1.6 christos if (ssid->disabled) 109 1.6 christos continue; 110 1.6 christos 111 1.6 christos disabled_for = wpas_temp_disabled(wpa_s, ssid); 112 1.6 christos if (!disabled_for) 113 1.6 christos return 0; 114 1.6 christos 115 1.6 christos if (!res || disabled_for < res) 116 1.6 christos res = disabled_for; 117 1.6 christos } 118 1.6 christos 119 1.6 christos return res; 120 1.6 christos } 121 1.6 christos #endif /* CONFIG_NO_SCAN_PROCESSING */ 122 1.6 christos 123 1.6 christos 124 1.6 christos void wpas_network_reenabled(void *eloop_ctx, void *timeout_ctx) 125 1.6 christos { 126 1.6 christos struct wpa_supplicant *wpa_s = eloop_ctx; 127 1.6 christos 128 1.6 christos if (wpa_s->disconnected || wpa_s->wpa_state != WPA_SCANNING) 129 1.6 christos return; 130 1.6 christos 131 1.6 christos wpa_dbg(wpa_s, MSG_DEBUG, 132 1.6 christos "Try to associate due to network getting re-enabled"); 133 1.6 christos if (wpa_supplicant_fast_associate(wpa_s) != 1) { 134 1.6 christos wpa_supplicant_cancel_sched_scan(wpa_s); 135 1.6 christos wpa_supplicant_req_scan(wpa_s, 0, 0); 136 1.6 christos } 137 1.6 christos } 138 1.6 christos 139 1.6 christos 140 1.10 christos static struct wpa_bss * __wpa_supplicant_get_new_bss( 141 1.10 christos struct wpa_supplicant *wpa_s, const u8 *bssid, const u8 *ssid, 142 1.10 christos size_t ssid_len) 143 1.10 christos { 144 1.10 christos if (ssid && ssid_len > 0) 145 1.10 christos return wpa_bss_get(wpa_s, bssid, ssid, ssid_len); 146 1.10 christos else 147 1.10 christos return wpa_bss_get_bssid(wpa_s, bssid); 148 1.10 christos } 149 1.10 christos 150 1.10 christos 151 1.10 christos static struct wpa_bss * _wpa_supplicant_get_new_bss( 152 1.10 christos struct wpa_supplicant *wpa_s, const u8 *bssid, const u8 *ssid, 153 1.10 christos size_t ssid_len, bool try_update_scan_results) 154 1.10 christos { 155 1.10 christos struct wpa_bss *bss = __wpa_supplicant_get_new_bss(wpa_s, bssid, ssid, 156 1.10 christos ssid_len); 157 1.10 christos 158 1.10 christos if (bss || !try_update_scan_results) 159 1.10 christos return bss; 160 1.10 christos 161 1.10 christos wpa_supplicant_update_scan_results(wpa_s, bssid); 162 1.10 christos 163 1.10 christos return __wpa_supplicant_get_new_bss(wpa_s, bssid, ssid, ssid_len); 164 1.10 christos } 165 1.10 christos 166 1.10 christos 167 1.2 joerg static struct wpa_bss * wpa_supplicant_get_new_bss( 168 1.2 joerg struct wpa_supplicant *wpa_s, const u8 *bssid) 169 1.2 joerg { 170 1.2 joerg struct wpa_bss *bss = NULL; 171 1.2 joerg struct wpa_ssid *ssid = wpa_s->current_ssid; 172 1.10 christos u8 drv_ssid[SSID_MAX_LEN]; 173 1.10 christos int res; 174 1.10 christos bool try_update_scan_results = true; 175 1.2 joerg 176 1.10 christos res = wpa_drv_get_ssid(wpa_s, drv_ssid); 177 1.10 christos if (res > 0) { 178 1.10 christos bss = _wpa_supplicant_get_new_bss(wpa_s, bssid, drv_ssid, res, 179 1.10 christos try_update_scan_results); 180 1.10 christos try_update_scan_results = false; 181 1.10 christos } 182 1.10 christos if (!bss && ssid && ssid->ssid_len > 0) { 183 1.10 christos bss = _wpa_supplicant_get_new_bss(wpa_s, bssid, ssid->ssid, 184 1.10 christos ssid->ssid_len, 185 1.10 christos try_update_scan_results); 186 1.10 christos try_update_scan_results = false; 187 1.10 christos } 188 1.2 joerg if (!bss) 189 1.10 christos bss = _wpa_supplicant_get_new_bss(wpa_s, bssid, NULL, 0, 190 1.10 christos try_update_scan_results); 191 1.2 joerg 192 1.2 joerg return bss; 193 1.2 joerg } 194 1.2 joerg 195 1.2 joerg 196 1.10 christos static struct wpa_bss * 197 1.10 christos wpa_supplicant_update_current_bss(struct wpa_supplicant *wpa_s, const u8 *bssid) 198 1.2 joerg { 199 1.10 christos struct wpa_bss *bss = wpa_supplicant_get_new_bss(wpa_s, bssid); 200 1.10 christos 201 1.10 christos if (bss) 202 1.10 christos wpa_s->current_bss = bss; 203 1.10 christos 204 1.10 christos return bss; 205 1.10 christos } 206 1.2 joerg 207 1.2 joerg 208 1.10 christos static void wpa_supplicant_update_link_bss(struct wpa_supplicant *wpa_s, 209 1.10 christos u8 link_id, const u8 *bssid) 210 1.10 christos { 211 1.10 christos struct wpa_bss *bss = wpa_supplicant_get_new_bss(wpa_s, bssid); 212 1.2 joerg 213 1.2 joerg if (bss) 214 1.10 christos wpa_s->links[link_id].bss = bss; 215 1.2 joerg } 216 1.1 christos 217 1.1 christos 218 1.10 christos static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s, 219 1.10 christos union wpa_event_data *data) 220 1.1 christos { 221 1.1 christos struct wpa_ssid *ssid, *old_ssid; 222 1.10 christos struct wpa_bss *bss; 223 1.6 christos u8 drv_ssid[SSID_MAX_LEN]; 224 1.6 christos size_t drv_ssid_len; 225 1.2 joerg int res; 226 1.1 christos 227 1.2 joerg if (wpa_s->conf->ap_scan == 1 && wpa_s->current_ssid) { 228 1.10 christos wpa_supplicant_update_current_bss(wpa_s, wpa_s->bssid); 229 1.6 christos 230 1.6 christos if (wpa_s->current_ssid->ssid_len == 0) 231 1.6 christos return 0; /* current profile still in use */ 232 1.6 christos res = wpa_drv_get_ssid(wpa_s, drv_ssid); 233 1.6 christos if (res < 0) { 234 1.6 christos wpa_msg(wpa_s, MSG_INFO, 235 1.6 christos "Failed to read SSID from driver"); 236 1.6 christos return 0; /* try to use current profile */ 237 1.6 christos } 238 1.6 christos drv_ssid_len = res; 239 1.6 christos 240 1.6 christos if (drv_ssid_len == wpa_s->current_ssid->ssid_len && 241 1.6 christos os_memcmp(drv_ssid, wpa_s->current_ssid->ssid, 242 1.6 christos drv_ssid_len) == 0) 243 1.6 christos return 0; /* current profile still in use */ 244 1.6 christos 245 1.10 christos #ifdef CONFIG_OWE 246 1.10 christos if ((wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_OWE) && 247 1.10 christos wpa_s->current_bss && 248 1.10 christos (wpa_s->current_bss->flags & WPA_BSS_OWE_TRANSITION) && 249 1.10 christos drv_ssid_len == wpa_s->current_bss->ssid_len && 250 1.10 christos os_memcmp(drv_ssid, wpa_s->current_bss->ssid, 251 1.10 christos drv_ssid_len) == 0) 252 1.10 christos return 0; /* current profile still in use */ 253 1.10 christos #endif /* CONFIG_OWE */ 254 1.10 christos 255 1.6 christos wpa_msg(wpa_s, MSG_DEBUG, 256 1.6 christos "Driver-initiated BSS selection changed the SSID to %s", 257 1.6 christos wpa_ssid_txt(drv_ssid, drv_ssid_len)); 258 1.6 christos /* continue selecting a new network profile */ 259 1.2 joerg } 260 1.1 christos 261 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Select network based on association " 262 1.2 joerg "information"); 263 1.1 christos ssid = wpa_supplicant_get_ssid(wpa_s); 264 1.1 christos if (ssid == NULL) { 265 1.2 joerg wpa_msg(wpa_s, MSG_INFO, 266 1.2 joerg "No network configuration found for the current AP"); 267 1.1 christos return -1; 268 1.1 christos } 269 1.1 christos 270 1.2 joerg if (wpas_network_disabled(wpa_s, ssid)) { 271 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Selected network is disabled"); 272 1.1 christos return -1; 273 1.1 christos } 274 1.1 christos 275 1.2 joerg if (disallowed_bssid(wpa_s, wpa_s->bssid) || 276 1.2 joerg disallowed_ssid(wpa_s, ssid->ssid, ssid->ssid_len)) { 277 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Selected BSS is disallowed"); 278 1.2 joerg return -1; 279 1.2 joerg } 280 1.2 joerg 281 1.2 joerg res = wpas_temp_disabled(wpa_s, ssid); 282 1.2 joerg if (res > 0) { 283 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Selected network is temporarily " 284 1.2 joerg "disabled for %d second(s)", res); 285 1.2 joerg return -1; 286 1.2 joerg } 287 1.2 joerg 288 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Network configuration found for the " 289 1.2 joerg "current AP"); 290 1.10 christos bss = wpa_supplicant_update_current_bss(wpa_s, wpa_s->bssid); 291 1.2 joerg if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) { 292 1.1 christos u8 wpa_ie[80]; 293 1.1 christos size_t wpa_ie_len = sizeof(wpa_ie); 294 1.10 christos bool skip_default_rsne; 295 1.10 christos 296 1.10 christos /* Do not override RSNE/RSNXE with the default values if the 297 1.10 christos * driver indicated the actual values used in the 298 1.10 christos * (Re)Association Request frame. */ 299 1.10 christos skip_default_rsne = data && data->assoc_info.req_ies; 300 1.10 christos if (wpa_supplicant_set_suites(wpa_s, bss, ssid, 301 1.10 christos wpa_ie, &wpa_ie_len, 302 1.10 christos skip_default_rsne) < 0) 303 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Could not set WPA suites"); 304 1.1 christos } else { 305 1.1 christos wpa_supplicant_set_non_wpa_policy(wpa_s, ssid); 306 1.1 christos } 307 1.1 christos 308 1.1 christos if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) 309 1.1 christos eapol_sm_invalidate_cached_session(wpa_s->eapol); 310 1.1 christos old_ssid = wpa_s->current_ssid; 311 1.1 christos wpa_s->current_ssid = ssid; 312 1.2 joerg 313 1.1 christos wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid); 314 1.1 christos wpa_supplicant_initiate_eapol(wpa_s); 315 1.1 christos if (old_ssid != wpa_s->current_ssid) 316 1.1 christos wpas_notify_network_changed(wpa_s); 317 1.1 christos 318 1.1 christos return 0; 319 1.1 christos } 320 1.1 christos 321 1.1 christos 322 1.2 joerg void wpa_supplicant_stop_countermeasures(void *eloop_ctx, void *sock_ctx) 323 1.1 christos { 324 1.1 christos struct wpa_supplicant *wpa_s = eloop_ctx; 325 1.1 christos 326 1.1 christos if (wpa_s->countermeasures) { 327 1.1 christos wpa_s->countermeasures = 0; 328 1.1 christos wpa_drv_set_countermeasures(wpa_s, 0); 329 1.1 christos wpa_msg(wpa_s, MSG_INFO, "WPA: TKIP countermeasures stopped"); 330 1.3 christos 331 1.3 christos /* 332 1.3 christos * It is possible that the device is sched scanning, which means 333 1.3 christos * that a connection attempt will be done only when we receive 334 1.3 christos * scan results. However, in this case, it would be preferable 335 1.3 christos * to scan and connect immediately, so cancel the sched_scan and 336 1.3 christos * issue a regular scan flow. 337 1.3 christos */ 338 1.3 christos wpa_supplicant_cancel_sched_scan(wpa_s); 339 1.1 christos wpa_supplicant_req_scan(wpa_s, 0, 0); 340 1.1 christos } 341 1.1 christos } 342 1.1 christos 343 1.1 christos 344 1.10 christos void wpas_reset_mlo_info(struct wpa_supplicant *wpa_s) 345 1.10 christos { 346 1.10 christos if (!wpa_s->valid_links) 347 1.10 christos return; 348 1.10 christos 349 1.10 christos wpa_s->valid_links = 0; 350 1.10 christos wpa_s->mlo_assoc_link_id = 0; 351 1.10 christos os_memset(wpa_s->ap_mld_addr, 0, ETH_ALEN); 352 1.10 christos os_memset(wpa_s->links, 0, sizeof(wpa_s->links)); 353 1.10 christos } 354 1.10 christos 355 1.10 christos 356 1.1 christos void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s) 357 1.1 christos { 358 1.1 christos int bssid_changed; 359 1.1 christos 360 1.2 joerg wnm_bss_keep_alive_deinit(wpa_s); 361 1.2 joerg 362 1.2 joerg #ifdef CONFIG_IBSS_RSN 363 1.2 joerg ibss_rsn_deinit(wpa_s->ibss_rsn); 364 1.2 joerg wpa_s->ibss_rsn = NULL; 365 1.2 joerg #endif /* CONFIG_IBSS_RSN */ 366 1.2 joerg 367 1.2 joerg #ifdef CONFIG_AP 368 1.2 joerg wpa_supplicant_ap_deinit(wpa_s); 369 1.2 joerg #endif /* CONFIG_AP */ 370 1.2 joerg 371 1.6 christos #ifdef CONFIG_HS20 372 1.6 christos /* Clear possibly configured frame filters */ 373 1.6 christos wpa_drv_configure_frame_filters(wpa_s, 0); 374 1.6 christos #endif /* CONFIG_HS20 */ 375 1.6 christos 376 1.2 joerg if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) 377 1.2 joerg return; 378 1.2 joerg 379 1.9 christos if (os_reltime_initialized(&wpa_s->session_start)) { 380 1.9 christos os_reltime_age(&wpa_s->session_start, &wpa_s->session_length); 381 1.9 christos wpa_s->session_start.sec = 0; 382 1.9 christos wpa_s->session_start.usec = 0; 383 1.9 christos wpas_notify_session_length(wpa_s); 384 1.9 christos } 385 1.9 christos 386 1.1 christos wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); 387 1.1 christos bssid_changed = !is_zero_ether_addr(wpa_s->bssid); 388 1.1 christos os_memset(wpa_s->bssid, 0, ETH_ALEN); 389 1.1 christos os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); 390 1.3 christos sme_clear_on_disassoc(wpa_s); 391 1.1 christos wpa_s->current_bss = NULL; 392 1.2 joerg wpa_s->assoc_freq = 0; 393 1.2 joerg 394 1.1 christos if (bssid_changed) 395 1.1 christos wpas_notify_bssid_changed(wpa_s); 396 1.1 christos 397 1.10 christos eapol_sm_notify_portEnabled(wpa_s->eapol, false); 398 1.10 christos eapol_sm_notify_portValid(wpa_s->eapol, false); 399 1.7 christos if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || 400 1.7 christos wpa_s->key_mgmt == WPA_KEY_MGMT_OWE || 401 1.10 christos wpa_s->key_mgmt == WPA_KEY_MGMT_DPP || wpa_s->drv_authorized_port) 402 1.10 christos eapol_sm_notify_eap_success(wpa_s->eapol, false); 403 1.10 christos wpa_s->drv_authorized_port = 0; 404 1.1 christos wpa_s->ap_ies_from_associnfo = 0; 405 1.2 joerg wpa_s->current_ssid = NULL; 406 1.2 joerg eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); 407 1.2 joerg wpa_s->key_mgmt = 0; 408 1.10 christos wpa_s->allowed_key_mgmts = 0; 409 1.3 christos 410 1.10 christos #ifndef CONFIG_NO_RRM 411 1.3 christos wpas_rrm_reset(wpa_s); 412 1.10 christos #endif /* CONFIG_NO_RRM */ 413 1.6 christos wpa_s->wnmsleep_used = 0; 414 1.10 christos #ifdef CONFIG_WNM 415 1.10 christos wpa_s->wnm_mode = 0; 416 1.10 christos #endif /* CONFIG_WNM */ 417 1.7 christos wnm_clear_coloc_intf_reporting(wpa_s); 418 1.10 christos wpa_s->disable_mbo_oce = 0; 419 1.7 christos 420 1.7 christos #ifdef CONFIG_TESTING_OPTIONS 421 1.7 christos wpa_s->last_tk_alg = WPA_ALG_NONE; 422 1.7 christos os_memset(wpa_s->last_tk, 0, sizeof(wpa_s->last_tk)); 423 1.7 christos #endif /* CONFIG_TESTING_OPTIONS */ 424 1.7 christos wpa_s->ieee80211ac = 0; 425 1.9 christos 426 1.9 christos if (wpa_s->enabled_4addr_mode && wpa_drv_set_4addr_mode(wpa_s, 0) == 0) 427 1.9 christos wpa_s->enabled_4addr_mode = 0; 428 1.10 christos 429 1.10 christos wpa_s->wps_scan_done = false; 430 1.10 christos wpas_reset_mlo_info(wpa_s); 431 1.10 christos 432 1.10 christos #ifdef CONFIG_SME 433 1.10 christos wpa_s->sme.bss_max_idle_period = 0; 434 1.10 christos #endif /* CONFIG_SME */ 435 1.10 christos 436 1.10 christos wpa_s->ssid_verified = false; 437 1.10 christos wpa_s->bigtk_set = false; 438 1.1 christos } 439 1.1 christos 440 1.1 christos 441 1.10 christos static void wpa_find_assoc_pmkid(struct wpa_supplicant *wpa_s, bool authorized) 442 1.1 christos { 443 1.1 christos struct wpa_ie_data ie; 444 1.1 christos int pmksa_set = -1; 445 1.1 christos size_t i; 446 1.10 christos struct rsn_pmksa_cache_entry *cur_pmksa; 447 1.10 christos 448 1.10 christos /* Start with assumption of no PMKSA cache entry match for cases other 449 1.10 christos * than SAE. In particular, this is needed to generate the PMKSA cache 450 1.10 christos * entries for Suite B cases with driver-based roaming indication. */ 451 1.10 christos cur_pmksa = pmksa_cache_get_current(wpa_s->wpa); 452 1.10 christos if (cur_pmksa && !wpa_key_mgmt_sae(cur_pmksa->akmp)) 453 1.10 christos pmksa_cache_clear_current(wpa_s->wpa); 454 1.1 christos 455 1.1 christos if (wpa_sm_parse_own_wpa_ie(wpa_s->wpa, &ie) < 0 || 456 1.1 christos ie.pmkid == NULL) 457 1.1 christos return; 458 1.1 christos 459 1.1 christos for (i = 0; i < ie.num_pmkid; i++) { 460 1.1 christos pmksa_set = pmksa_cache_set_current(wpa_s->wpa, 461 1.1 christos ie.pmkid + i * PMKID_LEN, 462 1.10 christos NULL, NULL, 0, NULL, 0, 463 1.10 christos true); 464 1.1 christos if (pmksa_set == 0) { 465 1.3 christos eapol_sm_notify_pmkid_attempt(wpa_s->eapol); 466 1.10 christos if (authorized) 467 1.10 christos wpa_sm_set_pmk_from_pmksa(wpa_s->wpa); 468 1.1 christos break; 469 1.1 christos } 470 1.1 christos } 471 1.1 christos 472 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "RSN: PMKID from assoc IE %sfound from " 473 1.2 joerg "PMKSA cache", pmksa_set == 0 ? "" : "not "); 474 1.1 christos } 475 1.1 christos 476 1.1 christos 477 1.1 christos static void wpa_supplicant_event_pmkid_candidate(struct wpa_supplicant *wpa_s, 478 1.1 christos union wpa_event_data *data) 479 1.1 christos { 480 1.1 christos if (data == NULL) { 481 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "RSN: No data in PMKID candidate " 482 1.2 joerg "event"); 483 1.1 christos return; 484 1.1 christos } 485 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "RSN: PMKID candidate event - bssid=" MACSTR 486 1.2 joerg " index=%d preauth=%d", 487 1.2 joerg MAC2STR(data->pmkid_candidate.bssid), 488 1.2 joerg data->pmkid_candidate.index, 489 1.2 joerg data->pmkid_candidate.preauth); 490 1.1 christos 491 1.1 christos pmksa_candidate_add(wpa_s->wpa, data->pmkid_candidate.bssid, 492 1.1 christos data->pmkid_candidate.index, 493 1.1 christos data->pmkid_candidate.preauth); 494 1.1 christos } 495 1.1 christos 496 1.1 christos 497 1.1 christos static int wpa_supplicant_dynamic_keys(struct wpa_supplicant *wpa_s) 498 1.1 christos { 499 1.1 christos if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE || 500 1.1 christos wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) 501 1.1 christos return 0; 502 1.1 christos 503 1.1 christos #ifdef IEEE8021X_EAPOL 504 1.1 christos if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA && 505 1.1 christos wpa_s->current_ssid && 506 1.1 christos !(wpa_s->current_ssid->eapol_flags & 507 1.1 christos (EAPOL_FLAG_REQUIRE_KEY_UNICAST | 508 1.1 christos EAPOL_FLAG_REQUIRE_KEY_BROADCAST))) { 509 1.1 christos /* IEEE 802.1X, but not using dynamic WEP keys (i.e., either 510 1.1 christos * plaintext or static WEP keys). */ 511 1.1 christos return 0; 512 1.1 christos } 513 1.1 christos #endif /* IEEE8021X_EAPOL */ 514 1.1 christos 515 1.1 christos return 1; 516 1.1 christos } 517 1.1 christos 518 1.1 christos 519 1.1 christos /** 520 1.1 christos * wpa_supplicant_scard_init - Initialize SIM/USIM access with PC/SC 521 1.1 christos * @wpa_s: pointer to wpa_supplicant data 522 1.1 christos * @ssid: Configuration data for the network 523 1.1 christos * Returns: 0 on success, -1 on failure 524 1.1 christos * 525 1.1 christos * This function is called when starting authentication with a network that is 526 1.1 christos * configured to use PC/SC for SIM/USIM access (EAP-SIM or EAP-AKA). 527 1.1 christos */ 528 1.1 christos int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s, 529 1.1 christos struct wpa_ssid *ssid) 530 1.1 christos { 531 1.1 christos #ifdef IEEE8021X_EAPOL 532 1.2 joerg #ifdef PCSC_FUNCS 533 1.2 joerg int aka = 0, sim = 0; 534 1.1 christos 535 1.2 joerg if ((ssid != NULL && ssid->eap.pcsc == NULL) || 536 1.2 joerg wpa_s->scard != NULL || wpa_s->conf->external_sim) 537 1.1 christos return 0; 538 1.1 christos 539 1.2 joerg if (ssid == NULL || ssid->eap.eap_methods == NULL) { 540 1.1 christos sim = 1; 541 1.1 christos aka = 1; 542 1.1 christos } else { 543 1.1 christos struct eap_method_type *eap = ssid->eap.eap_methods; 544 1.1 christos while (eap->vendor != EAP_VENDOR_IETF || 545 1.1 christos eap->method != EAP_TYPE_NONE) { 546 1.1 christos if (eap->vendor == EAP_VENDOR_IETF) { 547 1.1 christos if (eap->method == EAP_TYPE_SIM) 548 1.1 christos sim = 1; 549 1.2 joerg else if (eap->method == EAP_TYPE_AKA || 550 1.2 joerg eap->method == EAP_TYPE_AKA_PRIME) 551 1.1 christos aka = 1; 552 1.1 christos } 553 1.1 christos eap++; 554 1.1 christos } 555 1.1 christos } 556 1.1 christos 557 1.1 christos if (eap_peer_get_eap_method(EAP_VENDOR_IETF, EAP_TYPE_SIM) == NULL) 558 1.1 christos sim = 0; 559 1.2 joerg if (eap_peer_get_eap_method(EAP_VENDOR_IETF, EAP_TYPE_AKA) == NULL && 560 1.2 joerg eap_peer_get_eap_method(EAP_VENDOR_IETF, EAP_TYPE_AKA_PRIME) == 561 1.2 joerg NULL) 562 1.1 christos aka = 0; 563 1.1 christos 564 1.1 christos if (!sim && !aka) { 565 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Selected network is configured to " 566 1.2 joerg "use SIM, but neither EAP-SIM nor EAP-AKA are " 567 1.2 joerg "enabled"); 568 1.1 christos return 0; 569 1.1 christos } 570 1.1 christos 571 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Selected network is configured to use SIM " 572 1.2 joerg "(sim=%d aka=%d) - initialize PCSC", sim, aka); 573 1.1 christos 574 1.2 joerg wpa_s->scard = scard_init(wpa_s->conf->pcsc_reader); 575 1.1 christos if (wpa_s->scard == NULL) { 576 1.2 joerg wpa_msg(wpa_s, MSG_WARNING, "Failed to initialize SIM " 577 1.2 joerg "(pcsc-lite)"); 578 1.1 christos return -1; 579 1.1 christos } 580 1.1 christos wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard); 581 1.1 christos eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard); 582 1.2 joerg #endif /* PCSC_FUNCS */ 583 1.1 christos #endif /* IEEE8021X_EAPOL */ 584 1.1 christos 585 1.1 christos return 0; 586 1.1 christos } 587 1.1 christos 588 1.1 christos 589 1.1 christos #ifndef CONFIG_NO_SCAN_PROCESSING 590 1.2 joerg 591 1.10 christos #ifdef CONFIG_WEP 592 1.2 joerg static int has_wep_key(struct wpa_ssid *ssid) 593 1.2 joerg { 594 1.2 joerg int i; 595 1.2 joerg 596 1.2 joerg for (i = 0; i < NUM_WEP_KEYS; i++) { 597 1.2 joerg if (ssid->wep_key_len[i]) 598 1.2 joerg return 1; 599 1.2 joerg } 600 1.2 joerg 601 1.2 joerg return 0; 602 1.2 joerg } 603 1.10 christos #endif /* CONFIG_WEP */ 604 1.2 joerg 605 1.2 joerg 606 1.2 joerg static int wpa_supplicant_match_privacy(struct wpa_bss *bss, 607 1.1 christos struct wpa_ssid *ssid) 608 1.1 christos { 609 1.2 joerg int privacy = 0; 610 1.1 christos 611 1.1 christos if (ssid->mixed_cell) 612 1.1 christos return 1; 613 1.1 christos 614 1.1 christos #ifdef CONFIG_WPS 615 1.1 christos if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) 616 1.1 christos return 1; 617 1.1 christos #endif /* CONFIG_WPS */ 618 1.1 christos 619 1.7 christos #ifdef CONFIG_OWE 620 1.7 christos if ((ssid->key_mgmt & WPA_KEY_MGMT_OWE) && !ssid->owe_only) 621 1.7 christos return 1; 622 1.7 christos #endif /* CONFIG_OWE */ 623 1.7 christos 624 1.10 christos #ifdef CONFIG_WEP 625 1.2 joerg if (has_wep_key(ssid)) 626 1.2 joerg privacy = 1; 627 1.10 christos #endif /* CONFIG_WEP */ 628 1.2 joerg 629 1.1 christos #ifdef IEEE8021X_EAPOL 630 1.1 christos if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && 631 1.1 christos ssid->eapol_flags & (EAPOL_FLAG_REQUIRE_KEY_UNICAST | 632 1.1 christos EAPOL_FLAG_REQUIRE_KEY_BROADCAST)) 633 1.1 christos privacy = 1; 634 1.1 christos #endif /* IEEE8021X_EAPOL */ 635 1.1 christos 636 1.2 joerg if (wpa_key_mgmt_wpa(ssid->key_mgmt)) 637 1.2 joerg privacy = 1; 638 1.2 joerg 639 1.2 joerg if (ssid->key_mgmt & WPA_KEY_MGMT_OSEN) 640 1.2 joerg privacy = 1; 641 1.2 joerg 642 1.1 christos if (bss->caps & IEEE80211_CAP_PRIVACY) 643 1.1 christos return privacy; 644 1.1 christos return !privacy; 645 1.1 christos } 646 1.1 christos 647 1.1 christos 648 1.1 christos static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s, 649 1.1 christos struct wpa_ssid *ssid, 650 1.7 christos struct wpa_bss *bss, int debug_print) 651 1.1 christos { 652 1.1 christos struct wpa_ie_data ie; 653 1.1 christos int proto_match = 0; 654 1.1 christos const u8 *rsn_ie, *wpa_ie; 655 1.1 christos int ret; 656 1.10 christos #ifdef CONFIG_WEP 657 1.2 joerg int wep_ok; 658 1.10 christos #endif /* CONFIG_WEP */ 659 1.10 christos bool is_6ghz_bss = is_6ghz_freq(bss->freq); 660 1.1 christos 661 1.1 christos ret = wpas_wps_ssid_bss_match(wpa_s, ssid, bss); 662 1.1 christos if (ret >= 0) 663 1.1 christos return ret; 664 1.1 christos 665 1.10 christos #ifdef CONFIG_WEP 666 1.2 joerg /* Allow TSN if local configuration accepts WEP use without WPA/WPA2 */ 667 1.2 joerg wep_ok = !wpa_key_mgmt_wpa(ssid->key_mgmt) && 668 1.2 joerg (((ssid->key_mgmt & WPA_KEY_MGMT_NONE) && 669 1.2 joerg ssid->wep_key_len[ssid->wep_tx_keyidx] > 0) || 670 1.2 joerg (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)); 671 1.10 christos #endif /* CONFIG_WEP */ 672 1.2 joerg 673 1.2 joerg rsn_ie = wpa_bss_get_ie(bss, WLAN_EID_RSN); 674 1.10 christos if (is_6ghz_bss && !rsn_ie) { 675 1.10 christos if (debug_print) 676 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 677 1.10 christos " skip - 6 GHz BSS without RSNE"); 678 1.10 christos return 0; 679 1.10 christos } 680 1.10 christos 681 1.7 christos while ((ssid->proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN)) && rsn_ie) { 682 1.1 christos proto_match++; 683 1.1 christos 684 1.1 christos if (wpa_parse_wpa_ie(rsn_ie, 2 + rsn_ie[1], &ie)) { 685 1.7 christos if (debug_print) 686 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 687 1.7 christos " skip RSN IE - parse failed"); 688 1.1 christos break; 689 1.1 christos } 690 1.9 christos if (!ie.has_pairwise) 691 1.9 christos ie.pairwise_cipher = wpa_default_rsn_cipher(bss->freq); 692 1.9 christos if (!ie.has_group) 693 1.9 christos ie.group_cipher = wpa_default_rsn_cipher(bss->freq); 694 1.2 joerg 695 1.10 christos if (is_6ghz_bss || !is_zero_ether_addr(bss->mld_addr)) { 696 1.10 christos /* WEP and TKIP are not allowed on 6 GHz/MLD */ 697 1.10 christos ie.pairwise_cipher &= ~(WPA_CIPHER_WEP40 | 698 1.10 christos WPA_CIPHER_WEP104 | 699 1.10 christos WPA_CIPHER_TKIP); 700 1.10 christos ie.group_cipher &= ~(WPA_CIPHER_WEP40 | 701 1.10 christos WPA_CIPHER_WEP104 | 702 1.10 christos WPA_CIPHER_TKIP); 703 1.10 christos } 704 1.10 christos 705 1.10 christos #ifdef CONFIG_WEP 706 1.2 joerg if (wep_ok && 707 1.2 joerg (ie.group_cipher & (WPA_CIPHER_WEP40 | WPA_CIPHER_WEP104))) 708 1.2 joerg { 709 1.7 christos if (debug_print) 710 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 711 1.7 christos " selected based on TSN in RSN IE"); 712 1.2 joerg return 1; 713 1.2 joerg } 714 1.10 christos #endif /* CONFIG_WEP */ 715 1.2 joerg 716 1.7 christos if (!(ie.proto & ssid->proto) && 717 1.7 christos !(ssid->proto & WPA_PROTO_OSEN)) { 718 1.7 christos if (debug_print) 719 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 720 1.7 christos " skip RSN IE - proto mismatch"); 721 1.1 christos break; 722 1.1 christos } 723 1.1 christos 724 1.1 christos if (!(ie.pairwise_cipher & ssid->pairwise_cipher)) { 725 1.7 christos if (debug_print) 726 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 727 1.7 christos " skip RSN IE - PTK cipher mismatch"); 728 1.1 christos break; 729 1.1 christos } 730 1.1 christos 731 1.1 christos if (!(ie.group_cipher & ssid->group_cipher)) { 732 1.7 christos if (debug_print) 733 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 734 1.7 christos " skip RSN IE - GTK cipher mismatch"); 735 1.7 christos break; 736 1.7 christos } 737 1.7 christos 738 1.7 christos if (ssid->group_mgmt_cipher && 739 1.7 christos !(ie.mgmt_group_cipher & ssid->group_mgmt_cipher)) { 740 1.7 christos if (debug_print) 741 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 742 1.7 christos " skip RSN IE - group mgmt cipher mismatch"); 743 1.1 christos break; 744 1.1 christos } 745 1.1 christos 746 1.10 christos if (is_6ghz_bss) { 747 1.10 christos /* MFPC must be supported on 6 GHz */ 748 1.10 christos if (!(ie.capabilities & WPA_CAPABILITY_MFPC)) { 749 1.10 christos if (debug_print) 750 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 751 1.10 christos " skip RSNE - 6 GHz without MFPC"); 752 1.10 christos break; 753 1.10 christos } 754 1.10 christos 755 1.10 christos /* WPA PSK is not allowed on the 6 GHz band */ 756 1.10 christos ie.key_mgmt &= ~(WPA_KEY_MGMT_PSK | 757 1.10 christos WPA_KEY_MGMT_FT_PSK | 758 1.10 christos WPA_KEY_MGMT_PSK_SHA256); 759 1.10 christos } 760 1.10 christos 761 1.1 christos if (!(ie.key_mgmt & ssid->key_mgmt)) { 762 1.7 christos if (debug_print) 763 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 764 1.7 christos " skip RSN IE - key mgmt mismatch"); 765 1.1 christos break; 766 1.1 christos } 767 1.1 christos 768 1.1 christos if (!(ie.capabilities & WPA_CAPABILITY_MFPC) && 769 1.3 christos wpas_get_ssid_pmf(wpa_s, ssid) == 770 1.2 joerg MGMT_FRAME_PROTECTION_REQUIRED) { 771 1.7 christos if (debug_print) 772 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 773 1.7 christos " skip RSN IE - no mgmt frame protection"); 774 1.1 christos break; 775 1.1 christos } 776 1.6 christos if ((ie.capabilities & WPA_CAPABILITY_MFPR) && 777 1.6 christos wpas_get_ssid_pmf(wpa_s, ssid) == 778 1.6 christos NO_MGMT_FRAME_PROTECTION) { 779 1.7 christos if (debug_print) 780 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 781 1.7 christos " skip RSN IE - no mgmt frame protection enabled but AP requires it"); 782 1.6 christos break; 783 1.6 christos } 784 1.1 christos 785 1.7 christos if (debug_print) 786 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 787 1.7 christos " selected based on RSN IE"); 788 1.1 christos return 1; 789 1.1 christos } 790 1.1 christos 791 1.10 christos if (is_6ghz_bss) { 792 1.10 christos if (debug_print) 793 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 794 1.10 christos " skip - 6 GHz BSS without matching RSNE"); 795 1.10 christos return 0; 796 1.10 christos } 797 1.10 christos 798 1.10 christos wpa_ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); 799 1.10 christos 800 1.7 christos if (wpas_get_ssid_pmf(wpa_s, ssid) == MGMT_FRAME_PROTECTION_REQUIRED && 801 1.7 christos (!(ssid->key_mgmt & WPA_KEY_MGMT_OWE) || ssid->owe_only)) { 802 1.10 christos #ifdef CONFIG_OWE 803 1.10 christos if ((ssid->key_mgmt & WPA_KEY_MGMT_OWE) && ssid->owe_only && 804 1.10 christos !wpa_ie && !rsn_ie && 805 1.10 christos wpa_s->owe_transition_select && 806 1.10 christos wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE) && 807 1.10 christos ssid->owe_transition_bss_select_count + 1 <= 808 1.10 christos MAX_OWE_TRANSITION_BSS_SELECT_COUNT) { 809 1.10 christos ssid->owe_transition_bss_select_count++; 810 1.10 christos if (debug_print) 811 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 812 1.10 christos " skip OWE open BSS (selection count %d does not exceed %d)", 813 1.10 christos ssid->owe_transition_bss_select_count, 814 1.10 christos MAX_OWE_TRANSITION_BSS_SELECT_COUNT); 815 1.10 christos wpa_s->owe_transition_search = 1; 816 1.10 christos return 0; 817 1.10 christos } 818 1.10 christos #endif /* CONFIG_OWE */ 819 1.7 christos if (debug_print) 820 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 821 1.7 christos " skip - MFP Required but network not MFP Capable"); 822 1.6 christos return 0; 823 1.6 christos } 824 1.6 christos 825 1.1 christos while ((ssid->proto & WPA_PROTO_WPA) && wpa_ie) { 826 1.1 christos proto_match++; 827 1.1 christos 828 1.1 christos if (wpa_parse_wpa_ie(wpa_ie, 2 + wpa_ie[1], &ie)) { 829 1.7 christos if (debug_print) 830 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 831 1.7 christos " skip WPA IE - parse failed"); 832 1.1 christos break; 833 1.1 christos } 834 1.2 joerg 835 1.10 christos #ifdef CONFIG_WEP 836 1.2 joerg if (wep_ok && 837 1.2 joerg (ie.group_cipher & (WPA_CIPHER_WEP40 | WPA_CIPHER_WEP104))) 838 1.2 joerg { 839 1.7 christos if (debug_print) 840 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 841 1.7 christos " selected based on TSN in WPA IE"); 842 1.2 joerg return 1; 843 1.2 joerg } 844 1.10 christos #endif /* CONFIG_WEP */ 845 1.2 joerg 846 1.1 christos if (!(ie.proto & ssid->proto)) { 847 1.7 christos if (debug_print) 848 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 849 1.7 christos " skip WPA IE - proto mismatch"); 850 1.1 christos break; 851 1.1 christos } 852 1.1 christos 853 1.1 christos if (!(ie.pairwise_cipher & ssid->pairwise_cipher)) { 854 1.7 christos if (debug_print) 855 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 856 1.7 christos " skip WPA IE - PTK cipher mismatch"); 857 1.1 christos break; 858 1.1 christos } 859 1.1 christos 860 1.1 christos if (!(ie.group_cipher & ssid->group_cipher)) { 861 1.7 christos if (debug_print) 862 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 863 1.7 christos " skip WPA IE - GTK cipher mismatch"); 864 1.1 christos break; 865 1.1 christos } 866 1.1 christos 867 1.1 christos if (!(ie.key_mgmt & ssid->key_mgmt)) { 868 1.7 christos if (debug_print) 869 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 870 1.7 christos " skip WPA IE - key mgmt mismatch"); 871 1.1 christos break; 872 1.1 christos } 873 1.1 christos 874 1.7 christos if (debug_print) 875 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 876 1.7 christos " selected based on WPA IE"); 877 1.2 joerg return 1; 878 1.2 joerg } 879 1.2 joerg 880 1.2 joerg if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) && !wpa_ie && 881 1.2 joerg !rsn_ie) { 882 1.7 christos if (debug_print) 883 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 884 1.7 christos " allow for non-WPA IEEE 802.1X"); 885 1.7 christos return 1; 886 1.7 christos } 887 1.7 christos 888 1.7 christos #ifdef CONFIG_OWE 889 1.7 christos if ((ssid->key_mgmt & WPA_KEY_MGMT_OWE) && !ssid->owe_only && 890 1.7 christos !wpa_ie && !rsn_ie) { 891 1.7 christos if (wpa_s->owe_transition_select && 892 1.7 christos wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE) && 893 1.7 christos ssid->owe_transition_bss_select_count + 1 <= 894 1.7 christos MAX_OWE_TRANSITION_BSS_SELECT_COUNT) { 895 1.7 christos ssid->owe_transition_bss_select_count++; 896 1.7 christos if (debug_print) 897 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 898 1.7 christos " skip OWE transition BSS (selection count %d does not exceed %d)", 899 1.7 christos ssid->owe_transition_bss_select_count, 900 1.7 christos MAX_OWE_TRANSITION_BSS_SELECT_COUNT); 901 1.7 christos wpa_s->owe_transition_search = 1; 902 1.7 christos return 0; 903 1.7 christos } 904 1.7 christos if (debug_print) 905 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 906 1.7 christos " allow in OWE transition mode"); 907 1.2 joerg return 1; 908 1.2 joerg } 909 1.7 christos #endif /* CONFIG_OWE */ 910 1.2 joerg 911 1.2 joerg if ((ssid->proto & (WPA_PROTO_WPA | WPA_PROTO_RSN)) && 912 1.2 joerg wpa_key_mgmt_wpa(ssid->key_mgmt) && proto_match == 0) { 913 1.7 christos if (debug_print) 914 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 915 1.7 christos " skip - no WPA/RSN proto match"); 916 1.2 joerg return 0; 917 1.2 joerg } 918 1.2 joerg 919 1.2 joerg if ((ssid->key_mgmt & WPA_KEY_MGMT_OSEN) && 920 1.2 joerg wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE)) { 921 1.7 christos if (debug_print) 922 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, " allow in OSEN"); 923 1.2 joerg return 1; 924 1.2 joerg } 925 1.2 joerg 926 1.2 joerg if (!wpa_key_mgmt_wpa(ssid->key_mgmt)) { 927 1.7 christos if (debug_print) 928 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, " allow in non-WPA/WPA2"); 929 1.1 christos return 1; 930 1.1 christos } 931 1.1 christos 932 1.7 christos if (debug_print) 933 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 934 1.7 christos " reject due to mismatch with WPA/WPA2"); 935 1.1 christos 936 1.1 christos return 0; 937 1.1 christos } 938 1.1 christos 939 1.1 christos 940 1.1 christos static int freq_allowed(int *freqs, int freq) 941 1.1 christos { 942 1.1 christos int i; 943 1.1 christos 944 1.1 christos if (freqs == NULL) 945 1.1 christos return 1; 946 1.1 christos 947 1.1 christos for (i = 0; freqs[i]; i++) 948 1.1 christos if (freqs[i] == freq) 949 1.1 christos return 1; 950 1.1 christos return 0; 951 1.1 christos } 952 1.1 christos 953 1.1 christos 954 1.10 christos static int rate_match(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, 955 1.10 christos struct wpa_bss *bss, int debug_print) 956 1.1 christos { 957 1.2 joerg const struct hostapd_hw_modes *mode = NULL, *modes; 958 1.2 joerg const u8 scan_ie[2] = { WLAN_EID_SUPP_RATES, WLAN_EID_EXT_SUPP_RATES }; 959 1.2 joerg const u8 *rate_ie; 960 1.2 joerg int i, j, k; 961 1.2 joerg 962 1.2 joerg if (bss->freq == 0) 963 1.2 joerg return 1; /* Cannot do matching without knowing band */ 964 1.2 joerg 965 1.2 joerg modes = wpa_s->hw.modes; 966 1.2 joerg if (modes == NULL) { 967 1.2 joerg /* 968 1.2 joerg * The driver does not provide any additional information 969 1.2 joerg * about the utilized hardware, so allow the connection attempt 970 1.2 joerg * to continue. 971 1.2 joerg */ 972 1.2 joerg return 1; 973 1.2 joerg } 974 1.1 christos 975 1.2 joerg for (i = 0; i < wpa_s->hw.num_modes; i++) { 976 1.2 joerg for (j = 0; j < modes[i].num_channels; j++) { 977 1.2 joerg int freq = modes[i].channels[j].freq; 978 1.2 joerg if (freq == bss->freq) { 979 1.2 joerg if (mode && 980 1.2 joerg mode->mode == HOSTAPD_MODE_IEEE80211G) 981 1.2 joerg break; /* do not allow 802.11b replace 982 1.2 joerg * 802.11g */ 983 1.2 joerg mode = &modes[i]; 984 1.2 joerg break; 985 1.2 joerg } 986 1.1 christos } 987 1.2 joerg } 988 1.1 christos 989 1.2 joerg if (mode == NULL) 990 1.2 joerg return 0; 991 1.1 christos 992 1.2 joerg for (i = 0; i < (int) sizeof(scan_ie); i++) { 993 1.2 joerg rate_ie = wpa_bss_get_ie(bss, scan_ie[i]); 994 1.2 joerg if (rate_ie == NULL) 995 1.1 christos continue; 996 1.1 christos 997 1.2 joerg for (j = 2; j < rate_ie[1] + 2; j++) { 998 1.2 joerg int flagged = !!(rate_ie[j] & 0x80); 999 1.2 joerg int r = (rate_ie[j] & 0x7f) * 5; 1000 1.1 christos 1001 1.2 joerg /* 1002 1.2 joerg * IEEE Std 802.11n-2009 7.3.2.2: 1003 1.2 joerg * The new BSS Membership selector value is encoded 1004 1.2 joerg * like a legacy basic rate, but it is not a rate and 1005 1.2 joerg * only indicates if the BSS members are required to 1006 1.2 joerg * support the mandatory features of Clause 20 [HT PHY] 1007 1.2 joerg * in order to join the BSS. 1008 1.2 joerg */ 1009 1.2 joerg if (flagged && ((rate_ie[j] & 0x7f) == 1010 1.2 joerg BSS_MEMBERSHIP_SELECTOR_HT_PHY)) { 1011 1.2 joerg if (!ht_supported(mode)) { 1012 1.7 christos if (debug_print) 1013 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 1014 1.7 christos " hardware does not support HT PHY"); 1015 1.2 joerg return 0; 1016 1.2 joerg } 1017 1.1 christos continue; 1018 1.1 christos } 1019 1.1 christos 1020 1.2 joerg /* There's also a VHT selector for 802.11ac */ 1021 1.2 joerg if (flagged && ((rate_ie[j] & 0x7f) == 1022 1.2 joerg BSS_MEMBERSHIP_SELECTOR_VHT_PHY)) { 1023 1.2 joerg if (!vht_supported(mode)) { 1024 1.7 christos if (debug_print) 1025 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 1026 1.7 christos " hardware does not support VHT PHY"); 1027 1.2 joerg return 0; 1028 1.2 joerg } 1029 1.1 christos continue; 1030 1.1 christos } 1031 1.1 christos 1032 1.10 christos if (flagged && ((rate_ie[j] & 0x7f) == 1033 1.10 christos BSS_MEMBERSHIP_SELECTOR_HE_PHY)) { 1034 1.10 christos if (!he_supported(mode, IEEE80211_MODE_INFRA)) { 1035 1.10 christos if (debug_print) 1036 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1037 1.10 christos " hardware does not support HE PHY"); 1038 1.10 christos return 0; 1039 1.10 christos } 1040 1.10 christos continue; 1041 1.10 christos } 1042 1.10 christos 1043 1.10 christos #ifdef CONFIG_SAE 1044 1.10 christos if (flagged && ((rate_ie[j] & 0x7f) == 1045 1.10 christos BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY)) { 1046 1.10 christos if (wpa_s->conf->sae_pwe == 1047 1.10 christos SAE_PWE_HUNT_AND_PECK && 1048 1.10 christos !ssid->sae_password_id && 1049 1.10 christos !is_6ghz_freq(bss->freq) && 1050 1.10 christos wpa_key_mgmt_sae(ssid->key_mgmt)) { 1051 1.10 christos if (debug_print) 1052 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1053 1.10 christos " SAE H2E disabled"); 1054 1.10 christos #ifdef CONFIG_TESTING_OPTIONS 1055 1.10 christos if (wpa_s->ignore_sae_h2e_only) { 1056 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1057 1.10 christos "TESTING: Ignore SAE H2E requirement mismatch"); 1058 1.10 christos continue; 1059 1.10 christos } 1060 1.10 christos #endif /* CONFIG_TESTING_OPTIONS */ 1061 1.10 christos return 0; 1062 1.10 christos } 1063 1.10 christos continue; 1064 1.10 christos } 1065 1.10 christos #endif /* CONFIG_SAE */ 1066 1.10 christos 1067 1.2 joerg if (!flagged) 1068 1.1 christos continue; 1069 1.2 joerg 1070 1.2 joerg /* check for legacy basic rates */ 1071 1.2 joerg for (k = 0; k < mode->num_rates; k++) { 1072 1.2 joerg if (mode->rates[k] == r) 1073 1.2 joerg break; 1074 1.1 christos } 1075 1.2 joerg if (k == mode->num_rates) { 1076 1.2 joerg /* 1077 1.2 joerg * IEEE Std 802.11-2007 7.3.2.2 demands that in 1078 1.2 joerg * order to join a BSS all required rates 1079 1.2 joerg * have to be supported by the hardware. 1080 1.2 joerg */ 1081 1.7 christos if (debug_print) 1082 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 1083 1.7 christos " hardware does not support required rate %d.%d Mbps (freq=%d mode==%d num_rates=%d)", 1084 1.7 christos r / 10, r % 10, 1085 1.7 christos bss->freq, mode->mode, mode->num_rates); 1086 1.2 joerg return 0; 1087 1.2 joerg } 1088 1.2 joerg } 1089 1.2 joerg } 1090 1.1 christos 1091 1.2 joerg return 1; 1092 1.2 joerg } 1093 1.1 christos 1094 1.1 christos 1095 1.2 joerg /* 1096 1.2 joerg * Test whether BSS is in an ESS. 1097 1.2 joerg * This is done differently in DMG (60 GHz) and non-DMG bands 1098 1.2 joerg */ 1099 1.2 joerg static int bss_is_ess(struct wpa_bss *bss) 1100 1.2 joerg { 1101 1.2 joerg if (bss_is_dmg(bss)) { 1102 1.2 joerg return (bss->caps & IEEE80211_CAP_DMG_MASK) == 1103 1.2 joerg IEEE80211_CAP_DMG_AP; 1104 1.1 christos } 1105 1.1 christos 1106 1.2 joerg return ((bss->caps & (IEEE80211_CAP_ESS | IEEE80211_CAP_IBSS)) == 1107 1.2 joerg IEEE80211_CAP_ESS); 1108 1.1 christos } 1109 1.1 christos 1110 1.1 christos 1111 1.3 christos static int match_mac_mask(const u8 *addr_a, const u8 *addr_b, const u8 *mask) 1112 1.3 christos { 1113 1.3 christos size_t i; 1114 1.3 christos 1115 1.3 christos for (i = 0; i < ETH_ALEN; i++) { 1116 1.3 christos if ((addr_a[i] & mask[i]) != (addr_b[i] & mask[i])) 1117 1.3 christos return 0; 1118 1.3 christos } 1119 1.3 christos return 1; 1120 1.3 christos } 1121 1.3 christos 1122 1.3 christos 1123 1.3 christos static int addr_in_list(const u8 *addr, const u8 *list, size_t num) 1124 1.3 christos { 1125 1.3 christos size_t i; 1126 1.3 christos 1127 1.3 christos for (i = 0; i < num; i++) { 1128 1.3 christos const u8 *a = list + i * ETH_ALEN * 2; 1129 1.3 christos const u8 *m = a + ETH_ALEN; 1130 1.3 christos 1131 1.3 christos if (match_mac_mask(a, addr, m)) 1132 1.3 christos return 1; 1133 1.3 christos } 1134 1.3 christos return 0; 1135 1.3 christos } 1136 1.3 christos 1137 1.3 christos 1138 1.7 christos static void owe_trans_ssid(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, 1139 1.7 christos const u8 **ret_ssid, size_t *ret_ssid_len) 1140 1.7 christos { 1141 1.7 christos #ifdef CONFIG_OWE 1142 1.7 christos const u8 *owe, *pos, *end, *bssid; 1143 1.7 christos u8 ssid_len; 1144 1.7 christos 1145 1.7 christos owe = wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE); 1146 1.7 christos if (!owe || !wpa_bss_get_ie(bss, WLAN_EID_RSN)) 1147 1.7 christos return; 1148 1.7 christos 1149 1.7 christos pos = owe + 6; 1150 1.7 christos end = owe + 2 + owe[1]; 1151 1.7 christos 1152 1.7 christos if (end - pos < ETH_ALEN + 1) 1153 1.7 christos return; 1154 1.7 christos bssid = pos; 1155 1.7 christos pos += ETH_ALEN; 1156 1.7 christos ssid_len = *pos++; 1157 1.7 christos if (end - pos < ssid_len || ssid_len > SSID_MAX_LEN) 1158 1.7 christos return; 1159 1.7 christos 1160 1.7 christos /* Match the profile SSID against the OWE transition mode SSID on the 1161 1.7 christos * open network. */ 1162 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, "OWE: transition mode BSSID: " MACSTR 1163 1.7 christos " SSID: %s", MAC2STR(bssid), wpa_ssid_txt(pos, ssid_len)); 1164 1.7 christos *ret_ssid = pos; 1165 1.7 christos *ret_ssid_len = ssid_len; 1166 1.7 christos 1167 1.10 christos if (!(bss->flags & WPA_BSS_OWE_TRANSITION)) { 1168 1.10 christos struct wpa_ssid *ssid; 1169 1.7 christos 1170 1.10 christos for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { 1171 1.10 christos if (wpas_network_disabled(wpa_s, ssid)) 1172 1.10 christos continue; 1173 1.10 christos if (ssid->ssid_len == ssid_len && 1174 1.10 christos os_memcmp(ssid->ssid, pos, ssid_len) == 0) { 1175 1.10 christos /* OWE BSS in transition mode for a currently 1176 1.10 christos * enabled OWE network. */ 1177 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1178 1.10 christos "OWE: transition mode OWE SSID for active OWE profile"); 1179 1.10 christos bss->flags |= WPA_BSS_OWE_TRANSITION; 1180 1.10 christos break; 1181 1.10 christos } 1182 1.10 christos } 1183 1.7 christos } 1184 1.10 christos #endif /* CONFIG_OWE */ 1185 1.10 christos } 1186 1.7 christos 1187 1.10 christos 1188 1.10 christos static bool wpas_valid_ml_bss(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) 1189 1.10 christos { 1190 1.10 christos u16 removed_links; 1191 1.10 christos 1192 1.10 christos if (wpa_bss_parse_basic_ml_element(wpa_s, bss, NULL, NULL, NULL, NULL)) 1193 1.10 christos return true; 1194 1.10 christos 1195 1.10 christos if (!bss->valid_links) 1196 1.10 christos return true; 1197 1.10 christos 1198 1.10 christos /* Check if the current BSS is going to be removed */ 1199 1.10 christos removed_links = wpa_bss_parse_reconf_ml_element(wpa_s, bss); 1200 1.10 christos if (BIT(bss->mld_link_id) & removed_links) 1201 1.10 christos return false; 1202 1.10 christos 1203 1.10 christos return true; 1204 1.10 christos } 1205 1.10 christos 1206 1.10 christos 1207 1.10 christos int disabled_freq(struct wpa_supplicant *wpa_s, int freq) 1208 1.10 christos { 1209 1.10 christos int i, j; 1210 1.10 christos 1211 1.10 christos if (!wpa_s->hw.modes || !wpa_s->hw.num_modes) 1212 1.10 christos return 0; 1213 1.10 christos 1214 1.10 christos for (j = 0; j < wpa_s->hw.num_modes; j++) { 1215 1.10 christos struct hostapd_hw_modes *mode = &wpa_s->hw.modes[j]; 1216 1.10 christos 1217 1.10 christos for (i = 0; i < mode->num_channels; i++) { 1218 1.10 christos struct hostapd_channel_data *chan = &mode->channels[i]; 1219 1.10 christos 1220 1.10 christos if (chan->freq == freq) 1221 1.10 christos return !!(chan->flag & HOSTAPD_CHAN_DISABLED); 1222 1.10 christos } 1223 1.7 christos } 1224 1.7 christos 1225 1.10 christos return 1; 1226 1.10 christos } 1227 1.10 christos 1228 1.10 christos 1229 1.10 christos static bool wpa_scan_res_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, 1230 1.10 christos const u8 *match_ssid, size_t match_ssid_len, 1231 1.10 christos struct wpa_bss *bss, int bssid_ignore_count, 1232 1.10 christos bool debug_print); 1233 1.10 christos 1234 1.10 christos 1235 1.10 christos #ifdef CONFIG_SAE_PK 1236 1.10 christos static bool sae_pk_acceptable_bss_with_pk(struct wpa_supplicant *wpa_s, 1237 1.10 christos struct wpa_bss *orig_bss, 1238 1.10 christos struct wpa_ssid *ssid, 1239 1.10 christos const u8 *match_ssid, 1240 1.10 christos size_t match_ssid_len) 1241 1.10 christos { 1242 1.10 christos struct wpa_bss *bss; 1243 1.10 christos 1244 1.10 christos dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { 1245 1.10 christos int count; 1246 1.10 christos const u8 *ie; 1247 1.10 christos 1248 1.10 christos if (bss == orig_bss) 1249 1.10 christos continue; 1250 1.10 christos ie = wpa_bss_get_ie(bss, WLAN_EID_RSNX); 1251 1.10 christos if (!(ieee802_11_rsnx_capab(ie, WLAN_RSNX_CAPAB_SAE_PK))) 1252 1.10 christos continue; 1253 1.10 christos 1254 1.10 christos /* TODO: Could be more thorough in checking what kind of 1255 1.10 christos * signal strength or throughput estimate would be acceptable 1256 1.10 christos * compared to the originally selected BSS. */ 1257 1.10 christos if (bss->est_throughput < 2000) 1258 1.10 christos return false; 1259 1.7 christos 1260 1.10 christos count = wpa_bssid_ignore_is_listed(wpa_s, bss->bssid); 1261 1.10 christos if (wpa_scan_res_ok(wpa_s, ssid, match_ssid, match_ssid_len, 1262 1.10 christos bss, count, 0)) 1263 1.10 christos return true; 1264 1.7 christos } 1265 1.10 christos 1266 1.10 christos return false; 1267 1.7 christos } 1268 1.10 christos #endif /* CONFIG_SAE_PK */ 1269 1.7 christos 1270 1.7 christos 1271 1.10 christos static bool wpa_scan_res_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, 1272 1.10 christos const u8 *match_ssid, size_t match_ssid_len, 1273 1.10 christos struct wpa_bss *bss, int bssid_ignore_count, 1274 1.10 christos bool debug_print) 1275 1.1 christos { 1276 1.10 christos int res; 1277 1.10 christos bool wpa, check_ssid, osen, rsn_osen = false; 1278 1.10 christos struct wpa_ie_data data; 1279 1.6 christos #ifdef CONFIG_MBO 1280 1.6 christos const u8 *assoc_disallow; 1281 1.6 christos #endif /* CONFIG_MBO */ 1282 1.10 christos #ifdef CONFIG_SAE 1283 1.10 christos u8 rsnxe_capa = 0; 1284 1.10 christos #endif /* CONFIG_SAE */ 1285 1.10 christos const u8 *ie; 1286 1.2 joerg 1287 1.2 joerg ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); 1288 1.10 christos wpa = ie && ie[1]; 1289 1.2 joerg ie = wpa_bss_get_ie(bss, WLAN_EID_RSN); 1290 1.10 christos wpa |= ie && ie[1]; 1291 1.7 christos if (ie && wpa_parse_wpa_ie_rsn(ie, 2 + ie[1], &data) == 0 && 1292 1.7 christos (data.key_mgmt & WPA_KEY_MGMT_OSEN)) 1293 1.10 christos rsn_osen = true; 1294 1.2 joerg ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE); 1295 1.2 joerg osen = ie != NULL; 1296 1.2 joerg 1297 1.10 christos #ifdef CONFIG_SAE 1298 1.10 christos ie = wpa_bss_get_ie(bss, WLAN_EID_RSNX); 1299 1.10 christos if (ie && ie[1] >= 1) 1300 1.10 christos rsnxe_capa = ie[2]; 1301 1.10 christos #endif /* CONFIG_SAE */ 1302 1.10 christos 1303 1.10 christos check_ssid = wpa || ssid->ssid_len > 0; 1304 1.10 christos 1305 1.10 christos if (wpas_network_disabled(wpa_s, ssid)) { 1306 1.10 christos if (debug_print) 1307 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, " skip - disabled"); 1308 1.10 christos return false; 1309 1.10 christos } 1310 1.10 christos 1311 1.10 christos res = wpas_temp_disabled(wpa_s, ssid); 1312 1.10 christos if (res > 0) { 1313 1.10 christos if (debug_print) 1314 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1315 1.10 christos " skip - disabled temporarily for %d second(s)", 1316 1.10 christos res); 1317 1.10 christos return false; 1318 1.7 christos } 1319 1.2 joerg 1320 1.10 christos #ifdef CONFIG_WPS 1321 1.10 christos if ((ssid->key_mgmt & WPA_KEY_MGMT_WPS) && bssid_ignore_count) { 1322 1.10 christos if (debug_print) 1323 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1324 1.10 christos " skip - BSSID ignored (WPS)"); 1325 1.10 christos return false; 1326 1.2 joerg } 1327 1.2 joerg 1328 1.10 christos if (wpa && ssid->ssid_len == 0 && 1329 1.10 christos wpas_wps_ssid_wildcard_ok(wpa_s, ssid, bss)) 1330 1.10 christos check_ssid = false; 1331 1.10 christos 1332 1.10 christos if (!wpa && (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) { 1333 1.10 christos /* Only allow wildcard SSID match if an AP advertises active 1334 1.10 christos * WPS operation that matches our mode. */ 1335 1.10 christos check_ssid = ssid->ssid_len > 0 || 1336 1.10 christos !wpas_wps_ssid_wildcard_ok(wpa_s, ssid, bss); 1337 1.10 christos } 1338 1.10 christos #endif /* CONFIG_WPS */ 1339 1.7 christos 1340 1.10 christos if (ssid->bssid_set && ssid->ssid_len == 0 && 1341 1.10 christos ether_addr_equal(bss->bssid, ssid->bssid)) 1342 1.10 christos check_ssid = false; 1343 1.10 christos 1344 1.10 christos if (check_ssid && 1345 1.10 christos (match_ssid_len != ssid->ssid_len || 1346 1.10 christos os_memcmp(match_ssid, ssid->ssid, match_ssid_len) != 0)) { 1347 1.7 christos if (debug_print) 1348 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, " skip - SSID mismatch"); 1349 1.10 christos return false; 1350 1.2 joerg } 1351 1.2 joerg 1352 1.10 christos if (ssid->bssid_set && 1353 1.10 christos !ether_addr_equal(bss->bssid, ssid->bssid)) { 1354 1.7 christos if (debug_print) 1355 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, " skip - BSSID mismatch"); 1356 1.10 christos return false; 1357 1.2 joerg } 1358 1.2 joerg 1359 1.10 christos /* check the list of BSSIDs to ignore */ 1360 1.10 christos if (ssid->num_bssid_ignore && 1361 1.10 christos addr_in_list(bss->bssid, ssid->bssid_ignore, 1362 1.10 christos ssid->num_bssid_ignore)) { 1363 1.7 christos if (debug_print) 1364 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1365 1.10 christos " skip - BSSID configured to be ignored"); 1366 1.10 christos return false; 1367 1.2 joerg } 1368 1.2 joerg 1369 1.10 christos /* if there is a list of accepted BSSIDs, only accept those APs */ 1370 1.10 christos if (ssid->num_bssid_accept && 1371 1.10 christos !addr_in_list(bss->bssid, ssid->bssid_accept, 1372 1.10 christos ssid->num_bssid_accept)) { 1373 1.10 christos if (debug_print) 1374 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1375 1.10 christos " skip - BSSID not in list of accepted values"); 1376 1.10 christos return false; 1377 1.10 christos } 1378 1.2 joerg 1379 1.10 christos if (!wpa_supplicant_ssid_bss_match(wpa_s, ssid, bss, debug_print)) 1380 1.10 christos return false; 1381 1.2 joerg 1382 1.10 christos if (!osen && !wpa && 1383 1.10 christos !(ssid->key_mgmt & WPA_KEY_MGMT_NONE) && 1384 1.10 christos !(ssid->key_mgmt & WPA_KEY_MGMT_WPS) && 1385 1.10 christos !(ssid->key_mgmt & WPA_KEY_MGMT_OWE) && 1386 1.10 christos !(ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)) { 1387 1.10 christos if (debug_print) 1388 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1389 1.10 christos " skip - non-WPA network not allowed"); 1390 1.10 christos return false; 1391 1.10 christos } 1392 1.2 joerg 1393 1.10 christos #ifdef CONFIG_WEP 1394 1.10 christos if (wpa && !wpa_key_mgmt_wpa(ssid->key_mgmt) && has_wep_key(ssid)) { 1395 1.10 christos if (debug_print) 1396 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1397 1.10 christos " skip - ignore WPA/WPA2 AP for WEP network block"); 1398 1.10 christos return false; 1399 1.10 christos } 1400 1.10 christos #endif /* CONFIG_WEP */ 1401 1.1 christos 1402 1.10 christos if ((ssid->key_mgmt & WPA_KEY_MGMT_OSEN) && !osen && !rsn_osen) { 1403 1.10 christos if (debug_print) 1404 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1405 1.10 christos " skip - non-OSEN network not allowed"); 1406 1.10 christos return false; 1407 1.10 christos } 1408 1.2 joerg 1409 1.10 christos if (!wpa_supplicant_match_privacy(bss, ssid)) { 1410 1.10 christos if (debug_print) 1411 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, " skip - privacy mismatch"); 1412 1.10 christos return false; 1413 1.10 christos } 1414 1.2 joerg 1415 1.10 christos if (ssid->mode != WPAS_MODE_MESH && !bss_is_ess(bss) && 1416 1.10 christos !bss_is_pbss(bss)) { 1417 1.10 christos if (debug_print) 1418 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1419 1.10 christos " skip - not ESS, PBSS, or MBSS"); 1420 1.10 christos return false; 1421 1.10 christos } 1422 1.2 joerg 1423 1.10 christos if (ssid->pbss != 2 && ssid->pbss != bss_is_pbss(bss)) { 1424 1.10 christos if (debug_print) 1425 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1426 1.10 christos " skip - PBSS mismatch (ssid %d bss %d)", 1427 1.10 christos ssid->pbss, bss_is_pbss(bss)); 1428 1.10 christos return false; 1429 1.10 christos } 1430 1.2 joerg 1431 1.10 christos if (!freq_allowed(ssid->freq_list, bss->freq)) { 1432 1.10 christos if (debug_print) 1433 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1434 1.10 christos " skip - frequency not allowed"); 1435 1.10 christos return false; 1436 1.10 christos } 1437 1.3 christos 1438 1.10 christos #ifdef CONFIG_MESH 1439 1.10 christos if (ssid->mode == WPAS_MODE_MESH && ssid->frequency > 0 && 1440 1.10 christos ssid->frequency != bss->freq) { 1441 1.10 christos if (debug_print) 1442 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1443 1.10 christos " skip - frequency not allowed (mesh)"); 1444 1.10 christos return false; 1445 1.10 christos } 1446 1.10 christos #endif /* CONFIG_MESH */ 1447 1.3 christos 1448 1.10 christos if (!rate_match(wpa_s, ssid, bss, debug_print)) { 1449 1.10 christos if (debug_print) 1450 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1451 1.10 christos " skip - rate sets do not match"); 1452 1.10 christos return false; 1453 1.10 christos } 1454 1.2 joerg 1455 1.10 christos #ifdef CONFIG_SAE 1456 1.10 christos /* When using SAE Password Identifier and when operationg on the 6 GHz 1457 1.10 christos * band, only H2E is allowed. */ 1458 1.10 christos if ((wpa_s->conf->sae_pwe == SAE_PWE_HASH_TO_ELEMENT || 1459 1.10 christos is_6ghz_freq(bss->freq) || ssid->sae_password_id) && 1460 1.10 christos wpa_s->conf->sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK && 1461 1.10 christos wpa_key_mgmt_sae(ssid->key_mgmt) && 1462 1.10 christos !(rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_H2E))) { 1463 1.10 christos if (debug_print) 1464 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1465 1.10 christos " skip - SAE H2E required, but not supported by the AP"); 1466 1.10 christos return false; 1467 1.10 christos } 1468 1.10 christos #endif /* CONFIG_SAE */ 1469 1.1 christos 1470 1.10 christos #ifdef CONFIG_SAE_PK 1471 1.10 christos if (ssid->sae_pk == SAE_PK_MODE_ONLY && 1472 1.10 christos !(rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_PK))) { 1473 1.10 christos if (debug_print) 1474 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1475 1.10 christos " skip - SAE-PK required, but not supported by the AP"); 1476 1.10 christos return false; 1477 1.10 christos } 1478 1.10 christos #endif /* CONFIG_SAE_PK */ 1479 1.1 christos 1480 1.10 christos #ifndef CONFIG_IBSS_RSN 1481 1.10 christos if (ssid->mode == WPAS_MODE_IBSS && 1482 1.10 christos !(ssid->key_mgmt & (WPA_KEY_MGMT_NONE | WPA_KEY_MGMT_WPA_NONE))) { 1483 1.10 christos if (debug_print) 1484 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1485 1.10 christos " skip - IBSS RSN not supported in the build"); 1486 1.10 christos return false; 1487 1.10 christos } 1488 1.10 christos #endif /* !CONFIG_IBSS_RSN */ 1489 1.1 christos 1490 1.10 christos #ifdef CONFIG_P2P 1491 1.10 christos if (ssid->p2p_group && 1492 1.10 christos !wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) && 1493 1.10 christos !wpa_bss_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE)) { 1494 1.10 christos if (debug_print) 1495 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, " skip - no P2P IE seen"); 1496 1.10 christos return false; 1497 1.10 christos } 1498 1.1 christos 1499 1.10 christos if (!is_zero_ether_addr(ssid->go_p2p_dev_addr)) { 1500 1.10 christos struct wpabuf *p2p_ie; 1501 1.10 christos u8 dev_addr[ETH_ALEN]; 1502 1.6 christos 1503 1.10 christos ie = wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE); 1504 1.10 christos if (!ie) { 1505 1.7 christos if (debug_print) 1506 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 1507 1.10 christos " skip - no P2P element"); 1508 1.10 christos return false; 1509 1.2 joerg } 1510 1.10 christos p2p_ie = wpa_bss_get_vendor_ie_multi(bss, P2P_IE_VENDOR_TYPE); 1511 1.10 christos if (!p2p_ie) { 1512 1.7 christos if (debug_print) 1513 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 1514 1.10 christos " skip - could not fetch P2P element"); 1515 1.10 christos return false; 1516 1.2 joerg } 1517 1.1 christos 1518 1.10 christos if (p2p_parse_dev_addr_in_p2p_ie(p2p_ie, dev_addr) < 0 || 1519 1.10 christos !ether_addr_equal(dev_addr, ssid->go_p2p_dev_addr)) { 1520 1.7 christos if (debug_print) 1521 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 1522 1.10 christos " skip - no matching GO P2P Device Address in P2P element"); 1523 1.2 joerg wpabuf_free(p2p_ie); 1524 1.10 christos return false; 1525 1.2 joerg } 1526 1.10 christos wpabuf_free(p2p_ie); 1527 1.10 christos } 1528 1.1 christos 1529 1.10 christos /* 1530 1.10 christos * TODO: skip the AP if its P2P IE has Group Formation bit set in the 1531 1.10 christos * P2P Group Capability Bitmap and we are not in Group Formation with 1532 1.10 christos * that device. 1533 1.10 christos */ 1534 1.2 joerg #endif /* CONFIG_P2P */ 1535 1.1 christos 1536 1.10 christos if (os_reltime_before(&bss->last_update, &wpa_s->scan_min_time)) { 1537 1.10 christos struct os_reltime diff; 1538 1.6 christos 1539 1.10 christos os_reltime_sub(&wpa_s->scan_min_time, &bss->last_update, &diff); 1540 1.10 christos if (debug_print) 1541 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1542 1.10 christos " skip - scan result not recent enough (%u.%06u seconds too old)", 1543 1.6 christos (unsigned int) diff.sec, 1544 1.6 christos (unsigned int) diff.usec); 1545 1.10 christos return false; 1546 1.10 christos } 1547 1.6 christos #ifdef CONFIG_MBO 1548 1.6 christos #ifdef CONFIG_TESTING_OPTIONS 1549 1.10 christos if (wpa_s->ignore_assoc_disallow) 1550 1.10 christos goto skip_assoc_disallow; 1551 1.6 christos #endif /* CONFIG_TESTING_OPTIONS */ 1552 1.10 christos assoc_disallow = wpas_mbo_check_assoc_disallow(bss); 1553 1.10 christos if (assoc_disallow && assoc_disallow[1] >= 1) { 1554 1.10 christos if (debug_print) 1555 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1556 1.10 christos " skip - MBO association disallowed (reason %u)", 1557 1.6 christos assoc_disallow[2]); 1558 1.10 christos return false; 1559 1.10 christos } 1560 1.6 christos 1561 1.10 christos if (wpa_is_bss_tmp_disallowed(wpa_s, bss)) { 1562 1.10 christos if (debug_print) 1563 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1564 1.10 christos " skip - AP temporarily disallowed"); 1565 1.10 christos return false; 1566 1.10 christos } 1567 1.6 christos #ifdef CONFIG_TESTING_OPTIONS 1568 1.10 christos skip_assoc_disallow: 1569 1.6 christos #endif /* CONFIG_TESTING_OPTIONS */ 1570 1.6 christos #endif /* CONFIG_MBO */ 1571 1.6 christos 1572 1.7 christos #ifdef CONFIG_DPP 1573 1.10 christos if ((ssid->key_mgmt & WPA_KEY_MGMT_DPP) && 1574 1.10 christos !wpa_sm_pmksa_exists(wpa_s->wpa, bss->bssid, wpa_s->own_addr, 1575 1.10 christos ssid) && 1576 1.10 christos (!ssid->dpp_connector || !ssid->dpp_netaccesskey || 1577 1.10 christos !ssid->dpp_csign)) { 1578 1.10 christos if (debug_print) 1579 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1580 1.10 christos " skip - no PMKSA entry for DPP"); 1581 1.10 christos return false; 1582 1.10 christos } 1583 1.10 christos #endif /* CONFIG_DPP */ 1584 1.10 christos 1585 1.10 christos #ifdef CONFIG_SAE_PK 1586 1.10 christos if (ssid->sae_pk == SAE_PK_MODE_AUTOMATIC && 1587 1.10 christos wpa_key_mgmt_sae(ssid->key_mgmt) && 1588 1.10 christos ((ssid->sae_password && 1589 1.10 christos sae_pk_valid_password(ssid->sae_password)) || 1590 1.10 christos (!ssid->sae_password && ssid->passphrase && 1591 1.10 christos sae_pk_valid_password(ssid->passphrase))) && 1592 1.10 christos !(rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_PK)) && 1593 1.10 christos sae_pk_acceptable_bss_with_pk(wpa_s, bss, ssid, match_ssid, 1594 1.10 christos match_ssid_len)) { 1595 1.10 christos if (debug_print) 1596 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1597 1.10 christos " skip - another acceptable BSS with SAE-PK in the same ESS"); 1598 1.10 christos return false; 1599 1.10 christos } 1600 1.10 christos #endif /* CONFIG_SAE_PK */ 1601 1.10 christos 1602 1.10 christos if (bss->ssid_len == 0) { 1603 1.10 christos #ifdef CONFIG_OWE 1604 1.10 christos const u8 *owe_ssid = NULL; 1605 1.10 christos size_t owe_ssid_len = 0; 1606 1.10 christos 1607 1.10 christos owe_trans_ssid(wpa_s, bss, &owe_ssid, &owe_ssid_len); 1608 1.10 christos if (owe_ssid && owe_ssid_len && 1609 1.10 christos owe_ssid_len == ssid->ssid_len && 1610 1.10 christos os_memcmp(owe_ssid, ssid->ssid, owe_ssid_len) == 0) { 1611 1.7 christos if (debug_print) 1612 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 1613 1.10 christos " skip - no SSID in BSS entry for a possible OWE transition mode BSS"); 1614 1.10 christos int_array_add_unique(&wpa_s->owe_trans_scan_freq, 1615 1.10 christos bss->freq); 1616 1.10 christos return false; 1617 1.10 christos } 1618 1.10 christos #endif /* CONFIG_OWE */ 1619 1.10 christos if (debug_print) 1620 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1621 1.10 christos " skip - no SSID known for the BSS"); 1622 1.10 christos return false; 1623 1.10 christos } 1624 1.10 christos 1625 1.10 christos if (!wpas_valid_ml_bss(wpa_s, bss)) { 1626 1.10 christos if (debug_print) 1627 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1628 1.10 christos " skip - ML BSS going to be removed"); 1629 1.10 christos return false; 1630 1.10 christos } 1631 1.10 christos 1632 1.10 christos /* Matching configuration found */ 1633 1.10 christos return true; 1634 1.10 christos } 1635 1.10 christos 1636 1.10 christos 1637 1.10 christos struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s, 1638 1.10 christos int i, struct wpa_bss *bss, 1639 1.10 christos struct wpa_ssid *group, 1640 1.10 christos int only_first_ssid, int debug_print) 1641 1.10 christos { 1642 1.10 christos u8 wpa_ie_len, rsn_ie_len; 1643 1.10 christos const u8 *ie; 1644 1.10 christos struct wpa_ssid *ssid; 1645 1.10 christos int osen; 1646 1.10 christos const u8 *match_ssid; 1647 1.10 christos size_t match_ssid_len; 1648 1.10 christos int bssid_ignore_count; 1649 1.10 christos 1650 1.10 christos ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); 1651 1.10 christos wpa_ie_len = ie ? ie[1] : 0; 1652 1.10 christos 1653 1.10 christos ie = wpa_bss_get_ie(bss, WLAN_EID_RSN); 1654 1.10 christos rsn_ie_len = ie ? ie[1] : 0; 1655 1.10 christos 1656 1.10 christos ie = wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE); 1657 1.10 christos osen = ie != NULL; 1658 1.10 christos 1659 1.10 christos if (debug_print) { 1660 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, "%d: " MACSTR 1661 1.10 christos " ssid='%s' wpa_ie_len=%u rsn_ie_len=%u caps=0x%x level=%d freq=%d %s%s%s", 1662 1.10 christos i, MAC2STR(bss->bssid), 1663 1.10 christos wpa_ssid_txt(bss->ssid, bss->ssid_len), 1664 1.10 christos wpa_ie_len, rsn_ie_len, bss->caps, bss->level, 1665 1.10 christos bss->freq, 1666 1.10 christos wpa_bss_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE) ? 1667 1.10 christos " wps" : "", 1668 1.10 christos (wpa_bss_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) || 1669 1.10 christos wpa_bss_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE)) 1670 1.10 christos ? " p2p" : "", 1671 1.10 christos osen ? " osen=1" : ""); 1672 1.10 christos } 1673 1.10 christos 1674 1.10 christos bssid_ignore_count = wpa_bssid_ignore_is_listed(wpa_s, bss->bssid); 1675 1.10 christos if (bssid_ignore_count) { 1676 1.10 christos int limit = 1; 1677 1.10 christos if (wpa_supplicant_enabled_networks(wpa_s) == 1) { 1678 1.10 christos /* 1679 1.10 christos * When only a single network is enabled, we can 1680 1.10 christos * trigger BSSID ignoring on the first failure. This 1681 1.10 christos * should not be done with multiple enabled networks to 1682 1.10 christos * avoid getting forced to move into a worse ESS on 1683 1.10 christos * single error if there are no other BSSes of the 1684 1.10 christos * current ESS. 1685 1.10 christos */ 1686 1.10 christos limit = 0; 1687 1.10 christos } 1688 1.10 christos if (bssid_ignore_count > limit) { 1689 1.10 christos if (debug_print) { 1690 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1691 1.10 christos " skip - BSSID ignored (count=%d limit=%d)", 1692 1.10 christos bssid_ignore_count, limit); 1693 1.10 christos } 1694 1.10 christos return NULL; 1695 1.10 christos } 1696 1.10 christos } 1697 1.10 christos 1698 1.10 christos match_ssid = bss->ssid; 1699 1.10 christos match_ssid_len = bss->ssid_len; 1700 1.10 christos owe_trans_ssid(wpa_s, bss, &match_ssid, &match_ssid_len); 1701 1.10 christos 1702 1.10 christos if (match_ssid_len == 0) { 1703 1.10 christos if (debug_print) 1704 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, " skip - SSID not known"); 1705 1.10 christos return NULL; 1706 1.10 christos } 1707 1.10 christos 1708 1.10 christos if (disallowed_bssid(wpa_s, bss->bssid)) { 1709 1.10 christos if (debug_print) 1710 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, " skip - BSSID disallowed"); 1711 1.10 christos return NULL; 1712 1.10 christos } 1713 1.10 christos 1714 1.10 christos if (disallowed_ssid(wpa_s, match_ssid, match_ssid_len)) { 1715 1.10 christos if (debug_print) 1716 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, " skip - SSID disallowed"); 1717 1.10 christos return NULL; 1718 1.10 christos } 1719 1.10 christos 1720 1.10 christos if (disabled_freq(wpa_s, bss->freq)) { 1721 1.10 christos if (debug_print) 1722 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, " skip - channel disabled"); 1723 1.10 christos return NULL; 1724 1.10 christos } 1725 1.10 christos 1726 1.10 christos if (wnm_is_bss_excluded(wpa_s, bss)) { 1727 1.10 christos if (debug_print) 1728 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, " skip - BSSID excluded"); 1729 1.10 christos return NULL; 1730 1.10 christos } 1731 1.7 christos 1732 1.10 christos for (ssid = group; ssid; ssid = only_first_ssid ? NULL : ssid->pnext) { 1733 1.10 christos if (wpa_scan_res_ok(wpa_s, ssid, match_ssid, match_ssid_len, 1734 1.10 christos bss, bssid_ignore_count, debug_print)) 1735 1.10 christos return ssid; 1736 1.1 christos } 1737 1.1 christos 1738 1.2 joerg /* No matching configuration found */ 1739 1.1 christos return NULL; 1740 1.1 christos } 1741 1.1 christos 1742 1.1 christos 1743 1.1 christos static struct wpa_bss * 1744 1.1 christos wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, 1745 1.1 christos struct wpa_ssid *group, 1746 1.2 joerg struct wpa_ssid **selected_ssid, 1747 1.2 joerg int only_first_ssid) 1748 1.1 christos { 1749 1.2 joerg unsigned int i; 1750 1.2 joerg 1751 1.7 christos if (wpa_s->current_ssid) { 1752 1.7 christos struct wpa_ssid *ssid; 1753 1.7 christos 1754 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 1755 1.7 christos "Scan results matching the currently selected network"); 1756 1.7 christos for (i = 0; i < wpa_s->last_scan_res_used; i++) { 1757 1.7 christos struct wpa_bss *bss = wpa_s->last_scan_res[i]; 1758 1.7 christos 1759 1.7 christos ssid = wpa_scan_res_match(wpa_s, i, bss, group, 1760 1.7 christos only_first_ssid, 0); 1761 1.7 christos if (ssid != wpa_s->current_ssid) 1762 1.7 christos continue; 1763 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, "%u: " MACSTR 1764 1.7 christos " freq=%d level=%d snr=%d est_throughput=%u", 1765 1.7 christos i, MAC2STR(bss->bssid), bss->freq, bss->level, 1766 1.7 christos bss->snr, bss->est_throughput); 1767 1.7 christos } 1768 1.7 christos } 1769 1.7 christos 1770 1.2 joerg if (only_first_ssid) 1771 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Try to find BSS matching pre-selected network id=%d", 1772 1.2 joerg group->id); 1773 1.2 joerg else 1774 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Selecting BSS from priority group %d", 1775 1.2 joerg group->priority); 1776 1.1 christos 1777 1.2 joerg for (i = 0; i < wpa_s->last_scan_res_used; i++) { 1778 1.2 joerg struct wpa_bss *bss = wpa_s->last_scan_res[i]; 1779 1.7 christos 1780 1.7 christos wpa_s->owe_transition_select = 1; 1781 1.2 joerg *selected_ssid = wpa_scan_res_match(wpa_s, i, bss, group, 1782 1.7 christos only_first_ssid, 1); 1783 1.7 christos wpa_s->owe_transition_select = 0; 1784 1.2 joerg if (!*selected_ssid) 1785 1.2 joerg continue; 1786 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, " selected %sBSS " MACSTR 1787 1.2 joerg " ssid='%s'", 1788 1.10 christos bss == wpa_s->current_bss ? "current ": "", 1789 1.2 joerg MAC2STR(bss->bssid), 1790 1.2 joerg wpa_ssid_txt(bss->ssid, bss->ssid_len)); 1791 1.2 joerg return bss; 1792 1.2 joerg } 1793 1.1 christos 1794 1.2 joerg return NULL; 1795 1.1 christos } 1796 1.1 christos 1797 1.1 christos 1798 1.2 joerg struct wpa_bss * wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s, 1799 1.2 joerg struct wpa_ssid **selected_ssid) 1800 1.1 christos { 1801 1.1 christos struct wpa_bss *selected = NULL; 1802 1.10 christos size_t prio; 1803 1.2 joerg struct wpa_ssid *next_ssid = NULL; 1804 1.6 christos struct wpa_ssid *ssid; 1805 1.2 joerg 1806 1.2 joerg if (wpa_s->last_scan_res == NULL || 1807 1.2 joerg wpa_s->last_scan_res_used == 0) 1808 1.2 joerg return NULL; /* no scan results from last update */ 1809 1.2 joerg 1810 1.2 joerg if (wpa_s->next_ssid) { 1811 1.2 joerg /* check that next_ssid is still valid */ 1812 1.2 joerg for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { 1813 1.2 joerg if (ssid == wpa_s->next_ssid) 1814 1.2 joerg break; 1815 1.2 joerg } 1816 1.2 joerg next_ssid = ssid; 1817 1.2 joerg wpa_s->next_ssid = NULL; 1818 1.2 joerg } 1819 1.1 christos 1820 1.1 christos while (selected == NULL) { 1821 1.1 christos for (prio = 0; prio < wpa_s->conf->num_prio; prio++) { 1822 1.2 joerg if (next_ssid && next_ssid->priority == 1823 1.2 joerg wpa_s->conf->pssid[prio]->priority) { 1824 1.2 joerg selected = wpa_supplicant_select_bss( 1825 1.2 joerg wpa_s, next_ssid, selected_ssid, 1); 1826 1.2 joerg if (selected) 1827 1.2 joerg break; 1828 1.2 joerg } 1829 1.1 christos selected = wpa_supplicant_select_bss( 1830 1.2 joerg wpa_s, wpa_s->conf->pssid[prio], 1831 1.2 joerg selected_ssid, 0); 1832 1.1 christos if (selected) 1833 1.1 christos break; 1834 1.1 christos } 1835 1.1 christos 1836 1.10 christos if (!selected && 1837 1.10 christos (wpa_s->bssid_ignore || wnm_active_bss_trans_mgmt(wpa_s)) && 1838 1.2 joerg !wpa_s->countermeasures) { 1839 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1840 1.10 christos "No APs found - clear BSSID ignore list and try again"); 1841 1.10 christos wnm_btm_reset(wpa_s); 1842 1.10 christos wpa_bssid_ignore_clear(wpa_s); 1843 1.10 christos wpa_s->bssid_ignore_cleared = true; 1844 1.1 christos } else if (selected == NULL) 1845 1.1 christos break; 1846 1.1 christos } 1847 1.1 christos 1848 1.6 christos ssid = *selected_ssid; 1849 1.6 christos if (selected && ssid && ssid->mem_only_psk && !ssid->psk_set && 1850 1.6 christos !ssid->passphrase && !ssid->ext_psk) { 1851 1.6 christos const char *field_name, *txt = NULL; 1852 1.6 christos 1853 1.6 christos wpa_dbg(wpa_s, MSG_DEBUG, 1854 1.6 christos "PSK/passphrase not yet available for the selected network"); 1855 1.6 christos 1856 1.6 christos wpas_notify_network_request(wpa_s, ssid, 1857 1.6 christos WPA_CTRL_REQ_PSK_PASSPHRASE, NULL); 1858 1.6 christos 1859 1.6 christos field_name = wpa_supplicant_ctrl_req_to_string( 1860 1.6 christos WPA_CTRL_REQ_PSK_PASSPHRASE, NULL, &txt); 1861 1.6 christos if (field_name == NULL) 1862 1.6 christos return NULL; 1863 1.6 christos 1864 1.6 christos wpas_send_ctrl_req(wpa_s, ssid, field_name, txt); 1865 1.6 christos 1866 1.6 christos selected = NULL; 1867 1.6 christos } 1868 1.6 christos 1869 1.1 christos return selected; 1870 1.1 christos } 1871 1.1 christos 1872 1.1 christos 1873 1.1 christos static void wpa_supplicant_req_new_scan(struct wpa_supplicant *wpa_s, 1874 1.1 christos int timeout_sec, int timeout_usec) 1875 1.1 christos { 1876 1.2 joerg if (!wpa_supplicant_enabled_networks(wpa_s)) { 1877 1.1 christos /* 1878 1.1 christos * No networks are enabled; short-circuit request so 1879 1.1 christos * we don't wait timeout seconds before transitioning 1880 1.1 christos * to INACTIVE state. 1881 1.1 christos */ 1882 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Short-circuit new scan request " 1883 1.2 joerg "since there are no enabled networks"); 1884 1.1 christos wpa_supplicant_set_state(wpa_s, WPA_INACTIVE); 1885 1.1 christos return; 1886 1.1 christos } 1887 1.2 joerg 1888 1.2 joerg wpa_s->scan_for_connection = 1; 1889 1.1 christos wpa_supplicant_req_scan(wpa_s, timeout_sec, timeout_usec); 1890 1.1 christos } 1891 1.1 christos 1892 1.1 christos 1893 1.10 christos static bool ml_link_probe_scan(struct wpa_supplicant *wpa_s) 1894 1.10 christos { 1895 1.10 christos if (!wpa_s->ml_connect_probe_ssid || !wpa_s->ml_connect_probe_bss) 1896 1.10 christos return false; 1897 1.10 christos 1898 1.10 christos wpa_msg(wpa_s, MSG_DEBUG, 1899 1.10 christos "Request association with " MACSTR " after ML probe", 1900 1.10 christos MAC2STR(wpa_s->ml_connect_probe_bss->bssid)); 1901 1.10 christos 1902 1.10 christos wpa_supplicant_associate(wpa_s, wpa_s->ml_connect_probe_bss, 1903 1.10 christos wpa_s->ml_connect_probe_ssid); 1904 1.10 christos 1905 1.10 christos wpa_s->ml_connect_probe_ssid = NULL; 1906 1.10 christos wpa_s->ml_connect_probe_bss = NULL; 1907 1.10 christos 1908 1.10 christos return true; 1909 1.10 christos } 1910 1.10 christos 1911 1.10 christos 1912 1.10 christos static int wpa_supplicant_connect_ml_missing(struct wpa_supplicant *wpa_s, 1913 1.10 christos struct wpa_bss *selected, 1914 1.10 christos struct wpa_ssid *ssid) 1915 1.10 christos { 1916 1.10 christos int *freqs; 1917 1.10 christos u16 missing_links = 0, removed_links; 1918 1.10 christos u8 ap_mld_id; 1919 1.10 christos 1920 1.10 christos if (!((wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_MLO) && 1921 1.10 christos (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME))) 1922 1.10 christos return 0; 1923 1.10 christos 1924 1.10 christos if (wpa_bss_parse_basic_ml_element(wpa_s, selected, NULL, 1925 1.10 christos &missing_links, ssid, 1926 1.10 christos &ap_mld_id) || 1927 1.10 christos !missing_links) 1928 1.10 christos return 0; 1929 1.10 christos 1930 1.10 christos removed_links = wpa_bss_parse_reconf_ml_element(wpa_s, selected); 1931 1.10 christos missing_links &= ~removed_links; 1932 1.10 christos 1933 1.10 christos if (!missing_links) 1934 1.10 christos return 0; 1935 1.10 christos 1936 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 1937 1.10 christos "MLD: Doing an ML probe for missing links 0x%04x", 1938 1.10 christos missing_links); 1939 1.10 christos 1940 1.10 christos freqs = os_malloc(sizeof(int) * 2); 1941 1.10 christos if (!freqs) 1942 1.10 christos return 0; 1943 1.10 christos 1944 1.10 christos wpa_s->ml_connect_probe_ssid = ssid; 1945 1.10 christos wpa_s->ml_connect_probe_bss = selected; 1946 1.10 christos 1947 1.10 christos freqs[0] = selected->freq; 1948 1.10 christos freqs[1] = 0; 1949 1.10 christos 1950 1.10 christos wpa_s->manual_scan_passive = 0; 1951 1.10 christos wpa_s->manual_scan_use_id = 0; 1952 1.10 christos wpa_s->manual_scan_only_new = 0; 1953 1.10 christos wpa_s->scan_id_count = 0; 1954 1.10 christos os_free(wpa_s->manual_scan_freqs); 1955 1.10 christos wpa_s->manual_scan_freqs = freqs; 1956 1.10 christos 1957 1.10 christos os_memcpy(wpa_s->ml_probe_bssid, selected->bssid, ETH_ALEN); 1958 1.10 christos 1959 1.10 christos /* 1960 1.10 christos * In case the ML probe request is intended to retrieve information from 1961 1.10 christos * the transmitted BSS, the AP MLD ID should be included and should be 1962 1.10 christos * set to zero. 1963 1.10 christos * In case the ML probe requested is intended to retrieve information 1964 1.10 christos * from a non-transmitted BSS, the AP MLD ID should not be included. 1965 1.10 christos */ 1966 1.10 christos if (ap_mld_id) 1967 1.10 christos wpa_s->ml_probe_mld_id = -1; 1968 1.10 christos else 1969 1.10 christos wpa_s->ml_probe_mld_id = 0; 1970 1.10 christos 1971 1.10 christos if (ssid && ssid->ssid_len) { 1972 1.10 christos os_free(wpa_s->ssids_from_scan_req); 1973 1.10 christos wpa_s->num_ssids_from_scan_req = 0; 1974 1.10 christos 1975 1.10 christos wpa_s->ssids_from_scan_req = 1976 1.10 christos os_zalloc(sizeof(struct wpa_ssid_value)); 1977 1.10 christos if (wpa_s->ssids_from_scan_req) { 1978 1.10 christos wpa_printf(MSG_DEBUG, 1979 1.10 christos "MLD: ML probe: With direct SSID"); 1980 1.10 christos 1981 1.10 christos wpa_s->num_ssids_from_scan_req = 1; 1982 1.10 christos wpa_s->ssids_from_scan_req[0].ssid_len = ssid->ssid_len; 1983 1.10 christos os_memcpy(wpa_s->ssids_from_scan_req[0].ssid, 1984 1.10 christos ssid->ssid, ssid->ssid_len); 1985 1.10 christos } 1986 1.10 christos } 1987 1.10 christos 1988 1.10 christos wpa_s->ml_probe_links = missing_links; 1989 1.10 christos 1990 1.10 christos wpa_s->normal_scans = 0; 1991 1.10 christos wpa_s->scan_req = MANUAL_SCAN_REQ; 1992 1.10 christos wpa_s->after_wps = 0; 1993 1.10 christos wpa_s->known_wps_freq = 0; 1994 1.10 christos wpa_supplicant_req_scan(wpa_s, 0, 0); 1995 1.10 christos 1996 1.10 christos return 1; 1997 1.10 christos } 1998 1.10 christos 1999 1.10 christos 2000 1.2 joerg int wpa_supplicant_connect(struct wpa_supplicant *wpa_s, 2001 1.2 joerg struct wpa_bss *selected, 2002 1.2 joerg struct wpa_ssid *ssid) 2003 1.1 christos { 2004 1.10 christos #ifdef IEEE8021X_EAPOL 2005 1.10 christos if ((eap_is_wps_pbc_enrollee(&ssid->eap) && 2006 1.10 christos wpas_wps_partner_link_overlap_detect(wpa_s)) || 2007 1.10 christos wpas_wps_scan_pbc_overlap(wpa_s, selected, ssid)) { 2008 1.1 christos wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP 2009 1.1 christos "PBC session overlap"); 2010 1.6 christos wpas_notify_wps_event_pbc_overlap(wpa_s); 2011 1.10 christos wpa_s->wps_overlap = true; 2012 1.2 joerg #ifdef CONFIG_P2P 2013 1.2 joerg if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT || 2014 1.2 joerg wpa_s->p2p_in_provisioning) { 2015 1.2 joerg eloop_register_timeout(0, 0, wpas_p2p_pbc_overlap_cb, 2016 1.2 joerg wpa_s, NULL); 2017 1.2 joerg return -1; 2018 1.2 joerg } 2019 1.2 joerg #endif /* CONFIG_P2P */ 2020 1.2 joerg 2021 1.2 joerg #ifdef CONFIG_WPS 2022 1.6 christos wpas_wps_pbc_overlap(wpa_s); 2023 1.2 joerg wpas_wps_cancel(wpa_s); 2024 1.2 joerg #endif /* CONFIG_WPS */ 2025 1.2 joerg return -1; 2026 1.1 christos } 2027 1.10 christos #endif /* IEEE8021X_EAPOL */ 2028 1.1 christos 2029 1.2 joerg wpa_msg(wpa_s, MSG_DEBUG, 2030 1.2 joerg "Considering connect request: reassociate: %d selected: " 2031 1.2 joerg MACSTR " bssid: " MACSTR " pending: " MACSTR 2032 1.2 joerg " wpa_state: %s ssid=%p current_ssid=%p", 2033 1.2 joerg wpa_s->reassociate, MAC2STR(selected->bssid), 2034 1.2 joerg MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid), 2035 1.2 joerg wpa_supplicant_state_txt(wpa_s->wpa_state), 2036 1.2 joerg ssid, wpa_s->current_ssid); 2037 1.2 joerg 2038 1.1 christos /* 2039 1.1 christos * Do not trigger new association unless the BSSID has changed or if 2040 1.1 christos * reassociation is requested. If we are in process of associating with 2041 1.1 christos * the selected BSSID, do not trigger new attempt. 2042 1.1 christos */ 2043 1.1 christos if (wpa_s->reassociate || 2044 1.10 christos (!ether_addr_equal(selected->bssid, wpa_s->bssid) && 2045 1.2 joerg ((wpa_s->wpa_state != WPA_ASSOCIATING && 2046 1.2 joerg wpa_s->wpa_state != WPA_AUTHENTICATING) || 2047 1.2 joerg (!is_zero_ether_addr(wpa_s->pending_bssid) && 2048 1.10 christos !ether_addr_equal(selected->bssid, wpa_s->pending_bssid)) || 2049 1.2 joerg (is_zero_ether_addr(wpa_s->pending_bssid) && 2050 1.2 joerg ssid != wpa_s->current_ssid)))) { 2051 1.1 christos if (wpa_supplicant_scard_init(wpa_s, ssid)) { 2052 1.1 christos wpa_supplicant_req_new_scan(wpa_s, 10, 0); 2053 1.2 joerg return 0; 2054 1.1 christos } 2055 1.10 christos 2056 1.10 christos if (wpa_supplicant_connect_ml_missing(wpa_s, selected, ssid)) 2057 1.10 christos return 0; 2058 1.10 christos 2059 1.2 joerg wpa_msg(wpa_s, MSG_DEBUG, "Request association with " MACSTR, 2060 1.2 joerg MAC2STR(selected->bssid)); 2061 1.1 christos wpa_supplicant_associate(wpa_s, selected, ssid); 2062 1.1 christos } else { 2063 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Already associated or trying to " 2064 1.2 joerg "connect with the selected AP"); 2065 1.1 christos } 2066 1.2 joerg 2067 1.2 joerg return 0; 2068 1.1 christos } 2069 1.1 christos 2070 1.1 christos 2071 1.1 christos static struct wpa_ssid * 2072 1.1 christos wpa_supplicant_pick_new_network(struct wpa_supplicant *wpa_s) 2073 1.1 christos { 2074 1.10 christos size_t prio; 2075 1.1 christos struct wpa_ssid *ssid; 2076 1.1 christos 2077 1.1 christos for (prio = 0; prio < wpa_s->conf->num_prio; prio++) { 2078 1.1 christos for (ssid = wpa_s->conf->pssid[prio]; ssid; ssid = ssid->pnext) 2079 1.1 christos { 2080 1.2 joerg if (wpas_network_disabled(wpa_s, ssid)) 2081 1.1 christos continue; 2082 1.7 christos #ifndef CONFIG_IBSS_RSN 2083 1.7 christos if (ssid->mode == WPAS_MODE_IBSS && 2084 1.7 christos !(ssid->key_mgmt & (WPA_KEY_MGMT_NONE | 2085 1.7 christos WPA_KEY_MGMT_WPA_NONE))) { 2086 1.7 christos wpa_msg(wpa_s, MSG_INFO, 2087 1.7 christos "IBSS RSN not supported in the build - cannot use the profile for SSID '%s'", 2088 1.7 christos wpa_ssid_txt(ssid->ssid, 2089 1.7 christos ssid->ssid_len)); 2090 1.7 christos continue; 2091 1.7 christos } 2092 1.7 christos #endif /* !CONFIG_IBSS_RSN */ 2093 1.9 christos if (ssid->mode == WPAS_MODE_IBSS || 2094 1.9 christos ssid->mode == WPAS_MODE_AP || 2095 1.9 christos ssid->mode == WPAS_MODE_MESH) 2096 1.1 christos return ssid; 2097 1.1 christos } 2098 1.1 christos } 2099 1.1 christos return NULL; 2100 1.1 christos } 2101 1.1 christos 2102 1.1 christos 2103 1.1 christos /* TODO: move the rsn_preauth_scan_result*() to be called from notify.c based 2104 1.1 christos * on BSS added and BSS changed events */ 2105 1.1 christos static void wpa_supplicant_rsn_preauth_scan_results( 2106 1.2 joerg struct wpa_supplicant *wpa_s) 2107 1.1 christos { 2108 1.2 joerg struct wpa_bss *bss; 2109 1.1 christos 2110 1.1 christos if (rsn_preauth_scan_results(wpa_s->wpa) < 0) 2111 1.1 christos return; 2112 1.1 christos 2113 1.2 joerg dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { 2114 1.1 christos const u8 *ssid, *rsn; 2115 1.1 christos 2116 1.2 joerg ssid = wpa_bss_get_ie(bss, WLAN_EID_SSID); 2117 1.1 christos if (ssid == NULL) 2118 1.1 christos continue; 2119 1.1 christos 2120 1.2 joerg rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN); 2121 1.1 christos if (rsn == NULL) 2122 1.1 christos continue; 2123 1.1 christos 2124 1.2 joerg rsn_preauth_scan_result(wpa_s->wpa, bss->bssid, ssid, rsn); 2125 1.1 christos } 2126 1.1 christos 2127 1.1 christos } 2128 1.1 christos 2129 1.1 christos 2130 1.10 christos #ifndef CONFIG_NO_ROAMING 2131 1.10 christos 2132 1.10 christos static int wpas_get_snr_signal_info(u32 frequency, int avg_signal, int noise) 2133 1.1 christos { 2134 1.10 christos if (noise == WPA_INVALID_NOISE) { 2135 1.10 christos if (IS_5GHZ(frequency)) { 2136 1.10 christos noise = DEFAULT_NOISE_FLOOR_5GHZ; 2137 1.10 christos } else if (is_6ghz_freq(frequency)) { 2138 1.10 christos noise = DEFAULT_NOISE_FLOOR_6GHZ; 2139 1.10 christos } else { 2140 1.10 christos noise = DEFAULT_NOISE_FLOOR_2GHZ; 2141 1.10 christos } 2142 1.10 christos } 2143 1.10 christos return avg_signal - noise; 2144 1.10 christos } 2145 1.10 christos 2146 1.1 christos 2147 1.10 christos static unsigned int 2148 1.10 christos wpas_get_est_throughput_from_bss_snr(const struct wpa_supplicant *wpa_s, 2149 1.10 christos const struct wpa_bss *bss, int snr) 2150 1.10 christos { 2151 1.10 christos int rate = wpa_bss_get_max_rate(bss); 2152 1.10 christos const u8 *ies = wpa_bss_ie_ptr(bss); 2153 1.10 christos size_t ie_len = bss->ie_len ? bss->ie_len : bss->beacon_ie_len; 2154 1.10 christos enum chan_width max_cw = CHAN_WIDTH_UNKNOWN; 2155 1.1 christos 2156 1.10 christos return wpas_get_est_tpt(wpa_s, ies, ie_len, rate, snr, bss->freq, 2157 1.10 christos &max_cw); 2158 1.10 christos } 2159 1.1 christos 2160 1.1 christos 2161 1.10 christos static int wpas_evaluate_band_score(int frequency) 2162 1.10 christos { 2163 1.10 christos if (is_6ghz_freq(frequency)) 2164 1.10 christos return 2; 2165 1.10 christos if (IS_5GHZ(frequency)) 2166 1.10 christos return 1; 2167 1.10 christos return 0; 2168 1.10 christos } 2169 1.1 christos 2170 1.2 joerg 2171 1.10 christos int wpa_supplicant_need_to_roam_within_ess(struct wpa_supplicant *wpa_s, 2172 1.10 christos struct wpa_bss *current_bss, 2173 1.10 christos struct wpa_bss *selected) 2174 1.10 christos { 2175 1.10 christos int min_diff, diff; 2176 1.10 christos int cur_band_score, sel_band_score; 2177 1.10 christos int to_5ghz, to_6ghz; 2178 1.10 christos int cur_level, sel_level; 2179 1.10 christos unsigned int cur_est, sel_est; 2180 1.10 christos struct wpa_signal_info si; 2181 1.10 christos int cur_snr = 0; 2182 1.10 christos int ret = 0; 2183 1.10 christos const u8 *cur_ies = wpa_bss_ie_ptr(current_bss); 2184 1.10 christos const u8 *sel_ies = wpa_bss_ie_ptr(selected); 2185 1.10 christos size_t cur_ie_len = current_bss->ie_len ? current_bss->ie_len : 2186 1.10 christos current_bss->beacon_ie_len; 2187 1.10 christos size_t sel_ie_len = selected->ie_len ? selected->ie_len : 2188 1.10 christos selected->beacon_ie_len; 2189 1.2 joerg 2190 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Considering within-ESS reassociation"); 2191 1.3 christos wpa_dbg(wpa_s, MSG_DEBUG, "Current BSS: " MACSTR 2192 1.7 christos " freq=%d level=%d snr=%d est_throughput=%u", 2193 1.7 christos MAC2STR(current_bss->bssid), 2194 1.7 christos current_bss->freq, current_bss->level, 2195 1.3 christos current_bss->snr, current_bss->est_throughput); 2196 1.3 christos wpa_dbg(wpa_s, MSG_DEBUG, "Selected BSS: " MACSTR 2197 1.7 christos " freq=%d level=%d snr=%d est_throughput=%u", 2198 1.7 christos MAC2STR(selected->bssid), selected->freq, selected->level, 2199 1.3 christos selected->snr, selected->est_throughput); 2200 1.1 christos 2201 1.10 christos if (wpas_ap_link_address(wpa_s, selected->bssid)) { 2202 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, "MLD: associated to selected BSS"); 2203 1.10 christos return 0; 2204 1.10 christos } 2205 1.10 christos 2206 1.1 christos if (wpa_s->current_ssid->bssid_set && 2207 1.10 christos ether_addr_equal(selected->bssid, wpa_s->current_ssid->bssid)) { 2208 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Allow reassociation - selected BSS " 2209 1.2 joerg "has preferred BSSID"); 2210 1.1 christos return 1; 2211 1.1 christos } 2212 1.1 christos 2213 1.10 christos /* 2214 1.10 christos * Try to poll the signal from the driver since this will allow to get 2215 1.10 christos * more accurate values. In some cases, there can be big differences 2216 1.10 christos * between the RSSI of the Probe Response frames of the AP we are 2217 1.10 christos * associated with and the Beacon frames we hear from the same AP after 2218 1.10 christos * association. This can happen, e.g., when there are two antennas that 2219 1.10 christos * hear the AP very differently. If the driver chooses to hear the 2220 1.10 christos * Probe Response frames during the scan on the "bad" antenna because 2221 1.10 christos * it wants to save power, but knows to choose the other antenna after 2222 1.10 christos * association, we will hear our AP with a low RSSI as part of the 2223 1.10 christos * scan even when we can hear it decently on the other antenna. To cope 2224 1.10 christos * with this, ask the driver to teach us how it hears the AP. Also, the 2225 1.10 christos * scan results may be a bit old, since we can very quickly get fresh 2226 1.10 christos * information about our currently associated AP. 2227 1.10 christos */ 2228 1.10 christos if (wpa_drv_signal_poll(wpa_s, &si) == 0 && 2229 1.10 christos (si.data.avg_beacon_signal || si.data.avg_signal)) { 2230 1.10 christos /* 2231 1.10 christos * Normalize avg_signal to the RSSI over 20 MHz, as the 2232 1.10 christos * throughput is estimated based on the RSSI over 20 MHz 2233 1.10 christos */ 2234 1.10 christos cur_level = si.data.avg_beacon_signal ? 2235 1.10 christos si.data.avg_beacon_signal : 2236 1.10 christos (si.data.avg_signal - 2237 1.10 christos wpas_channel_width_rssi_bump(cur_ies, cur_ie_len, 2238 1.10 christos si.chanwidth)); 2239 1.10 christos cur_snr = wpas_get_snr_signal_info(si.frequency, cur_level, 2240 1.10 christos si.current_noise); 2241 1.10 christos 2242 1.10 christos cur_est = wpas_get_est_throughput_from_bss_snr(wpa_s, 2243 1.10 christos current_bss, 2244 1.10 christos cur_snr); 2245 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 2246 1.10 christos "Using signal poll values for the current BSS: level=%d snr=%d est_throughput=%u", 2247 1.10 christos cur_level, cur_snr, cur_est); 2248 1.10 christos } else { 2249 1.10 christos /* Level and SNR are measured over 20 MHz channel */ 2250 1.10 christos cur_level = current_bss->level; 2251 1.10 christos cur_snr = current_bss->snr; 2252 1.10 christos cur_est = current_bss->est_throughput; 2253 1.10 christos } 2254 1.10 christos 2255 1.10 christos /* Adjust the SNR of BSSes based on the channel width. */ 2256 1.10 christos cur_level += wpas_channel_width_rssi_bump(cur_ies, cur_ie_len, 2257 1.10 christos current_bss->max_cw); 2258 1.10 christos cur_snr = wpas_adjust_snr_by_chanwidth(cur_ies, cur_ie_len, 2259 1.10 christos current_bss->max_cw, cur_snr); 2260 1.10 christos 2261 1.10 christos sel_est = selected->est_throughput; 2262 1.10 christos sel_level = selected->level + 2263 1.10 christos wpas_channel_width_rssi_bump(sel_ies, sel_ie_len, 2264 1.10 christos selected->max_cw); 2265 1.10 christos 2266 1.10 christos if (sel_est > cur_est + 5000) { 2267 1.3 christos wpa_dbg(wpa_s, MSG_DEBUG, 2268 1.3 christos "Allow reassociation - selected BSS has better estimated throughput"); 2269 1.3 christos return 1; 2270 1.3 christos } 2271 1.3 christos 2272 1.6 christos to_5ghz = selected->freq > 4000 && current_bss->freq < 4000; 2273 1.10 christos to_6ghz = is_6ghz_freq(selected->freq) && 2274 1.10 christos !is_6ghz_freq(current_bss->freq); 2275 1.6 christos 2276 1.10 christos if (cur_level < 0 && 2277 1.10 christos cur_level > sel_level + to_5ghz * 2 + to_6ghz * 2 && 2278 1.10 christos sel_est < cur_est * 1.2) { 2279 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Skip roam - Current BSS has better " 2280 1.2 joerg "signal level"); 2281 1.2 joerg return 0; 2282 1.2 joerg } 2283 1.2 joerg 2284 1.10 christos if (cur_est > sel_est + 5000) { 2285 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 2286 1.7 christos "Skip roam - Current BSS has better estimated throughput"); 2287 1.7 christos return 0; 2288 1.7 christos } 2289 1.7 christos 2290 1.10 christos if (cur_snr > GREAT_SNR) { 2291 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 2292 1.10 christos "Skip roam - Current BSS has good SNR (%u > %u)", 2293 1.10 christos cur_snr, GREAT_SNR); 2294 1.10 christos return 0; 2295 1.10 christos } 2296 1.7 christos 2297 1.10 christos if (cur_level < -85) /* ..-86 dBm */ 2298 1.10 christos min_diff = 1; 2299 1.10 christos else if (cur_level < -80) /* -85..-81 dBm */ 2300 1.10 christos min_diff = 2; 2301 1.10 christos else if (cur_level < -75) /* -80..-76 dBm */ 2302 1.10 christos min_diff = 3; 2303 1.10 christos else if (cur_level < -70) /* -75..-71 dBm */ 2304 1.10 christos min_diff = 4; 2305 1.10 christos else if (cur_level < 0) /* -70..-1 dBm */ 2306 1.10 christos min_diff = 5; 2307 1.10 christos else /* unspecified units (not in dBm) */ 2308 1.10 christos min_diff = 2; 2309 1.10 christos 2310 1.10 christos if (cur_est > sel_est * 1.5) 2311 1.10 christos min_diff += 10; 2312 1.10 christos else if (cur_est > sel_est * 1.2) 2313 1.10 christos min_diff += 5; 2314 1.10 christos else if (cur_est > sel_est * 1.1) 2315 1.10 christos min_diff += 2; 2316 1.10 christos else if (cur_est > sel_est) 2317 1.10 christos min_diff++; 2318 1.10 christos else if (sel_est > cur_est * 1.5) 2319 1.10 christos min_diff -= 10; 2320 1.10 christos else if (sel_est > cur_est * 1.2) 2321 1.10 christos min_diff -= 5; 2322 1.10 christos else if (sel_est > cur_est * 1.1) 2323 1.10 christos min_diff -= 2; 2324 1.10 christos else if (sel_est > cur_est) 2325 1.10 christos min_diff--; 2326 1.10 christos 2327 1.10 christos cur_band_score = wpas_evaluate_band_score(current_bss->freq); 2328 1.10 christos sel_band_score = wpas_evaluate_band_score(selected->freq); 2329 1.10 christos min_diff += (cur_band_score - sel_band_score) * 2; 2330 1.10 christos if (wpa_s->signal_threshold && cur_level <= wpa_s->signal_threshold && 2331 1.10 christos sel_level > wpa_s->signal_threshold) 2332 1.10 christos min_diff -= 2; 2333 1.10 christos diff = sel_level - cur_level; 2334 1.7 christos if (diff < min_diff) { 2335 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 2336 1.7 christos "Skip roam - too small difference in signal level (%d < %d)", 2337 1.7 christos diff, min_diff); 2338 1.10 christos ret = 0; 2339 1.10 christos } else { 2340 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 2341 1.10 christos "Allow reassociation due to difference in signal level (%d >= %d)", 2342 1.10 christos diff, min_diff); 2343 1.10 christos ret = 1; 2344 1.10 christos } 2345 1.10 christos wpa_msg_ctrl(wpa_s, MSG_INFO, "%scur_bssid=" MACSTR 2346 1.10 christos " cur_freq=%d cur_level=%d cur_est=%d sel_bssid=" MACSTR 2347 1.10 christos " sel_freq=%d sel_level=%d sel_est=%d", 2348 1.10 christos ret ? WPA_EVENT_DO_ROAM : WPA_EVENT_SKIP_ROAM, 2349 1.10 christos MAC2STR(current_bss->bssid), 2350 1.10 christos current_bss->freq, cur_level, cur_est, 2351 1.10 christos MAC2STR(selected->bssid), 2352 1.10 christos selected->freq, sel_level, sel_est); 2353 1.10 christos return ret; 2354 1.10 christos } 2355 1.10 christos 2356 1.10 christos #endif /* CONFIG_NO_ROAMING */ 2357 1.10 christos 2358 1.10 christos 2359 1.10 christos static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s, 2360 1.10 christos struct wpa_bss *selected, 2361 1.10 christos struct wpa_ssid *ssid) 2362 1.10 christos { 2363 1.10 christos struct wpa_bss *current_bss = NULL; 2364 1.10 christos const u8 *bssid; 2365 1.10 christos 2366 1.10 christos if (wpa_s->reassociate) 2367 1.10 christos return 1; /* explicit request to reassociate */ 2368 1.10 christos if (wpa_s->wpa_state < WPA_ASSOCIATED) 2369 1.10 christos return 1; /* we are not associated; continue */ 2370 1.10 christos if (wpa_s->current_ssid == NULL) 2371 1.10 christos return 1; /* unknown current SSID */ 2372 1.10 christos if (wpa_s->current_ssid != ssid) 2373 1.10 christos return 1; /* different network block */ 2374 1.10 christos 2375 1.10 christos if (wpas_driver_bss_selection(wpa_s)) 2376 1.10 christos return 0; /* Driver-based roaming */ 2377 1.10 christos 2378 1.10 christos if (wpa_s->valid_links) 2379 1.10 christos bssid = wpa_s->links[wpa_s->mlo_assoc_link_id].bssid; 2380 1.10 christos else 2381 1.10 christos bssid = wpa_s->bssid; 2382 1.10 christos 2383 1.10 christos if (wpa_s->current_ssid->ssid) 2384 1.10 christos current_bss = wpa_bss_get(wpa_s, bssid, 2385 1.10 christos wpa_s->current_ssid->ssid, 2386 1.10 christos wpa_s->current_ssid->ssid_len); 2387 1.10 christos if (!current_bss) 2388 1.10 christos current_bss = wpa_bss_get_bssid(wpa_s, bssid); 2389 1.10 christos 2390 1.10 christos if (!current_bss) 2391 1.10 christos return 1; /* current BSS not seen in scan results */ 2392 1.10 christos 2393 1.10 christos if (current_bss == selected) 2394 1.1 christos return 0; 2395 1.1 christos 2396 1.10 christos if (selected->last_update_idx > current_bss->last_update_idx) 2397 1.10 christos return 1; /* current BSS not seen in the last scan */ 2398 1.10 christos 2399 1.10 christos #ifndef CONFIG_NO_ROAMING 2400 1.10 christos return wpa_supplicant_need_to_roam_within_ess(wpa_s, current_bss, 2401 1.10 christos selected); 2402 1.2 joerg #else /* CONFIG_NO_ROAMING */ 2403 1.2 joerg return 0; 2404 1.2 joerg #endif /* CONFIG_NO_ROAMING */ 2405 1.1 christos } 2406 1.1 christos 2407 1.1 christos 2408 1.7 christos /* 2409 1.7 christos * Return a negative value if no scan results could be fetched or if scan 2410 1.7 christos * results should not be shared with other virtual interfaces. 2411 1.7 christos * Return 0 if scan results were fetched and may be shared with other 2412 1.7 christos * interfaces. 2413 1.7 christos * Return 1 if scan results may be shared with other virtual interfaces but may 2414 1.7 christos * not trigger any operations. 2415 1.7 christos * Return 2 if the interface was removed and cannot be used. 2416 1.7 christos */ 2417 1.2 joerg static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, 2418 1.2 joerg union wpa_event_data *data, 2419 1.7 christos int own_request, int update_only) 2420 1.2 joerg { 2421 1.2 joerg struct wpa_scan_results *scan_res = NULL; 2422 1.2 joerg int ret = 0; 2423 1.2 joerg int ap = 0; 2424 1.10 christos bool trigger_6ghz_scan; 2425 1.2 joerg #ifndef CONFIG_NO_RANDOM_POOL 2426 1.2 joerg size_t i, num; 2427 1.2 joerg #endif /* CONFIG_NO_RANDOM_POOL */ 2428 1.2 joerg 2429 1.2 joerg #ifdef CONFIG_AP 2430 1.2 joerg if (wpa_s->ap_iface) 2431 1.2 joerg ap = 1; 2432 1.2 joerg #endif /* CONFIG_AP */ 2433 1.1 christos 2434 1.10 christos trigger_6ghz_scan = wpa_s->crossed_6ghz_dom && 2435 1.10 christos wpa_s->last_scan_all_chan; 2436 1.10 christos wpa_s->crossed_6ghz_dom = false; 2437 1.10 christos wpa_s->last_scan_all_chan = false; 2438 1.10 christos 2439 1.1 christos wpa_supplicant_notify_scanning(wpa_s, 0); 2440 1.1 christos 2441 1.1 christos scan_res = wpa_supplicant_get_scan_results(wpa_s, 2442 1.1 christos data ? &data->scan_info : 2443 1.10 christos NULL, 1, NULL); 2444 1.1 christos if (scan_res == NULL) { 2445 1.2 joerg if (wpa_s->conf->ap_scan == 2 || ap || 2446 1.2 joerg wpa_s->scan_res_handler == scan_only_handler) 2447 1.2 joerg return -1; 2448 1.2 joerg if (!own_request) 2449 1.2 joerg return -1; 2450 1.6 christos if (data && data->scan_info.external_scan) 2451 1.6 christos return -1; 2452 1.10 christos if (wpa_s->scan_res_fail_handler) { 2453 1.10 christos void (*handler)(struct wpa_supplicant *wpa_s); 2454 1.10 christos 2455 1.10 christos handler = wpa_s->scan_res_fail_handler; 2456 1.10 christos wpa_s->scan_res_fail_handler = NULL; 2457 1.10 christos handler(wpa_s); 2458 1.10 christos } else { 2459 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 2460 1.10 christos "Failed to get scan results - try scanning again"); 2461 1.10 christos wpa_supplicant_req_new_scan(wpa_s, 1, 0); 2462 1.10 christos } 2463 1.10 christos 2464 1.2 joerg ret = -1; 2465 1.2 joerg goto scan_work_done; 2466 1.1 christos } 2467 1.1 christos 2468 1.2 joerg #ifndef CONFIG_NO_RANDOM_POOL 2469 1.2 joerg num = scan_res->num; 2470 1.2 joerg if (num > 10) 2471 1.2 joerg num = 10; 2472 1.2 joerg for (i = 0; i < num; i++) { 2473 1.2 joerg u8 buf[5]; 2474 1.2 joerg struct wpa_scan_res *res = scan_res->res[i]; 2475 1.2 joerg buf[0] = res->bssid[5]; 2476 1.2 joerg buf[1] = res->qual & 0xff; 2477 1.2 joerg buf[2] = res->noise & 0xff; 2478 1.2 joerg buf[3] = res->level & 0xff; 2479 1.2 joerg buf[4] = res->tsf & 0xff; 2480 1.2 joerg random_add_randomness(buf, sizeof(buf)); 2481 1.2 joerg } 2482 1.2 joerg #endif /* CONFIG_NO_RANDOM_POOL */ 2483 1.2 joerg 2484 1.7 christos if (update_only) { 2485 1.7 christos ret = 1; 2486 1.7 christos goto scan_work_done; 2487 1.7 christos } 2488 1.7 christos 2489 1.2 joerg if (own_request && wpa_s->scan_res_handler && 2490 1.6 christos !(data && data->scan_info.external_scan)) { 2491 1.2 joerg void (*scan_res_handler)(struct wpa_supplicant *wpa_s, 2492 1.2 joerg struct wpa_scan_results *scan_res); 2493 1.2 joerg 2494 1.2 joerg scan_res_handler = wpa_s->scan_res_handler; 2495 1.1 christos wpa_s->scan_res_handler = NULL; 2496 1.2 joerg scan_res_handler(wpa_s, scan_res); 2497 1.7 christos ret = 1; 2498 1.2 joerg goto scan_work_done; 2499 1.2 joerg } 2500 1.2 joerg 2501 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "New scan results available (own=%u ext=%u)", 2502 1.6 christos wpa_s->own_scan_running, 2503 1.6 christos data ? data->scan_info.external_scan : 0); 2504 1.2 joerg if (wpa_s->last_scan_req == MANUAL_SCAN_REQ && 2505 1.6 christos wpa_s->manual_scan_use_id && wpa_s->own_scan_running && 2506 1.6 christos own_request && !(data && data->scan_info.external_scan)) { 2507 1.2 joerg wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS "id=%u", 2508 1.2 joerg wpa_s->manual_scan_id); 2509 1.2 joerg wpa_s->manual_scan_use_id = 0; 2510 1.1 christos } else { 2511 1.1 christos wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS); 2512 1.1 christos } 2513 1.2 joerg wpas_notify_scan_results(wpa_s); 2514 1.1 christos 2515 1.1 christos wpas_notify_scan_done(wpa_s, 1); 2516 1.1 christos 2517 1.10 christos if (ap) { 2518 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, "Ignore scan results in AP mode"); 2519 1.10 christos #ifdef CONFIG_AP 2520 1.10 christos if (wpa_s->ap_iface->scan_cb) 2521 1.10 christos wpa_s->ap_iface->scan_cb(wpa_s->ap_iface); 2522 1.10 christos #endif /* CONFIG_AP */ 2523 1.10 christos goto scan_work_done; 2524 1.10 christos } 2525 1.10 christos 2526 1.6 christos if (data && data->scan_info.external_scan) { 2527 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Do not use results from externally requested scan operation for network selection"); 2528 1.1 christos wpa_scan_results_free(scan_res); 2529 1.2 joerg return 0; 2530 1.1 christos } 2531 1.1 christos 2532 1.10 christos if (wnm_scan_process(wpa_s, false) > 0) 2533 1.3 christos goto scan_work_done; 2534 1.3 christos 2535 1.2 joerg if (sme_proc_obss_scan(wpa_s) > 0) 2536 1.2 joerg goto scan_work_done; 2537 1.2 joerg 2538 1.10 christos #ifndef CONFIG_NO_RRM 2539 1.9 christos if (own_request && data && 2540 1.7 christos wpas_beacon_rep_scan_process(wpa_s, scan_res, &data->scan_info) > 0) 2541 1.7 christos goto scan_work_done; 2542 1.10 christos #endif /* CONFIG_NO_RRM */ 2543 1.10 christos 2544 1.10 christos if (ml_link_probe_scan(wpa_s)) 2545 1.10 christos goto scan_work_done; 2546 1.7 christos 2547 1.2 joerg if ((wpa_s->conf->ap_scan == 2 && !wpas_wps_searching(wpa_s))) 2548 1.2 joerg goto scan_work_done; 2549 1.2 joerg 2550 1.2 joerg if (autoscan_notify_scan(wpa_s, scan_res)) 2551 1.2 joerg goto scan_work_done; 2552 1.2 joerg 2553 1.1 christos if (wpa_s->disconnected) { 2554 1.1 christos wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); 2555 1.2 joerg goto scan_work_done; 2556 1.2 joerg } 2557 1.2 joerg 2558 1.2 joerg if (!wpas_driver_bss_selection(wpa_s) && 2559 1.2 joerg bgscan_notify_scan(wpa_s, scan_res) == 1) 2560 1.2 joerg goto scan_work_done; 2561 1.2 joerg 2562 1.2 joerg wpas_wps_update_ap_info(wpa_s, scan_res); 2563 1.2 joerg 2564 1.6 christos if (wpa_s->wpa_state >= WPA_AUTHENTICATING && 2565 1.6 christos wpa_s->wpa_state < WPA_COMPLETED) 2566 1.6 christos goto scan_work_done; 2567 1.6 christos 2568 1.2 joerg wpa_scan_results_free(scan_res); 2569 1.2 joerg 2570 1.6 christos if (own_request && wpa_s->scan_work) { 2571 1.2 joerg struct wpa_radio_work *work = wpa_s->scan_work; 2572 1.2 joerg wpa_s->scan_work = NULL; 2573 1.2 joerg radio_work_done(work); 2574 1.1 christos } 2575 1.1 christos 2576 1.10 christos os_free(wpa_s->last_scan_freqs); 2577 1.10 christos wpa_s->last_scan_freqs = NULL; 2578 1.10 christos wpa_s->num_last_scan_freqs = 0; 2579 1.10 christos if (own_request && data && 2580 1.10 christos data->scan_info.freqs && data->scan_info.num_freqs) { 2581 1.10 christos wpa_s->last_scan_freqs = os_malloc(sizeof(int) * 2582 1.10 christos data->scan_info.num_freqs); 2583 1.10 christos if (wpa_s->last_scan_freqs) { 2584 1.10 christos os_memcpy(wpa_s->last_scan_freqs, 2585 1.10 christos data->scan_info.freqs, 2586 1.10 christos sizeof(int) * data->scan_info.num_freqs); 2587 1.10 christos wpa_s->num_last_scan_freqs = data->scan_info.num_freqs; 2588 1.10 christos } 2589 1.10 christos } 2590 1.10 christos 2591 1.10 christos if (wpa_s->supp_pbc_active && !wpas_wps_partner_link_scan_done(wpa_s)) 2592 1.10 christos return ret; 2593 1.10 christos 2594 1.10 christos return wpas_select_network_from_last_scan(wpa_s, 1, own_request, 2595 1.10 christos trigger_6ghz_scan, data); 2596 1.2 joerg 2597 1.2 joerg scan_work_done: 2598 1.2 joerg wpa_scan_results_free(scan_res); 2599 1.6 christos if (own_request && wpa_s->scan_work) { 2600 1.2 joerg struct wpa_radio_work *work = wpa_s->scan_work; 2601 1.2 joerg wpa_s->scan_work = NULL; 2602 1.2 joerg radio_work_done(work); 2603 1.1 christos } 2604 1.2 joerg return ret; 2605 1.2 joerg } 2606 1.2 joerg 2607 1.1 christos 2608 1.10 christos static int wpas_trigger_6ghz_scan(struct wpa_supplicant *wpa_s, 2609 1.10 christos union wpa_event_data *data) 2610 1.10 christos { 2611 1.10 christos struct wpa_driver_scan_params params; 2612 1.10 christos unsigned int j; 2613 1.10 christos 2614 1.10 christos wpa_dbg(wpa_s, MSG_INFO, "Triggering 6GHz-only scan"); 2615 1.10 christos os_memset(¶ms, 0, sizeof(params)); 2616 1.10 christos params.non_coloc_6ghz = wpa_s->last_scan_non_coloc_6ghz; 2617 1.10 christos for (j = 0; j < data->scan_info.num_ssids; j++) 2618 1.10 christos params.ssids[j] = data->scan_info.ssids[j]; 2619 1.10 christos params.num_ssids = data->scan_info.num_ssids; 2620 1.10 christos wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211A, ¶ms, 2621 1.10 christos true, !wpa_s->last_scan_non_coloc_6ghz, false); 2622 1.10 christos if (!wpa_supplicant_trigger_scan(wpa_s, ¶ms, true, true)) { 2623 1.10 christos os_free(params.freqs); 2624 1.10 christos return 1; 2625 1.10 christos } 2626 1.10 christos wpa_dbg(wpa_s, MSG_INFO, "Failed to trigger 6GHz-only scan"); 2627 1.10 christos os_free(params.freqs); 2628 1.10 christos return 0; 2629 1.10 christos } 2630 1.10 christos 2631 1.10 christos 2632 1.10 christos /** 2633 1.10 christos * Select a network from the last scan 2634 1.10 christos * @wpa_s: Pointer to wpa_supplicant data 2635 1.10 christos * @new_scan: Whether this function was called right after a scan has finished 2636 1.10 christos * @own_request: Whether the scan was requested by this interface 2637 1.10 christos * @trigger_6ghz_scan: Whether to trigger a 6ghz-only scan when applicable 2638 1.10 christos * @data: Scan data from scan that finished if applicable 2639 1.10 christos * 2640 1.10 christos * See _wpa_supplicant_event_scan_results() for return values. 2641 1.10 christos */ 2642 1.2 joerg static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s, 2643 1.10 christos int new_scan, int own_request, 2644 1.10 christos bool trigger_6ghz_scan, 2645 1.10 christos union wpa_event_data *data) 2646 1.2 joerg { 2647 1.2 joerg struct wpa_bss *selected; 2648 1.2 joerg struct wpa_ssid *ssid = NULL; 2649 1.6 christos int time_to_reenable = wpas_reenabled_network_time(wpa_s); 2650 1.6 christos 2651 1.6 christos if (time_to_reenable > 0) { 2652 1.6 christos wpa_dbg(wpa_s, MSG_DEBUG, 2653 1.6 christos "Postpone network selection by %d seconds since all networks are disabled", 2654 1.6 christos time_to_reenable); 2655 1.6 christos eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL); 2656 1.6 christos eloop_register_timeout(time_to_reenable, 0, 2657 1.6 christos wpas_network_reenabled, wpa_s, NULL); 2658 1.6 christos return 0; 2659 1.6 christos } 2660 1.1 christos 2661 1.3 christos if (wpa_s->p2p_mgmt) 2662 1.3 christos return 0; /* no normal connection on p2p_mgmt interface */ 2663 1.3 christos 2664 1.7 christos wpa_s->owe_transition_search = 0; 2665 1.10 christos #ifdef CONFIG_OWE 2666 1.10 christos os_free(wpa_s->owe_trans_scan_freq); 2667 1.10 christos wpa_s->owe_trans_scan_freq = NULL; 2668 1.10 christos #endif /* CONFIG_OWE */ 2669 1.2 joerg selected = wpa_supplicant_pick_network(wpa_s, &ssid); 2670 1.1 christos 2671 1.6 christos #ifdef CONFIG_MESH 2672 1.6 christos if (wpa_s->ifmsh) { 2673 1.6 christos wpa_msg(wpa_s, MSG_INFO, 2674 1.6 christos "Avoiding join because we already joined a mesh group"); 2675 1.6 christos return 0; 2676 1.6 christos } 2677 1.6 christos #endif /* CONFIG_MESH */ 2678 1.6 christos 2679 1.1 christos if (selected) { 2680 1.1 christos int skip; 2681 1.2 joerg skip = !wpa_supplicant_need_to_roam(wpa_s, selected, ssid); 2682 1.2 joerg if (skip) { 2683 1.2 joerg if (new_scan) 2684 1.2 joerg wpa_supplicant_rsn_preauth_scan_results(wpa_s); 2685 1.2 joerg return 0; 2686 1.2 joerg } 2687 1.2 joerg 2688 1.10 christos wpa_s->suitable_network++; 2689 1.10 christos 2690 1.6 christos if (ssid != wpa_s->current_ssid && 2691 1.6 christos wpa_s->wpa_state >= WPA_AUTHENTICATING) { 2692 1.6 christos wpa_s->own_disconnect_req = 1; 2693 1.6 christos wpa_supplicant_deauthenticate( 2694 1.6 christos wpa_s, WLAN_REASON_DEAUTH_LEAVING); 2695 1.6 christos } 2696 1.6 christos 2697 1.2 joerg if (wpa_supplicant_connect(wpa_s, selected, ssid) < 0) { 2698 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Connect failed"); 2699 1.2 joerg return -1; 2700 1.2 joerg } 2701 1.10 christos wpa_s->supp_pbc_active = false; 2702 1.10 christos 2703 1.2 joerg if (new_scan) 2704 1.2 joerg wpa_supplicant_rsn_preauth_scan_results(wpa_s); 2705 1.2 joerg /* 2706 1.7 christos * Do not allow other virtual radios to trigger operations based 2707 1.7 christos * on these scan results since we do not want them to start 2708 1.7 christos * other associations at the same time. 2709 1.2 joerg */ 2710 1.2 joerg return 1; 2711 1.1 christos } else { 2712 1.10 christos wpa_s->no_suitable_network++; 2713 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "No suitable network found"); 2714 1.1 christos ssid = wpa_supplicant_pick_new_network(wpa_s); 2715 1.1 christos if (ssid) { 2716 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Setup a new network"); 2717 1.1 christos wpa_supplicant_associate(wpa_s, NULL, ssid); 2718 1.2 joerg if (new_scan) 2719 1.2 joerg wpa_supplicant_rsn_preauth_scan_results(wpa_s); 2720 1.2 joerg } else if (own_request) { 2721 1.10 christos if (wpa_s->support_6ghz && trigger_6ghz_scan && data && 2722 1.10 christos wpas_trigger_6ghz_scan(wpa_s, data) < 0) 2723 1.10 christos return 1; 2724 1.10 christos 2725 1.2 joerg /* 2726 1.2 joerg * No SSID found. If SCAN results are as a result of 2727 1.2 joerg * own scan request and not due to a scan request on 2728 1.2 joerg * another shared interface, try another scan. 2729 1.2 joerg */ 2730 1.2 joerg int timeout_sec = wpa_s->scan_interval; 2731 1.1 christos int timeout_usec = 0; 2732 1.2 joerg #ifdef CONFIG_P2P 2733 1.3 christos int res; 2734 1.3 christos 2735 1.3 christos res = wpas_p2p_scan_no_go_seen(wpa_s); 2736 1.3 christos if (res == 2) 2737 1.3 christos return 2; 2738 1.3 christos if (res == 1) 2739 1.2 joerg return 0; 2740 1.2 joerg 2741 1.10 christos if (wpas_p2p_retry_limit_exceeded(wpa_s)) 2742 1.10 christos return 0; 2743 1.10 christos 2744 1.2 joerg if (wpa_s->p2p_in_provisioning || 2745 1.2 joerg wpa_s->show_group_started || 2746 1.2 joerg wpa_s->p2p_in_invitation) { 2747 1.2 joerg /* 2748 1.2 joerg * Use shorter wait during P2P Provisioning 2749 1.2 joerg * state and during P2P join-a-group operation 2750 1.2 joerg * to speed up group formation. 2751 1.2 joerg */ 2752 1.2 joerg timeout_sec = 0; 2753 1.2 joerg timeout_usec = 250000; 2754 1.2 joerg wpa_supplicant_req_new_scan(wpa_s, timeout_sec, 2755 1.2 joerg timeout_usec); 2756 1.2 joerg return 0; 2757 1.2 joerg } 2758 1.2 joerg #endif /* CONFIG_P2P */ 2759 1.2 joerg #ifdef CONFIG_INTERWORKING 2760 1.2 joerg if (wpa_s->conf->auto_interworking && 2761 1.2 joerg wpa_s->conf->interworking && 2762 1.2 joerg wpa_s->conf->cred) { 2763 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Interworking: " 2764 1.2 joerg "start ANQP fetch since no matching " 2765 1.2 joerg "networks found"); 2766 1.2 joerg wpa_s->network_select = 1; 2767 1.2 joerg wpa_s->auto_network_select = 1; 2768 1.2 joerg interworking_start_fetch_anqp(wpa_s); 2769 1.2 joerg return 1; 2770 1.2 joerg } 2771 1.2 joerg #endif /* CONFIG_INTERWORKING */ 2772 1.2 joerg #ifdef CONFIG_WPS 2773 1.2 joerg if (wpa_s->after_wps > 0 || wpas_wps_searching(wpa_s)) { 2774 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Use shorter wait during WPS processing"); 2775 1.2 joerg timeout_sec = 0; 2776 1.2 joerg timeout_usec = 500000; 2777 1.2 joerg wpa_supplicant_req_new_scan(wpa_s, timeout_sec, 2778 1.2 joerg timeout_usec); 2779 1.2 joerg return 0; 2780 1.2 joerg } 2781 1.2 joerg #endif /* CONFIG_WPS */ 2782 1.7 christos #ifdef CONFIG_OWE 2783 1.7 christos if (wpa_s->owe_transition_search) { 2784 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 2785 1.7 christos "OWE: Use shorter wait during transition mode search"); 2786 1.7 christos timeout_sec = 0; 2787 1.7 christos timeout_usec = 500000; 2788 1.10 christos if (wpa_s->owe_trans_scan_freq) { 2789 1.10 christos os_free(wpa_s->next_scan_freqs); 2790 1.10 christos wpa_s->next_scan_freqs = 2791 1.10 christos wpa_s->owe_trans_scan_freq; 2792 1.10 christos wpa_s->owe_trans_scan_freq = NULL; 2793 1.10 christos timeout_usec = 100000; 2794 1.10 christos } 2795 1.7 christos wpa_supplicant_req_new_scan(wpa_s, timeout_sec, 2796 1.7 christos timeout_usec); 2797 1.7 christos return 0; 2798 1.7 christos } 2799 1.7 christos #endif /* CONFIG_OWE */ 2800 1.2 joerg if (wpa_supplicant_req_sched_scan(wpa_s)) 2801 1.2 joerg wpa_supplicant_req_new_scan(wpa_s, timeout_sec, 2802 1.2 joerg timeout_usec); 2803 1.6 christos 2804 1.6 christos wpa_msg_ctrl(wpa_s, MSG_INFO, 2805 1.6 christos WPA_EVENT_NETWORK_NOT_FOUND); 2806 1.2 joerg } 2807 1.2 joerg } 2808 1.2 joerg return 0; 2809 1.2 joerg } 2810 1.2 joerg 2811 1.2 joerg 2812 1.3 christos static int wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, 2813 1.3 christos union wpa_event_data *data) 2814 1.2 joerg { 2815 1.2 joerg struct wpa_supplicant *ifs; 2816 1.3 christos int res; 2817 1.2 joerg 2818 1.7 christos res = _wpa_supplicant_event_scan_results(wpa_s, data, 1, 0); 2819 1.3 christos if (res == 2) { 2820 1.3 christos /* 2821 1.3 christos * Interface may have been removed, so must not dereference 2822 1.3 christos * wpa_s after this. 2823 1.3 christos */ 2824 1.3 christos return 1; 2825 1.3 christos } 2826 1.7 christos 2827 1.7 christos if (res < 0) { 2828 1.2 joerg /* 2829 1.2 joerg * If no scan results could be fetched, then no need to 2830 1.2 joerg * notify those interfaces that did not actually request 2831 1.2 joerg * this scan. Similarly, if scan results started a new operation on this 2832 1.2 joerg * interface, do not notify other interfaces to avoid concurrent 2833 1.2 joerg * operations during a connection attempt. 2834 1.2 joerg */ 2835 1.3 christos return 0; 2836 1.2 joerg } 2837 1.2 joerg 2838 1.2 joerg /* 2839 1.2 joerg * Check other interfaces to see if they share the same radio. If 2840 1.2 joerg * so, they get updated with this same scan info. 2841 1.2 joerg */ 2842 1.2 joerg dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant, 2843 1.2 joerg radio_list) { 2844 1.2 joerg if (ifs != wpa_s) { 2845 1.2 joerg wpa_printf(MSG_DEBUG, "%s: Updating scan results from " 2846 1.2 joerg "sibling", ifs->ifname); 2847 1.7 christos res = _wpa_supplicant_event_scan_results(ifs, data, 0, 2848 1.7 christos res > 0); 2849 1.7 christos if (res < 0) 2850 1.7 christos return 0; 2851 1.1 christos } 2852 1.1 christos } 2853 1.3 christos 2854 1.3 christos return 0; 2855 1.1 christos } 2856 1.2 joerg 2857 1.2 joerg #endif /* CONFIG_NO_SCAN_PROCESSING */ 2858 1.2 joerg 2859 1.2 joerg 2860 1.2 joerg int wpa_supplicant_fast_associate(struct wpa_supplicant *wpa_s) 2861 1.2 joerg { 2862 1.2 joerg #ifdef CONFIG_NO_SCAN_PROCESSING 2863 1.2 joerg return -1; 2864 1.2 joerg #else /* CONFIG_NO_SCAN_PROCESSING */ 2865 1.2 joerg struct os_reltime now; 2866 1.2 joerg 2867 1.7 christos wpa_s->ignore_post_flush_scan_res = 0; 2868 1.7 christos 2869 1.6 christos if (wpa_s->last_scan_res_used == 0) 2870 1.2 joerg return -1; 2871 1.2 joerg 2872 1.2 joerg os_get_reltime(&now); 2873 1.10 christos if (os_reltime_expired(&now, &wpa_s->last_scan, 2874 1.10 christos wpa_s->conf->scan_res_valid_for_connect)) { 2875 1.2 joerg wpa_printf(MSG_DEBUG, "Fast associate: Old scan results"); 2876 1.2 joerg return -1; 2877 1.10 christos } else if (wpa_s->crossed_6ghz_dom) { 2878 1.10 christos wpa_printf(MSG_DEBUG, "Fast associate: Crossed 6 GHz domain"); 2879 1.10 christos return -1; 2880 1.2 joerg } 2881 1.2 joerg 2882 1.10 christos return wpas_select_network_from_last_scan(wpa_s, 0, 1, false, NULL); 2883 1.10 christos #endif /* CONFIG_NO_SCAN_PROCESSING */ 2884 1.10 christos } 2885 1.10 christos 2886 1.10 christos 2887 1.10 christos int wpa_wps_supplicant_fast_associate(struct wpa_supplicant *wpa_s) 2888 1.10 christos { 2889 1.10 christos #ifdef CONFIG_NO_SCAN_PROCESSING 2890 1.10 christos return -1; 2891 1.10 christos #else /* CONFIG_NO_SCAN_PROCESSING */ 2892 1.10 christos return wpas_select_network_from_last_scan(wpa_s, 1, 1, false, NULL); 2893 1.1 christos #endif /* CONFIG_NO_SCAN_PROCESSING */ 2894 1.2 joerg } 2895 1.2 joerg 2896 1.10 christos 2897 1.2 joerg #ifdef CONFIG_WNM 2898 1.2 joerg 2899 1.2 joerg static void wnm_bss_keep_alive(void *eloop_ctx, void *sock_ctx) 2900 1.2 joerg { 2901 1.2 joerg struct wpa_supplicant *wpa_s = eloop_ctx; 2902 1.2 joerg 2903 1.2 joerg if (wpa_s->wpa_state < WPA_ASSOCIATED) 2904 1.2 joerg return; 2905 1.2 joerg 2906 1.2 joerg if (!wpa_s->no_keep_alive) { 2907 1.2 joerg wpa_printf(MSG_DEBUG, "WNM: Send keep-alive to AP " MACSTR, 2908 1.2 joerg MAC2STR(wpa_s->bssid)); 2909 1.2 joerg /* TODO: could skip this if normal data traffic has been sent */ 2910 1.2 joerg /* TODO: Consider using some more appropriate data frame for 2911 1.2 joerg * this */ 2912 1.2 joerg if (wpa_s->l2) 2913 1.2 joerg l2_packet_send(wpa_s->l2, wpa_s->bssid, 0x0800, 2914 1.2 joerg (u8 *) "", 0); 2915 1.2 joerg } 2916 1.2 joerg 2917 1.2 joerg #ifdef CONFIG_SME 2918 1.2 joerg if (wpa_s->sme.bss_max_idle_period) { 2919 1.2 joerg unsigned int msec; 2920 1.2 joerg msec = wpa_s->sme.bss_max_idle_period * 1024; /* times 1000 */ 2921 1.2 joerg if (msec > 100) 2922 1.2 joerg msec -= 100; 2923 1.2 joerg eloop_register_timeout(msec / 1000, msec % 1000 * 1000, 2924 1.2 joerg wnm_bss_keep_alive, wpa_s, NULL); 2925 1.2 joerg } 2926 1.2 joerg #endif /* CONFIG_SME */ 2927 1.2 joerg } 2928 1.2 joerg 2929 1.2 joerg 2930 1.2 joerg static void wnm_process_assoc_resp(struct wpa_supplicant *wpa_s, 2931 1.2 joerg const u8 *ies, size_t ies_len) 2932 1.2 joerg { 2933 1.2 joerg struct ieee802_11_elems elems; 2934 1.2 joerg 2935 1.2 joerg if (ies == NULL) 2936 1.2 joerg return; 2937 1.2 joerg 2938 1.2 joerg if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed) 2939 1.2 joerg return; 2940 1.2 joerg 2941 1.2 joerg #ifdef CONFIG_SME 2942 1.2 joerg if (elems.bss_max_idle_period) { 2943 1.2 joerg unsigned int msec; 2944 1.2 joerg wpa_s->sme.bss_max_idle_period = 2945 1.2 joerg WPA_GET_LE16(elems.bss_max_idle_period); 2946 1.2 joerg wpa_printf(MSG_DEBUG, "WNM: BSS Max Idle Period: %u (* 1000 " 2947 1.2 joerg "TU)%s", wpa_s->sme.bss_max_idle_period, 2948 1.2 joerg (elems.bss_max_idle_period[2] & 0x01) ? 2949 1.2 joerg " (protected keep-live required)" : ""); 2950 1.2 joerg if (wpa_s->sme.bss_max_idle_period == 0) 2951 1.2 joerg wpa_s->sme.bss_max_idle_period = 1; 2952 1.2 joerg if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) { 2953 1.2 joerg eloop_cancel_timeout(wnm_bss_keep_alive, wpa_s, NULL); 2954 1.2 joerg /* msec times 1000 */ 2955 1.2 joerg msec = wpa_s->sme.bss_max_idle_period * 1024; 2956 1.2 joerg if (msec > 100) 2957 1.2 joerg msec -= 100; 2958 1.2 joerg eloop_register_timeout(msec / 1000, msec % 1000 * 1000, 2959 1.2 joerg wnm_bss_keep_alive, wpa_s, 2960 1.2 joerg NULL); 2961 1.2 joerg } 2962 1.10 christos } else { 2963 1.10 christos wpa_s->sme.bss_max_idle_period = 0; 2964 1.2 joerg } 2965 1.2 joerg #endif /* CONFIG_SME */ 2966 1.2 joerg } 2967 1.2 joerg 2968 1.2 joerg #endif /* CONFIG_WNM */ 2969 1.2 joerg 2970 1.2 joerg 2971 1.2 joerg void wnm_bss_keep_alive_deinit(struct wpa_supplicant *wpa_s) 2972 1.2 joerg { 2973 1.2 joerg #ifdef CONFIG_WNM 2974 1.2 joerg eloop_cancel_timeout(wnm_bss_keep_alive, wpa_s, NULL); 2975 1.2 joerg #endif /* CONFIG_WNM */ 2976 1.2 joerg } 2977 1.2 joerg 2978 1.2 joerg 2979 1.2 joerg static int wpas_qos_map_set(struct wpa_supplicant *wpa_s, const u8 *qos_map, 2980 1.2 joerg size_t len) 2981 1.2 joerg { 2982 1.2 joerg int res; 2983 1.2 joerg 2984 1.2 joerg wpa_hexdump(MSG_DEBUG, "Interworking: QoS Map Set", qos_map, len); 2985 1.2 joerg res = wpa_drv_set_qos_map(wpa_s, qos_map, len); 2986 1.2 joerg if (res) { 2987 1.2 joerg wpa_printf(MSG_DEBUG, "Interworking: Failed to configure QoS Map Set to the driver"); 2988 1.2 joerg } 2989 1.2 joerg 2990 1.2 joerg return res; 2991 1.2 joerg } 2992 1.2 joerg 2993 1.2 joerg 2994 1.2 joerg static void interworking_process_assoc_resp(struct wpa_supplicant *wpa_s, 2995 1.2 joerg const u8 *ies, size_t ies_len) 2996 1.2 joerg { 2997 1.2 joerg struct ieee802_11_elems elems; 2998 1.2 joerg 2999 1.2 joerg if (ies == NULL) 3000 1.2 joerg return; 3001 1.2 joerg 3002 1.2 joerg if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed) 3003 1.2 joerg return; 3004 1.2 joerg 3005 1.2 joerg if (elems.qos_map_set) { 3006 1.2 joerg wpas_qos_map_set(wpa_s, elems.qos_map_set, 3007 1.2 joerg elems.qos_map_set_len); 3008 1.2 joerg } 3009 1.2 joerg } 3010 1.2 joerg 3011 1.10 christos 3012 1.10 christos static void wpa_supplicant_set_4addr_mode(struct wpa_supplicant *wpa_s) 3013 1.10 christos { 3014 1.10 christos if (wpa_s->enabled_4addr_mode) { 3015 1.10 christos wpa_printf(MSG_DEBUG, "4addr mode already set"); 3016 1.10 christos return; 3017 1.10 christos } 3018 1.10 christos 3019 1.10 christos if (wpa_drv_set_4addr_mode(wpa_s, 1) < 0) { 3020 1.10 christos wpa_msg(wpa_s, MSG_ERROR, "Failed to set 4addr mode"); 3021 1.10 christos goto fail; 3022 1.10 christos } 3023 1.10 christos wpa_s->enabled_4addr_mode = 1; 3024 1.10 christos wpa_msg(wpa_s, MSG_INFO, "Successfully set 4addr mode"); 3025 1.10 christos return; 3026 1.10 christos 3027 1.10 christos fail: 3028 1.10 christos wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); 3029 1.10 christos } 3030 1.1 christos 3031 1.1 christos 3032 1.9 christos static void multi_ap_process_assoc_resp(struct wpa_supplicant *wpa_s, 3033 1.9 christos const u8 *ies, size_t ies_len) 3034 1.9 christos { 3035 1.9 christos struct ieee802_11_elems elems; 3036 1.10 christos struct multi_ap_params multi_ap; 3037 1.10 christos u16 status; 3038 1.10 christos 3039 1.10 christos wpa_s->multi_ap_ie = 0; 3040 1.10 christos 3041 1.10 christos if (!ies || 3042 1.10 christos ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed || 3043 1.10 christos !elems.multi_ap) 3044 1.10 christos return; 3045 1.9 christos 3046 1.10 christos status = check_multi_ap_ie(elems.multi_ap + 4, elems.multi_ap_len - 4, 3047 1.10 christos &multi_ap); 3048 1.10 christos if (status != WLAN_STATUS_SUCCESS) 3049 1.9 christos return; 3050 1.9 christos 3051 1.10 christos wpa_s->multi_ap_backhaul = !!(multi_ap.capability & 3052 1.10 christos MULTI_AP_BACKHAUL_BSS); 3053 1.10 christos wpa_s->multi_ap_fronthaul = !!(multi_ap.capability & 3054 1.10 christos MULTI_AP_FRONTHAUL_BSS); 3055 1.10 christos wpa_s->multi_ap_ie = 1; 3056 1.10 christos } 3057 1.10 christos 3058 1.9 christos 3059 1.10 christos static void multi_ap_set_4addr_mode(struct wpa_supplicant *wpa_s) 3060 1.10 christos { 3061 1.10 christos if (!wpa_s->current_ssid || 3062 1.10 christos !wpa_s->current_ssid->multi_ap_backhaul_sta) 3063 1.10 christos return; 3064 1.9 christos 3065 1.10 christos if (!wpa_s->multi_ap_ie) { 3066 1.10 christos wpa_printf(MSG_INFO, 3067 1.10 christos "AP does not include valid Multi-AP element"); 3068 1.9 christos goto fail; 3069 1.9 christos } 3070 1.9 christos 3071 1.10 christos if (!wpa_s->multi_ap_backhaul) { 3072 1.10 christos if (wpa_s->multi_ap_fronthaul && 3073 1.9 christos wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS) { 3074 1.9 christos wpa_printf(MSG_INFO, 3075 1.9 christos "WPS active, accepting fronthaul-only BSS"); 3076 1.9 christos /* Don't set 4addr mode in this case, so just return */ 3077 1.9 christos return; 3078 1.9 christos } 3079 1.9 christos wpa_printf(MSG_INFO, "AP doesn't support backhaul BSS"); 3080 1.9 christos goto fail; 3081 1.9 christos } 3082 1.9 christos 3083 1.10 christos wpa_supplicant_set_4addr_mode(wpa_s); 3084 1.9 christos return; 3085 1.9 christos 3086 1.9 christos fail: 3087 1.9 christos wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); 3088 1.9 christos } 3089 1.9 christos 3090 1.9 christos 3091 1.6 christos #ifdef CONFIG_FST 3092 1.6 christos static int wpas_fst_update_mbie(struct wpa_supplicant *wpa_s, 3093 1.6 christos const u8 *ie, size_t ie_len) 3094 1.6 christos { 3095 1.6 christos struct mb_ies_info mb_ies; 3096 1.6 christos 3097 1.6 christos if (!ie || !ie_len || !wpa_s->fst) 3098 1.6 christos return -ENOENT; 3099 1.6 christos 3100 1.6 christos os_memset(&mb_ies, 0, sizeof(mb_ies)); 3101 1.6 christos 3102 1.6 christos while (ie_len >= 2 && mb_ies.nof_ies < MAX_NOF_MB_IES_SUPPORTED) { 3103 1.6 christos size_t len; 3104 1.6 christos 3105 1.6 christos len = 2 + ie[1]; 3106 1.6 christos if (len > ie_len) { 3107 1.6 christos wpa_hexdump(MSG_DEBUG, "FST: Truncated IE found", 3108 1.6 christos ie, ie_len); 3109 1.6 christos break; 3110 1.6 christos } 3111 1.6 christos 3112 1.6 christos if (ie[0] == WLAN_EID_MULTI_BAND) { 3113 1.6 christos wpa_printf(MSG_DEBUG, "MB IE of %u bytes found", 3114 1.6 christos (unsigned int) len); 3115 1.6 christos mb_ies.ies[mb_ies.nof_ies].ie = ie + 2; 3116 1.6 christos mb_ies.ies[mb_ies.nof_ies].ie_len = len - 2; 3117 1.6 christos mb_ies.nof_ies++; 3118 1.6 christos } 3119 1.6 christos 3120 1.6 christos ie_len -= len; 3121 1.6 christos ie += len; 3122 1.6 christos } 3123 1.6 christos 3124 1.6 christos if (mb_ies.nof_ies > 0) { 3125 1.6 christos wpabuf_free(wpa_s->received_mb_ies); 3126 1.6 christos wpa_s->received_mb_ies = mb_ies_by_info(&mb_ies); 3127 1.6 christos return 0; 3128 1.6 christos } 3129 1.6 christos 3130 1.6 christos return -ENOENT; 3131 1.6 christos } 3132 1.6 christos #endif /* CONFIG_FST */ 3133 1.6 christos 3134 1.6 christos 3135 1.10 christos static int wpa_supplicant_use_own_rsne_params(struct wpa_supplicant *wpa_s, 3136 1.10 christos union wpa_event_data *data) 3137 1.10 christos { 3138 1.10 christos int sel; 3139 1.10 christos const u8 *p; 3140 1.10 christos int l, len; 3141 1.10 christos bool found = false; 3142 1.10 christos struct wpa_ie_data ie; 3143 1.10 christos struct wpa_ssid *ssid = wpa_s->current_ssid; 3144 1.10 christos struct wpa_bss *bss = wpa_s->current_bss; 3145 1.10 christos int pmf; 3146 1.10 christos 3147 1.10 christos if (!ssid) 3148 1.10 christos return 0; 3149 1.10 christos 3150 1.10 christos p = data->assoc_info.req_ies; 3151 1.10 christos l = data->assoc_info.req_ies_len; 3152 1.10 christos 3153 1.10 christos while (p && l >= 2) { 3154 1.10 christos len = p[1] + 2; 3155 1.10 christos if (len > l) { 3156 1.10 christos wpa_hexdump(MSG_DEBUG, "Truncated IE in assoc_info", 3157 1.10 christos p, l); 3158 1.10 christos break; 3159 1.10 christos } 3160 1.10 christos if (((p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 && 3161 1.10 christos (os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0)) || 3162 1.10 christos (p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 4 && 3163 1.10 christos (os_memcmp(&p[2], "\x50\x6F\x9A\x12", 4) == 0)) || 3164 1.10 christos (p[0] == WLAN_EID_RSN && p[1] >= 2))) { 3165 1.10 christos found = true; 3166 1.10 christos break; 3167 1.10 christos } 3168 1.10 christos l -= len; 3169 1.10 christos p += len; 3170 1.10 christos } 3171 1.10 christos 3172 1.10 christos if (!found || wpa_parse_wpa_ie(p, len, &ie) < 0) { 3173 1.10 christos wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_OCV, 0); 3174 1.10 christos return 0; 3175 1.10 christos } 3176 1.10 christos 3177 1.10 christos wpa_hexdump(MSG_DEBUG, 3178 1.10 christos "WPA: Update cipher suite selection based on IEs in driver-generated WPA/RSNE in AssocReq", 3179 1.10 christos p, l); 3180 1.10 christos 3181 1.10 christos /* Update proto from (Re)Association Request frame info */ 3182 1.10 christos wpa_s->wpa_proto = ie.proto; 3183 1.10 christos wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, wpa_s->wpa_proto); 3184 1.10 christos wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_RSN_ENABLED, 3185 1.10 christos !!(wpa_s->wpa_proto & 3186 1.10 christos (WPA_PROTO_RSN | WPA_PROTO_OSEN))); 3187 1.10 christos 3188 1.10 christos /* Update AKMP suite from (Re)Association Request frame info */ 3189 1.10 christos sel = ie.key_mgmt; 3190 1.10 christos if (ssid->key_mgmt) 3191 1.10 christos sel &= ssid->key_mgmt; 3192 1.10 christos 3193 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 3194 1.10 christos "WPA: AP key_mgmt 0x%x network key_mgmt 0x%x; available key_mgmt 0x%x", 3195 1.10 christos ie.key_mgmt, ssid->key_mgmt, sel); 3196 1.10 christos if (ie.key_mgmt && !sel) { 3197 1.10 christos wpa_supplicant_deauthenticate( 3198 1.10 christos wpa_s, WLAN_REASON_AKMP_NOT_VALID); 3199 1.10 christos return -1; 3200 1.10 christos } 3201 1.10 christos 3202 1.10 christos #ifdef CONFIG_OCV 3203 1.10 christos if (((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) || 3204 1.10 christos (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_OCV)) && ssid->ocv) 3205 1.10 christos wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_OCV, 3206 1.10 christos !!(ie.capabilities & WPA_CAPABILITY_OCVC)); 3207 1.10 christos #endif /* CONFIG_OCV */ 3208 1.10 christos 3209 1.10 christos /* 3210 1.10 christos * Update PMK in wpa_sm and the driver if roamed to WPA/WPA2 PSK from a 3211 1.10 christos * different AKM. 3212 1.10 christos */ 3213 1.10 christos if (wpa_s->key_mgmt != ie.key_mgmt && 3214 1.10 christos wpa_key_mgmt_wpa_psk_no_sae(ie.key_mgmt)) { 3215 1.10 christos if (!ssid->psk_set) { 3216 1.10 christos wpa_dbg(wpa_s, MSG_INFO, 3217 1.10 christos "No PSK available for association"); 3218 1.10 christos wpas_auth_failed(wpa_s, "NO_PSK_AVAILABLE", NULL); 3219 1.10 christos return -1; 3220 1.10 christos } 3221 1.10 christos 3222 1.10 christos wpa_sm_set_pmk(wpa_s->wpa, ssid->psk, PMK_LEN, NULL, NULL); 3223 1.10 christos if (wpa_s->conf->key_mgmt_offload && 3224 1.10 christos (wpa_s->drv_flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD) && 3225 1.10 christos wpa_drv_set_key(wpa_s, -1, 0, NULL, 0, 0, NULL, 0, 3226 1.10 christos ssid->psk, PMK_LEN, KEY_FLAG_PMK)) 3227 1.10 christos wpa_dbg(wpa_s, MSG_ERROR, 3228 1.10 christos "WPA: Cannot set PMK for key management offload"); 3229 1.10 christos } 3230 1.10 christos 3231 1.10 christos wpa_s->key_mgmt = ie.key_mgmt; 3232 1.10 christos wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_KEY_MGMT, wpa_s->key_mgmt); 3233 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using KEY_MGMT %s and proto %d", 3234 1.10 christos wpa_key_mgmt_txt(wpa_s->key_mgmt, wpa_s->wpa_proto), 3235 1.10 christos wpa_s->wpa_proto); 3236 1.10 christos 3237 1.10 christos /* Update pairwise cipher from (Re)Association Request frame info */ 3238 1.10 christos sel = ie.pairwise_cipher; 3239 1.10 christos if (ssid->pairwise_cipher) 3240 1.10 christos sel &= ssid->pairwise_cipher; 3241 1.10 christos 3242 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 3243 1.10 christos "WPA: AP pairwise cipher 0x%x network pairwise cipher 0x%x; available pairwise cipher 0x%x", 3244 1.10 christos ie.pairwise_cipher, ssid->pairwise_cipher, sel); 3245 1.10 christos if (ie.pairwise_cipher && !sel) { 3246 1.10 christos wpa_supplicant_deauthenticate( 3247 1.10 christos wpa_s, WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID); 3248 1.10 christos return -1; 3249 1.10 christos } 3250 1.10 christos 3251 1.10 christos wpa_s->pairwise_cipher = ie.pairwise_cipher; 3252 1.10 christos wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE, 3253 1.10 christos wpa_s->pairwise_cipher); 3254 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using PTK %s", 3255 1.10 christos wpa_cipher_txt(wpa_s->pairwise_cipher)); 3256 1.10 christos 3257 1.10 christos /* Update other parameters based on AP's WPA IE/RSNE, if available */ 3258 1.10 christos if (!bss) { 3259 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 3260 1.10 christos "WPA: current_bss == NULL - skip AP IE check"); 3261 1.10 christos return 0; 3262 1.10 christos } 3263 1.10 christos 3264 1.10 christos /* Update GTK and IGTK from AP's RSNE */ 3265 1.10 christos found = false; 3266 1.10 christos 3267 1.10 christos if (wpa_s->wpa_proto & (WPA_PROTO_RSN | WPA_PROTO_OSEN)) { 3268 1.10 christos const u8 *bss_rsn; 3269 1.10 christos 3270 1.10 christos bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN); 3271 1.10 christos if (bss_rsn) { 3272 1.10 christos p = bss_rsn; 3273 1.10 christos len = 2 + bss_rsn[1]; 3274 1.10 christos found = true; 3275 1.10 christos } 3276 1.10 christos } else if (wpa_s->wpa_proto & WPA_PROTO_WPA) { 3277 1.10 christos const u8 *bss_wpa; 3278 1.10 christos 3279 1.10 christos bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); 3280 1.10 christos if (bss_wpa) { 3281 1.10 christos p = bss_wpa; 3282 1.10 christos len = 2 + bss_wpa[1]; 3283 1.10 christos found = true; 3284 1.10 christos } 3285 1.10 christos } 3286 1.10 christos 3287 1.10 christos if (!found || wpa_parse_wpa_ie(p, len, &ie) < 0) 3288 1.10 christos return 0; 3289 1.10 christos 3290 1.10 christos pmf = wpas_get_ssid_pmf(wpa_s, ssid); 3291 1.10 christos if (!(ie.capabilities & WPA_CAPABILITY_MFPC) && 3292 1.10 christos pmf == MGMT_FRAME_PROTECTION_REQUIRED) { 3293 1.10 christos /* AP does not support MFP, local configuration requires it */ 3294 1.10 christos wpa_supplicant_deauthenticate( 3295 1.10 christos wpa_s, WLAN_REASON_INVALID_RSN_IE_CAPAB); 3296 1.10 christos return -1; 3297 1.10 christos } 3298 1.10 christos if ((ie.capabilities & WPA_CAPABILITY_MFPR) && 3299 1.10 christos pmf == NO_MGMT_FRAME_PROTECTION) { 3300 1.10 christos /* AP requires MFP, local configuration disables it */ 3301 1.10 christos wpa_supplicant_deauthenticate( 3302 1.10 christos wpa_s, WLAN_REASON_INVALID_RSN_IE_CAPAB); 3303 1.10 christos return -1; 3304 1.10 christos } 3305 1.10 christos 3306 1.10 christos /* Update PMF from local configuration now that MFP validation was done 3307 1.10 christos * above */ 3308 1.10 christos wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP, pmf); 3309 1.10 christos 3310 1.10 christos /* Update GTK from AP's RSNE */ 3311 1.10 christos sel = ie.group_cipher; 3312 1.10 christos if (ssid->group_cipher) 3313 1.10 christos sel &= ssid->group_cipher; 3314 1.10 christos 3315 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 3316 1.10 christos "WPA: AP group cipher 0x%x network group cipher 0x%x; available group cipher 0x%x", 3317 1.10 christos ie.group_cipher, ssid->group_cipher, sel); 3318 1.10 christos if (ie.group_cipher && !sel) { 3319 1.10 christos wpa_supplicant_deauthenticate( 3320 1.10 christos wpa_s, WLAN_REASON_GROUP_CIPHER_NOT_VALID); 3321 1.10 christos return -1; 3322 1.10 christos } 3323 1.10 christos 3324 1.10 christos wpa_s->group_cipher = ie.group_cipher; 3325 1.10 christos wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher); 3326 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using GTK %s", 3327 1.10 christos wpa_cipher_txt(wpa_s->group_cipher)); 3328 1.10 christos 3329 1.10 christos /* Update IGTK from AP RSN IE */ 3330 1.10 christos sel = ie.mgmt_group_cipher; 3331 1.10 christos if (ssid->group_mgmt_cipher) 3332 1.10 christos sel &= ssid->group_mgmt_cipher; 3333 1.10 christos 3334 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 3335 1.10 christos "WPA: AP mgmt_group_cipher 0x%x network mgmt_group_cipher 0x%x; available mgmt_group_cipher 0x%x", 3336 1.10 christos ie.mgmt_group_cipher, ssid->group_mgmt_cipher, sel); 3337 1.10 christos 3338 1.10 christos if (pmf == NO_MGMT_FRAME_PROTECTION || 3339 1.10 christos !(ie.capabilities & WPA_CAPABILITY_MFPC)) { 3340 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, 3341 1.10 christos "WPA: STA/AP is not MFP capable; AP RSNE caps 0x%x", 3342 1.10 christos ie.capabilities); 3343 1.10 christos ie.mgmt_group_cipher = 0; 3344 1.10 christos } 3345 1.10 christos 3346 1.10 christos if (ie.mgmt_group_cipher && !sel) { 3347 1.10 christos wpa_supplicant_deauthenticate( 3348 1.10 christos wpa_s, WLAN_REASON_CIPHER_SUITE_REJECTED); 3349 1.10 christos return -1; 3350 1.10 christos } 3351 1.10 christos 3352 1.10 christos wpa_s->mgmt_group_cipher = ie.mgmt_group_cipher; 3353 1.10 christos wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP, 3354 1.10 christos wpa_s->mgmt_group_cipher); 3355 1.10 christos if (wpa_s->mgmt_group_cipher) 3356 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher %s", 3357 1.10 christos wpa_cipher_txt(wpa_s->mgmt_group_cipher)); 3358 1.10 christos else 3359 1.10 christos wpa_dbg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher"); 3360 1.10 christos 3361 1.10 christos return 0; 3362 1.10 christos } 3363 1.10 christos 3364 1.10 christos 3365 1.1 christos static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s, 3366 1.1 christos union wpa_event_data *data) 3367 1.1 christos { 3368 1.10 christos int l, len, found = 0, found_x = 0, wpa_found, rsn_found; 3369 1.1 christos const u8 *p; 3370 1.2 joerg u8 bssid[ETH_ALEN]; 3371 1.10 christos bool bssid_known; 3372 1.1 christos 3373 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Association info event"); 3374 1.10 christos wpa_s->ssid_verified = false; 3375 1.10 christos wpa_s->bigtk_set = false; 3376 1.10 christos #ifdef CONFIG_SAE 3377 1.10 christos #ifdef CONFIG_SME 3378 1.10 christos /* SAE H2E binds the SSID into PT and that verifies the SSID 3379 1.10 christos * implicitly. */ 3380 1.10 christos if (wpa_s->sme.sae.state == SAE_ACCEPTED && wpa_s->sme.sae.h2e) 3381 1.10 christos wpa_s->ssid_verified = true; 3382 1.10 christos #endif /* CONFIG_SME */ 3383 1.10 christos #endif /* CONFIG_SAE */ 3384 1.10 christos bssid_known = wpa_drv_get_bssid(wpa_s, bssid) == 0; 3385 1.1 christos if (data->assoc_info.req_ies) 3386 1.1 christos wpa_hexdump(MSG_DEBUG, "req_ies", data->assoc_info.req_ies, 3387 1.1 christos data->assoc_info.req_ies_len); 3388 1.2 joerg if (data->assoc_info.resp_ies) { 3389 1.1 christos wpa_hexdump(MSG_DEBUG, "resp_ies", data->assoc_info.resp_ies, 3390 1.1 christos data->assoc_info.resp_ies_len); 3391 1.2 joerg #ifdef CONFIG_TDLS 3392 1.2 joerg wpa_tdls_assoc_resp_ies(wpa_s->wpa, data->assoc_info.resp_ies, 3393 1.2 joerg data->assoc_info.resp_ies_len); 3394 1.2 joerg #endif /* CONFIG_TDLS */ 3395 1.2 joerg #ifdef CONFIG_WNM 3396 1.2 joerg wnm_process_assoc_resp(wpa_s, data->assoc_info.resp_ies, 3397 1.2 joerg data->assoc_info.resp_ies_len); 3398 1.2 joerg #endif /* CONFIG_WNM */ 3399 1.2 joerg interworking_process_assoc_resp(wpa_s, data->assoc_info.resp_ies, 3400 1.2 joerg data->assoc_info.resp_ies_len); 3401 1.7 christos if (wpa_s->hw_capab == CAPAB_VHT && 3402 1.7 christos get_ie(data->assoc_info.resp_ies, 3403 1.7 christos data->assoc_info.resp_ies_len, WLAN_EID_VHT_CAP)) 3404 1.7 christos wpa_s->ieee80211ac = 1; 3405 1.9 christos 3406 1.9 christos multi_ap_process_assoc_resp(wpa_s, data->assoc_info.resp_ies, 3407 1.9 christos data->assoc_info.resp_ies_len); 3408 1.2 joerg } 3409 1.1 christos if (data->assoc_info.beacon_ies) 3410 1.1 christos wpa_hexdump(MSG_DEBUG, "beacon_ies", 3411 1.1 christos data->assoc_info.beacon_ies, 3412 1.1 christos data->assoc_info.beacon_ies_len); 3413 1.1 christos if (data->assoc_info.freq) 3414 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "freq=%u MHz", 3415 1.2 joerg data->assoc_info.freq); 3416 1.1 christos 3417 1.9 christos wpa_s->connection_set = 0; 3418 1.9 christos if (data->assoc_info.req_ies && data->assoc_info.resp_ies) { 3419 1.9 christos struct ieee802_11_elems req_elems, resp_elems; 3420 1.9 christos 3421 1.9 christos if (ieee802_11_parse_elems(data->assoc_info.req_ies, 3422 1.9 christos data->assoc_info.req_ies_len, 3423 1.9 christos &req_elems, 0) != ParseFailed && 3424 1.9 christos ieee802_11_parse_elems(data->assoc_info.resp_ies, 3425 1.9 christos data->assoc_info.resp_ies_len, 3426 1.9 christos &resp_elems, 0) != ParseFailed) { 3427 1.9 christos wpa_s->connection_set = 1; 3428 1.9 christos wpa_s->connection_ht = req_elems.ht_capabilities && 3429 1.9 christos resp_elems.ht_capabilities; 3430 1.10 christos /* Do not include subset of VHT on 2.4 GHz vendor 3431 1.10 christos * extension in consideration for reporting VHT 3432 1.10 christos * association. */ 3433 1.9 christos wpa_s->connection_vht = req_elems.vht_capabilities && 3434 1.10 christos resp_elems.vht_capabilities && 3435 1.10 christos (!data->assoc_info.freq || 3436 1.10 christos wpas_freq_to_band(data->assoc_info.freq) != 3437 1.10 christos BAND_2_4_GHZ); 3438 1.9 christos wpa_s->connection_he = req_elems.he_capabilities && 3439 1.9 christos resp_elems.he_capabilities; 3440 1.10 christos wpa_s->connection_eht = req_elems.eht_capabilities && 3441 1.10 christos resp_elems.eht_capabilities; 3442 1.10 christos if (req_elems.rrm_enabled) 3443 1.10 christos wpa_s->rrm.rrm_used = 1; 3444 1.9 christos } 3445 1.9 christos } 3446 1.9 christos 3447 1.1 christos p = data->assoc_info.req_ies; 3448 1.1 christos l = data->assoc_info.req_ies_len; 3449 1.1 christos 3450 1.1 christos /* Go through the IEs and make a copy of the WPA/RSN IE, if present. */ 3451 1.1 christos while (p && l >= 2) { 3452 1.1 christos len = p[1] + 2; 3453 1.1 christos if (len > l) { 3454 1.1 christos wpa_hexdump(MSG_DEBUG, "Truncated IE in assoc_info", 3455 1.1 christos p, l); 3456 1.1 christos break; 3457 1.1 christos } 3458 1.10 christos if (!found && 3459 1.10 christos ((p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 && 3460 1.10 christos (os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0)) || 3461 1.10 christos (p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 4 && 3462 1.10 christos (os_memcmp(&p[2], "\x50\x6F\x9A\x12", 4) == 0)) || 3463 1.10 christos (p[0] == WLAN_EID_RSN && p[1] >= 2))) { 3464 1.1 christos if (wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, p, len)) 3465 1.1 christos break; 3466 1.1 christos found = 1; 3467 1.10 christos wpa_find_assoc_pmkid(wpa_s, 3468 1.10 christos data->assoc_info.authorized); 3469 1.10 christos } 3470 1.10 christos if (!found_x && p[0] == WLAN_EID_RSNX) { 3471 1.10 christos if (wpa_sm_set_assoc_rsnxe(wpa_s->wpa, p, len)) 3472 1.10 christos break; 3473 1.10 christos found_x = 1; 3474 1.1 christos } 3475 1.1 christos l -= len; 3476 1.1 christos p += len; 3477 1.1 christos } 3478 1.1 christos if (!found && data->assoc_info.req_ies) 3479 1.1 christos wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0); 3480 1.10 christos if (!found_x && data->assoc_info.req_ies) 3481 1.10 christos wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0); 3482 1.1 christos 3483 1.7 christos #ifdef CONFIG_FILS 3484 1.7 christos #ifdef CONFIG_SME 3485 1.10 christos if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS || 3486 1.10 christos wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS_SK_PFS) { 3487 1.10 christos if (!data->assoc_info.resp_frame || 3488 1.10 christos fils_process_assoc_resp(wpa_s->wpa, 3489 1.10 christos data->assoc_info.resp_frame, 3490 1.10 christos data->assoc_info.resp_frame_len) < 3491 1.10 christos 0) { 3492 1.10 christos wpa_supplicant_deauthenticate(wpa_s, 3493 1.10 christos WLAN_REASON_UNSPECIFIED); 3494 1.10 christos return -1; 3495 1.10 christos } 3496 1.10 christos 3497 1.10 christos /* FILS use of an AEAD cipher include the SSID element in 3498 1.10 christos * (Re)Association Request frame in the AAD and since the AP 3499 1.10 christos * accepted that, the SSID was verified. */ 3500 1.10 christos wpa_s->ssid_verified = true; 3501 1.7 christos } 3502 1.7 christos #endif /* CONFIG_SME */ 3503 1.7 christos 3504 1.7 christos /* Additional processing for FILS when SME is in driver */ 3505 1.7 christos if (wpa_s->auth_alg == WPA_AUTH_ALG_FILS && 3506 1.7 christos !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) 3507 1.7 christos wpa_sm_set_reset_fils_completed(wpa_s->wpa, 1); 3508 1.7 christos #endif /* CONFIG_FILS */ 3509 1.7 christos 3510 1.7 christos #ifdef CONFIG_OWE 3511 1.7 christos if (wpa_s->key_mgmt == WPA_KEY_MGMT_OWE && 3512 1.10 christos !(wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_OWE_OFFLOAD_STA) && 3513 1.10 christos (!bssid_known || 3514 1.10 christos owe_process_assoc_resp(wpa_s->wpa, 3515 1.10 christos wpa_s->valid_links ? 3516 1.10 christos wpa_s->ap_mld_addr : bssid, 3517 1.7 christos data->assoc_info.resp_ies, 3518 1.7 christos data->assoc_info.resp_ies_len) < 0)) { 3519 1.7 christos wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_UNSPECIFIED); 3520 1.7 christos return -1; 3521 1.7 christos } 3522 1.7 christos #endif /* CONFIG_OWE */ 3523 1.7 christos 3524 1.9 christos #ifdef CONFIG_DPP2 3525 1.9 christos wpa_sm_set_dpp_z(wpa_s->wpa, NULL); 3526 1.10 christos if (DPP_VERSION > 1 && wpa_s->key_mgmt == WPA_KEY_MGMT_DPP && 3527 1.10 christos wpa_s->dpp_pfs) { 3528 1.9 christos struct ieee802_11_elems elems; 3529 1.9 christos 3530 1.9 christos if (ieee802_11_parse_elems(data->assoc_info.resp_ies, 3531 1.9 christos data->assoc_info.resp_ies_len, 3532 1.9 christos &elems, 0) == ParseFailed || 3533 1.9 christos !elems.owe_dh) 3534 1.9 christos goto no_pfs; 3535 1.9 christos if (dpp_pfs_process(wpa_s->dpp_pfs, elems.owe_dh, 3536 1.9 christos elems.owe_dh_len) < 0) { 3537 1.9 christos wpa_supplicant_deauthenticate(wpa_s, 3538 1.9 christos WLAN_REASON_UNSPECIFIED); 3539 1.9 christos return -1; 3540 1.9 christos } 3541 1.9 christos 3542 1.9 christos wpa_sm_set_dpp_z(wpa_s->wpa, wpa_s->dpp_pfs->secret); 3543 1.9 christos } 3544 1.9 christos no_pfs: 3545 1.9 christos #endif /* CONFIG_DPP2 */ 3546 1.9 christos 3547 1.1 christos #ifdef CONFIG_IEEE80211R 3548 1.1 christos #ifdef CONFIG_SME 3549 1.1 christos if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FT) { 3550 1.10 christos if (!bssid_known || 3551 1.1 christos wpa_ft_validate_reassoc_resp(wpa_s->wpa, 3552 1.1 christos data->assoc_info.resp_ies, 3553 1.1 christos data->assoc_info.resp_ies_len, 3554 1.1 christos bssid) < 0) { 3555 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "FT: Validation of " 3556 1.2 joerg "Reassociation Response failed"); 3557 1.1 christos wpa_supplicant_deauthenticate( 3558 1.1 christos wpa_s, WLAN_REASON_INVALID_IE); 3559 1.1 christos return -1; 3560 1.1 christos } 3561 1.10 christos /* SSID is included in PMK-R0 derivation, so it is verified 3562 1.10 christos * implicitly. */ 3563 1.10 christos wpa_s->ssid_verified = true; 3564 1.1 christos } 3565 1.1 christos 3566 1.1 christos p = data->assoc_info.resp_ies; 3567 1.1 christos l = data->assoc_info.resp_ies_len; 3568 1.1 christos 3569 1.2 joerg #ifdef CONFIG_WPS_STRICT 3570 1.2 joerg if (p && wpa_s->current_ssid && 3571 1.2 joerg wpa_s->current_ssid->key_mgmt == WPA_KEY_MGMT_WPS) { 3572 1.2 joerg struct wpabuf *wps; 3573 1.2 joerg wps = ieee802_11_vendor_ie_concat(p, l, WPS_IE_VENDOR_TYPE); 3574 1.2 joerg if (wps == NULL) { 3575 1.2 joerg wpa_msg(wpa_s, MSG_INFO, "WPS-STRICT: AP did not " 3576 1.2 joerg "include WPS IE in (Re)Association Response"); 3577 1.2 joerg return -1; 3578 1.2 joerg } 3579 1.2 joerg 3580 1.2 joerg if (wps_validate_assoc_resp(wps) < 0) { 3581 1.2 joerg wpabuf_free(wps); 3582 1.2 joerg wpa_supplicant_deauthenticate( 3583 1.2 joerg wpa_s, WLAN_REASON_INVALID_IE); 3584 1.2 joerg return -1; 3585 1.2 joerg } 3586 1.2 joerg wpabuf_free(wps); 3587 1.2 joerg } 3588 1.2 joerg #endif /* CONFIG_WPS_STRICT */ 3589 1.2 joerg 3590 1.1 christos /* Go through the IEs and make a copy of the MDIE, if present. */ 3591 1.1 christos while (p && l >= 2) { 3592 1.1 christos len = p[1] + 2; 3593 1.1 christos if (len > l) { 3594 1.1 christos wpa_hexdump(MSG_DEBUG, "Truncated IE in assoc_info", 3595 1.1 christos p, l); 3596 1.1 christos break; 3597 1.1 christos } 3598 1.1 christos if (p[0] == WLAN_EID_MOBILITY_DOMAIN && 3599 1.1 christos p[1] >= MOBILITY_DOMAIN_ID_LEN) { 3600 1.1 christos wpa_s->sme.ft_used = 1; 3601 1.1 christos os_memcpy(wpa_s->sme.mobility_domain, p + 2, 3602 1.1 christos MOBILITY_DOMAIN_ID_LEN); 3603 1.1 christos break; 3604 1.1 christos } 3605 1.1 christos l -= len; 3606 1.1 christos p += len; 3607 1.1 christos } 3608 1.1 christos #endif /* CONFIG_SME */ 3609 1.1 christos 3610 1.2 joerg /* Process FT when SME is in the driver */ 3611 1.2 joerg if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) && 3612 1.2 joerg wpa_ft_is_completed(wpa_s->wpa)) { 3613 1.10 christos if (!bssid_known || 3614 1.2 joerg wpa_ft_validate_reassoc_resp(wpa_s->wpa, 3615 1.2 joerg data->assoc_info.resp_ies, 3616 1.2 joerg data->assoc_info.resp_ies_len, 3617 1.2 joerg bssid) < 0) { 3618 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "FT: Validation of " 3619 1.2 joerg "Reassociation Response failed"); 3620 1.2 joerg wpa_supplicant_deauthenticate( 3621 1.2 joerg wpa_s, WLAN_REASON_INVALID_IE); 3622 1.2 joerg return -1; 3623 1.2 joerg } 3624 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "FT: Reassociation Response done"); 3625 1.10 christos /* SSID is included in PMK-R0 derivation, so it is verified 3626 1.10 christos * implicitly. */ 3627 1.10 christos wpa_s->ssid_verified = true; 3628 1.2 joerg } 3629 1.2 joerg 3630 1.1 christos wpa_sm_set_ft_params(wpa_s->wpa, data->assoc_info.resp_ies, 3631 1.1 christos data->assoc_info.resp_ies_len); 3632 1.1 christos #endif /* CONFIG_IEEE80211R */ 3633 1.1 christos 3634 1.10 christos #ifndef CONFIG_NO_ROBUST_AV 3635 1.10 christos if (bssid_known) 3636 1.10 christos wpas_handle_assoc_resp_mscs(wpa_s, bssid, 3637 1.10 christos data->assoc_info.resp_ies, 3638 1.10 christos data->assoc_info.resp_ies_len); 3639 1.10 christos #endif /* CONFIG_NO_ROBUST_AV */ 3640 1.10 christos 3641 1.1 christos /* WPA/RSN IE from Beacon/ProbeResp */ 3642 1.1 christos p = data->assoc_info.beacon_ies; 3643 1.1 christos l = data->assoc_info.beacon_ies_len; 3644 1.1 christos 3645 1.1 christos /* Go through the IEs and make a copy of the WPA/RSN IEs, if present. 3646 1.1 christos */ 3647 1.1 christos wpa_found = rsn_found = 0; 3648 1.1 christos while (p && l >= 2) { 3649 1.1 christos len = p[1] + 2; 3650 1.1 christos if (len > l) { 3651 1.1 christos wpa_hexdump(MSG_DEBUG, "Truncated IE in beacon_ies", 3652 1.1 christos p, l); 3653 1.1 christos break; 3654 1.1 christos } 3655 1.1 christos if (!wpa_found && 3656 1.1 christos p[0] == WLAN_EID_VENDOR_SPECIFIC && p[1] >= 6 && 3657 1.1 christos os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0) { 3658 1.1 christos wpa_found = 1; 3659 1.1 christos wpa_sm_set_ap_wpa_ie(wpa_s->wpa, p, len); 3660 1.1 christos } 3661 1.1 christos 3662 1.1 christos if (!rsn_found && 3663 1.1 christos p[0] == WLAN_EID_RSN && p[1] >= 2) { 3664 1.1 christos rsn_found = 1; 3665 1.1 christos wpa_sm_set_ap_rsn_ie(wpa_s->wpa, p, len); 3666 1.1 christos } 3667 1.1 christos 3668 1.10 christos if (p[0] == WLAN_EID_RSNX && p[1] >= 1) 3669 1.10 christos wpa_sm_set_ap_rsnxe(wpa_s->wpa, p, len); 3670 1.10 christos 3671 1.1 christos l -= len; 3672 1.1 christos p += len; 3673 1.1 christos } 3674 1.1 christos 3675 1.1 christos if (!wpa_found && data->assoc_info.beacon_ies) 3676 1.1 christos wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0); 3677 1.10 christos if (!rsn_found && data->assoc_info.beacon_ies) { 3678 1.1 christos wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0); 3679 1.10 christos wpa_sm_set_ap_rsnxe(wpa_s->wpa, NULL, 0); 3680 1.10 christos } 3681 1.1 christos if (wpa_found || rsn_found) 3682 1.1 christos wpa_s->ap_ies_from_associnfo = 1; 3683 1.1 christos 3684 1.10 christos if (wpa_s->assoc_freq && data->assoc_info.freq) { 3685 1.10 christos struct wpa_bss *bss; 3686 1.10 christos unsigned int freq = 0; 3687 1.10 christos 3688 1.10 christos if (bssid_known) { 3689 1.10 christos bss = wpa_bss_get_bssid_latest(wpa_s, bssid); 3690 1.10 christos if (bss) 3691 1.10 christos freq = bss->freq; 3692 1.10 christos } 3693 1.10 christos if (freq != data->assoc_info.freq) { 3694 1.10 christos wpa_printf(MSG_DEBUG, 3695 1.10 christos "Operating frequency changed from %u to %u MHz", 3696 1.10 christos wpa_s->assoc_freq, data->assoc_info.freq); 3697 1.10 christos wpa_supplicant_update_scan_results(wpa_s, bssid); 3698 1.10 christos } 3699 1.2 joerg } 3700 1.2 joerg 3701 1.1 christos wpa_s->assoc_freq = data->assoc_info.freq; 3702 1.1 christos 3703 1.10 christos #ifndef CONFIG_NO_ROBUST_AV 3704 1.10 christos wpas_handle_assoc_resp_qos_mgmt(wpa_s, data->assoc_info.resp_ies, 3705 1.10 christos data->assoc_info.resp_ies_len); 3706 1.10 christos #endif /* CONFIG_NO_ROBUST_AV */ 3707 1.10 christos 3708 1.1 christos return 0; 3709 1.1 christos } 3710 1.1 christos 3711 1.1 christos 3712 1.2 joerg static int wpa_supplicant_assoc_update_ie(struct wpa_supplicant *wpa_s) 3713 1.2 joerg { 3714 1.10 christos const u8 *bss_wpa = NULL, *bss_rsn = NULL, *bss_rsnx = NULL; 3715 1.2 joerg 3716 1.2 joerg if (!wpa_s->current_bss || !wpa_s->current_ssid) 3717 1.2 joerg return -1; 3718 1.2 joerg 3719 1.2 joerg if (!wpa_key_mgmt_wpa_any(wpa_s->current_ssid->key_mgmt)) 3720 1.2 joerg return 0; 3721 1.2 joerg 3722 1.2 joerg bss_wpa = wpa_bss_get_vendor_ie(wpa_s->current_bss, 3723 1.2 joerg WPA_IE_VENDOR_TYPE); 3724 1.2 joerg bss_rsn = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_RSN); 3725 1.10 christos bss_rsnx = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_RSNX); 3726 1.2 joerg 3727 1.2 joerg if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, bss_wpa, 3728 1.2 joerg bss_wpa ? 2 + bss_wpa[1] : 0) || 3729 1.2 joerg wpa_sm_set_ap_rsn_ie(wpa_s->wpa, bss_rsn, 3730 1.10 christos bss_rsn ? 2 + bss_rsn[1] : 0) || 3731 1.10 christos wpa_sm_set_ap_rsnxe(wpa_s->wpa, bss_rsnx, 3732 1.10 christos bss_rsnx ? 2 + bss_rsnx[1] : 0)) 3733 1.2 joerg return -1; 3734 1.2 joerg 3735 1.2 joerg return 0; 3736 1.2 joerg } 3737 1.2 joerg 3738 1.2 joerg 3739 1.6 christos static void wpas_fst_update_mb_assoc(struct wpa_supplicant *wpa_s, 3740 1.6 christos union wpa_event_data *data) 3741 1.6 christos { 3742 1.6 christos #ifdef CONFIG_FST 3743 1.6 christos struct assoc_info *ai = data ? &data->assoc_info : NULL; 3744 1.6 christos struct wpa_bss *bss = wpa_s->current_bss; 3745 1.6 christos const u8 *ieprb, *iebcn; 3746 1.6 christos 3747 1.6 christos wpabuf_free(wpa_s->received_mb_ies); 3748 1.6 christos wpa_s->received_mb_ies = NULL; 3749 1.6 christos 3750 1.6 christos if (ai && 3751 1.6 christos !wpas_fst_update_mbie(wpa_s, ai->resp_ies, ai->resp_ies_len)) { 3752 1.6 christos wpa_printf(MSG_DEBUG, 3753 1.6 christos "FST: MB IEs updated from Association Response frame"); 3754 1.6 christos return; 3755 1.6 christos } 3756 1.6 christos 3757 1.6 christos if (ai && 3758 1.6 christos !wpas_fst_update_mbie(wpa_s, ai->beacon_ies, ai->beacon_ies_len)) { 3759 1.6 christos wpa_printf(MSG_DEBUG, 3760 1.6 christos "FST: MB IEs updated from association event Beacon IEs"); 3761 1.6 christos return; 3762 1.6 christos } 3763 1.6 christos 3764 1.10 christos if (!bss) 3765 1.10 christos return; 3766 1.10 christos 3767 1.10 christos ieprb = wpa_bss_ie_ptr(bss); 3768 1.10 christos iebcn = ieprb + bss->ie_len; 3769 1.10 christos 3770 1.10 christos if (!wpas_fst_update_mbie(wpa_s, ieprb, bss->ie_len)) 3771 1.10 christos wpa_printf(MSG_DEBUG, "FST: MB IEs updated from bss IE"); 3772 1.10 christos else if (!wpas_fst_update_mbie(wpa_s, iebcn, bss->beacon_ie_len)) 3773 1.10 christos wpa_printf(MSG_DEBUG, "FST: MB IEs updated from bss beacon IE"); 3774 1.10 christos #endif /* CONFIG_FST */ 3775 1.10 christos } 3776 1.10 christos 3777 1.10 christos 3778 1.10 christos static unsigned int wpas_ml_parse_assoc(struct wpa_supplicant *wpa_s, 3779 1.10 christos struct ieee802_11_elems *elems, 3780 1.10 christos struct ml_sta_link_info *ml_info) 3781 1.10 christos { 3782 1.10 christos struct wpabuf *mlbuf; 3783 1.10 christos struct ieee80211_eht_ml *ml; 3784 1.10 christos size_t ml_len; 3785 1.10 christos struct eht_ml_basic_common_info *common_info; 3786 1.10 christos const u8 *pos; 3787 1.10 christos u16 eml_capa = 0, mld_capa = 0; 3788 1.10 christos const u16 control = 3789 1.10 christos host_to_le16(MULTI_LINK_CONTROL_TYPE_BASIC | 3790 1.10 christos BASIC_MULTI_LINK_CTRL_PRES_LINK_ID | 3791 1.10 christos BASIC_MULTI_LINK_CTRL_PRES_BSS_PARAM_CH_COUNT); 3792 1.10 christos u8 expected_common_info_len = 9; 3793 1.10 christos unsigned int i = 0; 3794 1.10 christos u16 ml_control; 3795 1.10 christos 3796 1.10 christos if (!wpa_s->valid_links || !elems->basic_mle || !elems->basic_mle_len) 3797 1.10 christos return 0; 3798 1.10 christos 3799 1.10 christos mlbuf = ieee802_11_defrag(elems->basic_mle, elems->basic_mle_len, true); 3800 1.10 christos if (!mlbuf) 3801 1.10 christos return 0; 3802 1.10 christos 3803 1.10 christos ml = (struct ieee80211_eht_ml *) wpabuf_head(mlbuf); 3804 1.10 christos ml_len = wpabuf_len(mlbuf); 3805 1.10 christos if (ml_len < sizeof(*ml)) 3806 1.10 christos goto out; 3807 1.10 christos 3808 1.10 christos os_memset(ml_info, 0, sizeof(*ml_info) * MAX_NUM_MLD_LINKS); 3809 1.10 christos 3810 1.10 christos ml_control = le_to_host16(ml->ml_control); 3811 1.10 christos 3812 1.10 christos if ((ml_control & control) != control) { 3813 1.10 christos wpa_printf(MSG_DEBUG, "MLD: Invalid presence BM=0x%x", 3814 1.10 christos ml_control); 3815 1.10 christos goto out; 3816 1.10 christos } 3817 1.10 christos 3818 1.10 christos if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_EML_CAPA) { 3819 1.10 christos wpa_printf(MSG_DEBUG, "MLD: EML capabilities included"); 3820 1.10 christos expected_common_info_len += 2; 3821 1.10 christos } 3822 1.10 christos 3823 1.10 christos if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_MLD_CAPA) { 3824 1.10 christos wpa_printf(MSG_DEBUG, "MLD: MLD capabilities included"); 3825 1.10 christos expected_common_info_len += 2; 3826 1.10 christos } 3827 1.10 christos 3828 1.10 christos if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_MSD_INFO) { 3829 1.10 christos wpa_printf(MSG_DEBUG, 3830 1.10 christos "MLD: Unexpected: medium sync delay info present"); 3831 1.10 christos expected_common_info_len += 2; 3832 1.10 christos } 3833 1.10 christos 3834 1.10 christos if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_AP_MLD_ID) { 3835 1.10 christos wpa_printf(MSG_DEBUG, 3836 1.10 christos "MLD: Unexpected: MLD ID present"); 3837 1.10 christos expected_common_info_len++; 3838 1.10 christos } 3839 1.10 christos 3840 1.10 christos if (sizeof(*ml) + expected_common_info_len > ml_len) { 3841 1.10 christos wpa_printf(MSG_DEBUG, 3842 1.10 christos "MLD: Not enough bytes for common info. ml_len=%zu", 3843 1.10 christos ml_len); 3844 1.10 christos goto out; 3845 1.10 christos } 3846 1.10 christos 3847 1.10 christos common_info = (struct eht_ml_basic_common_info *) ml->variable; 3848 1.10 christos if (common_info->len != expected_common_info_len) { 3849 1.10 christos wpa_printf(MSG_DEBUG, 3850 1.10 christos "MLD: Invalid common info len=%u. expected=%u", 3851 1.10 christos common_info->len, expected_common_info_len); 3852 1.10 christos goto out; 3853 1.10 christos } 3854 1.10 christos 3855 1.10 christos wpa_printf(MSG_DEBUG, "MLD: address: " MACSTR, 3856 1.10 christos MAC2STR(common_info->mld_addr)); 3857 1.10 christos 3858 1.10 christos if (!ether_addr_equal(wpa_s->ap_mld_addr, common_info->mld_addr)) { 3859 1.10 christos wpa_printf(MSG_DEBUG, "MLD: Mismatching MLD address (expected " 3860 1.10 christos MACSTR ")", MAC2STR(wpa_s->ap_mld_addr)); 3861 1.10 christos goto out; 3862 1.10 christos } 3863 1.10 christos 3864 1.10 christos pos = common_info->variable; 3865 1.10 christos 3866 1.10 christos /* Store the information for the association link */ 3867 1.10 christos ml_info[i].link_id = *pos; 3868 1.10 christos pos++; 3869 1.10 christos 3870 1.10 christos /* Skip the BSS Parameters Change Count */ 3871 1.10 christos pos++; 3872 1.10 christos 3873 1.10 christos /* Skip the Medium Synchronization Delay Information if present */ 3874 1.10 christos if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_MSD_INFO) 3875 1.10 christos pos += 2; 3876 1.10 christos 3877 1.10 christos if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_EML_CAPA) { 3878 1.10 christos eml_capa = WPA_GET_LE16(pos); 3879 1.10 christos pos += 2; 3880 1.10 christos } 3881 1.10 christos 3882 1.10 christos if (ml_control & BASIC_MULTI_LINK_CTRL_PRES_MLD_CAPA) { 3883 1.10 christos mld_capa = WPA_GET_LE16(pos); 3884 1.10 christos pos += 2; 3885 1.10 christos } 3886 1.10 christos 3887 1.10 christos wpa_printf(MSG_DEBUG, 3888 1.10 christos "MLD: link_id=%u, eml=0x%x, mld=0x%x", 3889 1.10 christos ml_info[i].link_id, eml_capa, mld_capa); 3890 1.10 christos 3891 1.10 christos i++; 3892 1.10 christos 3893 1.10 christos pos = ((u8 *) common_info) + common_info->len; 3894 1.10 christos ml_len -= sizeof(*ml) + common_info->len; 3895 1.10 christos while (ml_len > 2 && i < MAX_NUM_MLD_LINKS) { 3896 1.10 christos u8 sub_elem_len = pos[1]; 3897 1.10 christos u8 sta_info_len; 3898 1.10 christos u8 nstr_bitmap_len = 0; 3899 1.10 christos u16 ctrl; 3900 1.10 christos const u8 *end; 3901 1.10 christos 3902 1.10 christos wpa_printf(MSG_DEBUG, "MLD: Subelement len=%u", sub_elem_len); 3903 1.10 christos 3904 1.10 christos if (sub_elem_len > ml_len - 2) { 3905 1.10 christos wpa_printf(MSG_DEBUG, 3906 1.10 christos "MLD: Invalid link info len: %u > %zu", 3907 1.10 christos 2 + sub_elem_len, ml_len); 3908 1.10 christos goto out; 3909 1.10 christos } 3910 1.10 christos 3911 1.10 christos switch (*pos) { 3912 1.10 christos case EHT_ML_SUB_ELEM_PER_STA_PROFILE: 3913 1.10 christos break; 3914 1.10 christos case EHT_ML_SUB_ELEM_FRAGMENT: 3915 1.10 christos case EHT_ML_SUB_ELEM_VENDOR: 3916 1.10 christos wpa_printf(MSG_DEBUG, 3917 1.10 christos "MLD: Skip subelement id=%u, len=%u", 3918 1.10 christos *pos, sub_elem_len); 3919 1.10 christos pos += 2 + sub_elem_len; 3920 1.10 christos ml_len -= 2 + sub_elem_len; 3921 1.10 christos continue; 3922 1.10 christos default: 3923 1.10 christos wpa_printf(MSG_DEBUG, "MLD: Unknown subelement ID=%u", 3924 1.10 christos *pos); 3925 1.10 christos goto out; 3926 1.10 christos } 3927 1.10 christos 3928 1.10 christos end = pos + 2 + sub_elem_len; 3929 1.10 christos 3930 1.10 christos /* Skip the subelement ID and the length */ 3931 1.10 christos pos += 2; 3932 1.10 christos ml_len -= 2; 3933 1.10 christos 3934 1.10 christos if (end - pos < 2) 3935 1.10 christos goto out; 3936 1.10 christos 3937 1.10 christos /* Get the station control field */ 3938 1.10 christos ctrl = WPA_GET_LE16(pos); 3939 1.10 christos 3940 1.10 christos pos += 2; 3941 1.10 christos ml_len -= 2; 3942 1.10 christos 3943 1.10 christos if (!(ctrl & EHT_PER_STA_CTRL_COMPLETE_PROFILE_MSK)) { 3944 1.10 christos wpa_printf(MSG_DEBUG, 3945 1.10 christos "MLD: Per STA complete profile expected"); 3946 1.10 christos goto out; 3947 1.10 christos } 3948 1.10 christos 3949 1.10 christos if (!(ctrl & EHT_PER_STA_CTRL_MAC_ADDR_PRESENT_MSK)) { 3950 1.10 christos wpa_printf(MSG_DEBUG, 3951 1.10 christos "MLD: Per STA MAC address not present"); 3952 1.10 christos goto out; 3953 1.10 christos } 3954 1.10 christos 3955 1.10 christos if (!(ctrl & EHT_PER_STA_CTRL_TSF_OFFSET_PRESENT_MSK)) { 3956 1.10 christos wpa_printf(MSG_DEBUG, 3957 1.10 christos "MLD: Per STA TSF offset not present"); 3958 1.10 christos goto out; 3959 1.10 christos } 3960 1.10 christos 3961 1.10 christos if (!(ctrl & EHT_PER_STA_CTRL_BEACON_INTERVAL_PRESENT_MSK)) { 3962 1.10 christos wpa_printf(MSG_DEBUG, 3963 1.10 christos "MLD: Beacon interval not present"); 3964 1.10 christos goto out; 3965 1.10 christos } 3966 1.10 christos 3967 1.10 christos if (!(ctrl & EHT_PER_STA_CTRL_DTIM_INFO_PRESENT_MSK)) { 3968 1.10 christos wpa_printf(MSG_DEBUG, 3969 1.10 christos "MLD: DTIM information not present"); 3970 1.10 christos goto out; 3971 1.10 christos } 3972 1.10 christos 3973 1.10 christos if (ctrl & EHT_PER_STA_CTRL_NSTR_LINK_PAIR_PRESENT_MSK) { 3974 1.10 christos if (ctrl & EHT_PER_STA_CTRL_NSTR_BM_SIZE_MSK) 3975 1.10 christos nstr_bitmap_len = 2; 3976 1.10 christos else 3977 1.10 christos nstr_bitmap_len = 1; 3978 1.10 christos } 3979 1.10 christos 3980 1.10 christos if (!(ctrl & EHT_PER_STA_CTRL_BSS_PARAM_CNT_PRESENT_MSK)) { 3981 1.10 christos wpa_printf(MSG_DEBUG, 3982 1.10 christos "MLD: BSS params change count not present"); 3983 1.10 christos goto out; 3984 1.10 christos } 3985 1.10 christos 3986 1.10 christos sta_info_len = 1 + ETH_ALEN + 8 + 2 + 2 + 1 + nstr_bitmap_len; 3987 1.10 christos if (sta_info_len > ml_len || sta_info_len > end - pos || 3988 1.10 christos sta_info_len + 2 > sub_elem_len || 3989 1.10 christos sta_info_len != *pos) { 3990 1.10 christos wpa_printf(MSG_DEBUG, 3991 1.10 christos "MLD: Invalid STA info len=%u, len=%u", 3992 1.10 christos sta_info_len, *pos); 3993 1.10 christos goto out; 3994 1.10 christos } 3995 1.10 christos 3996 1.10 christos /* Get the link address */ 3997 1.10 christos wpa_printf(MSG_DEBUG, 3998 1.10 christos "MLD: link addr: " MACSTR " nstr BM len=%u", 3999 1.10 christos MAC2STR(pos + 1), nstr_bitmap_len); 4000 1.10 christos 4001 1.10 christos ml_info[i].link_id = ctrl & EHT_PER_STA_CTRL_LINK_ID_MSK; 4002 1.10 christos os_memcpy(ml_info[i].bssid, pos + 1, ETH_ALEN); 4003 1.10 christos 4004 1.10 christos pos += sta_info_len; 4005 1.10 christos ml_len -= sta_info_len; 4006 1.10 christos 4007 1.10 christos wpa_printf(MSG_DEBUG, "MLD: sub_elem_len=%u, sta_info_len=%u", 4008 1.10 christos sub_elem_len, sta_info_len); 4009 1.10 christos 4010 1.10 christos sub_elem_len -= sta_info_len + 2; 4011 1.10 christos if (sub_elem_len < 4) { 4012 1.10 christos wpa_printf(MSG_DEBUG, "MLD: Per STA profile too short"); 4013 1.10 christos goto out; 4014 1.10 christos } 4015 1.10 christos 4016 1.10 christos wpa_hexdump(MSG_MSGDUMP, "MLD: STA profile", pos, sub_elem_len); 4017 1.10 christos ml_info[i].status = WPA_GET_LE16(pos + 2); 4018 1.10 christos 4019 1.10 christos pos += sub_elem_len; 4020 1.10 christos ml_len -= sub_elem_len; 4021 1.10 christos 4022 1.10 christos i++; 4023 1.10 christos } 4024 1.10 christos 4025 1.10 christos wpabuf_free(mlbuf); 4026 1.10 christos return i; 4027 1.10 christos out: 4028 1.10 christos wpabuf_free(mlbuf); 4029 1.10 christos return 0; 4030 1.10 christos } 4031 1.10 christos 4032 1.10 christos 4033 1.10 christos static int wpa_drv_get_mlo_info(struct wpa_supplicant *wpa_s) 4034 1.10 christos { 4035 1.10 christos struct driver_sta_mlo_info mlo; 4036 1.10 christos int i; 4037 1.10 christos 4038 1.10 christos os_memset(&mlo, 0, sizeof(mlo)); 4039 1.10 christos if (wpas_drv_get_sta_mlo_info(wpa_s, &mlo)) { 4040 1.10 christos wpa_dbg(wpa_s, MSG_ERROR, "Failed to get MLO link info"); 4041 1.10 christos wpa_supplicant_deauthenticate(wpa_s, 4042 1.10 christos WLAN_REASON_DEAUTH_LEAVING); 4043 1.10 christos return -1; 4044 1.10 christos } 4045 1.10 christos 4046 1.10 christos if (wpa_s->valid_links == mlo.valid_links) { 4047 1.10 christos bool match = true; 4048 1.10 christos 4049 1.10 christos if (!mlo.valid_links) 4050 1.10 christos return 0; 4051 1.10 christos 4052 1.10 christos for_each_link(mlo.valid_links, i) { 4053 1.10 christos if (!ether_addr_equal(wpa_s->links[i].addr, 4054 1.10 christos mlo.links[i].addr) || 4055 1.10 christos !ether_addr_equal(wpa_s->links[i].bssid, 4056 1.10 christos mlo.links[i].bssid)) { 4057 1.10 christos match = false; 4058 1.10 christos break; 4059 1.10 christos } 4060 1.10 christos } 4061 1.10 christos 4062 1.10 christos if (match && wpa_s->mlo_assoc_link_id == mlo.assoc_link_id && 4063 1.10 christos ether_addr_equal(wpa_s->ap_mld_addr, mlo.ap_mld_addr)) 4064 1.10 christos return 0; 4065 1.10 christos } 4066 1.10 christos 4067 1.10 christos wpa_s->valid_links = mlo.valid_links; 4068 1.10 christos wpa_s->mlo_assoc_link_id = mlo.assoc_link_id; 4069 1.10 christos os_memcpy(wpa_s->ap_mld_addr, mlo.ap_mld_addr, ETH_ALEN); 4070 1.10 christos for_each_link(wpa_s->valid_links, i) { 4071 1.10 christos os_memcpy(wpa_s->links[i].addr, mlo.links[i].addr, ETH_ALEN); 4072 1.10 christos os_memcpy(wpa_s->links[i].bssid, mlo.links[i].bssid, ETH_ALEN); 4073 1.10 christos wpa_s->links[i].freq = mlo.links[i].freq; 4074 1.10 christos wpa_supplicant_update_link_bss(wpa_s, i, mlo.links[i].bssid); 4075 1.10 christos } 4076 1.10 christos 4077 1.10 christos return 0; 4078 1.10 christos } 4079 1.10 christos 4080 1.10 christos 4081 1.10 christos static int wpa_sm_set_ml_info(struct wpa_supplicant *wpa_s) 4082 1.10 christos { 4083 1.10 christos struct driver_sta_mlo_info drv_mlo; 4084 1.10 christos struct wpa_sm_mlo wpa_mlo; 4085 1.10 christos const u8 *bss_rsn = NULL, *bss_rsnx = NULL; 4086 1.10 christos int i; 4087 1.10 christos 4088 1.10 christos os_memset(&drv_mlo, 0, sizeof(drv_mlo)); 4089 1.10 christos if (wpas_drv_get_sta_mlo_info(wpa_s, &drv_mlo)) { 4090 1.10 christos wpa_dbg(wpa_s, MSG_INFO, "Failed to get MLO link info"); 4091 1.10 christos return -1; 4092 1.10 christos } 4093 1.10 christos 4094 1.10 christos os_memset(&wpa_mlo, 0, sizeof(wpa_mlo)); 4095 1.10 christos if (!drv_mlo.valid_links) 4096 1.10 christos goto out; 4097 1.10 christos 4098 1.10 christos os_memcpy(wpa_mlo.ap_mld_addr, drv_mlo.ap_mld_addr, ETH_ALEN); 4099 1.10 christos wpa_mlo.assoc_link_id = drv_mlo.assoc_link_id; 4100 1.10 christos wpa_mlo.valid_links = drv_mlo.valid_links; 4101 1.10 christos wpa_mlo.req_links = drv_mlo.req_links; 4102 1.10 christos 4103 1.10 christos for_each_link(drv_mlo.req_links, i) { 4104 1.10 christos struct wpa_bss *bss; 4105 1.10 christos 4106 1.10 christos bss = wpa_supplicant_get_new_bss(wpa_s, drv_mlo.links[i].bssid); 4107 1.10 christos if (!bss) { 4108 1.10 christos wpa_dbg(wpa_s, MSG_INFO, 4109 1.10 christos "Failed to get MLO link %d BSS", i); 4110 1.10 christos return -1; 4111 1.10 christos } 4112 1.10 christos 4113 1.10 christos bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN); 4114 1.10 christos bss_rsnx = wpa_bss_get_ie(bss, WLAN_EID_RSNX); 4115 1.6 christos 4116 1.10 christos wpa_mlo.links[i].ap_rsne = bss_rsn ? (u8 *) bss_rsn : NULL; 4117 1.10 christos wpa_mlo.links[i].ap_rsne_len = bss_rsn ? 2 + bss_rsn[1] : 0; 4118 1.10 christos wpa_mlo.links[i].ap_rsnxe = bss_rsnx ? (u8 *) bss_rsnx : NULL; 4119 1.10 christos wpa_mlo.links[i].ap_rsnxe_len = bss_rsnx ? 2 + bss_rsnx[1] : 0; 4120 1.10 christos 4121 1.10 christos os_memcpy(wpa_mlo.links[i].bssid, drv_mlo.links[i].bssid, 4122 1.10 christos ETH_ALEN); 4123 1.10 christos os_memcpy(wpa_mlo.links[i].addr, drv_mlo.links[i].addr, 4124 1.10 christos ETH_ALEN); 4125 1.10 christos } 4126 1.6 christos 4127 1.10 christos out: 4128 1.10 christos return wpa_sm_set_mlo_params(wpa_s->wpa, &wpa_mlo); 4129 1.6 christos } 4130 1.6 christos 4131 1.6 christos 4132 1.1 christos static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s, 4133 1.1 christos union wpa_event_data *data) 4134 1.1 christos { 4135 1.1 christos u8 bssid[ETH_ALEN]; 4136 1.6 christos int ft_completed, already_authorized; 4137 1.6 christos int new_bss = 0; 4138 1.10 christos #if defined(CONFIG_FILS) || defined(CONFIG_MBO) 4139 1.10 christos struct wpa_bss *bss; 4140 1.10 christos #endif /* CONFIG_FILS || CONFIG_MBO */ 4141 1.1 christos 4142 1.1 christos #ifdef CONFIG_AP 4143 1.1 christos if (wpa_s->ap_iface) { 4144 1.2 joerg if (!data) 4145 1.2 joerg return; 4146 1.1 christos hostapd_notif_assoc(wpa_s->ap_iface->bss[0], 4147 1.1 christos data->assoc_info.addr, 4148 1.1 christos data->assoc_info.req_ies, 4149 1.10 christos data->assoc_info.req_ies_len, NULL, 0, 4150 1.10 christos NULL, data->assoc_info.reassoc); 4151 1.1 christos return; 4152 1.1 christos } 4153 1.1 christos #endif /* CONFIG_AP */ 4154 1.1 christos 4155 1.6 christos eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL); 4156 1.10 christos wpa_s->own_reconnect_req = 0; 4157 1.6 christos 4158 1.1 christos ft_completed = wpa_ft_is_completed(wpa_s->wpa); 4159 1.10 christos 4160 1.10 christos if (wpa_drv_get_bssid(wpa_s, bssid) < 0) { 4161 1.10 christos wpa_dbg(wpa_s, MSG_ERROR, "Failed to get BSSID"); 4162 1.10 christos wpa_supplicant_deauthenticate( 4163 1.10 christos wpa_s, WLAN_REASON_DEAUTH_LEAVING); 4164 1.10 christos return; 4165 1.10 christos } 4166 1.10 christos 4167 1.10 christos if (wpa_drv_get_mlo_info(wpa_s) < 0) { 4168 1.10 christos wpa_dbg(wpa_s, MSG_ERROR, "Failed to get MLO connection info"); 4169 1.10 christos wpa_supplicant_deauthenticate(wpa_s, 4170 1.10 christos WLAN_REASON_DEAUTH_LEAVING); 4171 1.10 christos return; 4172 1.10 christos } 4173 1.10 christos 4174 1.10 christos if (ft_completed && 4175 1.10 christos (wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION)) { 4176 1.10 christos wpa_msg(wpa_s, MSG_INFO, "Attempt to roam to " MACSTR, 4177 1.10 christos MAC2STR(bssid)); 4178 1.10 christos if (!wpa_supplicant_update_current_bss(wpa_s, bssid)) { 4179 1.10 christos wpa_printf(MSG_ERROR, 4180 1.10 christos "Can't find target AP's information!"); 4181 1.10 christos return; 4182 1.10 christos } 4183 1.10 christos wpa_supplicant_assoc_update_ie(wpa_s); 4184 1.10 christos } 4185 1.10 christos 4186 1.1 christos if (data && wpa_supplicant_event_associnfo(wpa_s, data) < 0) 4187 1.1 christos return; 4188 1.7 christos /* 4189 1.7 christos * FILS authentication can share the same mechanism to mark the 4190 1.7 christos * connection fully authenticated, so set ft_completed also based on 4191 1.7 christos * FILS result. 4192 1.7 christos */ 4193 1.7 christos if (!ft_completed) 4194 1.7 christos ft_completed = wpa_fils_is_completed(wpa_s->wpa); 4195 1.1 christos 4196 1.1 christos wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED); 4197 1.10 christos if (!ether_addr_equal(bssid, wpa_s->bssid)) { 4198 1.9 christos if (os_reltime_initialized(&wpa_s->session_start)) { 4199 1.9 christos os_reltime_age(&wpa_s->session_start, 4200 1.9 christos &wpa_s->session_length); 4201 1.9 christos wpa_s->session_start.sec = 0; 4202 1.9 christos wpa_s->session_start.usec = 0; 4203 1.9 christos wpas_notify_session_length(wpa_s); 4204 1.9 christos } else { 4205 1.9 christos wpas_notify_auth_changed(wpa_s); 4206 1.9 christos os_get_reltime(&wpa_s->session_start); 4207 1.9 christos } 4208 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Associated to a new BSS: BSSID=" 4209 1.1 christos MACSTR, MAC2STR(bssid)); 4210 1.6 christos new_bss = 1; 4211 1.2 joerg random_add_randomness(bssid, ETH_ALEN); 4212 1.1 christos os_memcpy(wpa_s->bssid, bssid, ETH_ALEN); 4213 1.1 christos os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); 4214 1.2 joerg wpas_notify_bssid_changed(wpa_s); 4215 1.1 christos 4216 1.1 christos if (wpa_supplicant_dynamic_keys(wpa_s) && !ft_completed) { 4217 1.1 christos wpa_clear_keys(wpa_s, bssid); 4218 1.1 christos } 4219 1.10 christos if (wpa_supplicant_select_config(wpa_s, data) < 0) { 4220 1.2 joerg wpa_supplicant_deauthenticate( 4221 1.1 christos wpa_s, WLAN_REASON_DEAUTH_LEAVING); 4222 1.1 christos return; 4223 1.1 christos } 4224 1.6 christos } 4225 1.2 joerg 4226 1.10 christos if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) && 4227 1.10 christos data && wpa_supplicant_use_own_rsne_params(wpa_s, data) < 0) 4228 1.10 christos return; 4229 1.10 christos 4230 1.10 christos multi_ap_set_4addr_mode(wpa_s); 4231 1.10 christos 4232 1.6 christos if (wpa_s->conf->ap_scan == 1 && 4233 1.6 christos wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION) { 4234 1.6 christos if (wpa_supplicant_assoc_update_ie(wpa_s) < 0 && new_bss) 4235 1.6 christos wpa_msg(wpa_s, MSG_WARNING, 4236 1.6 christos "WPA/RSN IEs not updated"); 4237 1.1 christos } 4238 1.1 christos 4239 1.6 christos wpas_fst_update_mb_assoc(wpa_s, data); 4240 1.6 christos 4241 1.1 christos #ifdef CONFIG_SME 4242 1.10 christos /* 4243 1.10 christos * Cache the current AP's BSSID (for non-MLO connection) or MLD address 4244 1.10 christos * (for MLO connection) as the previous BSSID for subsequent 4245 1.10 christos * reassociation requests handled by SME-in-wpa_supplicant. 4246 1.10 christos */ 4247 1.10 christos os_memcpy(wpa_s->sme.prev_bssid, 4248 1.10 christos wpa_s->valid_links ? wpa_s->ap_mld_addr : bssid, ETH_ALEN); 4249 1.1 christos wpa_s->sme.prev_bssid_set = 1; 4250 1.2 joerg wpa_s->sme.last_unprot_disconnect.sec = 0; 4251 1.1 christos #endif /* CONFIG_SME */ 4252 1.1 christos 4253 1.1 christos wpa_msg(wpa_s, MSG_INFO, "Associated with " MACSTR, MAC2STR(bssid)); 4254 1.1 christos if (wpa_s->current_ssid) { 4255 1.1 christos /* When using scanning (ap_scan=1), SIM PC/SC interface can be 4256 1.1 christos * initialized before association, but for other modes, 4257 1.1 christos * initialize PC/SC here, if the current configuration needs 4258 1.1 christos * smartcard or SIM/USIM. */ 4259 1.1 christos wpa_supplicant_scard_init(wpa_s, wpa_s->current_ssid); 4260 1.1 christos } 4261 1.1 christos wpa_sm_notify_assoc(wpa_s->wpa, bssid); 4262 1.10 christos 4263 1.10 christos if (wpa_sm_set_ml_info(wpa_s)) { 4264 1.10 christos wpa_dbg(wpa_s, MSG_INFO, 4265 1.10 christos "Failed to set MLO connection info to wpa_sm"); 4266 1.10 christos wpa_supplicant_deauthenticate(wpa_s, 4267 1.10 christos WLAN_REASON_DEAUTH_LEAVING); 4268 1.10 christos return; 4269 1.10 christos } 4270 1.10 christos 4271 1.2 joerg if (wpa_s->l2) 4272 1.2 joerg l2_packet_notify_auth_start(wpa_s->l2); 4273 1.1 christos 4274 1.6 christos already_authorized = data && data->assoc_info.authorized; 4275 1.6 christos 4276 1.1 christos /* 4277 1.10 christos * Set portEnabled first to false in order to get EAP state machine out 4278 1.1 christos * of the SUCCESS state and eapSuccess cleared. Without this, EAPOL PAE 4279 1.1 christos * state machine may transit to AUTHENTICATING state based on obsolete 4280 1.1 christos * eapSuccess and then trigger BE_AUTH to SUCCESS and PAE to 4281 1.1 christos * AUTHENTICATED without ever giving chance to EAP state machine to 4282 1.1 christos * reset the state. 4283 1.1 christos */ 4284 1.6 christos if (!ft_completed && !already_authorized) { 4285 1.10 christos eapol_sm_notify_portEnabled(wpa_s->eapol, false); 4286 1.10 christos eapol_sm_notify_portValid(wpa_s->eapol, false); 4287 1.1 christos } 4288 1.7 christos if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || 4289 1.7 christos wpa_s->key_mgmt == WPA_KEY_MGMT_DPP || 4290 1.7 christos wpa_s->key_mgmt == WPA_KEY_MGMT_OWE || ft_completed || 4291 1.10 christos already_authorized || wpa_s->drv_authorized_port) 4292 1.10 christos eapol_sm_notify_eap_success(wpa_s->eapol, false); 4293 1.1 christos /* 802.1X::portControl = Auto */ 4294 1.10 christos eapol_sm_notify_portEnabled(wpa_s->eapol, true); 4295 1.1 christos wpa_s->eapol_received = 0; 4296 1.1 christos if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE || 4297 1.1 christos wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE || 4298 1.1 christos (wpa_s->current_ssid && 4299 1.9 christos wpa_s->current_ssid->mode == WPAS_MODE_IBSS)) { 4300 1.2 joerg if (wpa_s->current_ssid && 4301 1.2 joerg wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE && 4302 1.2 joerg (wpa_s->drv_flags & 4303 1.2 joerg WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE)) { 4304 1.2 joerg /* 4305 1.2 joerg * Set the key after having received joined-IBSS event 4306 1.2 joerg * from the driver. 4307 1.2 joerg */ 4308 1.2 joerg wpa_supplicant_set_wpa_none_key(wpa_s, 4309 1.2 joerg wpa_s->current_ssid); 4310 1.2 joerg } 4311 1.1 christos wpa_supplicant_cancel_auth_timeout(wpa_s); 4312 1.1 christos wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); 4313 1.1 christos } else if (!ft_completed) { 4314 1.1 christos /* Timeout for receiving the first EAPOL packet */ 4315 1.1 christos wpa_supplicant_req_auth_timeout(wpa_s, 10, 0); 4316 1.1 christos } 4317 1.1 christos wpa_supplicant_cancel_scan(wpa_s); 4318 1.1 christos 4319 1.9 christos if (ft_completed) { 4320 1.9 christos /* 4321 1.9 christos * FT protocol completed - make sure EAPOL state machine ends 4322 1.9 christos * up in authenticated. 4323 1.9 christos */ 4324 1.9 christos wpa_supplicant_cancel_auth_timeout(wpa_s); 4325 1.9 christos wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); 4326 1.10 christos eapol_sm_notify_portValid(wpa_s->eapol, true); 4327 1.10 christos eapol_sm_notify_eap_success(wpa_s->eapol, true); 4328 1.9 christos } else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) && 4329 1.9 christos wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) { 4330 1.10 christos if (already_authorized) { 4331 1.10 christos /* 4332 1.10 christos * We are done; the driver will take care of RSN 4-way 4333 1.10 christos * handshake. 4334 1.10 christos */ 4335 1.10 christos wpa_supplicant_cancel_auth_timeout(wpa_s); 4336 1.10 christos wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); 4337 1.10 christos eapol_sm_notify_portValid(wpa_s->eapol, true); 4338 1.10 christos eapol_sm_notify_eap_success(wpa_s->eapol, true); 4339 1.10 christos } else { 4340 1.10 christos /* Update port, WPA_COMPLETED state from the 4341 1.10 christos * EVENT_PORT_AUTHORIZED handler when the driver is done 4342 1.10 christos * with the 4-way handshake. 4343 1.10 christos */ 4344 1.10 christos wpa_msg(wpa_s, MSG_DEBUG, 4345 1.10 christos "ASSOC INFO: wait for driver port authorized indication"); 4346 1.10 christos } 4347 1.9 christos } else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_8021X) && 4348 1.2 joerg wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt)) { 4349 1.2 joerg /* 4350 1.2 joerg * The driver will take care of RSN 4-way handshake, so we need 4351 1.2 joerg * to allow EAPOL supplicant to complete its work without 4352 1.2 joerg * waiting for WPA supplicant. 4353 1.2 joerg */ 4354 1.10 christos eapol_sm_notify_portValid(wpa_s->eapol, true); 4355 1.1 christos } 4356 1.1 christos 4357 1.2 joerg wpa_s->last_eapol_matches_bssid = 0; 4358 1.2 joerg 4359 1.10 christos #ifdef CONFIG_TESTING_OPTIONS 4360 1.10 christos if (wpa_s->rsne_override_eapol) { 4361 1.10 christos wpa_printf(MSG_DEBUG, 4362 1.10 christos "TESTING: RSNE EAPOL-Key msg 2/4 override"); 4363 1.10 christos wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, 4364 1.10 christos wpabuf_head(wpa_s->rsne_override_eapol), 4365 1.10 christos wpabuf_len(wpa_s->rsne_override_eapol)); 4366 1.10 christos } 4367 1.10 christos if (wpa_s->rsnxe_override_eapol) { 4368 1.10 christos wpa_printf(MSG_DEBUG, 4369 1.10 christos "TESTING: RSNXE EAPOL-Key msg 2/4 override"); 4370 1.10 christos wpa_sm_set_assoc_rsnxe(wpa_s->wpa, 4371 1.10 christos wpabuf_head(wpa_s->rsnxe_override_eapol), 4372 1.10 christos wpabuf_len(wpa_s->rsnxe_override_eapol)); 4373 1.10 christos } 4374 1.10 christos #endif /* CONFIG_TESTING_OPTIONS */ 4375 1.10 christos 4376 1.1 christos if (wpa_s->pending_eapol_rx) { 4377 1.2 joerg struct os_reltime now, age; 4378 1.2 joerg os_get_reltime(&now); 4379 1.2 joerg os_reltime_sub(&now, &wpa_s->pending_eapol_rx_time, &age); 4380 1.7 christos if (age.sec == 0 && age.usec < 200000 && 4381 1.10 christos ether_addr_equal(wpa_s->pending_eapol_rx_src, 4382 1.10 christos wpa_s->valid_links ? wpa_s->ap_mld_addr : 4383 1.10 christos bssid)) { 4384 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Process pending EAPOL " 4385 1.2 joerg "frame that was received just before " 4386 1.2 joerg "association notification"); 4387 1.1 christos wpa_supplicant_rx_eapol( 4388 1.1 christos wpa_s, wpa_s->pending_eapol_rx_src, 4389 1.1 christos wpabuf_head(wpa_s->pending_eapol_rx), 4390 1.10 christos wpabuf_len(wpa_s->pending_eapol_rx), 4391 1.10 christos wpa_s->pending_eapol_encrypted); 4392 1.1 christos } 4393 1.1 christos wpabuf_free(wpa_s->pending_eapol_rx); 4394 1.1 christos wpa_s->pending_eapol_rx = NULL; 4395 1.1 christos } 4396 1.1 christos 4397 1.10 christos #ifdef CONFIG_WEP 4398 1.1 christos if ((wpa_s->key_mgmt == WPA_KEY_MGMT_NONE || 4399 1.1 christos wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) && 4400 1.2 joerg wpa_s->current_ssid && 4401 1.2 joerg (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE)) { 4402 1.1 christos /* Set static WEP keys again */ 4403 1.1 christos wpa_set_wep_keys(wpa_s, wpa_s->current_ssid); 4404 1.1 christos } 4405 1.10 christos #endif /* CONFIG_WEP */ 4406 1.2 joerg 4407 1.2 joerg #ifdef CONFIG_IBSS_RSN 4408 1.2 joerg if (wpa_s->current_ssid && 4409 1.2 joerg wpa_s->current_ssid->mode == WPAS_MODE_IBSS && 4410 1.2 joerg wpa_s->key_mgmt != WPA_KEY_MGMT_NONE && 4411 1.2 joerg wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE && 4412 1.2 joerg wpa_s->ibss_rsn == NULL) { 4413 1.6 christos wpa_s->ibss_rsn = ibss_rsn_init(wpa_s, wpa_s->current_ssid); 4414 1.2 joerg if (!wpa_s->ibss_rsn) { 4415 1.2 joerg wpa_msg(wpa_s, MSG_INFO, "Failed to init IBSS RSN"); 4416 1.2 joerg wpa_supplicant_deauthenticate( 4417 1.2 joerg wpa_s, WLAN_REASON_DEAUTH_LEAVING); 4418 1.2 joerg return; 4419 1.2 joerg } 4420 1.2 joerg 4421 1.2 joerg ibss_rsn_set_psk(wpa_s->ibss_rsn, wpa_s->current_ssid->psk); 4422 1.2 joerg } 4423 1.2 joerg #endif /* CONFIG_IBSS_RSN */ 4424 1.2 joerg 4425 1.2 joerg wpas_wps_notify_assoc(wpa_s, bssid); 4426 1.3 christos 4427 1.10 christos #ifndef CONFIG_NO_WMM_AC 4428 1.3 christos if (data) { 4429 1.3 christos wmm_ac_notify_assoc(wpa_s, data->assoc_info.resp_ies, 4430 1.3 christos data->assoc_info.resp_ies_len, 4431 1.3 christos &data->assoc_info.wmm_params); 4432 1.3 christos 4433 1.3 christos if (wpa_s->reassoc_same_bss) 4434 1.3 christos wmm_ac_restore_tspecs(wpa_s); 4435 1.3 christos } 4436 1.10 christos #endif /* CONFIG_NO_WMM_AC */ 4437 1.7 christos 4438 1.10 christos #if defined(CONFIG_FILS) || defined(CONFIG_MBO) 4439 1.10 christos bss = wpa_bss_get_bssid(wpa_s, bssid); 4440 1.10 christos #endif /* CONFIG_FILS || CONFIG_MBO */ 4441 1.7 christos #ifdef CONFIG_FILS 4442 1.7 christos if (wpa_key_mgmt_fils(wpa_s->key_mgmt)) { 4443 1.7 christos const u8 *fils_cache_id = wpa_bss_get_fils_cache_id(bss); 4444 1.7 christos 4445 1.7 christos if (fils_cache_id) 4446 1.7 christos wpa_sm_set_fils_cache_id(wpa_s->wpa, fils_cache_id); 4447 1.7 christos } 4448 1.7 christos #endif /* CONFIG_FILS */ 4449 1.10 christos 4450 1.10 christos #ifdef CONFIG_MBO 4451 1.10 christos wpas_mbo_check_pmf(wpa_s, bss, wpa_s->current_ssid); 4452 1.10 christos #endif /* CONFIG_MBO */ 4453 1.10 christos 4454 1.10 christos #ifdef CONFIG_DPP2 4455 1.10 christos wpa_s->dpp_pfs_fallback = 0; 4456 1.10 christos #endif /* CONFIG_DPP2 */ 4457 1.10 christos 4458 1.10 christos if (wpa_s->current_ssid && wpa_s->current_ssid->enable_4addr_mode) 4459 1.10 christos wpa_supplicant_set_4addr_mode(wpa_s); 4460 1.2 joerg } 4461 1.2 joerg 4462 1.2 joerg 4463 1.2 joerg static int disconnect_reason_recoverable(u16 reason_code) 4464 1.2 joerg { 4465 1.2 joerg return reason_code == WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY || 4466 1.2 joerg reason_code == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA || 4467 1.2 joerg reason_code == WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA; 4468 1.1 christos } 4469 1.1 christos 4470 1.1 christos 4471 1.1 christos static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s, 4472 1.2 joerg u16 reason_code, 4473 1.2 joerg int locally_generated) 4474 1.1 christos { 4475 1.1 christos const u8 *bssid; 4476 1.1 christos 4477 1.1 christos if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { 4478 1.1 christos /* 4479 1.1 christos * At least Host AP driver and a Prism3 card seemed to be 4480 1.1 christos * generating streams of disconnected events when configuring 4481 1.1 christos * IBSS for WPA-None. Ignore them for now. 4482 1.1 christos */ 4483 1.1 christos return; 4484 1.1 christos } 4485 1.1 christos 4486 1.2 joerg bssid = wpa_s->bssid; 4487 1.2 joerg if (is_zero_ether_addr(bssid)) 4488 1.2 joerg bssid = wpa_s->pending_bssid; 4489 1.2 joerg 4490 1.2 joerg if (!is_zero_ether_addr(bssid) || 4491 1.2 joerg wpa_s->wpa_state >= WPA_AUTHENTICATING) { 4492 1.2 joerg wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR 4493 1.2 joerg " reason=%d%s", 4494 1.2 joerg MAC2STR(bssid), reason_code, 4495 1.2 joerg locally_generated ? " locally_generated=1" : ""); 4496 1.2 joerg } 4497 1.2 joerg } 4498 1.2 joerg 4499 1.2 joerg 4500 1.2 joerg static int could_be_psk_mismatch(struct wpa_supplicant *wpa_s, u16 reason_code, 4501 1.2 joerg int locally_generated) 4502 1.2 joerg { 4503 1.2 joerg if (wpa_s->wpa_state != WPA_4WAY_HANDSHAKE || 4504 1.10 christos !wpa_s->new_connection || 4505 1.10 christos !wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || 4506 1.10 christos wpa_key_mgmt_sae(wpa_s->key_mgmt)) 4507 1.10 christos return 0; /* Not in initial 4-way handshake with PSK */ 4508 1.2 joerg 4509 1.2 joerg /* 4510 1.2 joerg * It looks like connection was lost while trying to go through PSK 4511 1.2 joerg * 4-way handshake. Filter out known disconnection cases that are caused 4512 1.2 joerg * by something else than PSK mismatch to avoid confusing reports. 4513 1.2 joerg */ 4514 1.2 joerg 4515 1.2 joerg if (locally_generated) { 4516 1.2 joerg if (reason_code == WLAN_REASON_IE_IN_4WAY_DIFFERS) 4517 1.2 joerg return 0; 4518 1.2 joerg } 4519 1.2 joerg 4520 1.2 joerg return 1; 4521 1.2 joerg } 4522 1.2 joerg 4523 1.2 joerg 4524 1.2 joerg static void wpa_supplicant_event_disassoc_finish(struct wpa_supplicant *wpa_s, 4525 1.2 joerg u16 reason_code, 4526 1.2 joerg int locally_generated) 4527 1.2 joerg { 4528 1.2 joerg const u8 *bssid; 4529 1.2 joerg struct wpa_bss *fast_reconnect = NULL; 4530 1.2 joerg struct wpa_ssid *fast_reconnect_ssid = NULL; 4531 1.6 christos struct wpa_bss *curr = NULL; 4532 1.2 joerg 4533 1.2 joerg if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { 4534 1.2 joerg /* 4535 1.2 joerg * At least Host AP driver and a Prism3 card seemed to be 4536 1.2 joerg * generating streams of disconnected events when configuring 4537 1.2 joerg * IBSS for WPA-None. Ignore them for now. 4538 1.2 joerg */ 4539 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Disconnect event - ignore in " 4540 1.2 joerg "IBSS/WPA-None mode"); 4541 1.2 joerg return; 4542 1.2 joerg } 4543 1.2 joerg 4544 1.6 christos if (!wpa_s->disconnected && wpa_s->wpa_state >= WPA_AUTHENTICATING && 4545 1.6 christos reason_code == WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY && 4546 1.6 christos locally_generated) 4547 1.6 christos /* 4548 1.6 christos * Remove the inactive AP (which is probably out of range) from 4549 1.6 christos * the BSS list after marking disassociation. In particular 4550 1.6 christos * mac80211-based drivers use the 4551 1.6 christos * WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY reason code in 4552 1.6 christos * locally generated disconnection events for cases where the 4553 1.6 christos * AP does not reply anymore. 4554 1.6 christos */ 4555 1.6 christos curr = wpa_s->current_bss; 4556 1.6 christos 4557 1.2 joerg if (could_be_psk_mismatch(wpa_s, reason_code, locally_generated)) { 4558 1.1 christos wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - " 4559 1.1 christos "pre-shared key may be incorrect"); 4560 1.2 joerg if (wpas_p2p_4way_hs_failed(wpa_s) > 0) 4561 1.2 joerg return; /* P2P group removed */ 4562 1.10 christos wpas_auth_failed(wpa_s, "WRONG_KEY", wpa_s->pending_bssid); 4563 1.10 christos wpas_notify_psk_mismatch(wpa_s); 4564 1.10 christos #ifdef CONFIG_DPP2 4565 1.10 christos wpas_dpp_send_conn_status_result(wpa_s, 4566 1.10 christos DPP_STATUS_AUTH_FAILURE); 4567 1.10 christos #endif /* CONFIG_DPP2 */ 4568 1.2 joerg } 4569 1.2 joerg if (!wpa_s->disconnected && 4570 1.2 joerg (!wpa_s->auto_reconnect_disabled || 4571 1.2 joerg wpa_s->key_mgmt == WPA_KEY_MGMT_WPS || 4572 1.6 christos wpas_wps_searching(wpa_s) || 4573 1.6 christos wpas_wps_reenable_networks_pending(wpa_s))) { 4574 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Auto connect enabled: try to " 4575 1.2 joerg "reconnect (wps=%d/%d wpa_state=%d)", 4576 1.2 joerg wpa_s->key_mgmt == WPA_KEY_MGMT_WPS, 4577 1.2 joerg wpas_wps_searching(wpa_s), 4578 1.2 joerg wpa_s->wpa_state); 4579 1.2 joerg if (wpa_s->wpa_state == WPA_COMPLETED && 4580 1.2 joerg wpa_s->current_ssid && 4581 1.2 joerg wpa_s->current_ssid->mode == WPAS_MODE_INFRA && 4582 1.10 christos (wpa_s->own_reconnect_req || 4583 1.10 christos (!locally_generated && 4584 1.10 christos disconnect_reason_recoverable(reason_code)))) { 4585 1.2 joerg /* 4586 1.2 joerg * It looks like the AP has dropped association with 4587 1.10 christos * us, but could allow us to get back in. This is also 4588 1.10 christos * triggered for cases where local reconnection request 4589 1.10 christos * is used to force reassociation with the same BSS. 4590 1.10 christos * Try to reconnect to the same BSS without a full scan 4591 1.10 christos * to save time for some common cases. 4592 1.2 joerg */ 4593 1.2 joerg fast_reconnect = wpa_s->current_bss; 4594 1.2 joerg fast_reconnect_ssid = wpa_s->current_ssid; 4595 1.10 christos } else if (wpa_s->wpa_state >= WPA_ASSOCIATING) { 4596 1.2 joerg wpa_supplicant_req_scan(wpa_s, 0, 100000); 4597 1.10 christos } else { 4598 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Do not request new " 4599 1.2 joerg "immediate scan"); 4600 1.10 christos } 4601 1.2 joerg } else { 4602 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Auto connect disabled: do not " 4603 1.2 joerg "try to re-connect"); 4604 1.2 joerg wpa_s->reassociate = 0; 4605 1.2 joerg wpa_s->disconnected = 1; 4606 1.6 christos if (!wpa_s->pno) 4607 1.6 christos wpa_supplicant_cancel_sched_scan(wpa_s); 4608 1.1 christos } 4609 1.1 christos bssid = wpa_s->bssid; 4610 1.1 christos if (is_zero_ether_addr(bssid)) 4611 1.1 christos bssid = wpa_s->pending_bssid; 4612 1.2 joerg if (wpa_s->wpa_state >= WPA_AUTHENTICATING) 4613 1.10 christos wpas_connection_failed(wpa_s, bssid, NULL); 4614 1.1 christos wpa_sm_notify_disassoc(wpa_s->wpa); 4615 1.10 christos ptksa_cache_flush(wpa_s->ptksa, wpa_s->bssid, WPA_CIPHER_NONE); 4616 1.10 christos 4617 1.2 joerg if (locally_generated) 4618 1.2 joerg wpa_s->disconnect_reason = -reason_code; 4619 1.2 joerg else 4620 1.2 joerg wpa_s->disconnect_reason = reason_code; 4621 1.2 joerg wpas_notify_disconnect_reason(wpa_s); 4622 1.1 christos if (wpa_supplicant_dynamic_keys(wpa_s)) { 4623 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Disconnect event - remove keys"); 4624 1.1 christos wpa_clear_keys(wpa_s, wpa_s->bssid); 4625 1.1 christos } 4626 1.1 christos wpa_supplicant_mark_disassoc(wpa_s); 4627 1.2 joerg 4628 1.6 christos if (curr) 4629 1.6 christos wpa_bss_remove(wpa_s, curr, "Connection to AP lost"); 4630 1.6 christos 4631 1.2 joerg if (fast_reconnect && 4632 1.2 joerg !wpas_network_disabled(wpa_s, fast_reconnect_ssid) && 4633 1.2 joerg !disallowed_bssid(wpa_s, fast_reconnect->bssid) && 4634 1.2 joerg !disallowed_ssid(wpa_s, fast_reconnect->ssid, 4635 1.2 joerg fast_reconnect->ssid_len) && 4636 1.6 christos !wpas_temp_disabled(wpa_s, fast_reconnect_ssid) && 4637 1.9 christos !wpa_is_bss_tmp_disallowed(wpa_s, fast_reconnect)) { 4638 1.2 joerg #ifndef CONFIG_NO_SCAN_PROCESSING 4639 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Try to reconnect to the same BSS"); 4640 1.2 joerg if (wpa_supplicant_connect(wpa_s, fast_reconnect, 4641 1.2 joerg fast_reconnect_ssid) < 0) { 4642 1.2 joerg /* Recover through full scan */ 4643 1.2 joerg wpa_supplicant_req_scan(wpa_s, 0, 100000); 4644 1.2 joerg } 4645 1.2 joerg #endif /* CONFIG_NO_SCAN_PROCESSING */ 4646 1.2 joerg } else if (fast_reconnect) { 4647 1.1 christos /* 4648 1.2 joerg * Could not reconnect to the same BSS due to network being 4649 1.2 joerg * disabled. Use a new scan to match the alternative behavior 4650 1.2 joerg * above, i.e., to continue automatic reconnection attempt in a 4651 1.2 joerg * way that enforces disabled network rules. 4652 1.1 christos */ 4653 1.2 joerg wpa_supplicant_req_scan(wpa_s, 0, 100000); 4654 1.1 christos } 4655 1.1 christos } 4656 1.1 christos 4657 1.1 christos 4658 1.1 christos #ifdef CONFIG_DELAYED_MIC_ERROR_REPORT 4659 1.2 joerg void wpa_supplicant_delayed_mic_error_report(void *eloop_ctx, void *sock_ctx) 4660 1.1 christos { 4661 1.1 christos struct wpa_supplicant *wpa_s = eloop_ctx; 4662 1.1 christos 4663 1.1 christos if (!wpa_s->pending_mic_error_report) 4664 1.1 christos return; 4665 1.1 christos 4666 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Sending pending MIC error report"); 4667 1.1 christos wpa_sm_key_request(wpa_s->wpa, 1, wpa_s->pending_mic_error_pairwise); 4668 1.1 christos wpa_s->pending_mic_error_report = 0; 4669 1.1 christos } 4670 1.1 christos #endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */ 4671 1.1 christos 4672 1.1 christos 4673 1.1 christos static void 4674 1.1 christos wpa_supplicant_event_michael_mic_failure(struct wpa_supplicant *wpa_s, 4675 1.1 christos union wpa_event_data *data) 4676 1.1 christos { 4677 1.1 christos int pairwise; 4678 1.2 joerg struct os_reltime t; 4679 1.1 christos 4680 1.1 christos wpa_msg(wpa_s, MSG_WARNING, "Michael MIC failure detected"); 4681 1.1 christos pairwise = (data && data->michael_mic_failure.unicast); 4682 1.2 joerg os_get_reltime(&t); 4683 1.10 christos if ((os_reltime_initialized(&wpa_s->last_michael_mic_error) && 4684 1.2 joerg !os_reltime_expired(&t, &wpa_s->last_michael_mic_error, 60)) || 4685 1.1 christos wpa_s->pending_mic_error_report) { 4686 1.1 christos if (wpa_s->pending_mic_error_report) { 4687 1.1 christos /* 4688 1.1 christos * Send the pending MIC error report immediately since 4689 1.1 christos * we are going to start countermeasures and AP better 4690 1.1 christos * do the same. 4691 1.1 christos */ 4692 1.1 christos wpa_sm_key_request(wpa_s->wpa, 1, 4693 1.1 christos wpa_s->pending_mic_error_pairwise); 4694 1.1 christos } 4695 1.1 christos 4696 1.1 christos /* Send the new MIC error report immediately since we are going 4697 1.1 christos * to start countermeasures and AP better do the same. 4698 1.1 christos */ 4699 1.1 christos wpa_sm_key_request(wpa_s->wpa, 1, pairwise); 4700 1.1 christos 4701 1.1 christos /* initialize countermeasures */ 4702 1.1 christos wpa_s->countermeasures = 1; 4703 1.2 joerg 4704 1.10 christos wpa_bssid_ignore_add(wpa_s, wpa_s->bssid); 4705 1.2 joerg 4706 1.1 christos wpa_msg(wpa_s, MSG_WARNING, "TKIP countermeasures started"); 4707 1.1 christos 4708 1.1 christos /* 4709 1.1 christos * Need to wait for completion of request frame. We do not get 4710 1.1 christos * any callback for the message completion, so just wait a 4711 1.1 christos * short while and hope for the best. */ 4712 1.1 christos os_sleep(0, 10000); 4713 1.1 christos 4714 1.1 christos wpa_drv_set_countermeasures(wpa_s, 1); 4715 1.1 christos wpa_supplicant_deauthenticate(wpa_s, 4716 1.1 christos WLAN_REASON_MICHAEL_MIC_FAILURE); 4717 1.1 christos eloop_cancel_timeout(wpa_supplicant_stop_countermeasures, 4718 1.1 christos wpa_s, NULL); 4719 1.1 christos eloop_register_timeout(60, 0, 4720 1.1 christos wpa_supplicant_stop_countermeasures, 4721 1.1 christos wpa_s, NULL); 4722 1.1 christos /* TODO: mark the AP rejected for 60 second. STA is 4723 1.1 christos * allowed to associate with another AP.. */ 4724 1.1 christos } else { 4725 1.1 christos #ifdef CONFIG_DELAYED_MIC_ERROR_REPORT 4726 1.1 christos if (wpa_s->mic_errors_seen) { 4727 1.1 christos /* 4728 1.1 christos * Reduce the effectiveness of Michael MIC error 4729 1.1 christos * reports as a means for attacking against TKIP if 4730 1.1 christos * more than one MIC failure is noticed with the same 4731 1.1 christos * PTK. We delay the transmission of the reports by a 4732 1.1 christos * random time between 0 and 60 seconds in order to 4733 1.1 christos * force the attacker wait 60 seconds before getting 4734 1.1 christos * the information on whether a frame resulted in a MIC 4735 1.1 christos * failure. 4736 1.1 christos */ 4737 1.1 christos u8 rval[4]; 4738 1.1 christos int sec; 4739 1.1 christos 4740 1.1 christos if (os_get_random(rval, sizeof(rval)) < 0) 4741 1.1 christos sec = os_random() % 60; 4742 1.1 christos else 4743 1.1 christos sec = WPA_GET_BE32(rval) % 60; 4744 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Delay MIC error " 4745 1.2 joerg "report %d seconds", sec); 4746 1.1 christos wpa_s->pending_mic_error_report = 1; 4747 1.1 christos wpa_s->pending_mic_error_pairwise = pairwise; 4748 1.1 christos eloop_cancel_timeout( 4749 1.1 christos wpa_supplicant_delayed_mic_error_report, 4750 1.1 christos wpa_s, NULL); 4751 1.1 christos eloop_register_timeout( 4752 1.1 christos sec, os_random() % 1000000, 4753 1.1 christos wpa_supplicant_delayed_mic_error_report, 4754 1.1 christos wpa_s, NULL); 4755 1.1 christos } else { 4756 1.1 christos wpa_sm_key_request(wpa_s->wpa, 1, pairwise); 4757 1.1 christos } 4758 1.1 christos #else /* CONFIG_DELAYED_MIC_ERROR_REPORT */ 4759 1.1 christos wpa_sm_key_request(wpa_s->wpa, 1, pairwise); 4760 1.1 christos #endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */ 4761 1.1 christos } 4762 1.2 joerg wpa_s->last_michael_mic_error = t; 4763 1.1 christos wpa_s->mic_errors_seen++; 4764 1.1 christos } 4765 1.1 christos 4766 1.1 christos 4767 1.1 christos #ifdef CONFIG_TERMINATE_ONLASTIF 4768 1.1 christos static int any_interfaces(struct wpa_supplicant *head) 4769 1.1 christos { 4770 1.1 christos struct wpa_supplicant *wpa_s; 4771 1.1 christos 4772 1.1 christos for (wpa_s = head; wpa_s != NULL; wpa_s = wpa_s->next) 4773 1.1 christos if (!wpa_s->interface_removed) 4774 1.1 christos return 1; 4775 1.1 christos return 0; 4776 1.1 christos } 4777 1.1 christos #endif /* CONFIG_TERMINATE_ONLASTIF */ 4778 1.1 christos 4779 1.1 christos 4780 1.1 christos static void 4781 1.1 christos wpa_supplicant_event_interface_status(struct wpa_supplicant *wpa_s, 4782 1.1 christos union wpa_event_data *data) 4783 1.1 christos { 4784 1.1 christos if (os_strcmp(wpa_s->ifname, data->interface_status.ifname) != 0) 4785 1.1 christos return; 4786 1.1 christos 4787 1.1 christos switch (data->interface_status.ievent) { 4788 1.1 christos case EVENT_INTERFACE_ADDED: 4789 1.1 christos if (!wpa_s->interface_removed) 4790 1.1 christos break; 4791 1.1 christos wpa_s->interface_removed = 0; 4792 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Configured interface was added"); 4793 1.1 christos if (wpa_supplicant_driver_init(wpa_s) < 0) { 4794 1.2 joerg wpa_msg(wpa_s, MSG_INFO, "Failed to initialize the " 4795 1.2 joerg "driver after interface was added"); 4796 1.1 christos } 4797 1.6 christos 4798 1.6 christos #ifdef CONFIG_P2P 4799 1.6 christos if (!wpa_s->global->p2p && 4800 1.6 christos !wpa_s->global->p2p_disabled && 4801 1.6 christos !wpa_s->conf->p2p_disabled && 4802 1.6 christos (wpa_s->drv_flags & 4803 1.6 christos WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) && 4804 1.6 christos wpas_p2p_add_p2pdev_interface( 4805 1.6 christos wpa_s, wpa_s->global->params.conf_p2p_dev) < 0) { 4806 1.6 christos wpa_printf(MSG_INFO, 4807 1.6 christos "P2P: Failed to enable P2P Device interface"); 4808 1.6 christos /* Try to continue without. P2P will be disabled. */ 4809 1.6 christos } 4810 1.6 christos #endif /* CONFIG_P2P */ 4811 1.6 christos 4812 1.1 christos break; 4813 1.1 christos case EVENT_INTERFACE_REMOVED: 4814 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Configured interface was removed"); 4815 1.1 christos wpa_s->interface_removed = 1; 4816 1.1 christos wpa_supplicant_mark_disassoc(wpa_s); 4817 1.2 joerg wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED); 4818 1.1 christos l2_packet_deinit(wpa_s->l2); 4819 1.1 christos wpa_s->l2 = NULL; 4820 1.5 roy 4821 1.6 christos #ifdef CONFIG_P2P 4822 1.6 christos if (wpa_s->global->p2p && 4823 1.6 christos wpa_s->global->p2p_init_wpa_s->parent == wpa_s && 4824 1.6 christos (wpa_s->drv_flags & 4825 1.6 christos WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) { 4826 1.6 christos wpa_dbg(wpa_s, MSG_DEBUG, 4827 1.6 christos "Removing P2P Device interface"); 4828 1.6 christos wpa_supplicant_remove_iface( 4829 1.6 christos wpa_s->global, wpa_s->global->p2p_init_wpa_s, 4830 1.6 christos 0); 4831 1.6 christos wpa_s->global->p2p_init_wpa_s = NULL; 4832 1.6 christos } 4833 1.6 christos #endif /* CONFIG_P2P */ 4834 1.6 christos 4835 1.5 roy #ifdef CONFIG_MATCH_IFACE 4836 1.5 roy if (wpa_s->matched) { 4837 1.5 roy wpa_supplicant_remove_iface(wpa_s->global, wpa_s, 0); 4838 1.5 roy break; 4839 1.5 roy } 4840 1.5 roy #endif /* CONFIG_MATCH_IFACE */ 4841 1.5 roy 4842 1.1 christos #ifdef CONFIG_TERMINATE_ONLASTIF 4843 1.1 christos /* check if last interface */ 4844 1.1 christos if (!any_interfaces(wpa_s->global->ifaces)) 4845 1.1 christos eloop_terminate(); 4846 1.1 christos #endif /* CONFIG_TERMINATE_ONLASTIF */ 4847 1.1 christos break; 4848 1.1 christos } 4849 1.1 christos } 4850 1.1 christos 4851 1.1 christos 4852 1.2 joerg #ifdef CONFIG_TDLS 4853 1.2 joerg static void wpa_supplicant_event_tdls(struct wpa_supplicant *wpa_s, 4854 1.2 joerg union wpa_event_data *data) 4855 1.2 joerg { 4856 1.2 joerg if (data == NULL) 4857 1.2 joerg return; 4858 1.2 joerg switch (data->tdls.oper) { 4859 1.2 joerg case TDLS_REQUEST_SETUP: 4860 1.2 joerg wpa_tdls_remove(wpa_s->wpa, data->tdls.peer); 4861 1.2 joerg if (wpa_tdls_is_external_setup(wpa_s->wpa)) 4862 1.2 joerg wpa_tdls_start(wpa_s->wpa, data->tdls.peer); 4863 1.2 joerg else 4864 1.2 joerg wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, data->tdls.peer); 4865 1.2 joerg break; 4866 1.2 joerg case TDLS_REQUEST_TEARDOWN: 4867 1.2 joerg if (wpa_tdls_is_external_setup(wpa_s->wpa)) 4868 1.2 joerg wpa_tdls_teardown_link(wpa_s->wpa, data->tdls.peer, 4869 1.2 joerg data->tdls.reason_code); 4870 1.2 joerg else 4871 1.2 joerg wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, 4872 1.2 joerg data->tdls.peer); 4873 1.2 joerg break; 4874 1.3 christos case TDLS_REQUEST_DISCOVER: 4875 1.3 christos wpa_tdls_send_discovery_request(wpa_s->wpa, 4876 1.3 christos data->tdls.peer); 4877 1.3 christos break; 4878 1.2 joerg } 4879 1.2 joerg } 4880 1.2 joerg #endif /* CONFIG_TDLS */ 4881 1.2 joerg 4882 1.2 joerg 4883 1.2 joerg #ifdef CONFIG_WNM 4884 1.2 joerg static void wpa_supplicant_event_wnm(struct wpa_supplicant *wpa_s, 4885 1.2 joerg union wpa_event_data *data) 4886 1.2 joerg { 4887 1.2 joerg if (data == NULL) 4888 1.2 joerg return; 4889 1.2 joerg switch (data->wnm.oper) { 4890 1.2 joerg case WNM_OPER_SLEEP: 4891 1.2 joerg wpa_printf(MSG_DEBUG, "Start sending WNM-Sleep Request " 4892 1.2 joerg "(action=%d, intval=%d)", 4893 1.2 joerg data->wnm.sleep_action, data->wnm.sleep_intval); 4894 1.2 joerg ieee802_11_send_wnmsleep_req(wpa_s, data->wnm.sleep_action, 4895 1.2 joerg data->wnm.sleep_intval, NULL); 4896 1.2 joerg break; 4897 1.2 joerg } 4898 1.2 joerg } 4899 1.2 joerg #endif /* CONFIG_WNM */ 4900 1.2 joerg 4901 1.2 joerg 4902 1.1 christos #ifdef CONFIG_IEEE80211R 4903 1.1 christos static void 4904 1.1 christos wpa_supplicant_event_ft_response(struct wpa_supplicant *wpa_s, 4905 1.1 christos union wpa_event_data *data) 4906 1.1 christos { 4907 1.1 christos if (data == NULL) 4908 1.1 christos return; 4909 1.1 christos 4910 1.1 christos if (wpa_ft_process_response(wpa_s->wpa, data->ft_ies.ies, 4911 1.1 christos data->ft_ies.ies_len, 4912 1.1 christos data->ft_ies.ft_action, 4913 1.1 christos data->ft_ies.target_ap, 4914 1.1 christos data->ft_ies.ric_ies, 4915 1.1 christos data->ft_ies.ric_ies_len) < 0) { 4916 1.1 christos /* TODO: prevent MLME/driver from trying to associate? */ 4917 1.1 christos } 4918 1.1 christos } 4919 1.1 christos #endif /* CONFIG_IEEE80211R */ 4920 1.1 christos 4921 1.1 christos 4922 1.1 christos #ifdef CONFIG_IBSS_RSN 4923 1.1 christos static void wpa_supplicant_event_ibss_rsn_start(struct wpa_supplicant *wpa_s, 4924 1.1 christos union wpa_event_data *data) 4925 1.1 christos { 4926 1.2 joerg struct wpa_ssid *ssid; 4927 1.2 joerg if (wpa_s->wpa_state < WPA_ASSOCIATED) 4928 1.2 joerg return; 4929 1.1 christos if (data == NULL) 4930 1.1 christos return; 4931 1.2 joerg ssid = wpa_s->current_ssid; 4932 1.2 joerg if (ssid == NULL) 4933 1.2 joerg return; 4934 1.2 joerg if (ssid->mode != WPAS_MODE_IBSS || !wpa_key_mgmt_wpa(ssid->key_mgmt)) 4935 1.2 joerg return; 4936 1.2 joerg 4937 1.1 christos ibss_rsn_start(wpa_s->ibss_rsn, data->ibss_rsn_start.peer); 4938 1.1 christos } 4939 1.2 joerg 4940 1.2 joerg 4941 1.2 joerg static void wpa_supplicant_event_ibss_auth(struct wpa_supplicant *wpa_s, 4942 1.2 joerg union wpa_event_data *data) 4943 1.2 joerg { 4944 1.2 joerg struct wpa_ssid *ssid = wpa_s->current_ssid; 4945 1.2 joerg 4946 1.2 joerg if (ssid == NULL) 4947 1.2 joerg return; 4948 1.2 joerg 4949 1.2 joerg /* check if the ssid is correctly configured as IBSS/RSN */ 4950 1.2 joerg if (ssid->mode != WPAS_MODE_IBSS || !wpa_key_mgmt_wpa(ssid->key_mgmt)) 4951 1.2 joerg return; 4952 1.2 joerg 4953 1.2 joerg ibss_rsn_handle_auth(wpa_s->ibss_rsn, data->rx_mgmt.frame, 4954 1.2 joerg data->rx_mgmt.frame_len); 4955 1.2 joerg } 4956 1.1 christos #endif /* CONFIG_IBSS_RSN */ 4957 1.1 christos 4958 1.1 christos 4959 1.1 christos #ifdef CONFIG_IEEE80211R 4960 1.1 christos static void ft_rx_action(struct wpa_supplicant *wpa_s, const u8 *data, 4961 1.1 christos size_t len) 4962 1.1 christos { 4963 1.1 christos const u8 *sta_addr, *target_ap_addr; 4964 1.1 christos u16 status; 4965 1.1 christos 4966 1.1 christos wpa_hexdump(MSG_MSGDUMP, "FT: RX Action", data, len); 4967 1.1 christos if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) 4968 1.1 christos return; /* only SME case supported for now */ 4969 1.1 christos if (len < 1 + 2 * ETH_ALEN + 2) 4970 1.1 christos return; 4971 1.1 christos if (data[0] != 2) 4972 1.1 christos return; /* Only FT Action Response is supported for now */ 4973 1.1 christos sta_addr = data + 1; 4974 1.1 christos target_ap_addr = data + 1 + ETH_ALEN; 4975 1.1 christos status = WPA_GET_LE16(data + 1 + 2 * ETH_ALEN); 4976 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "FT: Received FT Action Response: STA " 4977 1.2 joerg MACSTR " TargetAP " MACSTR " status %u", 4978 1.2 joerg MAC2STR(sta_addr), MAC2STR(target_ap_addr), status); 4979 1.1 christos 4980 1.10 christos if (!ether_addr_equal(sta_addr, wpa_s->own_addr)) { 4981 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "FT: Foreign STA Address " MACSTR 4982 1.2 joerg " in FT Action Response", MAC2STR(sta_addr)); 4983 1.1 christos return; 4984 1.1 christos } 4985 1.1 christos 4986 1.1 christos if (status) { 4987 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "FT: FT Action Response indicates " 4988 1.2 joerg "failure (status code %d)", status); 4989 1.1 christos /* TODO: report error to FT code(?) */ 4990 1.1 christos return; 4991 1.1 christos } 4992 1.1 christos 4993 1.1 christos if (wpa_ft_process_response(wpa_s->wpa, data + 1 + 2 * ETH_ALEN + 2, 4994 1.1 christos len - (1 + 2 * ETH_ALEN + 2), 1, 4995 1.1 christos target_ap_addr, NULL, 0) < 0) 4996 1.1 christos return; 4997 1.1 christos 4998 1.1 christos #ifdef CONFIG_SME 4999 1.1 christos { 5000 1.1 christos struct wpa_bss *bss; 5001 1.1 christos bss = wpa_bss_get_bssid(wpa_s, target_ap_addr); 5002 1.1 christos if (bss) 5003 1.1 christos wpa_s->sme.freq = bss->freq; 5004 1.1 christos wpa_s->sme.auth_alg = WPA_AUTH_ALG_FT; 5005 1.1 christos sme_associate(wpa_s, WPAS_MODE_INFRA, target_ap_addr, 5006 1.1 christos WLAN_AUTH_FT); 5007 1.1 christos } 5008 1.1 christos #endif /* CONFIG_SME */ 5009 1.1 christos } 5010 1.1 christos #endif /* CONFIG_IEEE80211R */ 5011 1.1 christos 5012 1.1 christos 5013 1.2 joerg static void wpa_supplicant_event_unprot_deauth(struct wpa_supplicant *wpa_s, 5014 1.2 joerg struct unprot_deauth *e) 5015 1.2 joerg { 5016 1.2 joerg wpa_printf(MSG_DEBUG, "Unprotected Deauthentication frame " 5017 1.2 joerg "dropped: " MACSTR " -> " MACSTR 5018 1.2 joerg " (reason code %u)", 5019 1.2 joerg MAC2STR(e->sa), MAC2STR(e->da), e->reason_code); 5020 1.2 joerg sme_event_unprot_disconnect(wpa_s, e->sa, e->da, e->reason_code); 5021 1.2 joerg } 5022 1.2 joerg 5023 1.2 joerg 5024 1.2 joerg static void wpa_supplicant_event_unprot_disassoc(struct wpa_supplicant *wpa_s, 5025 1.2 joerg struct unprot_disassoc *e) 5026 1.2 joerg { 5027 1.2 joerg wpa_printf(MSG_DEBUG, "Unprotected Disassociation frame " 5028 1.2 joerg "dropped: " MACSTR " -> " MACSTR 5029 1.2 joerg " (reason code %u)", 5030 1.2 joerg MAC2STR(e->sa), MAC2STR(e->da), e->reason_code); 5031 1.2 joerg sme_event_unprot_disconnect(wpa_s, e->sa, e->da, e->reason_code); 5032 1.2 joerg } 5033 1.2 joerg 5034 1.2 joerg 5035 1.2 joerg static void wpas_event_disconnect(struct wpa_supplicant *wpa_s, const u8 *addr, 5036 1.2 joerg u16 reason_code, int locally_generated, 5037 1.2 joerg const u8 *ie, size_t ie_len, int deauth) 5038 1.2 joerg { 5039 1.2 joerg #ifdef CONFIG_AP 5040 1.2 joerg if (wpa_s->ap_iface && addr) { 5041 1.2 joerg hostapd_notif_disassoc(wpa_s->ap_iface->bss[0], addr); 5042 1.2 joerg return; 5043 1.2 joerg } 5044 1.2 joerg 5045 1.2 joerg if (wpa_s->ap_iface) { 5046 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Ignore deauth event in AP mode"); 5047 1.2 joerg return; 5048 1.2 joerg } 5049 1.2 joerg #endif /* CONFIG_AP */ 5050 1.2 joerg 5051 1.3 christos if (!locally_generated) 5052 1.3 christos wpa_s->own_disconnect_req = 0; 5053 1.3 christos 5054 1.2 joerg wpa_supplicant_event_disassoc(wpa_s, reason_code, locally_generated); 5055 1.2 joerg 5056 1.2 joerg if (((reason_code == WLAN_REASON_IEEE_802_1X_AUTH_FAILED || 5057 1.2 joerg ((wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) || 5058 1.2 joerg (wpa_s->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)) && 5059 1.2 joerg eapol_sm_failed(wpa_s->eapol))) && 5060 1.2 joerg !wpa_s->eap_expected_failure)) 5061 1.10 christos wpas_auth_failed(wpa_s, "AUTH_FAILED", addr); 5062 1.2 joerg 5063 1.2 joerg #ifdef CONFIG_P2P 5064 1.2 joerg if (deauth && reason_code > 0) { 5065 1.2 joerg if (wpas_p2p_deauth_notif(wpa_s, addr, reason_code, ie, ie_len, 5066 1.2 joerg locally_generated) > 0) { 5067 1.2 joerg /* 5068 1.2 joerg * The interface was removed, so cannot continue 5069 1.2 joerg * processing any additional operations after this. 5070 1.2 joerg */ 5071 1.2 joerg return; 5072 1.2 joerg } 5073 1.2 joerg } 5074 1.2 joerg #endif /* CONFIG_P2P */ 5075 1.2 joerg 5076 1.2 joerg wpa_supplicant_event_disassoc_finish(wpa_s, reason_code, 5077 1.2 joerg locally_generated); 5078 1.2 joerg } 5079 1.2 joerg 5080 1.2 joerg 5081 1.2 joerg static void wpas_event_disassoc(struct wpa_supplicant *wpa_s, 5082 1.2 joerg struct disassoc_info *info) 5083 1.2 joerg { 5084 1.2 joerg u16 reason_code = 0; 5085 1.2 joerg int locally_generated = 0; 5086 1.2 joerg const u8 *addr = NULL; 5087 1.2 joerg const u8 *ie = NULL; 5088 1.2 joerg size_t ie_len = 0; 5089 1.2 joerg 5090 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Disassociation notification"); 5091 1.2 joerg 5092 1.2 joerg if (info) { 5093 1.2 joerg addr = info->addr; 5094 1.2 joerg ie = info->ie; 5095 1.2 joerg ie_len = info->ie_len; 5096 1.2 joerg reason_code = info->reason_code; 5097 1.2 joerg locally_generated = info->locally_generated; 5098 1.9 christos wpa_dbg(wpa_s, MSG_DEBUG, " * reason %u (%s)%s", reason_code, 5099 1.9 christos reason2str(reason_code), 5100 1.9 christos locally_generated ? " locally_generated=1" : ""); 5101 1.2 joerg if (addr) 5102 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, " * address " MACSTR, 5103 1.2 joerg MAC2STR(addr)); 5104 1.2 joerg wpa_hexdump(MSG_DEBUG, "Disassociation frame IE(s)", 5105 1.2 joerg ie, ie_len); 5106 1.2 joerg } 5107 1.2 joerg 5108 1.2 joerg #ifdef CONFIG_AP 5109 1.2 joerg if (wpa_s->ap_iface && info && info->addr) { 5110 1.2 joerg hostapd_notif_disassoc(wpa_s->ap_iface->bss[0], info->addr); 5111 1.2 joerg return; 5112 1.2 joerg } 5113 1.2 joerg 5114 1.2 joerg if (wpa_s->ap_iface) { 5115 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Ignore disassoc event in AP mode"); 5116 1.2 joerg return; 5117 1.2 joerg } 5118 1.2 joerg #endif /* CONFIG_AP */ 5119 1.2 joerg 5120 1.2 joerg #ifdef CONFIG_P2P 5121 1.2 joerg if (info) { 5122 1.2 joerg wpas_p2p_disassoc_notif( 5123 1.2 joerg wpa_s, info->addr, reason_code, info->ie, info->ie_len, 5124 1.2 joerg locally_generated); 5125 1.2 joerg } 5126 1.2 joerg #endif /* CONFIG_P2P */ 5127 1.2 joerg 5128 1.2 joerg if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) 5129 1.2 joerg sme_event_disassoc(wpa_s, info); 5130 1.2 joerg 5131 1.2 joerg wpas_event_disconnect(wpa_s, addr, reason_code, locally_generated, 5132 1.2 joerg ie, ie_len, 0); 5133 1.2 joerg } 5134 1.2 joerg 5135 1.2 joerg 5136 1.2 joerg static void wpas_event_deauth(struct wpa_supplicant *wpa_s, 5137 1.2 joerg struct deauth_info *info) 5138 1.2 joerg { 5139 1.2 joerg u16 reason_code = 0; 5140 1.2 joerg int locally_generated = 0; 5141 1.2 joerg const u8 *addr = NULL; 5142 1.2 joerg const u8 *ie = NULL; 5143 1.2 joerg size_t ie_len = 0; 5144 1.2 joerg 5145 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Deauthentication notification"); 5146 1.2 joerg 5147 1.2 joerg if (info) { 5148 1.2 joerg addr = info->addr; 5149 1.2 joerg ie = info->ie; 5150 1.2 joerg ie_len = info->ie_len; 5151 1.2 joerg reason_code = info->reason_code; 5152 1.2 joerg locally_generated = info->locally_generated; 5153 1.9 christos wpa_dbg(wpa_s, MSG_DEBUG, " * reason %u (%s)%s", 5154 1.9 christos reason_code, reason2str(reason_code), 5155 1.9 christos locally_generated ? " locally_generated=1" : ""); 5156 1.2 joerg if (addr) { 5157 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, " * address " MACSTR, 5158 1.2 joerg MAC2STR(addr)); 5159 1.2 joerg } 5160 1.2 joerg wpa_hexdump(MSG_DEBUG, "Deauthentication frame IE(s)", 5161 1.2 joerg ie, ie_len); 5162 1.2 joerg } 5163 1.2 joerg 5164 1.2 joerg wpa_reset_ft_completed(wpa_s->wpa); 5165 1.2 joerg 5166 1.2 joerg wpas_event_disconnect(wpa_s, addr, reason_code, 5167 1.2 joerg locally_generated, ie, ie_len, 1); 5168 1.2 joerg } 5169 1.2 joerg 5170 1.2 joerg 5171 1.2 joerg static const char * reg_init_str(enum reg_change_initiator init) 5172 1.2 joerg { 5173 1.2 joerg switch (init) { 5174 1.2 joerg case REGDOM_SET_BY_CORE: 5175 1.2 joerg return "CORE"; 5176 1.2 joerg case REGDOM_SET_BY_USER: 5177 1.2 joerg return "USER"; 5178 1.2 joerg case REGDOM_SET_BY_DRIVER: 5179 1.2 joerg return "DRIVER"; 5180 1.2 joerg case REGDOM_SET_BY_COUNTRY_IE: 5181 1.2 joerg return "COUNTRY_IE"; 5182 1.2 joerg case REGDOM_BEACON_HINT: 5183 1.2 joerg return "BEACON_HINT"; 5184 1.2 joerg } 5185 1.2 joerg return "?"; 5186 1.2 joerg } 5187 1.2 joerg 5188 1.2 joerg 5189 1.2 joerg static const char * reg_type_str(enum reg_type type) 5190 1.2 joerg { 5191 1.2 joerg switch (type) { 5192 1.2 joerg case REGDOM_TYPE_UNKNOWN: 5193 1.2 joerg return "UNKNOWN"; 5194 1.2 joerg case REGDOM_TYPE_COUNTRY: 5195 1.2 joerg return "COUNTRY"; 5196 1.2 joerg case REGDOM_TYPE_WORLD: 5197 1.2 joerg return "WORLD"; 5198 1.2 joerg case REGDOM_TYPE_CUSTOM_WORLD: 5199 1.2 joerg return "CUSTOM_WORLD"; 5200 1.2 joerg case REGDOM_TYPE_INTERSECTION: 5201 1.2 joerg return "INTERSECTION"; 5202 1.2 joerg } 5203 1.2 joerg return "?"; 5204 1.2 joerg } 5205 1.2 joerg 5206 1.2 joerg 5207 1.10 christos static void wpas_beacon_hint(struct wpa_supplicant *wpa_s, const char *title, 5208 1.10 christos struct frequency_attrs *attrs) 5209 1.10 christos { 5210 1.10 christos if (!attrs->freq) 5211 1.10 christos return; 5212 1.10 christos wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_REGDOM_BEACON_HINT 5213 1.10 christos "%s freq=%u max_tx_power=%u%s%s%s", 5214 1.10 christos title, attrs->freq, attrs->max_tx_power, 5215 1.10 christos attrs->disabled ? " disabled=1" : "", 5216 1.10 christos attrs->no_ir ? " no_ir=1" : "", 5217 1.10 christos attrs->radar ? " radar=1" : ""); 5218 1.10 christos } 5219 1.10 christos 5220 1.10 christos 5221 1.9 christos void wpa_supplicant_update_channel_list(struct wpa_supplicant *wpa_s, 5222 1.9 christos struct channel_list_changed *info) 5223 1.2 joerg { 5224 1.2 joerg struct wpa_supplicant *ifs; 5225 1.7 christos u8 dfs_domain; 5226 1.2 joerg 5227 1.6 christos /* 5228 1.6 christos * To allow backwards compatibility with higher level layers that 5229 1.6 christos * assumed the REGDOM_CHANGE event is sent over the initially added 5230 1.6 christos * interface. Find the highest parent of this interface and use it to 5231 1.6 christos * send the event. 5232 1.6 christos */ 5233 1.6 christos for (ifs = wpa_s; ifs->parent && ifs != ifs->parent; ifs = ifs->parent) 5234 1.6 christos ; 5235 1.6 christos 5236 1.9 christos if (info) { 5237 1.9 christos wpa_msg(ifs, MSG_INFO, 5238 1.9 christos WPA_EVENT_REGDOM_CHANGE "init=%s type=%s%s%s", 5239 1.9 christos reg_init_str(info->initiator), reg_type_str(info->type), 5240 1.9 christos info->alpha2[0] ? " alpha2=" : "", 5241 1.9 christos info->alpha2[0] ? info->alpha2 : ""); 5242 1.10 christos 5243 1.10 christos if (info->initiator == REGDOM_BEACON_HINT) { 5244 1.10 christos wpas_beacon_hint(ifs, "before", 5245 1.10 christos &info->beacon_hint_before); 5246 1.10 christos wpas_beacon_hint(ifs, "after", 5247 1.10 christos &info->beacon_hint_after); 5248 1.10 christos } 5249 1.9 christos } 5250 1.2 joerg 5251 1.2 joerg if (wpa_s->drv_priv == NULL) 5252 1.2 joerg return; /* Ignore event during drv initialization */ 5253 1.2 joerg 5254 1.2 joerg dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant, 5255 1.2 joerg radio_list) { 5256 1.10 christos bool was_6ghz_enabled; 5257 1.10 christos 5258 1.6 christos wpa_printf(MSG_DEBUG, "%s: Updating hw mode", 5259 1.6 christos ifs->ifname); 5260 1.6 christos free_hw_features(ifs); 5261 1.6 christos ifs->hw.modes = wpa_drv_get_hw_feature_data( 5262 1.7 christos ifs, &ifs->hw.num_modes, &ifs->hw.flags, &dfs_domain); 5263 1.6 christos 5264 1.10 christos was_6ghz_enabled = ifs->is_6ghz_enabled; 5265 1.10 christos ifs->is_6ghz_enabled = wpas_is_6ghz_supported(ifs, true); 5266 1.10 christos 5267 1.6 christos /* Restart PNO/sched_scan with updated channel list */ 5268 1.6 christos if (ifs->pno) { 5269 1.6 christos wpas_stop_pno(ifs); 5270 1.6 christos wpas_start_pno(ifs); 5271 1.6 christos } else if (ifs->sched_scanning && !ifs->pno_sched_pending) { 5272 1.6 christos wpa_dbg(ifs, MSG_DEBUG, 5273 1.6 christos "Channel list changed - restart sched_scan"); 5274 1.6 christos wpas_scan_restart_sched_scan(ifs); 5275 1.10 christos } else if (!was_6ghz_enabled && ifs->is_6ghz_enabled) { 5276 1.10 christos wpa_dbg(ifs, MSG_INFO, 5277 1.10 christos "Channel list changed: 6 GHz was enabled"); 5278 1.10 christos 5279 1.10 christos ifs->crossed_6ghz_dom = true; 5280 1.2 joerg } 5281 1.2 joerg } 5282 1.6 christos 5283 1.6 christos wpas_p2p_update_channel_list(wpa_s, WPAS_P2P_CHANNEL_UPDATE_DRIVER); 5284 1.2 joerg } 5285 1.2 joerg 5286 1.2 joerg 5287 1.2 joerg static void wpas_event_rx_mgmt_action(struct wpa_supplicant *wpa_s, 5288 1.3 christos const u8 *frame, size_t len, int freq, 5289 1.3 christos int rssi) 5290 1.2 joerg { 5291 1.2 joerg const struct ieee80211_mgmt *mgmt; 5292 1.2 joerg const u8 *payload; 5293 1.2 joerg size_t plen; 5294 1.2 joerg u8 category; 5295 1.2 joerg 5296 1.2 joerg if (len < IEEE80211_HDRLEN + 2) 5297 1.2 joerg return; 5298 1.2 joerg 5299 1.2 joerg mgmt = (const struct ieee80211_mgmt *) frame; 5300 1.2 joerg payload = frame + IEEE80211_HDRLEN; 5301 1.2 joerg category = *payload++; 5302 1.2 joerg plen = len - IEEE80211_HDRLEN - 1; 5303 1.2 joerg 5304 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Received Action frame: SA=" MACSTR 5305 1.2 joerg " Category=%u DataLen=%d freq=%d MHz", 5306 1.2 joerg MAC2STR(mgmt->sa), category, (int) plen, freq); 5307 1.2 joerg 5308 1.10 christos #ifndef CONFIG_NO_WMM_AC 5309 1.3 christos if (category == WLAN_ACTION_WMM) { 5310 1.3 christos wmm_ac_rx_action(wpa_s, mgmt->da, mgmt->sa, payload, plen); 5311 1.3 christos return; 5312 1.3 christos } 5313 1.10 christos #endif /* CONFIG_NO_WMM_AC */ 5314 1.3 christos 5315 1.2 joerg #ifdef CONFIG_IEEE80211R 5316 1.2 joerg if (category == WLAN_ACTION_FT) { 5317 1.2 joerg ft_rx_action(wpa_s, payload, plen); 5318 1.2 joerg return; 5319 1.2 joerg } 5320 1.2 joerg #endif /* CONFIG_IEEE80211R */ 5321 1.2 joerg 5322 1.2 joerg #ifdef CONFIG_SME 5323 1.2 joerg if (category == WLAN_ACTION_SA_QUERY) { 5324 1.10 christos sme_sa_query_rx(wpa_s, mgmt->da, mgmt->sa, payload, plen); 5325 1.2 joerg return; 5326 1.2 joerg } 5327 1.2 joerg #endif /* CONFIG_SME */ 5328 1.2 joerg 5329 1.2 joerg #ifdef CONFIG_WNM 5330 1.2 joerg if (mgmt->u.action.category == WLAN_ACTION_WNM) { 5331 1.2 joerg ieee802_11_rx_wnm_action(wpa_s, mgmt, len); 5332 1.2 joerg return; 5333 1.2 joerg } 5334 1.2 joerg #endif /* CONFIG_WNM */ 5335 1.2 joerg 5336 1.2 joerg #ifdef CONFIG_GAS 5337 1.2 joerg if ((mgmt->u.action.category == WLAN_ACTION_PUBLIC || 5338 1.2 joerg mgmt->u.action.category == WLAN_ACTION_PROTECTED_DUAL) && 5339 1.2 joerg gas_query_rx(wpa_s->gas, mgmt->da, mgmt->sa, mgmt->bssid, 5340 1.2 joerg mgmt->u.action.category, 5341 1.2 joerg payload, plen, freq) == 0) 5342 1.2 joerg return; 5343 1.2 joerg #endif /* CONFIG_GAS */ 5344 1.2 joerg 5345 1.7 christos #ifdef CONFIG_GAS_SERVER 5346 1.7 christos if ((mgmt->u.action.category == WLAN_ACTION_PUBLIC || 5347 1.7 christos mgmt->u.action.category == WLAN_ACTION_PROTECTED_DUAL) && 5348 1.7 christos gas_server_rx(wpa_s->gas_server, mgmt->da, mgmt->sa, mgmt->bssid, 5349 1.7 christos mgmt->u.action.category, 5350 1.7 christos payload, plen, freq) == 0) 5351 1.7 christos return; 5352 1.7 christos #endif /* CONFIG_GAS_SERVER */ 5353 1.7 christos 5354 1.2 joerg #ifdef CONFIG_TDLS 5355 1.2 joerg if (category == WLAN_ACTION_PUBLIC && plen >= 4 && 5356 1.2 joerg payload[0] == WLAN_TDLS_DISCOVERY_RESPONSE) { 5357 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, 5358 1.2 joerg "TDLS: Received Discovery Response from " MACSTR, 5359 1.2 joerg MAC2STR(mgmt->sa)); 5360 1.10 christos if (wpa_s->valid_links && 5361 1.10 christos wpa_tdls_process_discovery_response(wpa_s->wpa, mgmt->sa, 5362 1.10 christos &payload[1], plen - 1)) 5363 1.10 christos wpa_dbg(wpa_s, MSG_ERROR, 5364 1.10 christos "TDLS: Discovery Response process failed for " 5365 1.10 christos MACSTR, MAC2STR(mgmt->sa)); 5366 1.2 joerg return; 5367 1.2 joerg } 5368 1.2 joerg #endif /* CONFIG_TDLS */ 5369 1.2 joerg 5370 1.2 joerg #ifdef CONFIG_INTERWORKING 5371 1.2 joerg if (category == WLAN_ACTION_QOS && plen >= 1 && 5372 1.2 joerg payload[0] == QOS_QOS_MAP_CONFIG) { 5373 1.2 joerg const u8 *pos = payload + 1; 5374 1.2 joerg size_t qlen = plen - 1; 5375 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Interworking: Received QoS Map Configure frame from " 5376 1.2 joerg MACSTR, MAC2STR(mgmt->sa)); 5377 1.10 christos if (ether_addr_equal(mgmt->sa, wpa_s->bssid) && 5378 1.2 joerg qlen > 2 && pos[0] == WLAN_EID_QOS_MAP_SET && 5379 1.2 joerg pos[1] <= qlen - 2 && pos[1] >= 16) 5380 1.2 joerg wpas_qos_map_set(wpa_s, pos + 2, pos[1]); 5381 1.2 joerg return; 5382 1.2 joerg } 5383 1.2 joerg #endif /* CONFIG_INTERWORKING */ 5384 1.2 joerg 5385 1.10 christos #ifndef CONFIG_NO_RRM 5386 1.3 christos if (category == WLAN_ACTION_RADIO_MEASUREMENT && 5387 1.6 christos payload[0] == WLAN_RRM_RADIO_MEASUREMENT_REQUEST) { 5388 1.6 christos wpas_rrm_handle_radio_measurement_request(wpa_s, mgmt->sa, 5389 1.7 christos mgmt->da, 5390 1.6 christos payload + 1, 5391 1.6 christos plen - 1); 5392 1.6 christos return; 5393 1.6 christos } 5394 1.6 christos 5395 1.6 christos if (category == WLAN_ACTION_RADIO_MEASUREMENT && 5396 1.3 christos payload[0] == WLAN_RRM_NEIGHBOR_REPORT_RESPONSE) { 5397 1.3 christos wpas_rrm_process_neighbor_rep(wpa_s, payload + 1, plen - 1); 5398 1.3 christos return; 5399 1.3 christos } 5400 1.3 christos 5401 1.3 christos if (category == WLAN_ACTION_RADIO_MEASUREMENT && 5402 1.3 christos payload[0] == WLAN_RRM_LINK_MEASUREMENT_REQUEST) { 5403 1.3 christos wpas_rrm_handle_link_measurement_request(wpa_s, mgmt->sa, 5404 1.3 christos payload + 1, plen - 1, 5405 1.3 christos rssi); 5406 1.3 christos return; 5407 1.3 christos } 5408 1.10 christos #endif /* CONFIG_NO_RRM */ 5409 1.3 christos 5410 1.6 christos #ifdef CONFIG_FST 5411 1.6 christos if (mgmt->u.action.category == WLAN_ACTION_FST && wpa_s->fst) { 5412 1.6 christos fst_rx_action(wpa_s->fst, mgmt, len); 5413 1.6 christos return; 5414 1.6 christos } 5415 1.6 christos #endif /* CONFIG_FST */ 5416 1.6 christos 5417 1.10 christos #ifdef CONFIG_NAN_USD 5418 1.10 christos if (category == WLAN_ACTION_PUBLIC && plen >= 5 && 5419 1.10 christos payload[0] == WLAN_PA_VENDOR_SPECIFIC && 5420 1.10 christos WPA_GET_BE32(&payload[1]) == NAN_SDF_VENDOR_TYPE) { 5421 1.10 christos payload += 5; 5422 1.10 christos plen -= 5; 5423 1.10 christos wpas_nan_usd_rx_sdf(wpa_s, mgmt->sa, freq, payload, plen); 5424 1.10 christos return; 5425 1.10 christos } 5426 1.10 christos #endif /* CONFIG_NAN_USD */ 5427 1.10 christos 5428 1.7 christos #ifdef CONFIG_DPP 5429 1.7 christos if (category == WLAN_ACTION_PUBLIC && plen >= 5 && 5430 1.7 christos payload[0] == WLAN_PA_VENDOR_SPECIFIC && 5431 1.7 christos WPA_GET_BE24(&payload[1]) == OUI_WFA && 5432 1.7 christos payload[4] == DPP_OUI_TYPE) { 5433 1.7 christos payload++; 5434 1.7 christos plen--; 5435 1.7 christos wpas_dpp_rx_action(wpa_s, mgmt->sa, payload, plen, freq); 5436 1.7 christos return; 5437 1.7 christos } 5438 1.7 christos #endif /* CONFIG_DPP */ 5439 1.7 christos 5440 1.10 christos #ifndef CONFIG_NO_ROBUST_AV 5441 1.10 christos if (category == WLAN_ACTION_ROBUST_AV_STREAMING && 5442 1.10 christos payload[0] == ROBUST_AV_SCS_RESP) { 5443 1.10 christos wpas_handle_robust_av_scs_recv_action(wpa_s, mgmt->sa, 5444 1.10 christos payload + 1, plen - 1); 5445 1.10 christos return; 5446 1.10 christos } 5447 1.10 christos 5448 1.10 christos if (category == WLAN_ACTION_ROBUST_AV_STREAMING && 5449 1.10 christos payload[0] == ROBUST_AV_MSCS_RESP) { 5450 1.10 christos wpas_handle_robust_av_recv_action(wpa_s, mgmt->sa, 5451 1.10 christos payload + 1, plen - 1); 5452 1.10 christos return; 5453 1.10 christos } 5454 1.10 christos 5455 1.10 christos if (category == WLAN_ACTION_VENDOR_SPECIFIC_PROTECTED && plen > 4 && 5456 1.10 christos WPA_GET_BE32(payload) == QM_ACTION_VENDOR_TYPE) { 5457 1.10 christos wpas_handle_qos_mgmt_recv_action(wpa_s, mgmt->sa, 5458 1.10 christos payload + 4, plen - 4); 5459 1.10 christos return; 5460 1.10 christos } 5461 1.10 christos #endif /* CONFIG_NO_ROBUST_AV */ 5462 1.10 christos 5463 1.2 joerg wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid, 5464 1.2 joerg category, payload, plen, freq); 5465 1.3 christos if (wpa_s->ifmsh) 5466 1.3 christos mesh_mpm_action_rx(wpa_s, mgmt, len); 5467 1.2 joerg } 5468 1.2 joerg 5469 1.2 joerg 5470 1.2 joerg static void wpa_supplicant_notify_avoid_freq(struct wpa_supplicant *wpa_s, 5471 1.2 joerg union wpa_event_data *event) 5472 1.2 joerg { 5473 1.2 joerg struct wpa_freq_range_list *list; 5474 1.2 joerg char *str = NULL; 5475 1.2 joerg 5476 1.2 joerg list = &event->freq_range; 5477 1.2 joerg 5478 1.2 joerg if (list->num) 5479 1.2 joerg str = freq_range_list_str(list); 5480 1.2 joerg wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_AVOID_FREQ "ranges=%s", 5481 1.2 joerg str ? str : ""); 5482 1.2 joerg 5483 1.2 joerg #ifdef CONFIG_P2P 5484 1.2 joerg if (freq_range_list_parse(&wpa_s->global->p2p_go_avoid_freq, str)) { 5485 1.2 joerg wpa_dbg(wpa_s, MSG_ERROR, "%s: Failed to parse freq range", 5486 1.2 joerg __func__); 5487 1.2 joerg } else { 5488 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Update channel list based on frequency avoid event"); 5489 1.2 joerg 5490 1.6 christos /* 5491 1.6 christos * The update channel flow will also take care of moving a GO 5492 1.6 christos * from the unsafe frequency if needed. 5493 1.6 christos */ 5494 1.6 christos wpas_p2p_update_channel_list(wpa_s, 5495 1.6 christos WPAS_P2P_CHANNEL_UPDATE_AVOID); 5496 1.2 joerg } 5497 1.2 joerg #endif /* CONFIG_P2P */ 5498 1.2 joerg 5499 1.2 joerg os_free(str); 5500 1.2 joerg } 5501 1.2 joerg 5502 1.2 joerg 5503 1.7 christos static void wpa_supplicant_event_port_authorized(struct wpa_supplicant *wpa_s) 5504 1.3 christos { 5505 1.3 christos if (wpa_s->wpa_state == WPA_ASSOCIATED) { 5506 1.3 christos wpa_supplicant_cancel_auth_timeout(wpa_s); 5507 1.3 christos wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); 5508 1.10 christos eapol_sm_notify_portValid(wpa_s->eapol, true); 5509 1.10 christos eapol_sm_notify_eap_success(wpa_s->eapol, true); 5510 1.10 christos wpa_s->drv_authorized_port = 1; 5511 1.3 christos } 5512 1.7 christos } 5513 1.7 christos 5514 1.7 christos 5515 1.7 christos static unsigned int wpas_event_cac_ms(const struct wpa_supplicant *wpa_s, 5516 1.7 christos int freq) 5517 1.7 christos { 5518 1.7 christos size_t i; 5519 1.7 christos int j; 5520 1.7 christos 5521 1.7 christos for (i = 0; i < wpa_s->hw.num_modes; i++) { 5522 1.7 christos const struct hostapd_hw_modes *mode = &wpa_s->hw.modes[i]; 5523 1.7 christos 5524 1.7 christos for (j = 0; j < mode->num_channels; j++) { 5525 1.7 christos const struct hostapd_channel_data *chan; 5526 1.7 christos 5527 1.7 christos chan = &mode->channels[j]; 5528 1.7 christos if (chan->freq == freq) 5529 1.7 christos return chan->dfs_cac_ms; 5530 1.7 christos } 5531 1.7 christos } 5532 1.7 christos 5533 1.7 christos return 0; 5534 1.7 christos } 5535 1.7 christos 5536 1.7 christos 5537 1.7 christos static void wpas_event_dfs_cac_started(struct wpa_supplicant *wpa_s, 5538 1.7 christos struct dfs_event *radar) 5539 1.7 christos { 5540 1.7 christos #if defined(NEED_AP_MLME) && defined(CONFIG_AP) 5541 1.9 christos if (wpa_s->ap_iface || wpa_s->ifmsh) { 5542 1.7 christos wpas_ap_event_dfs_cac_started(wpa_s, radar); 5543 1.7 christos } else 5544 1.7 christos #endif /* NEED_AP_MLME && CONFIG_AP */ 5545 1.7 christos { 5546 1.7 christos unsigned int cac_time = wpas_event_cac_ms(wpa_s, radar->freq); 5547 1.7 christos 5548 1.7 christos cac_time /= 1000; /* convert from ms to sec */ 5549 1.7 christos if (!cac_time) 5550 1.7 christos cac_time = 10 * 60; /* max timeout: 10 minutes */ 5551 1.7 christos 5552 1.7 christos /* Restart auth timeout: CAC time added to initial timeout */ 5553 1.7 christos wpas_auth_timeout_restart(wpa_s, cac_time); 5554 1.7 christos } 5555 1.7 christos } 5556 1.7 christos 5557 1.7 christos 5558 1.7 christos static void wpas_event_dfs_cac_finished(struct wpa_supplicant *wpa_s, 5559 1.7 christos struct dfs_event *radar) 5560 1.7 christos { 5561 1.7 christos #if defined(NEED_AP_MLME) && defined(CONFIG_AP) 5562 1.9 christos if (wpa_s->ap_iface || wpa_s->ifmsh) { 5563 1.7 christos wpas_ap_event_dfs_cac_finished(wpa_s, radar); 5564 1.7 christos } else 5565 1.7 christos #endif /* NEED_AP_MLME && CONFIG_AP */ 5566 1.7 christos { 5567 1.7 christos /* Restart auth timeout with original value after CAC is 5568 1.7 christos * finished */ 5569 1.7 christos wpas_auth_timeout_restart(wpa_s, 0); 5570 1.7 christos } 5571 1.7 christos } 5572 1.7 christos 5573 1.7 christos 5574 1.7 christos static void wpas_event_dfs_cac_aborted(struct wpa_supplicant *wpa_s, 5575 1.7 christos struct dfs_event *radar) 5576 1.7 christos { 5577 1.7 christos #if defined(NEED_AP_MLME) && defined(CONFIG_AP) 5578 1.9 christos if (wpa_s->ap_iface || wpa_s->ifmsh) { 5579 1.7 christos wpas_ap_event_dfs_cac_aborted(wpa_s, radar); 5580 1.7 christos } else 5581 1.7 christos #endif /* NEED_AP_MLME && CONFIG_AP */ 5582 1.7 christos { 5583 1.7 christos /* Restart auth timeout with original value after CAC is 5584 1.7 christos * aborted */ 5585 1.7 christos wpas_auth_timeout_restart(wpa_s, 0); 5586 1.7 christos } 5587 1.7 christos } 5588 1.7 christos 5589 1.7 christos 5590 1.7 christos static void wpa_supplicant_event_assoc_auth(struct wpa_supplicant *wpa_s, 5591 1.7 christos union wpa_event_data *data) 5592 1.7 christos { 5593 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, 5594 1.7 christos "Connection authorized by device, previous state %d", 5595 1.7 christos wpa_s->wpa_state); 5596 1.7 christos 5597 1.7 christos wpa_supplicant_event_port_authorized(wpa_s); 5598 1.7 christos 5599 1.10 christos wpa_s->last_eapol_matches_bssid = 1; 5600 1.10 christos 5601 1.3 christos wpa_sm_set_rx_replay_ctr(wpa_s->wpa, data->assoc_info.key_replay_ctr); 5602 1.3 christos wpa_sm_set_ptk_kck_kek(wpa_s->wpa, data->assoc_info.ptk_kck, 5603 1.3 christos data->assoc_info.ptk_kck_len, 5604 1.3 christos data->assoc_info.ptk_kek, 5605 1.3 christos data->assoc_info.ptk_kek_len); 5606 1.7 christos #ifdef CONFIG_FILS 5607 1.7 christos if (wpa_s->auth_alg == WPA_AUTH_ALG_FILS) { 5608 1.7 christos struct wpa_bss *bss = wpa_bss_get_bssid(wpa_s, wpa_s->bssid); 5609 1.7 christos const u8 *fils_cache_id = wpa_bss_get_fils_cache_id(bss); 5610 1.7 christos 5611 1.7 christos /* Update ERP next sequence number */ 5612 1.7 christos eapol_sm_update_erp_next_seq_num( 5613 1.7 christos wpa_s->eapol, data->assoc_info.fils_erp_next_seq_num); 5614 1.7 christos 5615 1.7 christos if (data->assoc_info.fils_pmk && data->assoc_info.fils_pmkid) { 5616 1.7 christos /* Add the new PMK and PMKID to the PMKSA cache */ 5617 1.7 christos wpa_sm_pmksa_cache_add(wpa_s->wpa, 5618 1.7 christos data->assoc_info.fils_pmk, 5619 1.7 christos data->assoc_info.fils_pmk_len, 5620 1.7 christos data->assoc_info.fils_pmkid, 5621 1.10 christos wpa_s->valid_links ? 5622 1.10 christos wpa_s->ap_mld_addr : 5623 1.10 christos wpa_s->bssid, 5624 1.10 christos fils_cache_id); 5625 1.7 christos } else if (data->assoc_info.fils_pmkid) { 5626 1.7 christos /* Update the current PMKSA used for this connection */ 5627 1.7 christos pmksa_cache_set_current(wpa_s->wpa, 5628 1.7 christos data->assoc_info.fils_pmkid, 5629 1.10 christos NULL, NULL, 0, NULL, 0, true); 5630 1.7 christos } 5631 1.7 christos } 5632 1.7 christos #endif /* CONFIG_FILS */ 5633 1.7 christos } 5634 1.7 christos 5635 1.7 christos 5636 1.10 christos static const char * connect_fail_reason(enum sta_connect_fail_reason_codes code) 5637 1.10 christos { 5638 1.10 christos switch (code) { 5639 1.10 christos case STA_CONNECT_FAIL_REASON_UNSPECIFIED: 5640 1.10 christos return ""; 5641 1.10 christos case STA_CONNECT_FAIL_REASON_NO_BSS_FOUND: 5642 1.10 christos return "no_bss_found"; 5643 1.10 christos case STA_CONNECT_FAIL_REASON_AUTH_TX_FAIL: 5644 1.10 christos return "auth_tx_fail"; 5645 1.10 christos case STA_CONNECT_FAIL_REASON_AUTH_NO_ACK_RECEIVED: 5646 1.10 christos return "auth_no_ack_received"; 5647 1.10 christos case STA_CONNECT_FAIL_REASON_AUTH_NO_RESP_RECEIVED: 5648 1.10 christos return "auth_no_resp_received"; 5649 1.10 christos case STA_CONNECT_FAIL_REASON_ASSOC_REQ_TX_FAIL: 5650 1.10 christos return "assoc_req_tx_fail"; 5651 1.10 christos case STA_CONNECT_FAIL_REASON_ASSOC_NO_ACK_RECEIVED: 5652 1.10 christos return "assoc_no_ack_received"; 5653 1.10 christos case STA_CONNECT_FAIL_REASON_ASSOC_NO_RESP_RECEIVED: 5654 1.10 christos return "assoc_no_resp_received"; 5655 1.10 christos default: 5656 1.10 christos return "unknown_reason"; 5657 1.10 christos } 5658 1.10 christos } 5659 1.10 christos 5660 1.10 christos 5661 1.7 christos static void wpas_event_assoc_reject(struct wpa_supplicant *wpa_s, 5662 1.7 christos union wpa_event_data *data) 5663 1.7 christos { 5664 1.7 christos const u8 *bssid = data->assoc_reject.bssid; 5665 1.10 christos struct ieee802_11_elems elems; 5666 1.10 christos struct ml_sta_link_info ml_info[MAX_NUM_MLD_LINKS]; 5667 1.10 christos const u8 *link_bssids[MAX_NUM_MLD_LINKS + 1]; 5668 1.9 christos #ifdef CONFIG_MBO 5669 1.9 christos struct wpa_bss *reject_bss; 5670 1.9 christos #endif /* CONFIG_MBO */ 5671 1.7 christos 5672 1.7 christos if (!bssid || is_zero_ether_addr(bssid)) 5673 1.7 christos bssid = wpa_s->pending_bssid; 5674 1.9 christos #ifdef CONFIG_MBO 5675 1.9 christos if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) 5676 1.9 christos reject_bss = wpa_s->current_bss; 5677 1.9 christos else 5678 1.9 christos reject_bss = wpa_bss_get_bssid(wpa_s, bssid); 5679 1.9 christos #endif /* CONFIG_MBO */ 5680 1.7 christos 5681 1.7 christos if (data->assoc_reject.bssid) 5682 1.7 christos wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_ASSOC_REJECT 5683 1.10 christos "bssid=" MACSTR " status_code=%u%s%s%s%s%s", 5684 1.7 christos MAC2STR(data->assoc_reject.bssid), 5685 1.7 christos data->assoc_reject.status_code, 5686 1.7 christos data->assoc_reject.timed_out ? " timeout" : "", 5687 1.7 christos data->assoc_reject.timeout_reason ? "=" : "", 5688 1.7 christos data->assoc_reject.timeout_reason ? 5689 1.10 christos data->assoc_reject.timeout_reason : "", 5690 1.10 christos data->assoc_reject.reason_code != 5691 1.10 christos STA_CONNECT_FAIL_REASON_UNSPECIFIED ? 5692 1.10 christos " qca_driver_reason=" : "", 5693 1.10 christos connect_fail_reason(data->assoc_reject.reason_code)); 5694 1.7 christos else 5695 1.7 christos wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_ASSOC_REJECT 5696 1.10 christos "status_code=%u%s%s%s%s%s", 5697 1.7 christos data->assoc_reject.status_code, 5698 1.7 christos data->assoc_reject.timed_out ? " timeout" : "", 5699 1.7 christos data->assoc_reject.timeout_reason ? "=" : "", 5700 1.7 christos data->assoc_reject.timeout_reason ? 5701 1.10 christos data->assoc_reject.timeout_reason : "", 5702 1.10 christos data->assoc_reject.reason_code != 5703 1.10 christos STA_CONNECT_FAIL_REASON_UNSPECIFIED ? 5704 1.10 christos " qca_driver_reason=" : "", 5705 1.10 christos connect_fail_reason(data->assoc_reject.reason_code)); 5706 1.7 christos wpa_s->assoc_status_code = data->assoc_reject.status_code; 5707 1.7 christos wpas_notify_assoc_status_code(wpa_s); 5708 1.7 christos 5709 1.7 christos #ifdef CONFIG_OWE 5710 1.7 christos if (data->assoc_reject.status_code == 5711 1.7 christos WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED && 5712 1.7 christos wpa_s->key_mgmt == WPA_KEY_MGMT_OWE && 5713 1.7 christos wpa_s->current_ssid && 5714 1.7 christos wpa_s->current_ssid->owe_group == 0 && 5715 1.7 christos wpa_s->last_owe_group != 21) { 5716 1.7 christos struct wpa_ssid *ssid = wpa_s->current_ssid; 5717 1.7 christos struct wpa_bss *bss = wpa_s->current_bss; 5718 1.7 christos 5719 1.7 christos if (!bss) { 5720 1.7 christos bss = wpa_supplicant_get_new_bss(wpa_s, bssid); 5721 1.7 christos if (!bss) { 5722 1.10 christos wpas_connection_failed(wpa_s, bssid, NULL); 5723 1.7 christos wpa_supplicant_mark_disassoc(wpa_s); 5724 1.7 christos return; 5725 1.7 christos } 5726 1.7 christos } 5727 1.7 christos wpa_printf(MSG_DEBUG, "OWE: Try next supported DH group"); 5728 1.7 christos wpas_connect_work_done(wpa_s); 5729 1.7 christos wpa_supplicant_mark_disassoc(wpa_s); 5730 1.7 christos wpa_supplicant_connect(wpa_s, bss, ssid); 5731 1.7 christos return; 5732 1.7 christos } 5733 1.7 christos #endif /* CONFIG_OWE */ 5734 1.7 christos 5735 1.10 christos #ifdef CONFIG_DPP2 5736 1.10 christos /* Try to follow AP's PFS policy. WLAN_STATUS_ASSOC_DENIED_UNSPEC is 5737 1.10 christos * the status code defined in the DPP R2 tech spec. 5738 1.10 christos * WLAN_STATUS_AKMP_NOT_VALID is addressed in the same manner as an 5739 1.10 christos * interoperability workaround with older hostapd implementation. */ 5740 1.10 christos if (DPP_VERSION > 1 && wpa_s->current_ssid && 5741 1.10 christos (wpa_s->current_ssid->key_mgmt == WPA_KEY_MGMT_DPP || 5742 1.10 christos ((wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_DPP) && 5743 1.10 christos wpa_s->key_mgmt == WPA_KEY_MGMT_DPP)) && 5744 1.10 christos wpa_s->current_ssid->dpp_pfs == 0 && 5745 1.10 christos (data->assoc_reject.status_code == 5746 1.10 christos WLAN_STATUS_ASSOC_DENIED_UNSPEC || 5747 1.10 christos data->assoc_reject.status_code == WLAN_STATUS_AKMP_NOT_VALID)) { 5748 1.10 christos struct wpa_ssid *ssid = wpa_s->current_ssid; 5749 1.10 christos struct wpa_bss *bss = wpa_s->current_bss; 5750 1.10 christos 5751 1.10 christos wpa_s->current_ssid->dpp_pfs_fallback ^= 1; 5752 1.10 christos if (!bss) 5753 1.10 christos bss = wpa_supplicant_get_new_bss(wpa_s, bssid); 5754 1.10 christos if (!bss || wpa_s->dpp_pfs_fallback) { 5755 1.10 christos wpa_printf(MSG_DEBUG, 5756 1.10 christos "DPP: Updated PFS policy for next try"); 5757 1.10 christos wpas_connection_failed(wpa_s, bssid, NULL); 5758 1.10 christos wpa_supplicant_mark_disassoc(wpa_s); 5759 1.10 christos return; 5760 1.10 christos } 5761 1.10 christos wpa_printf(MSG_DEBUG, "DPP: Try again with updated PFS policy"); 5762 1.10 christos wpa_s->dpp_pfs_fallback = 1; 5763 1.10 christos wpas_connect_work_done(wpa_s); 5764 1.10 christos wpa_supplicant_mark_disassoc(wpa_s); 5765 1.10 christos wpa_supplicant_connect(wpa_s, bss, ssid); 5766 1.10 christos return; 5767 1.10 christos } 5768 1.10 christos #endif /* CONFIG_DPP2 */ 5769 1.10 christos 5770 1.9 christos #ifdef CONFIG_MBO 5771 1.9 christos if (data->assoc_reject.status_code == 5772 1.9 christos WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS && 5773 1.9 christos reject_bss && data->assoc_reject.resp_ies) { 5774 1.9 christos const u8 *rssi_rej; 5775 1.9 christos 5776 1.9 christos rssi_rej = mbo_get_attr_from_ies( 5777 1.9 christos data->assoc_reject.resp_ies, 5778 1.9 christos data->assoc_reject.resp_ies_len, 5779 1.9 christos OCE_ATTR_ID_RSSI_BASED_ASSOC_REJECT); 5780 1.9 christos if (rssi_rej && rssi_rej[1] == 2) { 5781 1.9 christos wpa_printf(MSG_DEBUG, 5782 1.9 christos "OCE: RSSI-based association rejection from " 5783 1.9 christos MACSTR " (Delta RSSI: %u, Retry Delay: %u)", 5784 1.9 christos MAC2STR(reject_bss->bssid), 5785 1.9 christos rssi_rej[2], rssi_rej[3]); 5786 1.9 christos wpa_bss_tmp_disallow(wpa_s, 5787 1.9 christos reject_bss->bssid, 5788 1.9 christos rssi_rej[3], 5789 1.9 christos rssi_rej[2] + reject_bss->level); 5790 1.9 christos } 5791 1.9 christos } 5792 1.9 christos #endif /* CONFIG_MBO */ 5793 1.9 christos 5794 1.10 christos /* Check for other failed links in the response */ 5795 1.10 christos os_memset(link_bssids, 0, sizeof(link_bssids)); 5796 1.10 christos if (ieee802_11_parse_elems(data->assoc_reject.resp_ies, 5797 1.10 christos data->assoc_reject.resp_ies_len, 5798 1.10 christos &elems, 1) != ParseFailed) { 5799 1.10 christos unsigned int n_links, i, idx; 5800 1.10 christos 5801 1.10 christos idx = 0; 5802 1.10 christos n_links = wpas_ml_parse_assoc(wpa_s, &elems, ml_info); 5803 1.10 christos 5804 1.10 christos for (i = 1; i < n_links; i++) { 5805 1.10 christos /* The status cannot be success here. 5806 1.10 christos * Add the link to the failed list if it is reporting 5807 1.10 christos * an error. The only valid "non-error" status is 5808 1.10 christos * TX_LINK_NOT_ACCEPTED as that means this link may 5809 1.10 christos * still accept an association from us. 5810 1.10 christos */ 5811 1.10 christos if (ml_info[i].status != 5812 1.10 christos WLAN_STATUS_DENIED_TX_LINK_NOT_ACCEPTED) { 5813 1.10 christos link_bssids[idx] = ml_info[i].bssid; 5814 1.10 christos idx++; 5815 1.10 christos } 5816 1.10 christos } 5817 1.10 christos } 5818 1.10 christos 5819 1.7 christos if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) { 5820 1.10 christos sme_event_assoc_reject(wpa_s, data, link_bssids); 5821 1.7 christos return; 5822 1.7 christos } 5823 1.7 christos 5824 1.7 christos /* Driver-based SME cases */ 5825 1.7 christos 5826 1.7 christos #ifdef CONFIG_SAE 5827 1.7 christos if (wpa_s->current_ssid && 5828 1.7 christos wpa_key_mgmt_sae(wpa_s->current_ssid->key_mgmt) && 5829 1.7 christos !data->assoc_reject.timed_out) { 5830 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, "SAE: Drop PMKSA cache entry"); 5831 1.7 christos wpa_sm_aborted_cached(wpa_s->wpa); 5832 1.7 christos wpa_sm_pmksa_cache_flush(wpa_s->wpa, wpa_s->current_ssid); 5833 1.7 christos } 5834 1.7 christos #endif /* CONFIG_SAE */ 5835 1.7 christos 5836 1.7 christos #ifdef CONFIG_DPP 5837 1.7 christos if (wpa_s->current_ssid && 5838 1.7 christos wpa_s->current_ssid->key_mgmt == WPA_KEY_MGMT_DPP && 5839 1.7 christos !data->assoc_reject.timed_out) { 5840 1.7 christos wpa_dbg(wpa_s, MSG_DEBUG, "DPP: Drop PMKSA cache entry"); 5841 1.7 christos wpa_sm_aborted_cached(wpa_s->wpa); 5842 1.7 christos wpa_sm_pmksa_cache_flush(wpa_s->wpa, wpa_s->current_ssid); 5843 1.7 christos } 5844 1.7 christos #endif /* CONFIG_DPP */ 5845 1.7 christos 5846 1.7 christos #ifdef CONFIG_FILS 5847 1.7 christos /* Update ERP next sequence number */ 5848 1.7 christos if (wpa_s->auth_alg == WPA_AUTH_ALG_FILS) { 5849 1.10 christos fils_pmksa_cache_flush(wpa_s); 5850 1.7 christos eapol_sm_update_erp_next_seq_num( 5851 1.7 christos wpa_s->eapol, 5852 1.7 christos data->assoc_reject.fils_erp_next_seq_num); 5853 1.7 christos fils_connection_failure(wpa_s); 5854 1.7 christos } 5855 1.7 christos #endif /* CONFIG_FILS */ 5856 1.7 christos 5857 1.10 christos wpas_connection_failed(wpa_s, bssid, link_bssids); 5858 1.7 christos wpa_supplicant_mark_disassoc(wpa_s); 5859 1.3 christos } 5860 1.3 christos 5861 1.3 christos 5862 1.10 christos static void wpas_event_unprot_beacon(struct wpa_supplicant *wpa_s, 5863 1.10 christos struct unprot_beacon *data) 5864 1.10 christos { 5865 1.10 christos struct wpabuf *buf; 5866 1.10 christos int res; 5867 1.10 christos 5868 1.10 christos if (!data || wpa_s->wpa_state != WPA_COMPLETED || 5869 1.10 christos !ether_addr_equal(data->sa, wpa_s->bssid)) 5870 1.10 christos return; 5871 1.10 christos wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_UNPROT_BEACON MACSTR, 5872 1.10 christos MAC2STR(data->sa)); 5873 1.10 christos 5874 1.10 christos buf = wpabuf_alloc(4); 5875 1.10 christos if (!buf) 5876 1.10 christos return; 5877 1.10 christos 5878 1.10 christos wpabuf_put_u8(buf, WLAN_ACTION_WNM); 5879 1.10 christos wpabuf_put_u8(buf, WNM_NOTIFICATION_REQ); 5880 1.10 christos wpabuf_put_u8(buf, 1); /* Dialog Token */ 5881 1.10 christos wpabuf_put_u8(buf, WNM_NOTIF_TYPE_BEACON_PROTECTION_FAILURE); 5882 1.10 christos 5883 1.10 christos res = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid, 5884 1.10 christos wpa_s->own_addr, wpa_s->bssid, 5885 1.10 christos wpabuf_head(buf), wpabuf_len(buf), 0); 5886 1.10 christos if (res < 0) 5887 1.10 christos wpa_printf(MSG_DEBUG, 5888 1.10 christos "Failed to send WNM-Notification Request frame"); 5889 1.10 christos 5890 1.10 christos wpabuf_free(buf); 5891 1.10 christos } 5892 1.10 christos 5893 1.10 christos 5894 1.10 christos static const char * bitmap_to_str(u8 value, char *buf) 5895 1.10 christos { 5896 1.10 christos char *pos = buf; 5897 1.10 christos int i, k = 0; 5898 1.10 christos 5899 1.10 christos for (i = 7; i >= 0; i--) 5900 1.10 christos pos[k++] = (value & BIT(i)) ? '1' : '0'; 5901 1.10 christos 5902 1.10 christos pos[8] = '\0'; 5903 1.10 christos return pos; 5904 1.10 christos } 5905 1.10 christos 5906 1.10 christos 5907 1.10 christos static void wpas_tid_link_map(struct wpa_supplicant *wpa_s, 5908 1.10 christos struct tid_link_map_info *info) 5909 1.10 christos { 5910 1.10 christos char map_info[1000], *pos, *end; 5911 1.10 christos int res, i; 5912 1.10 christos 5913 1.10 christos pos = map_info; 5914 1.10 christos end = pos + sizeof(map_info); 5915 1.10 christos res = os_snprintf(map_info, sizeof(map_info), "default=%d", 5916 1.10 christos info->default_map); 5917 1.10 christos if (os_snprintf_error(end - pos, res)) 5918 1.10 christos return; 5919 1.10 christos pos += res; 5920 1.10 christos 5921 1.10 christos if (!info->default_map) { 5922 1.10 christos for_each_link(info->valid_links, i) { 5923 1.10 christos char uplink_map_str[9]; 5924 1.10 christos char downlink_map_str[9]; 5925 1.10 christos 5926 1.10 christos bitmap_to_str(info->t2lmap[i].uplink, uplink_map_str); 5927 1.10 christos bitmap_to_str(info->t2lmap[i].downlink, 5928 1.10 christos downlink_map_str); 5929 1.10 christos 5930 1.10 christos res = os_snprintf(pos, end - pos, 5931 1.10 christos " link_id=%d up_link=%s down_link=%s", 5932 1.10 christos i, uplink_map_str, 5933 1.10 christos downlink_map_str); 5934 1.10 christos if (os_snprintf_error(end - pos, res)) 5935 1.10 christos return; 5936 1.10 christos pos += res; 5937 1.10 christos } 5938 1.10 christos } 5939 1.10 christos 5940 1.10 christos wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_T2LM_UPDATE "%s", map_info); 5941 1.10 christos } 5942 1.10 christos 5943 1.10 christos 5944 1.10 christos static void wpas_link_reconfig(struct wpa_supplicant *wpa_s) 5945 1.10 christos { 5946 1.10 christos u8 bssid[ETH_ALEN]; 5947 1.10 christos 5948 1.10 christos if (wpa_drv_get_bssid(wpa_s, bssid) < 0) { 5949 1.10 christos wpa_printf(MSG_ERROR, "LINK_RECONFIG: Failed to get BSSID"); 5950 1.10 christos wpa_supplicant_deauthenticate(wpa_s, 5951 1.10 christos WLAN_REASON_DEAUTH_LEAVING); 5952 1.10 christos return; 5953 1.10 christos } 5954 1.10 christos 5955 1.10 christos if (!ether_addr_equal(bssid, wpa_s->bssid)) { 5956 1.10 christos os_memcpy(wpa_s->bssid, bssid, ETH_ALEN); 5957 1.10 christos wpa_supplicant_update_current_bss(wpa_s, wpa_s->bssid); 5958 1.10 christos wpas_notify_bssid_changed(wpa_s); 5959 1.10 christos } 5960 1.10 christos 5961 1.10 christos if (wpa_drv_get_mlo_info(wpa_s) < 0) { 5962 1.10 christos wpa_printf(MSG_ERROR, 5963 1.10 christos "LINK_RECONFIG: Failed to get MLO connection info"); 5964 1.10 christos wpa_supplicant_deauthenticate(wpa_s, 5965 1.10 christos WLAN_REASON_DEAUTH_LEAVING); 5966 1.10 christos return; 5967 1.10 christos } 5968 1.10 christos 5969 1.10 christos if (wpa_sm_set_ml_info(wpa_s)) { 5970 1.10 christos wpa_printf(MSG_ERROR, 5971 1.10 christos "LINK_RECONFIG: Failed to set MLO connection info to wpa_sm"); 5972 1.10 christos wpa_supplicant_deauthenticate(wpa_s, 5973 1.10 christos WLAN_REASON_DEAUTH_LEAVING); 5974 1.10 christos return; 5975 1.10 christos } 5976 1.10 christos 5977 1.10 christos wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_LINK_RECONFIG "valid_links=0x%x", 5978 1.10 christos wpa_s->valid_links); 5979 1.10 christos } 5980 1.10 christos 5981 1.10 christos 5982 1.1 christos void wpa_supplicant_event(void *ctx, enum wpa_event_type event, 5983 1.1 christos union wpa_event_data *data) 5984 1.1 christos { 5985 1.1 christos struct wpa_supplicant *wpa_s = ctx; 5986 1.6 christos int resched; 5987 1.10 christos struct os_reltime age, clear_at; 5988 1.7 christos #ifndef CONFIG_NO_STDOUT_DEBUG 5989 1.7 christos int level = MSG_DEBUG; 5990 1.7 christos #endif /* CONFIG_NO_STDOUT_DEBUG */ 5991 1.2 joerg 5992 1.2 joerg if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED && 5993 1.2 joerg event != EVENT_INTERFACE_ENABLED && 5994 1.2 joerg event != EVENT_INTERFACE_STATUS && 5995 1.6 christos event != EVENT_SCAN_RESULTS && 5996 1.2 joerg event != EVENT_SCHED_SCAN_STOPPED) { 5997 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, 5998 1.2 joerg "Ignore event %s (%d) while interface is disabled", 5999 1.2 joerg event_to_string(event), event); 6000 1.2 joerg return; 6001 1.2 joerg } 6002 1.2 joerg 6003 1.2 joerg #ifndef CONFIG_NO_STDOUT_DEBUG 6004 1.2 joerg if (event == EVENT_RX_MGMT && data->rx_mgmt.frame_len >= 24) { 6005 1.2 joerg const struct ieee80211_hdr *hdr; 6006 1.2 joerg u16 fc; 6007 1.2 joerg hdr = (const struct ieee80211_hdr *) data->rx_mgmt.frame; 6008 1.2 joerg fc = le_to_host16(hdr->frame_control); 6009 1.2 joerg if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && 6010 1.2 joerg WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON) 6011 1.2 joerg level = MSG_EXCESSIVE; 6012 1.2 joerg } 6013 1.2 joerg 6014 1.2 joerg wpa_dbg(wpa_s, level, "Event %s (%d) received", 6015 1.2 joerg event_to_string(event), event); 6016 1.2 joerg #endif /* CONFIG_NO_STDOUT_DEBUG */ 6017 1.1 christos 6018 1.1 christos switch (event) { 6019 1.1 christos case EVENT_AUTH: 6020 1.6 christos #ifdef CONFIG_FST 6021 1.6 christos if (!wpas_fst_update_mbie(wpa_s, data->auth.ies, 6022 1.6 christos data->auth.ies_len)) 6023 1.6 christos wpa_printf(MSG_DEBUG, 6024 1.6 christos "FST: MB IEs updated from auth IE"); 6025 1.6 christos #endif /* CONFIG_FST */ 6026 1.1 christos sme_event_auth(wpa_s, data); 6027 1.9 christos wpa_s->auth_status_code = data->auth.status_code; 6028 1.9 christos wpas_notify_auth_status_code(wpa_s); 6029 1.1 christos break; 6030 1.1 christos case EVENT_ASSOC: 6031 1.6 christos #ifdef CONFIG_TESTING_OPTIONS 6032 1.6 christos if (wpa_s->ignore_auth_resp) { 6033 1.6 christos wpa_printf(MSG_INFO, 6034 1.6 christos "EVENT_ASSOC - ignore_auth_resp active!"); 6035 1.6 christos break; 6036 1.6 christos } 6037 1.7 christos if (wpa_s->testing_resend_assoc) { 6038 1.7 christos wpa_printf(MSG_INFO, 6039 1.7 christos "EVENT_DEAUTH - testing_resend_assoc"); 6040 1.7 christos break; 6041 1.7 christos } 6042 1.6 christos #endif /* CONFIG_TESTING_OPTIONS */ 6043 1.10 christos if (wpa_s->disconnected) { 6044 1.10 christos wpa_printf(MSG_INFO, 6045 1.10 christos "Ignore unexpected EVENT_ASSOC in disconnected state"); 6046 1.10 christos break; 6047 1.10 christos } 6048 1.1 christos wpa_supplicant_event_assoc(wpa_s, data); 6049 1.7 christos wpa_s->assoc_status_code = WLAN_STATUS_SUCCESS; 6050 1.7 christos if (data && 6051 1.7 christos (data->assoc_info.authorized || 6052 1.7 christos (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) && 6053 1.7 christos wpa_fils_is_completed(wpa_s->wpa)))) 6054 1.3 christos wpa_supplicant_event_assoc_auth(wpa_s, data); 6055 1.6 christos if (data) { 6056 1.6 christos wpa_msg(wpa_s, MSG_INFO, 6057 1.6 christos WPA_EVENT_SUBNET_STATUS_UPDATE "status=%u", 6058 1.6 christos data->assoc_info.subnet_status); 6059 1.6 christos } 6060 1.1 christos break; 6061 1.1 christos case EVENT_DISASSOC: 6062 1.2 joerg wpas_event_disassoc(wpa_s, 6063 1.2 joerg data ? &data->disassoc_info : NULL); 6064 1.2 joerg break; 6065 1.1 christos case EVENT_DEAUTH: 6066 1.6 christos #ifdef CONFIG_TESTING_OPTIONS 6067 1.6 christos if (wpa_s->ignore_auth_resp) { 6068 1.6 christos wpa_printf(MSG_INFO, 6069 1.6 christos "EVENT_DEAUTH - ignore_auth_resp active!"); 6070 1.6 christos break; 6071 1.6 christos } 6072 1.7 christos if (wpa_s->testing_resend_assoc) { 6073 1.7 christos wpa_printf(MSG_INFO, 6074 1.7 christos "EVENT_DEAUTH - testing_resend_assoc"); 6075 1.7 christos break; 6076 1.7 christos } 6077 1.6 christos #endif /* CONFIG_TESTING_OPTIONS */ 6078 1.2 joerg wpas_event_deauth(wpa_s, 6079 1.2 joerg data ? &data->deauth_info : NULL); 6080 1.1 christos break; 6081 1.10 christos case EVENT_LINK_RECONFIG: 6082 1.10 christos wpas_link_reconfig(wpa_s); 6083 1.10 christos break; 6084 1.1 christos case EVENT_MICHAEL_MIC_FAILURE: 6085 1.1 christos wpa_supplicant_event_michael_mic_failure(wpa_s, data); 6086 1.1 christos break; 6087 1.1 christos #ifndef CONFIG_NO_SCAN_PROCESSING 6088 1.2 joerg case EVENT_SCAN_STARTED: 6089 1.6 christos if (wpa_s->own_scan_requested || 6090 1.6 christos (data && !data->scan_info.external_scan)) { 6091 1.2 joerg struct os_reltime diff; 6092 1.2 joerg 6093 1.6 christos os_get_reltime(&wpa_s->scan_start_time); 6094 1.2 joerg os_reltime_sub(&wpa_s->scan_start_time, 6095 1.2 joerg &wpa_s->scan_trigger_time, &diff); 6096 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Own scan request started a scan in %jd.%06ld seconds", 6097 1.2 joerg (intmax_t)diff.sec, (long)diff.usec); 6098 1.2 joerg wpa_s->own_scan_requested = 0; 6099 1.2 joerg wpa_s->own_scan_running = 1; 6100 1.2 joerg if (wpa_s->last_scan_req == MANUAL_SCAN_REQ && 6101 1.2 joerg wpa_s->manual_scan_use_id) { 6102 1.2 joerg wpa_msg_ctrl(wpa_s, MSG_INFO, 6103 1.2 joerg WPA_EVENT_SCAN_STARTED "id=%u", 6104 1.2 joerg wpa_s->manual_scan_id); 6105 1.2 joerg } else { 6106 1.2 joerg wpa_msg_ctrl(wpa_s, MSG_INFO, 6107 1.2 joerg WPA_EVENT_SCAN_STARTED); 6108 1.2 joerg } 6109 1.2 joerg } else { 6110 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "External program started a scan"); 6111 1.10 christos wpa_s->radio->external_scan_req_interface = wpa_s; 6112 1.2 joerg wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_STARTED); 6113 1.2 joerg } 6114 1.2 joerg break; 6115 1.1 christos case EVENT_SCAN_RESULTS: 6116 1.6 christos if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { 6117 1.6 christos wpa_s->scan_res_handler = NULL; 6118 1.6 christos wpa_s->own_scan_running = 0; 6119 1.10 christos wpa_s->radio->external_scan_req_interface = NULL; 6120 1.6 christos wpa_s->last_scan_req = NORMAL_SCAN_REQ; 6121 1.6 christos break; 6122 1.6 christos } 6123 1.6 christos 6124 1.6 christos if (!(data && data->scan_info.external_scan) && 6125 1.6 christos os_reltime_initialized(&wpa_s->scan_start_time)) { 6126 1.2 joerg struct os_reltime now, diff; 6127 1.2 joerg os_get_reltime(&now); 6128 1.2 joerg os_reltime_sub(&now, &wpa_s->scan_start_time, &diff); 6129 1.2 joerg wpa_s->scan_start_time.sec = 0; 6130 1.2 joerg wpa_s->scan_start_time.usec = 0; 6131 1.10 christos wpa_s->wps_scan_done = true; 6132 1.11 christos wpa_dbg(wpa_s, MSG_DEBUG, "Scan completed in %jd.%06ld seconds", 6133 1.11 christos (intmax_t)diff.sec, (long)diff.usec); 6134 1.2 joerg } 6135 1.3 christos if (wpa_supplicant_event_scan_results(wpa_s, data)) 6136 1.3 christos break; /* interface may have been removed */ 6137 1.6 christos if (!(data && data->scan_info.external_scan)) 6138 1.6 christos wpa_s->own_scan_running = 0; 6139 1.6 christos if (data && data->scan_info.nl_scan_event) 6140 1.10 christos wpa_s->radio->external_scan_req_interface = NULL; 6141 1.2 joerg radio_work_check_next(wpa_s); 6142 1.1 christos break; 6143 1.1 christos #endif /* CONFIG_NO_SCAN_PROCESSING */ 6144 1.1 christos case EVENT_ASSOCINFO: 6145 1.1 christos wpa_supplicant_event_associnfo(wpa_s, data); 6146 1.1 christos break; 6147 1.1 christos case EVENT_INTERFACE_STATUS: 6148 1.1 christos wpa_supplicant_event_interface_status(wpa_s, data); 6149 1.1 christos break; 6150 1.1 christos case EVENT_PMKID_CANDIDATE: 6151 1.1 christos wpa_supplicant_event_pmkid_candidate(wpa_s, data); 6152 1.1 christos break; 6153 1.2 joerg #ifdef CONFIG_TDLS 6154 1.2 joerg case EVENT_TDLS: 6155 1.2 joerg wpa_supplicant_event_tdls(wpa_s, data); 6156 1.2 joerg break; 6157 1.2 joerg #endif /* CONFIG_TDLS */ 6158 1.2 joerg #ifdef CONFIG_WNM 6159 1.2 joerg case EVENT_WNM: 6160 1.2 joerg wpa_supplicant_event_wnm(wpa_s, data); 6161 1.2 joerg break; 6162 1.2 joerg #endif /* CONFIG_WNM */ 6163 1.1 christos #ifdef CONFIG_IEEE80211R 6164 1.1 christos case EVENT_FT_RESPONSE: 6165 1.1 christos wpa_supplicant_event_ft_response(wpa_s, data); 6166 1.1 christos break; 6167 1.1 christos #endif /* CONFIG_IEEE80211R */ 6168 1.1 christos #ifdef CONFIG_IBSS_RSN 6169 1.1 christos case EVENT_IBSS_RSN_START: 6170 1.1 christos wpa_supplicant_event_ibss_rsn_start(wpa_s, data); 6171 1.1 christos break; 6172 1.1 christos #endif /* CONFIG_IBSS_RSN */ 6173 1.1 christos case EVENT_ASSOC_REJECT: 6174 1.7 christos wpas_event_assoc_reject(wpa_s, data); 6175 1.1 christos break; 6176 1.1 christos case EVENT_AUTH_TIMED_OUT: 6177 1.3 christos /* It is possible to get this event from earlier connection */ 6178 1.3 christos if (wpa_s->current_ssid && 6179 1.3 christos wpa_s->current_ssid->mode == WPAS_MODE_MESH) { 6180 1.3 christos wpa_dbg(wpa_s, MSG_DEBUG, 6181 1.3 christos "Ignore AUTH_TIMED_OUT in mesh configuration"); 6182 1.3 christos break; 6183 1.3 christos } 6184 1.2 joerg if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) 6185 1.2 joerg sme_event_auth_timed_out(wpa_s, data); 6186 1.1 christos break; 6187 1.1 christos case EVENT_ASSOC_TIMED_OUT: 6188 1.3 christos /* It is possible to get this event from earlier connection */ 6189 1.3 christos if (wpa_s->current_ssid && 6190 1.3 christos wpa_s->current_ssid->mode == WPAS_MODE_MESH) { 6191 1.3 christos wpa_dbg(wpa_s, MSG_DEBUG, 6192 1.3 christos "Ignore ASSOC_TIMED_OUT in mesh configuration"); 6193 1.3 christos break; 6194 1.3 christos } 6195 1.2 joerg if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) 6196 1.2 joerg sme_event_assoc_timed_out(wpa_s, data); 6197 1.1 christos break; 6198 1.2 joerg case EVENT_TX_STATUS: 6199 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "EVENT_TX_STATUS dst=" MACSTR 6200 1.2 joerg " type=%d stype=%d", 6201 1.2 joerg MAC2STR(data->tx_status.dst), 6202 1.2 joerg data->tx_status.type, data->tx_status.stype); 6203 1.10 christos #ifdef CONFIG_WNM 6204 1.10 christos if (data->tx_status.type == WLAN_FC_TYPE_MGMT && 6205 1.10 christos data->tx_status.stype == WLAN_FC_STYPE_ACTION && 6206 1.10 christos wnm_btm_resp_tx_status(wpa_s, data->tx_status.data, 6207 1.10 christos data->tx_status.data_len) == 0) 6208 1.10 christos break; 6209 1.10 christos #endif /* CONFIG_WNM */ 6210 1.10 christos #ifdef CONFIG_PASN 6211 1.10 christos if (data->tx_status.type == WLAN_FC_TYPE_MGMT && 6212 1.10 christos data->tx_status.stype == WLAN_FC_STYPE_AUTH && 6213 1.10 christos wpas_pasn_auth_tx_status(wpa_s, data->tx_status.data, 6214 1.10 christos data->tx_status.data_len, 6215 1.10 christos data->tx_status.ack) == 0) 6216 1.10 christos break; 6217 1.10 christos #endif /* CONFIG_PASN */ 6218 1.1 christos #ifdef CONFIG_AP 6219 1.2 joerg if (wpa_s->ap_iface == NULL) { 6220 1.2 joerg #ifdef CONFIG_OFFCHANNEL 6221 1.2 joerg if (data->tx_status.type == WLAN_FC_TYPE_MGMT && 6222 1.2 joerg data->tx_status.stype == WLAN_FC_STYPE_ACTION) 6223 1.2 joerg offchannel_send_action_tx_status( 6224 1.2 joerg wpa_s, data->tx_status.dst, 6225 1.2 joerg data->tx_status.data, 6226 1.2 joerg data->tx_status.data_len, 6227 1.2 joerg data->tx_status.ack ? 6228 1.2 joerg OFFCHANNEL_SEND_ACTION_SUCCESS : 6229 1.2 joerg OFFCHANNEL_SEND_ACTION_NO_ACK); 6230 1.2 joerg #endif /* CONFIG_OFFCHANNEL */ 6231 1.2 joerg break; 6232 1.2 joerg } 6233 1.2 joerg #endif /* CONFIG_AP */ 6234 1.2 joerg #ifdef CONFIG_OFFCHANNEL 6235 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "EVENT_TX_STATUS pending_dst=" 6236 1.6 christos MACSTR, MAC2STR(wpa_s->p2pdev->pending_action_dst)); 6237 1.2 joerg /* 6238 1.2 joerg * Catch TX status events for Action frames we sent via group 6239 1.6 christos * interface in GO mode, or via standalone AP interface. 6240 1.6 christos * Note, wpa_s->p2pdev will be the same as wpa_s->parent, 6241 1.6 christos * except when the primary interface is used as a GO interface 6242 1.6 christos * (for drivers which do not have group interface concurrency) 6243 1.2 joerg */ 6244 1.2 joerg if (data->tx_status.type == WLAN_FC_TYPE_MGMT && 6245 1.2 joerg data->tx_status.stype == WLAN_FC_STYPE_ACTION && 6246 1.10 christos ether_addr_equal(wpa_s->p2pdev->pending_action_dst, 6247 1.10 christos data->tx_status.dst)) { 6248 1.2 joerg offchannel_send_action_tx_status( 6249 1.6 christos wpa_s->p2pdev, data->tx_status.dst, 6250 1.2 joerg data->tx_status.data, 6251 1.2 joerg data->tx_status.data_len, 6252 1.2 joerg data->tx_status.ack ? 6253 1.2 joerg OFFCHANNEL_SEND_ACTION_SUCCESS : 6254 1.2 joerg OFFCHANNEL_SEND_ACTION_NO_ACK); 6255 1.1 christos break; 6256 1.2 joerg } 6257 1.2 joerg #endif /* CONFIG_OFFCHANNEL */ 6258 1.2 joerg #ifdef CONFIG_AP 6259 1.1 christos switch (data->tx_status.type) { 6260 1.1 christos case WLAN_FC_TYPE_MGMT: 6261 1.1 christos ap_mgmt_tx_cb(wpa_s, data->tx_status.data, 6262 1.1 christos data->tx_status.data_len, 6263 1.1 christos data->tx_status.stype, 6264 1.1 christos data->tx_status.ack); 6265 1.1 christos break; 6266 1.1 christos case WLAN_FC_TYPE_DATA: 6267 1.1 christos ap_tx_status(wpa_s, data->tx_status.dst, 6268 1.1 christos data->tx_status.data, 6269 1.1 christos data->tx_status.data_len, 6270 1.1 christos data->tx_status.ack); 6271 1.1 christos break; 6272 1.1 christos } 6273 1.2 joerg #endif /* CONFIG_AP */ 6274 1.2 joerg break; 6275 1.2 joerg #ifdef CONFIG_AP 6276 1.2 joerg case EVENT_EAPOL_TX_STATUS: 6277 1.2 joerg ap_eapol_tx_status(wpa_s, data->eapol_tx_status.dst, 6278 1.2 joerg data->eapol_tx_status.data, 6279 1.2 joerg data->eapol_tx_status.data_len, 6280 1.2 joerg data->eapol_tx_status.ack); 6281 1.2 joerg break; 6282 1.2 joerg case EVENT_DRIVER_CLIENT_POLL_OK: 6283 1.2 joerg ap_client_poll_ok(wpa_s, data->client_poll.addr); 6284 1.1 christos break; 6285 1.1 christos case EVENT_RX_FROM_UNKNOWN: 6286 1.1 christos if (wpa_s->ap_iface == NULL) 6287 1.1 christos break; 6288 1.2 joerg ap_rx_from_unknown_sta(wpa_s, data->rx_from_unknown.addr, 6289 1.2 joerg data->rx_from_unknown.wds); 6290 1.1 christos break; 6291 1.7 christos #endif /* CONFIG_AP */ 6292 1.9 christos 6293 1.10 christos case EVENT_LINK_CH_SWITCH_STARTED: 6294 1.10 christos case EVENT_LINK_CH_SWITCH: 6295 1.10 christos if (!data || !wpa_s->current_ssid || 6296 1.10 christos !(wpa_s->valid_links & BIT(data->ch_switch.link_id))) 6297 1.10 christos break; 6298 1.10 christos 6299 1.10 christos wpa_msg(wpa_s, MSG_INFO, 6300 1.10 christos "%sfreq=%d link_id=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d", 6301 1.10 christos event == EVENT_LINK_CH_SWITCH ? 6302 1.10 christos WPA_EVENT_LINK_CHANNEL_SWITCH : 6303 1.10 christos WPA_EVENT_LINK_CHANNEL_SWITCH_STARTED, 6304 1.10 christos data->ch_switch.freq, 6305 1.10 christos data->ch_switch.link_id, 6306 1.10 christos data->ch_switch.ht_enabled, 6307 1.10 christos data->ch_switch.ch_offset, 6308 1.10 christos channel_width_to_string(data->ch_switch.ch_width), 6309 1.10 christos data->ch_switch.cf1, 6310 1.10 christos data->ch_switch.cf2); 6311 1.10 christos if (event == EVENT_LINK_CH_SWITCH_STARTED) 6312 1.10 christos break; 6313 1.10 christos 6314 1.10 christos wpa_s->links[data->ch_switch.link_id].freq = 6315 1.10 christos data->ch_switch.freq; 6316 1.10 christos if (wpa_s->links[data->ch_switch.link_id].bss && 6317 1.10 christos wpa_s->links[data->ch_switch.link_id].bss->freq != 6318 1.10 christos data->ch_switch.freq) { 6319 1.10 christos wpa_s->links[data->ch_switch.link_id].bss->freq = 6320 1.10 christos data->ch_switch.freq; 6321 1.10 christos notify_bss_changes( 6322 1.10 christos wpa_s, WPA_BSS_FREQ_CHANGED_FLAG, 6323 1.10 christos wpa_s->links[data->ch_switch.link_id].bss); 6324 1.10 christos } 6325 1.10 christos break; 6326 1.9 christos case EVENT_CH_SWITCH_STARTED: 6327 1.2 joerg case EVENT_CH_SWITCH: 6328 1.6 christos if (!data || !wpa_s->current_ssid) 6329 1.1 christos break; 6330 1.6 christos 6331 1.9 christos wpa_msg(wpa_s, MSG_INFO, 6332 1.9 christos "%sfreq=%d ht_enabled=%d ch_offset=%d ch_width=%s cf1=%d cf2=%d", 6333 1.9 christos event == EVENT_CH_SWITCH ? WPA_EVENT_CHANNEL_SWITCH : 6334 1.9 christos WPA_EVENT_CHANNEL_SWITCH_STARTED, 6335 1.6 christos data->ch_switch.freq, 6336 1.6 christos data->ch_switch.ht_enabled, 6337 1.6 christos data->ch_switch.ch_offset, 6338 1.6 christos channel_width_to_string(data->ch_switch.ch_width), 6339 1.6 christos data->ch_switch.cf1, 6340 1.6 christos data->ch_switch.cf2); 6341 1.9 christos if (event == EVENT_CH_SWITCH_STARTED) 6342 1.9 christos break; 6343 1.6 christos 6344 1.6 christos wpa_s->assoc_freq = data->ch_switch.freq; 6345 1.6 christos wpa_s->current_ssid->frequency = data->ch_switch.freq; 6346 1.10 christos if (wpa_s->current_bss && 6347 1.10 christos wpa_s->current_bss->freq != data->ch_switch.freq) { 6348 1.10 christos wpa_s->current_bss->freq = data->ch_switch.freq; 6349 1.10 christos notify_bss_changes(wpa_s, WPA_BSS_FREQ_CHANGED_FLAG, 6350 1.10 christos wpa_s->current_bss); 6351 1.10 christos } 6352 1.10 christos 6353 1.10 christos #ifdef CONFIG_SME 6354 1.10 christos switch (data->ch_switch.ch_offset) { 6355 1.10 christos case 1: 6356 1.10 christos wpa_s->sme.ht_sec_chan = HT_SEC_CHAN_ABOVE; 6357 1.10 christos break; 6358 1.10 christos case -1: 6359 1.10 christos wpa_s->sme.ht_sec_chan = HT_SEC_CHAN_BELOW; 6360 1.10 christos break; 6361 1.10 christos default: 6362 1.10 christos wpa_s->sme.ht_sec_chan = HT_SEC_CHAN_UNKNOWN; 6363 1.10 christos break; 6364 1.10 christos } 6365 1.10 christos #endif /* CONFIG_SME */ 6366 1.6 christos 6367 1.7 christos #ifdef CONFIG_AP 6368 1.6 christos if (wpa_s->current_ssid->mode == WPAS_MODE_AP || 6369 1.6 christos wpa_s->current_ssid->mode == WPAS_MODE_P2P_GO || 6370 1.9 christos wpa_s->current_ssid->mode == WPAS_MODE_MESH || 6371 1.6 christos wpa_s->current_ssid->mode == 6372 1.6 christos WPAS_MODE_P2P_GROUP_FORMATION) { 6373 1.6 christos wpas_ap_ch_switch(wpa_s, data->ch_switch.freq, 6374 1.6 christos data->ch_switch.ht_enabled, 6375 1.6 christos data->ch_switch.ch_offset, 6376 1.6 christos data->ch_switch.ch_width, 6377 1.6 christos data->ch_switch.cf1, 6378 1.9 christos data->ch_switch.cf2, 6379 1.10 christos data->ch_switch.punct_bitmap, 6380 1.9 christos 1); 6381 1.2 joerg } 6382 1.7 christos #endif /* CONFIG_AP */ 6383 1.2 joerg 6384 1.10 christos if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) 6385 1.10 christos sme_event_ch_switch(wpa_s); 6386 1.10 christos 6387 1.6 christos wpas_p2p_update_channel_list(wpa_s, WPAS_P2P_CHANNEL_UPDATE_CS); 6388 1.7 christos wnm_clear_coloc_intf_reporting(wpa_s); 6389 1.1 christos break; 6390 1.7 christos #ifdef CONFIG_AP 6391 1.3 christos #ifdef NEED_AP_MLME 6392 1.3 christos case EVENT_DFS_RADAR_DETECTED: 6393 1.3 christos if (data) 6394 1.7 christos wpas_ap_event_dfs_radar_detected(wpa_s, 6395 1.7 christos &data->dfs_event); 6396 1.3 christos break; 6397 1.7 christos case EVENT_DFS_NOP_FINISHED: 6398 1.7 christos if (data) 6399 1.7 christos wpas_ap_event_dfs_cac_nop_finished(wpa_s, 6400 1.7 christos &data->dfs_event); 6401 1.7 christos break; 6402 1.7 christos #endif /* NEED_AP_MLME */ 6403 1.7 christos #endif /* CONFIG_AP */ 6404 1.3 christos case EVENT_DFS_CAC_STARTED: 6405 1.3 christos if (data) 6406 1.3 christos wpas_event_dfs_cac_started(wpa_s, &data->dfs_event); 6407 1.3 christos break; 6408 1.3 christos case EVENT_DFS_CAC_FINISHED: 6409 1.3 christos if (data) 6410 1.3 christos wpas_event_dfs_cac_finished(wpa_s, &data->dfs_event); 6411 1.3 christos break; 6412 1.3 christos case EVENT_DFS_CAC_ABORTED: 6413 1.3 christos if (data) 6414 1.3 christos wpas_event_dfs_cac_aborted(wpa_s, &data->dfs_event); 6415 1.3 christos break; 6416 1.2 joerg case EVENT_RX_MGMT: { 6417 1.2 joerg u16 fc, stype; 6418 1.2 joerg const struct ieee80211_mgmt *mgmt; 6419 1.2 joerg 6420 1.2 joerg #ifdef CONFIG_TESTING_OPTIONS 6421 1.2 joerg if (wpa_s->ext_mgmt_frame_handling) { 6422 1.2 joerg struct rx_mgmt *rx = &data->rx_mgmt; 6423 1.2 joerg size_t hex_len = 2 * rx->frame_len + 1; 6424 1.2 joerg char *hex = os_malloc(hex_len); 6425 1.2 joerg if (hex) { 6426 1.2 joerg wpa_snprintf_hex(hex, hex_len, 6427 1.2 joerg rx->frame, rx->frame_len); 6428 1.2 joerg wpa_msg(wpa_s, MSG_INFO, "MGMT-RX freq=%d datarate=%u ssi_signal=%d %s", 6429 1.2 joerg rx->freq, rx->datarate, rx->ssi_signal, 6430 1.2 joerg hex); 6431 1.2 joerg os_free(hex); 6432 1.2 joerg } 6433 1.2 joerg break; 6434 1.2 joerg } 6435 1.2 joerg #endif /* CONFIG_TESTING_OPTIONS */ 6436 1.2 joerg 6437 1.2 joerg mgmt = (const struct ieee80211_mgmt *) 6438 1.2 joerg data->rx_mgmt.frame; 6439 1.2 joerg fc = le_to_host16(mgmt->frame_control); 6440 1.2 joerg stype = WLAN_FC_GET_STYPE(fc); 6441 1.2 joerg 6442 1.2 joerg #ifdef CONFIG_AP 6443 1.2 joerg if (wpa_s->ap_iface == NULL) { 6444 1.2 joerg #endif /* CONFIG_AP */ 6445 1.2 joerg #ifdef CONFIG_P2P 6446 1.2 joerg if (stype == WLAN_FC_STYPE_PROBE_REQ && 6447 1.6 christos data->rx_mgmt.frame_len > IEEE80211_HDRLEN) { 6448 1.2 joerg const u8 *src = mgmt->sa; 6449 1.6 christos const u8 *ie; 6450 1.6 christos size_t ie_len; 6451 1.6 christos 6452 1.6 christos ie = data->rx_mgmt.frame + IEEE80211_HDRLEN; 6453 1.6 christos ie_len = data->rx_mgmt.frame_len - 6454 1.6 christos IEEE80211_HDRLEN; 6455 1.2 joerg wpas_p2p_probe_req_rx( 6456 1.2 joerg wpa_s, src, mgmt->da, 6457 1.2 joerg mgmt->bssid, ie, ie_len, 6458 1.6 christos data->rx_mgmt.freq, 6459 1.2 joerg data->rx_mgmt.ssi_signal); 6460 1.2 joerg break; 6461 1.2 joerg } 6462 1.2 joerg #endif /* CONFIG_P2P */ 6463 1.2 joerg #ifdef CONFIG_IBSS_RSN 6464 1.3 christos if (wpa_s->current_ssid && 6465 1.3 christos wpa_s->current_ssid->mode == WPAS_MODE_IBSS && 6466 1.3 christos stype == WLAN_FC_STYPE_AUTH && 6467 1.2 joerg data->rx_mgmt.frame_len >= 30) { 6468 1.2 joerg wpa_supplicant_event_ibss_auth(wpa_s, data); 6469 1.2 joerg break; 6470 1.2 joerg } 6471 1.2 joerg #endif /* CONFIG_IBSS_RSN */ 6472 1.2 joerg 6473 1.2 joerg if (stype == WLAN_FC_STYPE_ACTION) { 6474 1.2 joerg wpas_event_rx_mgmt_action( 6475 1.2 joerg wpa_s, data->rx_mgmt.frame, 6476 1.2 joerg data->rx_mgmt.frame_len, 6477 1.3 christos data->rx_mgmt.freq, 6478 1.3 christos data->rx_mgmt.ssi_signal); 6479 1.3 christos break; 6480 1.3 christos } 6481 1.3 christos 6482 1.3 christos if (wpa_s->ifmsh) { 6483 1.3 christos mesh_mpm_mgmt_rx(wpa_s, &data->rx_mgmt); 6484 1.2 joerg break; 6485 1.2 joerg } 6486 1.10 christos #ifdef CONFIG_PASN 6487 1.10 christos if (stype == WLAN_FC_STYPE_AUTH && 6488 1.10 christos wpas_pasn_auth_rx(wpa_s, mgmt, 6489 1.10 christos data->rx_mgmt.frame_len) != -2) 6490 1.10 christos break; 6491 1.10 christos #endif /* CONFIG_PASN */ 6492 1.2 joerg 6493 1.7 christos #ifdef CONFIG_SAE 6494 1.7 christos if (stype == WLAN_FC_STYPE_AUTH && 6495 1.7 christos !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) && 6496 1.7 christos (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE)) { 6497 1.7 christos sme_external_auth_mgmt_rx( 6498 1.7 christos wpa_s, data->rx_mgmt.frame, 6499 1.7 christos data->rx_mgmt.frame_len); 6500 1.7 christos break; 6501 1.7 christos } 6502 1.7 christos #endif /* CONFIG_SAE */ 6503 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "AP: ignore received " 6504 1.2 joerg "management frame in non-AP mode"); 6505 1.1 christos break; 6506 1.2 joerg #ifdef CONFIG_AP 6507 1.1 christos } 6508 1.2 joerg 6509 1.2 joerg if (stype == WLAN_FC_STYPE_PROBE_REQ && 6510 1.6 christos data->rx_mgmt.frame_len > IEEE80211_HDRLEN) { 6511 1.6 christos const u8 *ie; 6512 1.6 christos size_t ie_len; 6513 1.6 christos 6514 1.6 christos ie = data->rx_mgmt.frame + IEEE80211_HDRLEN; 6515 1.6 christos ie_len = data->rx_mgmt.frame_len - IEEE80211_HDRLEN; 6516 1.2 joerg 6517 1.2 joerg wpas_notify_preq(wpa_s, mgmt->sa, mgmt->da, 6518 1.2 joerg mgmt->bssid, ie, ie_len, 6519 1.2 joerg data->rx_mgmt.ssi_signal); 6520 1.2 joerg } 6521 1.2 joerg 6522 1.2 joerg ap_mgmt_rx(wpa_s, &data->rx_mgmt); 6523 1.2 joerg #endif /* CONFIG_AP */ 6524 1.1 christos break; 6525 1.2 joerg } 6526 1.2 joerg case EVENT_RX_PROBE_REQ: 6527 1.2 joerg if (data->rx_probe_req.sa == NULL || 6528 1.2 joerg data->rx_probe_req.ie == NULL) 6529 1.2 joerg break; 6530 1.2 joerg #ifdef CONFIG_AP 6531 1.2 joerg if (wpa_s->ap_iface) { 6532 1.2 joerg hostapd_probe_req_rx(wpa_s->ap_iface->bss[0], 6533 1.2 joerg data->rx_probe_req.sa, 6534 1.2 joerg data->rx_probe_req.da, 6535 1.2 joerg data->rx_probe_req.bssid, 6536 1.2 joerg data->rx_probe_req.ie, 6537 1.2 joerg data->rx_probe_req.ie_len, 6538 1.2 joerg data->rx_probe_req.ssi_signal); 6539 1.2 joerg break; 6540 1.2 joerg } 6541 1.2 joerg #endif /* CONFIG_AP */ 6542 1.2 joerg wpas_p2p_probe_req_rx(wpa_s, data->rx_probe_req.sa, 6543 1.2 joerg data->rx_probe_req.da, 6544 1.2 joerg data->rx_probe_req.bssid, 6545 1.2 joerg data->rx_probe_req.ie, 6546 1.2 joerg data->rx_probe_req.ie_len, 6547 1.6 christos 0, 6548 1.2 joerg data->rx_probe_req.ssi_signal); 6549 1.2 joerg break; 6550 1.2 joerg case EVENT_REMAIN_ON_CHANNEL: 6551 1.2 joerg #ifdef CONFIG_OFFCHANNEL 6552 1.2 joerg offchannel_remain_on_channel_cb( 6553 1.2 joerg wpa_s, data->remain_on_channel.freq, 6554 1.2 joerg data->remain_on_channel.duration); 6555 1.2 joerg #endif /* CONFIG_OFFCHANNEL */ 6556 1.2 joerg wpas_p2p_remain_on_channel_cb( 6557 1.2 joerg wpa_s, data->remain_on_channel.freq, 6558 1.2 joerg data->remain_on_channel.duration); 6559 1.10 christos #ifdef CONFIG_DPP 6560 1.10 christos wpas_dpp_remain_on_channel_cb( 6561 1.10 christos wpa_s, data->remain_on_channel.freq, 6562 1.10 christos data->remain_on_channel.duration); 6563 1.10 christos #endif /* CONFIG_DPP */ 6564 1.10 christos #ifdef CONFIG_NAN_USD 6565 1.10 christos wpas_nan_usd_remain_on_channel_cb( 6566 1.10 christos wpa_s, data->remain_on_channel.freq, 6567 1.10 christos data->remain_on_channel.duration); 6568 1.10 christos #endif /* CONFIG_NAN_USD */ 6569 1.2 joerg break; 6570 1.2 joerg case EVENT_CANCEL_REMAIN_ON_CHANNEL: 6571 1.2 joerg #ifdef CONFIG_OFFCHANNEL 6572 1.2 joerg offchannel_cancel_remain_on_channel_cb( 6573 1.2 joerg wpa_s, data->remain_on_channel.freq); 6574 1.2 joerg #endif /* CONFIG_OFFCHANNEL */ 6575 1.2 joerg wpas_p2p_cancel_remain_on_channel_cb( 6576 1.2 joerg wpa_s, data->remain_on_channel.freq); 6577 1.7 christos #ifdef CONFIG_DPP 6578 1.7 christos wpas_dpp_cancel_remain_on_channel_cb( 6579 1.7 christos wpa_s, data->remain_on_channel.freq); 6580 1.7 christos #endif /* CONFIG_DPP */ 6581 1.10 christos #ifdef CONFIG_NAN_USD 6582 1.10 christos wpas_nan_usd_cancel_remain_on_channel_cb( 6583 1.10 christos wpa_s, data->remain_on_channel.freq); 6584 1.10 christos #endif /* CONFIG_NAN_USD */ 6585 1.1 christos break; 6586 1.1 christos case EVENT_EAPOL_RX: 6587 1.1 christos wpa_supplicant_rx_eapol(wpa_s, data->eapol_rx.src, 6588 1.1 christos data->eapol_rx.data, 6589 1.10 christos data->eapol_rx.data_len, 6590 1.10 christos data->eapol_rx.encrypted); 6591 1.1 christos break; 6592 1.1 christos case EVENT_SIGNAL_CHANGE: 6593 1.2 joerg wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SIGNAL_CHANGE 6594 1.10 christos "above=%d signal=%d noise=%d txrate=%lu", 6595 1.2 joerg data->signal_change.above_threshold, 6596 1.10 christos data->signal_change.data.signal, 6597 1.2 joerg data->signal_change.current_noise, 6598 1.10 christos data->signal_change.data.current_tx_rate); 6599 1.3 christos wpa_bss_update_level(wpa_s->current_bss, 6600 1.10 christos data->signal_change.data.signal); 6601 1.1 christos bgscan_notify_signal_change( 6602 1.2 joerg wpa_s, data->signal_change.above_threshold, 6603 1.10 christos data->signal_change.data.signal, 6604 1.2 joerg data->signal_change.current_noise, 6605 1.10 christos data->signal_change.data.current_tx_rate); 6606 1.10 christos os_memcpy(&wpa_s->last_signal_info, data, 6607 1.10 christos sizeof(struct wpa_signal_info)); 6608 1.10 christos wpas_notify_signal_change(wpa_s); 6609 1.2 joerg break; 6610 1.7 christos case EVENT_INTERFACE_MAC_CHANGED: 6611 1.7 christos wpa_supplicant_update_mac_addr(wpa_s); 6612 1.10 christos wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL); 6613 1.7 christos break; 6614 1.2 joerg case EVENT_INTERFACE_ENABLED: 6615 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Interface was enabled"); 6616 1.2 joerg if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { 6617 1.10 christos u8 addr[ETH_ALEN]; 6618 1.10 christos 6619 1.10 christos eloop_cancel_timeout(wpas_clear_disabled_interface, 6620 1.10 christos wpa_s, NULL); 6621 1.10 christos os_memcpy(addr, wpa_s->own_addr, ETH_ALEN); 6622 1.2 joerg wpa_supplicant_update_mac_addr(wpa_s); 6623 1.10 christos if (!ether_addr_equal(addr, wpa_s->own_addr)) 6624 1.10 christos wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL); 6625 1.10 christos else 6626 1.10 christos wpa_sm_pmksa_cache_reconfig(wpa_s->wpa); 6627 1.9 christos wpa_supplicant_set_default_scan_ies(wpa_s); 6628 1.2 joerg if (wpa_s->p2p_mgmt) { 6629 1.2 joerg wpa_supplicant_set_state(wpa_s, 6630 1.2 joerg WPA_DISCONNECTED); 6631 1.2 joerg break; 6632 1.2 joerg } 6633 1.2 joerg 6634 1.2 joerg #ifdef CONFIG_AP 6635 1.2 joerg if (!wpa_s->ap_iface) { 6636 1.2 joerg wpa_supplicant_set_state(wpa_s, 6637 1.2 joerg WPA_DISCONNECTED); 6638 1.3 christos wpa_s->scan_req = NORMAL_SCAN_REQ; 6639 1.2 joerg wpa_supplicant_req_scan(wpa_s, 0, 0); 6640 1.2 joerg } else 6641 1.2 joerg wpa_supplicant_set_state(wpa_s, 6642 1.2 joerg WPA_COMPLETED); 6643 1.2 joerg #else /* CONFIG_AP */ 6644 1.2 joerg wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); 6645 1.2 joerg wpa_supplicant_req_scan(wpa_s, 0, 0); 6646 1.2 joerg #endif /* CONFIG_AP */ 6647 1.2 joerg } 6648 1.2 joerg break; 6649 1.2 joerg case EVENT_INTERFACE_DISABLED: 6650 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Interface was disabled"); 6651 1.2 joerg #ifdef CONFIG_P2P 6652 1.2 joerg if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO || 6653 1.2 joerg (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group && 6654 1.2 joerg wpa_s->current_ssid->mode == WPAS_MODE_P2P_GO)) { 6655 1.2 joerg /* 6656 1.3 christos * Mark interface disabled if this happens to end up not 6657 1.3 christos * being removed as a separate P2P group interface. 6658 1.3 christos */ 6659 1.3 christos wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED); 6660 1.3 christos /* 6661 1.2 joerg * The interface was externally disabled. Remove 6662 1.2 joerg * it assuming an external entity will start a 6663 1.2 joerg * new session if needed. 6664 1.2 joerg */ 6665 1.3 christos if (wpa_s->current_ssid && 6666 1.3 christos wpa_s->current_ssid->p2p_group) 6667 1.3 christos wpas_p2p_interface_unavailable(wpa_s); 6668 1.3 christos else 6669 1.3 christos wpas_p2p_disconnect(wpa_s); 6670 1.3 christos /* 6671 1.3 christos * wpa_s instance may have been freed, so must not use 6672 1.3 christos * it here anymore. 6673 1.3 christos */ 6674 1.2 joerg break; 6675 1.2 joerg } 6676 1.2 joerg if (wpa_s->p2p_scan_work && wpa_s->global->p2p && 6677 1.2 joerg p2p_in_progress(wpa_s->global->p2p) > 1) { 6678 1.2 joerg /* This radio work will be cancelled, so clear P2P 6679 1.2 joerg * state as well. 6680 1.2 joerg */ 6681 1.2 joerg p2p_stop_find(wpa_s->global->p2p); 6682 1.2 joerg } 6683 1.2 joerg #endif /* CONFIG_P2P */ 6684 1.2 joerg 6685 1.2 joerg if (wpa_s->wpa_state >= WPA_AUTHENTICATING) { 6686 1.2 joerg /* 6687 1.2 joerg * Indicate disconnection to keep ctrl_iface events 6688 1.2 joerg * consistent. 6689 1.2 joerg */ 6690 1.2 joerg wpa_supplicant_event_disassoc( 6691 1.2 joerg wpa_s, WLAN_REASON_DEAUTH_LEAVING, 1); 6692 1.2 joerg } 6693 1.2 joerg wpa_supplicant_mark_disassoc(wpa_s); 6694 1.10 christos os_reltime_age(&wpa_s->last_scan, &age); 6695 1.10 christos if (age.sec >= wpa_s->conf->scan_res_valid_for_connect) { 6696 1.10 christos clear_at.sec = wpa_s->conf->scan_res_valid_for_connect; 6697 1.10 christos clear_at.usec = 0; 6698 1.10 christos } else { 6699 1.10 christos struct os_reltime tmp; 6700 1.10 christos 6701 1.10 christos tmp.sec = wpa_s->conf->scan_res_valid_for_connect; 6702 1.10 christos tmp.usec = 0; 6703 1.10 christos os_reltime_sub(&tmp, &age, &clear_at); 6704 1.10 christos } 6705 1.10 christos eloop_register_timeout(clear_at.sec, clear_at.usec, 6706 1.10 christos wpas_clear_disabled_interface, 6707 1.10 christos wpa_s, NULL); 6708 1.2 joerg radio_remove_works(wpa_s, NULL, 0); 6709 1.2 joerg 6710 1.2 joerg wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED); 6711 1.2 joerg break; 6712 1.2 joerg case EVENT_CHANNEL_LIST_CHANGED: 6713 1.2 joerg wpa_supplicant_update_channel_list( 6714 1.2 joerg wpa_s, &data->channel_list_changed); 6715 1.2 joerg break; 6716 1.2 joerg case EVENT_INTERFACE_UNAVAILABLE: 6717 1.2 joerg wpas_p2p_interface_unavailable(wpa_s); 6718 1.2 joerg break; 6719 1.2 joerg case EVENT_BEST_CHANNEL: 6720 1.2 joerg wpa_dbg(wpa_s, MSG_DEBUG, "Best channel event received " 6721 1.2 joerg "(%d %d %d)", 6722 1.2 joerg data->best_chan.freq_24, data->best_chan.freq_5, 6723 1.2 joerg data->best_chan.freq_overall); 6724 1.2 joerg wpa_s->best_24_freq = data->best_chan.freq_24; 6725 1.2 joerg wpa_s->best_5_freq = data->best_chan.freq_5; 6726 1.2 joerg wpa_s->best_overall_freq = data->best_chan.freq_overall; 6727 1.2 joerg wpas_p2p_update_best_channels(wpa_s, data->best_chan.freq_24, 6728 1.2 joerg data->best_chan.freq_5, 6729 1.2 joerg data->best_chan.freq_overall); 6730 1.2 joerg break; 6731 1.2 joerg case EVENT_UNPROT_DEAUTH: 6732 1.2 joerg wpa_supplicant_event_unprot_deauth(wpa_s, 6733 1.2 joerg &data->unprot_deauth); 6734 1.2 joerg break; 6735 1.2 joerg case EVENT_UNPROT_DISASSOC: 6736 1.2 joerg wpa_supplicant_event_unprot_disassoc(wpa_s, 6737 1.2 joerg &data->unprot_disassoc); 6738 1.2 joerg break; 6739 1.2 joerg case EVENT_STATION_LOW_ACK: 6740 1.2 joerg #ifdef CONFIG_AP 6741 1.2 joerg if (wpa_s->ap_iface && data) 6742 1.2 joerg hostapd_event_sta_low_ack(wpa_s->ap_iface->bss[0], 6743 1.2 joerg data->low_ack.addr); 6744 1.2 joerg #endif /* CONFIG_AP */ 6745 1.2 joerg #ifdef CONFIG_TDLS 6746 1.2 joerg if (data) 6747 1.2 joerg wpa_tdls_disable_unreachable_link(wpa_s->wpa, 6748 1.2 joerg data->low_ack.addr); 6749 1.2 joerg #endif /* CONFIG_TDLS */ 6750 1.2 joerg break; 6751 1.2 joerg case EVENT_IBSS_PEER_LOST: 6752 1.2 joerg #ifdef CONFIG_IBSS_RSN 6753 1.2 joerg ibss_rsn_stop(wpa_s->ibss_rsn, data->ibss_peer_lost.peer); 6754 1.2 joerg #endif /* CONFIG_IBSS_RSN */ 6755 1.2 joerg break; 6756 1.2 joerg case EVENT_DRIVER_GTK_REKEY: 6757 1.10 christos if (!ether_addr_equal(data->driver_gtk_rekey.bssid, 6758 1.10 christos wpa_s->bssid)) 6759 1.2 joerg break; 6760 1.2 joerg if (!wpa_s->wpa) 6761 1.2 joerg break; 6762 1.2 joerg wpa_sm_update_replay_ctr(wpa_s->wpa, 6763 1.2 joerg data->driver_gtk_rekey.replay_ctr); 6764 1.2 joerg break; 6765 1.2 joerg case EVENT_SCHED_SCAN_STOPPED: 6766 1.2 joerg wpa_s->sched_scanning = 0; 6767 1.6 christos resched = wpa_s->scanning && wpas_scan_scheduled(wpa_s); 6768 1.2 joerg wpa_supplicant_notify_scanning(wpa_s, 0); 6769 1.2 joerg 6770 1.2 joerg if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) 6771 1.2 joerg break; 6772 1.2 joerg 6773 1.2 joerg /* 6774 1.6 christos * If the driver stopped scanning without being requested to, 6775 1.6 christos * request a new scan to continue scanning for networks. 6776 1.6 christos */ 6777 1.6 christos if (!wpa_s->sched_scan_stop_req && 6778 1.6 christos wpa_s->wpa_state == WPA_SCANNING) { 6779 1.6 christos wpa_dbg(wpa_s, MSG_DEBUG, 6780 1.6 christos "Restart scanning after unexpected sched_scan stop event"); 6781 1.6 christos wpa_supplicant_req_scan(wpa_s, 1, 0); 6782 1.6 christos break; 6783 1.6 christos } 6784 1.6 christos 6785 1.6 christos wpa_s->sched_scan_stop_req = 0; 6786 1.6 christos 6787 1.6 christos /* 6788 1.2 joerg * Start a new sched scan to continue searching for more SSIDs 6789 1.2 joerg * either if timed out or PNO schedule scan is pending. 6790 1.2 joerg */ 6791 1.2 joerg if (wpa_s->sched_scan_timed_out) { 6792 1.2 joerg wpa_supplicant_req_sched_scan(wpa_s); 6793 1.2 joerg } else if (wpa_s->pno_sched_pending) { 6794 1.2 joerg wpa_s->pno_sched_pending = 0; 6795 1.2 joerg wpas_start_pno(wpa_s); 6796 1.6 christos } else if (resched) { 6797 1.6 christos wpa_supplicant_req_scan(wpa_s, 0, 0); 6798 1.2 joerg } 6799 1.2 joerg 6800 1.2 joerg break; 6801 1.2 joerg case EVENT_WPS_BUTTON_PUSHED: 6802 1.2 joerg #ifdef CONFIG_WPS 6803 1.9 christos wpas_wps_start_pbc(wpa_s, NULL, 0, 0); 6804 1.2 joerg #endif /* CONFIG_WPS */ 6805 1.2 joerg break; 6806 1.2 joerg case EVENT_AVOID_FREQUENCIES: 6807 1.2 joerg wpa_supplicant_notify_avoid_freq(wpa_s, data); 6808 1.2 joerg break; 6809 1.2 joerg case EVENT_CONNECT_FAILED_REASON: 6810 1.2 joerg #ifdef CONFIG_AP 6811 1.2 joerg if (!wpa_s->ap_iface || !data) 6812 1.2 joerg break; 6813 1.2 joerg hostapd_event_connect_failed_reason( 6814 1.2 joerg wpa_s->ap_iface->bss[0], 6815 1.2 joerg data->connect_failed_reason.addr, 6816 1.2 joerg data->connect_failed_reason.code); 6817 1.2 joerg #endif /* CONFIG_AP */ 6818 1.1 christos break; 6819 1.3 christos case EVENT_NEW_PEER_CANDIDATE: 6820 1.3 christos #ifdef CONFIG_MESH 6821 1.3 christos if (!wpa_s->ifmsh || !data) 6822 1.3 christos break; 6823 1.3 christos wpa_mesh_notify_peer(wpa_s, data->mesh_peer.peer, 6824 1.3 christos data->mesh_peer.ies, 6825 1.3 christos data->mesh_peer.ie_len); 6826 1.3 christos #endif /* CONFIG_MESH */ 6827 1.3 christos break; 6828 1.6 christos case EVENT_SURVEY: 6829 1.6 christos #ifdef CONFIG_AP 6830 1.6 christos if (!wpa_s->ap_iface) 6831 1.6 christos break; 6832 1.6 christos hostapd_event_get_survey(wpa_s->ap_iface, 6833 1.6 christos &data->survey_results); 6834 1.6 christos #endif /* CONFIG_AP */ 6835 1.6 christos break; 6836 1.6 christos case EVENT_ACS_CHANNEL_SELECTED: 6837 1.7 christos #ifdef CONFIG_AP 6838 1.6 christos #ifdef CONFIG_ACS 6839 1.6 christos if (!wpa_s->ap_iface) 6840 1.6 christos break; 6841 1.6 christos hostapd_acs_channel_selected(wpa_s->ap_iface->bss[0], 6842 1.6 christos &data->acs_selected_channels); 6843 1.6 christos #endif /* CONFIG_ACS */ 6844 1.7 christos #endif /* CONFIG_AP */ 6845 1.6 christos break; 6846 1.6 christos case EVENT_P2P_LO_STOP: 6847 1.6 christos #ifdef CONFIG_P2P 6848 1.6 christos wpa_s->p2p_lo_started = 0; 6849 1.6 christos wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_LISTEN_OFFLOAD_STOP 6850 1.6 christos P2P_LISTEN_OFFLOAD_STOP_REASON "reason=%d", 6851 1.6 christos data->p2p_lo_stop.reason_code); 6852 1.6 christos #endif /* CONFIG_P2P */ 6853 1.6 christos break; 6854 1.7 christos case EVENT_BEACON_LOSS: 6855 1.7 christos if (!wpa_s->current_bss || !wpa_s->current_ssid) 6856 1.7 christos break; 6857 1.7 christos wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_BEACON_LOSS); 6858 1.7 christos bgscan_notify_beacon_loss(wpa_s); 6859 1.7 christos break; 6860 1.7 christos case EVENT_EXTERNAL_AUTH: 6861 1.7 christos #ifdef CONFIG_SAE 6862 1.7 christos if (!wpa_s->current_ssid) { 6863 1.7 christos wpa_printf(MSG_DEBUG, "SAE: current_ssid is NULL"); 6864 1.7 christos break; 6865 1.7 christos } 6866 1.7 christos sme_external_auth_trigger(wpa_s, data); 6867 1.7 christos #endif /* CONFIG_SAE */ 6868 1.7 christos break; 6869 1.10 christos #ifdef CONFIG_PASN 6870 1.10 christos case EVENT_PASN_AUTH: 6871 1.10 christos wpas_pasn_auth_trigger(wpa_s, &data->pasn_auth); 6872 1.10 christos break; 6873 1.10 christos #endif /* CONFIG_PASN */ 6874 1.7 christos case EVENT_PORT_AUTHORIZED: 6875 1.10 christos #ifdef CONFIG_AP 6876 1.10 christos if (wpa_s->ap_iface && wpa_s->ap_iface->bss[0]) { 6877 1.10 christos struct sta_info *sta; 6878 1.10 christos 6879 1.10 christos sta = ap_get_sta(wpa_s->ap_iface->bss[0], 6880 1.10 christos data->port_authorized.sta_addr); 6881 1.10 christos if (sta) 6882 1.10 christos ap_sta_set_authorized(wpa_s->ap_iface->bss[0], 6883 1.10 christos sta, 1); 6884 1.10 christos else 6885 1.10 christos wpa_printf(MSG_DEBUG, 6886 1.10 christos "No STA info matching port authorized event found"); 6887 1.10 christos break; 6888 1.10 christos } 6889 1.10 christos #endif /* CONFIG_AP */ 6890 1.10 christos #ifndef CONFIG_NO_WPA 6891 1.10 christos if (data->port_authorized.td_bitmap_len) { 6892 1.10 christos wpa_printf(MSG_DEBUG, 6893 1.10 christos "WPA3: Transition Disable bitmap from the driver event: 0x%x", 6894 1.10 christos data->port_authorized.td_bitmap[0]); 6895 1.10 christos wpas_transition_disable( 6896 1.10 christos wpa_s, data->port_authorized.td_bitmap[0]); 6897 1.10 christos } 6898 1.10 christos #endif /* CONFIG_NO_WPA */ 6899 1.7 christos wpa_supplicant_event_port_authorized(wpa_s); 6900 1.7 christos break; 6901 1.7 christos case EVENT_STATION_OPMODE_CHANGED: 6902 1.7 christos #ifdef CONFIG_AP 6903 1.7 christos if (!wpa_s->ap_iface || !data) 6904 1.7 christos break; 6905 1.7 christos 6906 1.7 christos hostapd_event_sta_opmode_changed(wpa_s->ap_iface->bss[0], 6907 1.7 christos data->sta_opmode.addr, 6908 1.7 christos data->sta_opmode.smps_mode, 6909 1.7 christos data->sta_opmode.chan_width, 6910 1.7 christos data->sta_opmode.rx_nss); 6911 1.7 christos #endif /* CONFIG_AP */ 6912 1.7 christos break; 6913 1.10 christos case EVENT_UNPROT_BEACON: 6914 1.10 christos wpas_event_unprot_beacon(wpa_s, &data->unprot_beacon); 6915 1.10 christos break; 6916 1.10 christos case EVENT_TX_WAIT_EXPIRE: 6917 1.10 christos #ifdef CONFIG_DPP 6918 1.10 christos wpas_dpp_tx_wait_expire(wpa_s); 6919 1.10 christos #endif /* CONFIG_DPP */ 6920 1.10 christos #ifdef CONFIG_NAN_USD 6921 1.10 christos wpas_nan_usd_tx_wait_expire(wpa_s); 6922 1.10 christos #endif /* CONFIG_NAN_USD */ 6923 1.10 christos break; 6924 1.10 christos case EVENT_TID_LINK_MAP: 6925 1.10 christos if (data) 6926 1.10 christos wpas_tid_link_map(wpa_s, &data->t2l_map_info); 6927 1.10 christos break; 6928 1.1 christos default: 6929 1.2 joerg wpa_msg(wpa_s, MSG_INFO, "Unknown event %d", event); 6930 1.1 christos break; 6931 1.1 christos } 6932 1.1 christos } 6933 1.4 roy 6934 1.4 roy 6935 1.4 roy void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event, 6936 1.4 roy union wpa_event_data *data) 6937 1.4 roy { 6938 1.4 roy struct wpa_supplicant *wpa_s; 6939 1.4 roy 6940 1.4 roy if (event != EVENT_INTERFACE_STATUS) 6941 1.4 roy return; 6942 1.4 roy 6943 1.4 roy wpa_s = wpa_supplicant_get_iface(ctx, data->interface_status.ifname); 6944 1.4 roy if (wpa_s && wpa_s->driver->get_ifindex) { 6945 1.4 roy unsigned int ifindex; 6946 1.4 roy 6947 1.4 roy ifindex = wpa_s->driver->get_ifindex(wpa_s->drv_priv); 6948 1.4 roy if (ifindex != data->interface_status.ifindex) { 6949 1.4 roy wpa_dbg(wpa_s, MSG_DEBUG, 6950 1.4 roy "interface status ifindex %d mismatch (%d)", 6951 1.4 roy ifindex, data->interface_status.ifindex); 6952 1.4 roy return; 6953 1.4 roy } 6954 1.4 roy } 6955 1.5 roy #ifdef CONFIG_MATCH_IFACE 6956 1.5 roy else if (data->interface_status.ievent == EVENT_INTERFACE_ADDED) { 6957 1.5 roy struct wpa_interface *wpa_i; 6958 1.5 roy 6959 1.5 roy wpa_i = wpa_supplicant_match_iface( 6960 1.5 roy ctx, data->interface_status.ifname); 6961 1.5 roy if (!wpa_i) 6962 1.5 roy return; 6963 1.5 roy wpa_s = wpa_supplicant_add_iface(ctx, wpa_i, NULL); 6964 1.5 roy os_free(wpa_i); 6965 1.5 roy } 6966 1.5 roy #endif /* CONFIG_MATCH_IFACE */ 6967 1.4 roy 6968 1.4 roy if (wpa_s) 6969 1.4 roy wpa_supplicant_event(wpa_s, event, data); 6970 1.4 roy } 6971