/**
 * 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;
}
예제 #2
0
/**
 * 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;
}
예제 #3
0
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;
}
예제 #4
0
파일: sme.c 프로젝트: PR2/linux_networking
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));
}
예제 #5
0
파일: sme.c 프로젝트: PR2/linux_networking
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));
}
예제 #6
0
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;
}
예제 #7
0
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;
}
예제 #8
0
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;
}
예제 #9
0
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;
}
예제 #10
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;
}
예제 #11
0
파일: events.c 프로젝트: AxelLin/Drv
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;
}