/** * wpa_blacklist_add - Add an BSSID to the blacklist * @wpa_s: Pointer to wpa_supplicant data * @bssid: BSSID to be added to the blacklist * Returns: Current blacklist count on success, -1 on failure * * This function adds the specified BSSID to the blacklist or increases the * blacklist count if the BSSID was already listed. It should be called when * an association attempt fails either due to the selected BSS rejecting * association or due to timeout. * * This blacklist is used to force %wpa_supplicant to go through all available * BSSes before retrying to associate with an BSS that rejected or timed out * association. It does not prevent the listed BSS from being used; it only * changes the order in which they are tried. */ int wpa_blacklist_add(struct wpa_supplicant *wpa_s, const u8 *bssid) { struct wpa_blacklist *e; if (wpa_s == NULL || bssid == NULL) return -1; e = wpa_blacklist_get(wpa_s, bssid); if (e) { e->count++; wpa_printf(MSG_DEBUG, "BSSID " MACSTR " blacklist count " "incremented to %d", MAC2STR(bssid), e->count); return e->count; } e = os_zalloc(sizeof(*e)); if (e == NULL) return -1; os_memcpy(e->bssid, bssid, ETH_ALEN); e->count = 1; e->next = wpa_s->blacklist; wpa_s->blacklist = e; wpa_printf(MSG_DEBUG, "Added BSSID " MACSTR " into blacklist", MAC2STR(bssid)); return e->count; }
/** * wpa_blacklist_add - Add an BSSID to the blacklist * @wpa_s: Pointer to wpa_supplicant data * @bssid: BSSID to be added to the blacklist * Returns: Current blacklist count on success, -1 on failure * * This function adds the specified BSSID to the blacklist or increases the * blacklist count if the BSSID was already listed. It should be called when * an association attempt fails either due to the selected BSS rejecting * association or due to timeout. * * This blacklist is used to force %wpa_supplicant to go through all available * BSSes before retrying to associate with an BSS that rejected or timed out * association. It does not prevent the listed BSS from being used; it only * changes the order in which they are tried. */ int wpa_blacklist_add(struct wpa_supplicant *wpa_s, const u8 *bssid) { struct wpa_blacklist *e; e = wpa_blacklist_get(wpa_s, bssid); if (e) { e->count++; os_get_time(&e->last_add); wpa_printf(MSG_DEBUG, "BSSID " MACSTR " blacklist count " "incremented to %d", MAC2STR(bssid), e->count); return e->count; } e = os_zalloc(sizeof(*e)); if (e == NULL) return -1; os_memcpy(e->bssid, bssid, ETH_ALEN); e->count = 1; os_get_time(&e->last_add); e->next = wpa_s->blacklist; wpa_s->blacklist = e; wpa_printf(MSG_DEBUG, "Added BSSID " MACSTR " into blacklist", MAC2STR(bssid)); if (!e->next) eloop_register_timeout(BLACKLIST_TIMEOUT, 0, blacklist_timeout, wpa_s, NULL); return e->count; }
static int wpas_blacklist_module_tests(void) { struct wpa_supplicant wpa_s; int ret = -1; os_memset(&wpa_s, 0, sizeof(wpa_s)); wpa_blacklist_clear(&wpa_s); if (wpa_blacklist_get(NULL, NULL) != NULL || wpa_blacklist_get(NULL, (u8 *) "123456") != NULL || wpa_blacklist_get(&wpa_s, NULL) != NULL || wpa_blacklist_get(&wpa_s, (u8 *) "123456") != NULL) goto fail; if (wpa_blacklist_add(NULL, NULL) == 0 || wpa_blacklist_add(NULL, (u8 *) "123456") == 0 || wpa_blacklist_add(&wpa_s, NULL) == 0) goto fail; if (wpa_blacklist_del(NULL, NULL) == 0 || wpa_blacklist_del(NULL, (u8 *) "123456") == 0 || wpa_blacklist_del(&wpa_s, NULL) == 0 || wpa_blacklist_del(&wpa_s, (u8 *) "123456") == 0) goto fail; if (wpa_blacklist_add(&wpa_s, (u8 *) "111111") < 0 || wpa_blacklist_add(&wpa_s, (u8 *) "111111") < 0 || wpa_blacklist_add(&wpa_s, (u8 *) "222222") < 0 || wpa_blacklist_add(&wpa_s, (u8 *) "333333") < 0 || wpa_blacklist_add(&wpa_s, (u8 *) "444444") < 0 || wpa_blacklist_del(&wpa_s, (u8 *) "333333") < 0 || wpa_blacklist_del(&wpa_s, (u8 *) "xxxxxx") == 0 || wpa_blacklist_get(&wpa_s, (u8 *) "xxxxxx") != NULL || wpa_blacklist_get(&wpa_s, (u8 *) "111111") == NULL || wpa_blacklist_get(&wpa_s, (u8 *) "222222") == NULL || wpa_blacklist_get(&wpa_s, (u8 *) "444444") == NULL || wpa_blacklist_del(&wpa_s, (u8 *) "111111") < 0 || wpa_blacklist_del(&wpa_s, (u8 *) "222222") < 0 || wpa_blacklist_del(&wpa_s, (u8 *) "444444") < 0 || wpa_blacklist_add(&wpa_s, (u8 *) "111111") < 0 || wpa_blacklist_add(&wpa_s, (u8 *) "222222") < 0 || wpa_blacklist_add(&wpa_s, (u8 *) "333333") < 0) goto fail; ret = 0; fail: wpa_blacklist_clear(&wpa_s); if (ret) wpa_printf(MSG_ERROR, "blacklist module test failure"); return ret; }
void sme_event_assoc_reject(struct wpa_supplicant *wpa_s, union wpa_event_data *data) { int bssid_changed; int timeout = 5000; wpa_printf(MSG_DEBUG, "SME: Association with " MACSTR " failed: " "status code %d", MAC2STR(wpa_s->pending_bssid), data->assoc_reject.status_code); bssid_changed = !is_zero_ether_addr(wpa_s->bssid); /* * For now, unconditionally terminate the previous authentication. In * theory, this should not be needed, but mac80211 gets quite confused * if the authentication is left pending.. Some roaming cases might * benefit from using the previous authentication, so this could be * optimized in the future. */ if (wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid, WLAN_REASON_DEAUTH_LEAVING) < 0) { wpa_msg(wpa_s, MSG_INFO, "Deauth request to the driver failed"); } wpa_s->sme.prev_bssid_set = 0; if (wpa_blacklist_add(wpa_s, wpa_s->pending_bssid) == 0) { struct wpa_blacklist *b; b = wpa_blacklist_get(wpa_s, wpa_s->pending_bssid); if (b && b->count < 3) { /* * Speed up next attempt if there could be other APs * that could accept association. */ timeout = 100; } } wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); os_memset(wpa_s->bssid, 0, ETH_ALEN); os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); if (bssid_changed) wpas_notify_bssid_changed(wpa_s); /* * TODO: if more than one possible AP is available in scan results, * could try the other ones before requesting a new scan. */ ros_assoc_failed(wpa_s, wpa_s->pending_bssid, "Association rejected"); //wpa_supplicant_req_scan(wpa_s, timeout / 1000, // 1000 * (timeout % 1000)); }
void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s, union wpa_event_data *data) { int timeout = 5000; wpa_printf(MSG_DEBUG, "SME: Authentication timed out"); if (wpa_blacklist_add(wpa_s, wpa_s->pending_bssid) == 0) { struct wpa_blacklist *b; b = wpa_blacklist_get(wpa_s, wpa_s->pending_bssid); if (b && b->count < 3) { /* * Speed up next attempt if there could be other APs * that could accept association. */ timeout = 100; } } ros_assoc_failed(wpa_s, wpa_s->pending_bssid, "Authentication timed out"); //wpa_supplicant_req_scan(wpa_s, timeout / 1000, // 1000 * (timeout % 1000)); }
static struct wpa_scan_res * wpa_supplicant_select_bss_non_wpa(struct wpa_supplicant *wpa_s, struct wpa_ssid *group, struct wpa_ssid **selected_ssid) { struct wpa_ssid *ssid; struct wpa_scan_res *bss; size_t i; struct wpa_blacklist *e; const u8 *ie; wpa_printf(MSG_DEBUG, "Try to find non-WPA AP"); for (i = 0; i < wpa_s->scan_res->num; i++) { const u8 *ssid_; u8 wpa_ie_len, rsn_ie_len, ssid_len; bss = wpa_s->scan_res->res[i]; ie = wpa_scan_get_ie(bss, WLAN_EID_SSID); ssid_ = ie ? ie + 2 : (u8 *) ""; ssid_len = ie ? ie[1] : 0; ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); wpa_ie_len = ie ? ie[1] : 0; ie = wpa_scan_get_ie(bss, WLAN_EID_RSN); rsn_ie_len = ie ? ie[1] : 0; wpa_printf(MSG_DEBUG, "%d: " MACSTR " ssid='%s' " "wpa_ie_len=%u rsn_ie_len=%u caps=0x%x", (int) i, MAC2STR(bss->bssid), wpa_ssid_txt(ssid_, ssid_len), wpa_ie_len, rsn_ie_len, bss->caps); e = wpa_blacklist_get(wpa_s, bss->bssid); if (e && e->count > 1) { wpa_printf(MSG_DEBUG, " skip - blacklisted"); continue; } if (ssid_len == 0) { wpa_printf(MSG_DEBUG, " skip - SSID not known"); continue; } for (ssid = group; ssid; ssid = ssid->pnext) { int check_ssid = ssid->ssid_len != 0; if (ssid->disabled) { wpa_printf(MSG_DEBUG, " skip - disabled"); continue; } #ifdef CONFIG_WPS if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) { /* Only allow wildcard SSID match if an AP * advertises active WPS operation that matches * with our mode. */ check_ssid = 1; if (ssid->ssid_len == 0 && wpas_wps_ssid_wildcard_ok(wpa_s, ssid, bss)) check_ssid = 0; } #endif /* CONFIG_WPS */ if (check_ssid && (ssid_len != ssid->ssid_len || os_memcmp(ssid_, ssid->ssid, ssid_len) != 0)) { wpa_printf(MSG_DEBUG, " skip - " "SSID mismatch"); continue; } if (ssid->bssid_set && os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0) { wpa_printf(MSG_DEBUG, " skip - " "BSSID mismatch"); continue; } if (!(ssid->key_mgmt & WPA_KEY_MGMT_NONE) && !(ssid->key_mgmt & WPA_KEY_MGMT_WPS) && !(ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)) { wpa_printf(MSG_DEBUG, " skip - " "non-WPA network not allowed"); continue; } if ((ssid->key_mgmt & (WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_IEEE8021X | WPA_KEY_MGMT_FT_PSK | WPA_KEY_MGMT_IEEE8021X_SHA256 | WPA_KEY_MGMT_PSK_SHA256)) && (wpa_ie_len != 0 || rsn_ie_len != 0)) { wpa_printf(MSG_DEBUG, " skip - " "WPA network"); continue; } if (!wpa_supplicant_match_privacy(bss, ssid)) { wpa_printf(MSG_DEBUG, " skip - " "privacy mismatch"); continue; } if (bss->caps & IEEE80211_CAP_IBSS) { wpa_printf(MSG_DEBUG, " skip - " "IBSS (adhoc) network"); continue; } wpa_printf(MSG_DEBUG, " selected non-WPA AP " MACSTR " ssid='%s'", MAC2STR(bss->bssid), wpa_ssid_txt(ssid_, ssid_len)); *selected_ssid = ssid; return bss; } } return NULL; }
static struct wpa_scan_res * wpa_supplicant_select_bss_wpa(struct wpa_supplicant *wpa_s, struct wpa_ssid *group, struct wpa_ssid **selected_ssid) { struct wpa_ssid *ssid; struct wpa_scan_res *bss; size_t i; struct wpa_blacklist *e; const u8 *ie; wpa_printf(MSG_DEBUG, "Try to find WPA-enabled AP"); for (i = 0; i < wpa_s->scan_res->num; i++) { const u8 *ssid_; u8 wpa_ie_len, rsn_ie_len, ssid_len; bss = wpa_s->scan_res->res[i]; ie = wpa_scan_get_ie(bss, WLAN_EID_SSID); ssid_ = ie ? ie + 2 : (u8 *) ""; ssid_len = ie ? ie[1] : 0; ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); wpa_ie_len = ie ? ie[1] : 0; ie = wpa_scan_get_ie(bss, WLAN_EID_RSN); rsn_ie_len = ie ? ie[1] : 0; wpa_printf(MSG_DEBUG, "%d: " MACSTR " ssid='%s' " "wpa_ie_len=%u rsn_ie_len=%u caps=0x%x", (int) i, MAC2STR(bss->bssid), wpa_ssid_txt(ssid_, ssid_len), wpa_ie_len, rsn_ie_len, bss->caps); e = wpa_blacklist_get(wpa_s, bss->bssid); if (e && e->count > 1) { wpa_printf(MSG_DEBUG, " skip - blacklisted"); continue; } if (ssid_len == 0) { wpa_printf(MSG_DEBUG, " skip - SSID not known"); continue; } if (wpa_ie_len == 0 && rsn_ie_len == 0) { wpa_printf(MSG_DEBUG, " skip - no WPA/RSN IE"); continue; } for (ssid = group; ssid; ssid = ssid->pnext) { int check_ssid = 1; if (ssid->disabled) { wpa_printf(MSG_DEBUG, " skip - disabled"); continue; } #ifdef CONFIG_WPS if (ssid->ssid_len == 0 && wpas_wps_ssid_wildcard_ok(wpa_s, ssid, bss)) check_ssid = 0; #endif /* CONFIG_WPS */ if (check_ssid && (ssid_len != ssid->ssid_len || os_memcmp(ssid_, ssid->ssid, ssid_len) != 0)) { wpa_printf(MSG_DEBUG, " skip - " "SSID mismatch"); continue; } if (ssid->bssid_set && os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0) { wpa_printf(MSG_DEBUG, " skip - " "BSSID mismatch"); continue; } if (!wpa_supplicant_ssid_bss_match(wpa_s, ssid, bss)) continue; wpa_printf(MSG_DEBUG, " selected WPA AP " MACSTR " ssid='%s'", MAC2STR(bss->bssid), wpa_ssid_txt(ssid_, ssid_len)); *selected_ssid = ssid; return bss; } } return NULL; }
static struct wpa_scan_res * wpa_supplicant_select_bss_wapi(struct wpa_supplicant *wpa_s, struct wpa_ssid *group, struct wpa_ssid **selected_ssid) { struct wpa_ssid *ssid; struct wpa_scan_res *bss; size_t i; struct wpa_blacklist *e; const u8 *ie; wpa_printf(MSG_DEBUG, "Try to find WAPI-enabled AP"); for (i = 0; i < wpa_s->scan_res->num; i++) { const u8 *ssid_; u8 wapi_ie_len, ssid_len; bss = wpa_s->scan_res->res[i]; ie = wpa_scan_get_ie(bss, WLAN_EID_SSID); ssid_ = ie ? ie + 2 : (u8 *) ""; ssid_len = ie ? ie[1] : 0; //ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); //wpa_ie_len = ie ? ie[1] : 0; ie = wpa_scan_get_ie(bss, WAPI_INFO_ELEM); wapi_ie_len = ie ? ie[1] : 0; wpa_printf(MSG_DEBUG, "%d: " MACSTR " ssid='%s' " "wapi_ie_len=%u caps=0x%x", (int) i, MAC2STR(bss->bssid), wpa_ssid_txt(ssid_, ssid_len), wapi_ie_len, bss->caps); e = wpa_blacklist_get(wpa_s, bss->bssid); if (e && e->count > 1) { wpa_printf(MSG_DEBUG, " skip - blacklisted"); continue; } if (ssid_len == 0) { wpa_printf(MSG_DEBUG, " skip - SSID not known"); continue; } if (wapi_ie_len == 0) { wpa_printf(MSG_DEBUG, " skip - no WAPI IE"); continue; } for (ssid = group; ssid; ssid = ssid->pnext) { int check_ssid = 1; if (ssid->disabled) { wpa_printf(MSG_DEBUG, " skip - disabled"); continue; } if (check_ssid && (ssid_len != ssid->ssid_len || os_memcmp(ssid_, ssid->ssid, ssid_len) != 0)) { wpa_printf(MSG_DEBUG, " skip - " "SSID mismatch"); continue; } if (ssid->bssid_set && os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0) { wpa_printf(MSG_DEBUG, " skip - " "BSSID mismatch"); continue; } if (!wpa_supplicant_ssid_wapi_bss_match(wpa_s, ssid, bss)) continue; { /* Record the WAPI AP's IE, will be reported to WAPI Module */ const u8* wapi_ie; wapi_ie = wpa_scan_get_ie(bss, WAPI_INFO_ELEM); wpa_s->bss_wapi_ie_len = 2 + wapi_ie[1]; os_memcpy(wpa_s->bss_wapi_ie, wapi_ie, wpa_s->bss_wapi_ie_len); wpa_printf(MSG_DEBUG, "[WAPI-Debug ^_^] selected WAPI AP !!!!!!! Ready to connect +_+"); } wpa_printf(MSG_DEBUG, " selected WAPI AP " MACSTR " ssid='%s'", MAC2STR(bss->bssid), wpa_ssid_txt(ssid_, ssid_len)); *selected_ssid = ssid; return bss; } } return NULL; }
static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s, int i, struct wpa_scan_res *bss, struct wpa_ssid *group) { const u8 *ssid_; u8 wpa_ie_len, rsn_ie_len, ssid_len; int wpa; struct wpa_blacklist *e; const u8 *ie; struct wpa_ssid *ssid; ie = wpa_scan_get_ie(bss, WLAN_EID_SSID); ssid_ = ie ? ie + 2 : (u8 *) ""; ssid_len = ie ? ie[1] : 0; ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); wpa_ie_len = ie ? ie[1] : 0; ie = wpa_scan_get_ie(bss, WLAN_EID_RSN); rsn_ie_len = ie ? ie[1] : 0; wpa_printf(MSG_DEBUG, "%d: " MACSTR " ssid='%s' " "wpa_ie_len=%u rsn_ie_len=%u caps=0x%x level=%d%s", i, MAC2STR(bss->bssid), wpa_ssid_txt(ssid_, ssid_len), wpa_ie_len, rsn_ie_len, bss->caps, bss->level, wpa_scan_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE) ? " wps" : ""); e = wpa_blacklist_get(wpa_s, bss->bssid); if (e && e->count > 1) { wpa_printf(MSG_DEBUG, " skip - blacklisted"); return 0; } if (ssid_len == 0) { wpa_printf(MSG_DEBUG, " skip - SSID not known"); return 0; } wpa = wpa_ie_len > 0 || rsn_ie_len > 0; for (ssid = group; ssid; ssid = ssid->pnext) { int check_ssid = wpa ? 1 : (ssid->ssid_len != 0); if (ssid->disabled) { wpa_printf(MSG_DEBUG, " skip - disabled"); continue; } #ifdef CONFIG_WPS if ((ssid->key_mgmt & WPA_KEY_MGMT_WPS) && e && e->count > 0) { wpa_printf(MSG_DEBUG, " skip - blacklisted (WPS)"); continue; } if (wpa && ssid->ssid_len == 0 && wpas_wps_ssid_wildcard_ok(wpa_s, ssid, bss)) check_ssid = 0; if (!wpa && (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) { /* Only allow wildcard SSID match if an AP * advertises active WPS operation that matches * with our mode. */ check_ssid = 1; if (ssid->ssid_len == 0 && wpas_wps_ssid_wildcard_ok(wpa_s, ssid, bss)) check_ssid = 0; } #endif /* CONFIG_WPS */ if (check_ssid && (ssid_len != ssid->ssid_len || os_memcmp(ssid_, ssid->ssid, ssid_len) != 0)) { wpa_printf(MSG_DEBUG, " skip - SSID mismatch"); continue; } if (ssid->bssid_set && os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0) { wpa_printf(MSG_DEBUG, " skip - BSSID mismatch"); continue; } if (wpa && !wpa_supplicant_ssid_bss_match(wpa_s, ssid, bss)) continue; if (!wpa && !(ssid->key_mgmt & WPA_KEY_MGMT_NONE) && !(ssid->key_mgmt & WPA_KEY_MGMT_WPS) && !(ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)) { wpa_printf(MSG_DEBUG, " skip - non-WPA network not " "allowed"); continue; } if (!wpa && !wpa_supplicant_match_privacy(bss, ssid)) { wpa_printf(MSG_DEBUG, " skip - privacy mismatch"); continue; } if (!wpa && (bss->caps & IEEE80211_CAP_IBSS)) { wpa_printf(MSG_DEBUG, " skip - IBSS (adhoc) " "network"); continue; } if (!freq_allowed(ssid->freq_list, bss->freq)) { wpa_printf(MSG_DEBUG, " skip - frequency not " "allowed"); continue; } #ifdef CONFIG_P2P /* * TODO: skip the AP if its P2P IE has Group Formation * bit set in the P2P Group Capability Bitmap and we * are not in Group Formation with that device. */ #endif /* CONFIG_P2P */ /* Matching configuration found */ return ssid; } /* No matching configuration found */ return 0; }
static struct wpa_bss * wpa_supplicant_select_bss_wpa(struct wpa_supplicant *wpa_s, struct wpa_scan_results *scan_res, struct wpa_ssid *group, struct wpa_ssid **selected_ssid) { struct wpa_ssid *ssid; struct wpa_scan_res *bss; size_t i; struct wpa_blacklist *e; const u8 *ie; wpa_printf(MSG_DEBUG, "Try to find WPA-enabled AP"); for (i = 0; i < scan_res->num; i++) { const u8 *ssid_; u8 wpa_ie_len, rsn_ie_len, ssid_len; bss = scan_res->res[i]; ie = wpa_scan_get_ie(bss, WLAN_EID_SSID); ssid_ = ie ? ie + 2 : (u8 *) ""; ssid_len = ie ? ie[1] : 0; ie = wpa_scan_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); wpa_ie_len = ie ? ie[1] : 0; ie = wpa_scan_get_ie(bss, WLAN_EID_RSN); rsn_ie_len = ie ? ie[1] : 0; wpa_printf(MSG_DEBUG, "%d: " MACSTR " ssid='%s' " "wpa_ie_len=%u rsn_ie_len=%u caps=0x%x", (int) i, MAC2STR(bss->bssid), wpa_ssid_txt(ssid_, ssid_len), wpa_ie_len, rsn_ie_len, bss->caps); e = wpa_blacklist_get(wpa_s, bss->bssid); if (e) { int limit = 1; if (wpa_supplicant_enabled_networks(wpa_s->conf) == 1) { /* * When only a single network is enabled, we can * trigger blacklisting on the first failure. This * should not be done with multiple enabled networks to * avoid getting forced to move into a worse ESS on * single error if there are no other BSSes of the * current ESS. */ limit = 0; } if (e->count > limit) { wpa_printf(MSG_DEBUG, " skip - blacklisted " "(count=%d limit=%d)", e->count, limit); continue; } } if (ssid_len == 0) { wpa_printf(MSG_DEBUG, " skip - SSID not known"); continue; } if (wpa_ie_len == 0 && rsn_ie_len == 0) { wpa_printf(MSG_DEBUG, " skip - no WPA/RSN IE"); continue; } for (ssid = group; ssid; ssid = ssid->pnext) { int check_ssid = 1; if (ssid->disabled) { wpa_printf(MSG_DEBUG, " skip - disabled"); continue; } #ifdef CONFIG_WPS if (ssid->ssid_len == 0 && wpas_wps_ssid_wildcard_ok(wpa_s, ssid, bss)) check_ssid = 0; #endif /* CONFIG_WPS */ if (check_ssid && (ssid_len != ssid->ssid_len || os_memcmp(ssid_, ssid->ssid, ssid_len) != 0)) { wpa_printf(MSG_DEBUG, " skip - " "SSID mismatch"); continue; } if (ssid->bssid_set && os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0) { wpa_printf(MSG_DEBUG, " skip - " "BSSID mismatch"); continue; } if (!wpa_supplicant_ssid_bss_match(wpa_s, ssid, bss)) continue; if (!freq_allowed(ssid->freq_list, bss->freq)) { wpa_printf(MSG_DEBUG, " skip - " "frequency not allowed"); continue; } wpa_printf(MSG_DEBUG, " selected WPA AP " MACSTR " ssid='%s'", MAC2STR(bss->bssid), wpa_ssid_txt(ssid_, ssid_len)); *selected_ssid = ssid; return wpa_bss_get(wpa_s, bss->bssid, ssid_, ssid_len); } } return NULL; }
static struct wpa_scan_result * wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, struct wpa_ssid *group, struct wpa_scan_result *results, int num, struct wpa_ssid **selected_ssid) { struct wpa_ssid *ssid; struct wpa_scan_result *bss, *selected = NULL; int i; struct wpa_blacklist *e; wpa_printf(MSG_DEBUG, "Selecting BSS from priority group %d", group->priority); bss = NULL; ssid = NULL; /* First, try to find WPA-enabled AP */ wpa_printf(MSG_DEBUG, "Try to find WPA-enabled AP"); for (i = 0; i < num && !selected; i++) { bss = &results[i]; wpa_printf(MSG_DEBUG, "%d: " MACSTR " ssid='%s' " "wpa_ie_len=%lu rsn_ie_len=%lu caps=0x%x", i, MAC2STR(bss->bssid), wpa_ssid_txt(bss->ssid, bss->ssid_len), (unsigned long) bss->wpa_ie_len, (unsigned long) bss->rsn_ie_len, bss->caps); e = wpa_blacklist_get(wpa_s, bss->bssid); if (e && e->count > 1) { wpa_printf(MSG_DEBUG, " skip - blacklisted"); continue; } if (bss->wpa_ie_len == 0 && bss->rsn_ie_len == 0) { wpa_printf(MSG_DEBUG, " skip - no WPA/RSN IE"); continue; } for (ssid = group; ssid; ssid = ssid->pnext) { if (ssid->disabled) { wpa_printf(MSG_DEBUG, " skip - disabled"); continue; } //if (bss->ssid_len != ssid->ssid_len || <--carella modify if (bss->ssid_len && (bss->ssid_len != ssid->ssid_len || //-->carella os_memcmp(bss->ssid, ssid->ssid, bss->ssid_len) != 0)) { wpa_printf(MSG_DEBUG, " skip - " "SSID mismatch"); continue; } if (ssid->bssid_set && os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0) { wpa_printf(MSG_DEBUG, " skip - " "BSSID mismatch"); continue; } if (wpa_supplicant_ssid_bss_match(ssid, bss)) { selected = bss; *selected_ssid = ssid; wpa_printf(MSG_DEBUG, " selected WPA AP " MACSTR " ssid='%s'", MAC2STR(bss->bssid), wpa_ssid_txt(bss->ssid, bss->ssid_len)); break; } } } /* If no WPA-enabled AP found, try to find non-WPA AP, if configuration * allows this. */ wpa_printf(MSG_DEBUG, "Try to find non-WPA AP"); for (i = 0; i < num && !selected; i++) { bss = &results[i]; wpa_printf(MSG_DEBUG, "%d: " MACSTR " ssid='%s' " "wpa_ie_len=%lu rsn_ie_len=%lu caps=0x%x", i, MAC2STR(bss->bssid), wpa_ssid_txt(bss->ssid, bss->ssid_len), (unsigned long) bss->wpa_ie_len, (unsigned long) bss->rsn_ie_len, bss->caps); e = wpa_blacklist_get(wpa_s, bss->bssid); if (e && e->count > 1) { wpa_printf(MSG_DEBUG, " skip - blacklisted"); continue; } for (ssid = group; ssid; ssid = ssid->pnext) { if (ssid->disabled) { wpa_printf(MSG_DEBUG, " skip - disabled"); continue; } //if (bss->ssid_len != ssid->ssid_len || <--carella modify if (bss->ssid_len && (bss->ssid_len != ssid->ssid_len || //-->carella os_memcmp(bss->ssid, ssid->ssid, bss->ssid_len) != 0)) { wpa_printf(MSG_DEBUG, " skip - " "SSID mismatch"); continue; } if (ssid->bssid_set && os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0) { wpa_printf(MSG_DEBUG, " skip - " "BSSID mismatch"); continue; } if (!(ssid->key_mgmt & WPA_KEY_MGMT_NONE) && !(ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)) { wpa_printf(MSG_DEBUG, " skip - " "non-WPA network not allowed"); continue; } if ((ssid->key_mgmt & (WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_PSK)) || bss->wpa_ie_len != 0 || bss->rsn_ie_len != 0) { wpa_printf(MSG_DEBUG, " skip - " "WPA network"); continue; } if (!wpa_supplicant_match_privacy(bss, ssid)) { wpa_printf(MSG_DEBUG, " skip - " "privacy mismatch"); continue; } if (bss->caps & IEEE80211_CAP_IBSS) { wpa_printf(MSG_DEBUG, " skip - " "IBSS (adhoc) network"); continue; } selected = bss; *selected_ssid = ssid; wpa_printf(MSG_DEBUG, " selected non-WPA AP " MACSTR " ssid='%s'", MAC2STR(bss->bssid), wpa_ssid_txt(bss->ssid, bss->ssid_len)); break; } } return selected; }