#include "wps_supplicant.h"
#include "ibss_rsn.h"
#include "sme.h"
+#include "gas_query.h"
#include "p2p_supplicant.h"
#include "bgscan.h"
#include "ap.h"
{
int bssid_changed;
+#ifdef CONFIG_IBSS_RSN
+ ibss_rsn_deinit(wpa_s->ibss_rsn);
+ wpa_s->ibss_rsn = NULL;
+#endif /* CONFIG_IBSS_RSN */
+
+#ifdef CONFIG_AP
+ wpa_supplicant_ap_deinit(wpa_s);
+#endif /* CONFIG_AP */
+
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
return;
os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
wpa_s->current_bss = NULL;
wpa_s->assoc_freq = 0;
+#ifdef CONFIG_IEEE80211R
+#ifdef CONFIG_SME
+ if (wpa_s->sme.ft_ies)
+ sme_update_ft_ies(wpa_s, NULL, NULL, 0);
+#endif /* CONFIG_SME */
+#endif /* CONFIG_IEEE80211R */
+
if (bssid_changed)
wpas_notify_bssid_changed(wpa_s);
privacy = 1;
#endif /* IEEE8021X_EAPOL */
+ if (wpa_key_mgmt_wpa(ssid->key_mgmt))
+ privacy = 1;
+
if (bss->caps & IEEE80211_CAP_PRIVACY)
return privacy;
return !privacy;
return 0;
}
- /* Allow in non-WPA configuration */
- return 1;
+ if (!wpa_key_mgmt_wpa(ssid->key_mgmt)) {
+ wpa_dbg(wpa_s, MSG_DEBUG, " allow in non-WPA/WPA2");
+ return 1;
+ }
+
+ wpa_dbg(wpa_s, MSG_DEBUG, " reject due to mismatch with "
+ "WPA/WPA2");
+
+ return 0;
}
if (e->count > limit) {
wpa_dbg(wpa_s, MSG_DEBUG, " skip - blacklisted "
"(count=%d limit=%d)", e->count, limit);
- return 0;
+ return NULL;
}
}
if (ssid_len == 0) {
wpa_dbg(wpa_s, MSG_DEBUG, " skip - SSID not known");
- return 0;
+ return NULL;
}
wpa = wpa_ie_len > 0 || rsn_ie_len > 0;
continue;
}
- if (!wpa && !wpa_supplicant_match_privacy(bss, ssid)) {
+ if (!wpa_supplicant_match_privacy(bss, ssid)) {
wpa_dbg(wpa_s, MSG_DEBUG, " skip - privacy "
"mismatch");
continue;
}
- if (!wpa && (bss->caps & IEEE80211_CAP_IBSS)) {
+ if (bss->caps & IEEE80211_CAP_IBSS) {
wpa_dbg(wpa_s, MSG_DEBUG, " skip - IBSS (adhoc) "
"network");
continue;
}
/* No matching configuration found */
- return 0;
+ return NULL;
}
/* TODO: move the rsn_preauth_scan_result*() to be called from notify.c based
* on BSS added and BSS changed events */
static void wpa_supplicant_rsn_preauth_scan_results(
- struct wpa_supplicant *wpa_s, struct wpa_scan_results *scan_res)
+ struct wpa_supplicant *wpa_s)
{
- int i;
+ struct wpa_bss *bss;
if (rsn_preauth_scan_results(wpa_s->wpa) < 0)
return;
- for (i = scan_res->num - 1; i >= 0; i--) {
+ dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
const u8 *ssid, *rsn;
- struct wpa_scan_res *r;
- r = scan_res->res[i];
-
- ssid = wpa_scan_get_ie(r, WLAN_EID_SSID);
+ ssid = wpa_bss_get_ie(bss, WLAN_EID_SSID);
if (ssid == NULL)
continue;
- rsn = wpa_scan_get_ie(r, WLAN_EID_RSN);
+ rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
if (rsn == NULL)
continue;
- rsn_preauth_scan_result(wpa_s->wpa, r->bssid, ssid, rsn);
+ rsn_preauth_scan_result(wpa_s->wpa, bss->bssid, ssid, rsn);
}
}
if (wpa_s->current_ssid != ssid)
return 1; /* different network block */
+ if (wpas_driver_bss_selection(wpa_s))
+ return 0; /* Driver-based roaming */
+
for (i = 0; i < scan_res->num; i++) {
struct wpa_scan_res *res = scan_res->res[i];
const u8 *ie;
return 0;
}
- if (bgscan_notify_scan(wpa_s, scan_res) == 1) {
+ if (!wpas_driver_bss_selection(wpa_s) &&
+ bgscan_notify_scan(wpa_s, scan_res) == 1) {
wpa_scan_results_free(scan_res);
return 0;
}
- wpa_supplicant_rsn_preauth_scan_results(wpa_s, scan_res);
-
selected = wpa_supplicant_pick_network(wpa_s, scan_res, &ssid);
if (selected) {
if (skip)
return 0;
wpa_supplicant_connect(wpa_s, selected, ssid);
+ wpa_supplicant_rsn_preauth_scan_results(wpa_s);
} else {
wpa_scan_results_free(scan_res);
wpa_dbg(wpa_s, MSG_DEBUG, "No suitable network found");
if (ssid) {
wpa_dbg(wpa_s, MSG_DEBUG, "Setup a new network");
wpa_supplicant_associate(wpa_s, NULL, ssid);
+ wpa_supplicant_rsn_preauth_scan_results(wpa_s);
} else {
- int timeout_sec = 5;
+ int timeout_sec = wpa_s->scan_interval;
int timeout_usec = 0;
#ifdef CONFIG_P2P
if (wpa_s->p2p_in_provisioning) {
l = data->assoc_info.resp_ies_len;
#ifdef CONFIG_WPS_STRICT
- if (wpa_s->current_ssid &&
+ if (p && wpa_s->current_ssid &&
wpa_s->current_ssid->key_mgmt == WPA_KEY_MGMT_WPS) {
struct wpabuf *wps;
wps = ieee802_11_vendor_ie_concat(p, l, WPS_IE_VENDOR_TYPE);
if (wpa_found || rsn_found)
wpa_s->ap_ies_from_associnfo = 1;
+ if (wpa_s->assoc_freq && data->assoc_info.freq &&
+ wpa_s->assoc_freq != data->assoc_info.freq) {
+ wpa_printf(MSG_DEBUG, "Operating frequency changed from "
+ "%u to %u MHz",
+ wpa_s->assoc_freq, data->assoc_info.freq);
+ wpa_supplicant_update_scan_results(wpa_s);
+ }
+
wpa_s->assoc_freq = data->assoc_info.freq;
return 0;
if (wpa_s->current_ssid &&
wpa_s->current_ssid->mode == WPAS_MODE_IBSS &&
wpa_s->key_mgmt != WPA_KEY_MGMT_NONE &&
- wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE)
- ibss_rsn_connected(wpa_s->ibss_rsn);
+ wpa_s->key_mgmt != WPA_KEY_MGMT_WPA_NONE &&
+ wpa_s->ibss_rsn == NULL) {
+ wpa_s->ibss_rsn = ibss_rsn_init(wpa_s);
+ if (!wpa_s->ibss_rsn) {
+ wpa_msg(wpa_s, MSG_INFO, "Failed to init IBSS RSN");
+ wpa_supplicant_deauthenticate(
+ wpa_s, WLAN_REASON_DEAUTH_LEAVING);
+ return;
+ }
+
+ ibss_rsn_set_psk(wpa_s->ibss_rsn, wpa_s->current_ssid->psk);
+ }
#endif /* CONFIG_IBSS_RSN */
}
l2_packet_deinit(wpa_s->l2);
wpa_s->l2 = NULL;
#ifdef CONFIG_IBSS_RSN
- ibss_rsn_stop(wpa_s->ibss_rsn, NULL);
+ ibss_rsn_deinit(wpa_s->ibss_rsn);
+ wpa_s->ibss_rsn = NULL;
#endif /* CONFIG_IBSS_RSN */
#ifdef CONFIG_TERMINATE_ONLASTIF
/* check if last interface */
size_t ie_len = data->rx_mgmt.frame_len -
(mgmt->u.probe_req.variable -
data->rx_mgmt.frame);
- wpas_p2p_probe_req_rx(wpa_s, src, ie, ie_len);
+ wpas_p2p_probe_req_rx(wpa_s, src, mgmt->da,
+ mgmt->bssid, ie, ie_len);
break;
}
#endif /* CONFIG_P2P */
}
#endif /* CONFIG_SME */
#endif /* CONFIG_IEEE80211W */
+#ifdef CONFIG_GAS
+ if (data->rx_action.category == WLAN_ACTION_PUBLIC &&
+ gas_query_rx(wpa_s->gas, data->rx_action.da,
+ data->rx_action.sa, data->rx_action.bssid,
+ data->rx_action.data, data->rx_action.len,
+ data->rx_action.freq) == 0)
+ break;
+#endif /* CONFIG_GAS */
#ifdef CONFIG_P2P
wpas_p2p_rx_action(wpa_s, data->rx_action.da,
data->rx_action.sa,
#endif /* CONFIG_P2P */
break;
case EVENT_RX_PROBE_REQ:
+ if (data->rx_probe_req.sa == NULL ||
+ data->rx_probe_req.ie == NULL)
+ break;
#ifdef CONFIG_AP
if (wpa_s->ap_iface) {
hostapd_probe_req_rx(wpa_s->ap_iface->bss[0],
data->rx_probe_req.sa,
+ data->rx_probe_req.da,
+ data->rx_probe_req.bssid,
data->rx_probe_req.ie,
data->rx_probe_req.ie_len);
break;
#endif /* CONFIG_AP */
#ifdef CONFIG_P2P
wpas_p2p_probe_req_rx(wpa_s, data->rx_probe_req.sa,
+ data->rx_probe_req.da,
+ data->rx_probe_req.bssid,
data->rx_probe_req.ie,
data->rx_probe_req.ie_len);
#endif /* CONFIG_P2P */
ibss_rsn_stop(wpa_s->ibss_rsn, data->ibss_peer_lost.peer);
#endif /* CONFIG_IBSS_RSN */
break;
+ case EVENT_DRIVER_GTK_REKEY:
+ if (os_memcmp(data->driver_gtk_rekey.bssid,
+ wpa_s->bssid, ETH_ALEN))
+ break;
+ if (!wpa_s->wpa)
+ break;
+ wpa_sm_update_replay_ctr(wpa_s->wpa,
+ data->driver_gtk_rekey.replay_ctr);
+ break;
default:
wpa_msg(wpa_s, MSG_INFO, "Unknown event %d", event);
break;