static int are_ies_equal(const struct wpa_bss *old, const struct wpa_scan_res *new_res, u32 ie) { const u8 *old_ie, *new_ie; struct wpabuf *old_ie_buff = NULL; struct wpabuf *new_ie_buff = NULL; int new_ie_len, old_ie_len, ret, is_multi; switch (ie) { case WPA_IE_VENDOR_TYPE: old_ie = wpa_bss_get_vendor_ie(old, ie); new_ie = wpa_scan_get_vendor_ie(new_res, ie); is_multi = 0; break; case WPS_IE_VENDOR_TYPE: old_ie_buff = wpa_bss_get_vendor_ie_multi(old, ie); new_ie_buff = wpa_scan_get_vendor_ie_multi(new_res, ie); is_multi = 1; break; case WLAN_EID_RSN: case WLAN_EID_SUPP_RATES: case WLAN_EID_EXT_SUPP_RATES: old_ie = wpa_bss_get_ie(old, ie); new_ie = wpa_scan_get_ie(new_res, ie); is_multi = 0; break; default: wpa_printf(MSG_DEBUG, "bss: %s: cannot compare IEs", __func__); return 0; } if (is_multi) { /* in case of multiple IEs stored in buffer */ old_ie = old_ie_buff ? wpabuf_head_u8(old_ie_buff) : NULL; new_ie = new_ie_buff ? wpabuf_head_u8(new_ie_buff) : NULL; old_ie_len = old_ie_buff ? wpabuf_len(old_ie_buff) : 0; new_ie_len = new_ie_buff ? wpabuf_len(new_ie_buff) : 0; } else { /* in case of single IE */ old_ie_len = old_ie ? old_ie[1] + 2 : 0; new_ie_len = new_ie ? new_ie[1] + 2 : 0; } if (!old_ie || !new_ie) ret = !old_ie && !new_ie; else ret = (old_ie_len == new_ie_len && os_memcmp(old_ie, new_ie, old_ie_len) == 0); wpabuf_free(old_ie_buff); wpabuf_free(new_ie_buff); return ret; }
void wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { struct rsn_supp_config conf; if (ssid) { os_memset(&conf, 0, sizeof(conf)); conf.network_ctx = ssid; conf.allowed_pairwise_cipher = ssid->pairwise_cipher; #ifdef IEEE8021X_EAPOL conf.proactive_key_caching = ssid->proactive_key_caching < 0 ? wpa_s->conf->okc : ssid->proactive_key_caching; conf.eap_workaround = ssid->eap_workaround; conf.eap_conf_ctx = &ssid->eap; #endif /* IEEE8021X_EAPOL */ conf.ssid = ssid->ssid; conf.ssid_len = ssid->ssid_len; conf.wpa_ptk_rekey = ssid->wpa_ptk_rekey; #ifdef CONFIG_P2P if (ssid->p2p_group && wpa_s->current_bss && !wpa_s->p2p_disable_ip_addr_req) { struct wpabuf *p2p; p2p = wpa_bss_get_vendor_ie_multi(wpa_s->current_bss, P2P_IE_VENDOR_TYPE); if (p2p) { u8 group_capab; group_capab = p2p_get_group_capab(p2p); if (group_capab & P2P_GROUP_CAPAB_IP_ADDR_ALLOCATION) conf.p2p = 1; wpabuf_free(p2p); } } #endif /* CONFIG_P2P */ conf.wpa_rsc_relaxation = wpa_s->conf->wpa_rsc_relaxation; #ifdef CONFIG_FILS if (wpa_key_mgmt_fils(wpa_s->key_mgmt)) conf.fils_cache_id = wpa_bss_get_fils_cache_id(wpa_s->current_bss); #endif /* CONFIG_FILS */ } wpa_sm_set_config(wpa_s->wpa, ssid ? &conf : NULL); }
int wpas_wps_scan_pbc_overlap(struct wpa_supplicant *wpa_s, struct wpa_bss *selected, struct wpa_ssid *ssid) { const u8 *sel_uuid, *uuid; struct wpabuf *wps_ie; int ret = 0; struct wpa_bss *bss; if (!eap_is_wps_pbc_enrollee(&ssid->eap)) return 0; wpa_printf(MSG_DEBUG, "WPS: Check whether PBC session overlap is " "present in scan results; selected BSSID " MACSTR, MAC2STR(selected->bssid)); /* Make sure that only one AP is in active PBC mode */ wps_ie = wpa_bss_get_vendor_ie_multi(selected, WPS_IE_VENDOR_TYPE); if (wps_ie) { sel_uuid = wps_get_uuid_e(wps_ie); wpa_hexdump(MSG_DEBUG, "WPS: UUID of the selected BSS", sel_uuid, UUID_LEN); } else { wpa_printf(MSG_DEBUG, "WPS: Selected BSS does not include " "WPS IE?!"); sel_uuid = NULL; } dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { struct wpabuf *ie; if (bss == selected) continue; ie = wpa_bss_get_vendor_ie_multi(bss, WPS_IE_VENDOR_TYPE); if (!ie) continue; if (!wps_is_selected_pbc_registrar(ie)) { wpabuf_free(ie); continue; } wpa_printf(MSG_DEBUG, "WPS: Another BSS in active PBC mode: " MACSTR, MAC2STR(bss->bssid)); uuid = wps_get_uuid_e(ie); wpa_hexdump(MSG_DEBUG, "WPS: UUID of the other BSS", uuid, UUID_LEN); if (sel_uuid == NULL || uuid == NULL || os_memcmp(sel_uuid, uuid, UUID_LEN) != 0) { ret = 1; /* PBC overlap */ wpa_msg(wpa_s, MSG_INFO, "WPS: PBC overlap detected: " MACSTR " and " MACSTR, MAC2STR(selected->bssid), MAC2STR(bss->bssid)); wpabuf_free(ie); break; } /* TODO: verify that this is reasonable dual-band situation */ wpabuf_free(ie); } wpabuf_free(wps_ie); return ret; }