[PATCH] Passively set drv->ssid on connect/associate event
Ningyuan Wang
nywang at google.com
Mon Oct 24 10:59:52 PDT 2016
On a connect nl80211 event, wpa_supplicant uses wpa_driver_
nl80211_get_ssid() to fetch the current associated ssid to
compare to existing configurations.
However, wpa_driver_nl80211_get_ssid() uses drv->ssid, which is
a cached value. It is set when we explicitly initial a connect
request using wpa_supplicant. if the association was initiated
outside of wpa_supplicant, we need another way to populate drv->ssid.
This patch sets drv->ssid passively on connect/associate nl80211
events.
Signed-off-by: Ningyuan Wang <nywang at google.com>
---
src/drivers/driver_nl80211.c | 21 +++++++++++++++++++++
src/drivers/driver_nl80211.h | 3 +++
src/drivers/driver_nl80211_event.c | 15 +++++++++++++++
src/drivers/driver_nl80211_scan.c | 15 +++++++++++++--
4 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 1210d43..d8b0ebf 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -1181,6 +1181,27 @@ static void wpa_driver_nl80211_event_rtm_dellink(void *ctx,
}
+unsigned int nl80211_get_assoc_ssid(struct wpa_driver_nl80211_data *drv, u8* ssid)
+{
+ struct nl_msg *msg;
+ int ret;
+ struct nl80211_bss_info_arg arg;
+
+ msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_GET_SCAN);
+ os_memset(&arg, 0, sizeof(arg));
+ arg.drv = drv;
+ ret = send_and_recv_msgs(drv, msg, bss_info_handler, &arg);
+ if (ret == 0) {
+ if (arg.assoc_ssid_len == 0)
+ return 0;
+ os_memcpy(ssid, arg.assoc_ssid, arg.assoc_ssid_len);
+ return arg.assoc_ssid_len;
+ }
+ wpa_printf(MSG_DEBUG, "nl80211: Scan result fetch failed: ret=%d "
+ "(%s)", ret, strerror(-ret));
+ return 0;
+}
+
unsigned int nl80211_get_assoc_freq(struct wpa_driver_nl80211_data *drv)
{
struct nl_msg *msg;
diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
index d0ec48c..db843ad 100644
--- a/src/drivers/driver_nl80211.h
+++ b/src/drivers/driver_nl80211.h
@@ -228,6 +228,7 @@ int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
void *arg, int use_existing);
void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv, int ifidx);
unsigned int nl80211_get_assoc_freq(struct wpa_driver_nl80211_data *drv);
+unsigned int nl80211_get_assoc_ssid(struct wpa_driver_nl80211_data *drv, u8* ssid);
enum chan_width convert2width(int width);
void nl80211_mark_disconnected(struct wpa_driver_nl80211_data *drv);
struct i802_bss * get_bss_ifindex(struct wpa_driver_nl80211_data *drv,
@@ -288,6 +289,8 @@ struct nl80211_bss_info_arg {
unsigned int assoc_freq;
unsigned int ibss_freq;
u8 assoc_bssid[ETH_ALEN];
+ u8 assoc_ssid[SSID_MAX_LEN];
+ u8 assoc_ssid_len;
};
int bss_info_handler(struct nl_msg *msg, void *arg);
diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
index 762e3ac..41305bc 100644
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -255,6 +255,14 @@ static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
event.assoc_info.freq = drv->assoc_freq;
+#ifdef ANDROID
+ // When this associate event was initiated outside of wpa_supplicant,
+ // drv->ssid needs to be set here to satisfy later checking.
+ u8 ssid_len = nl80211_get_assoc_ssid(drv, drv->ssid);
+ if (ssid_len) drv->ssid_len = ssid_len;
+#endif /* ANDROID */
+
+
nl80211_parse_wmm_params(wmm, &event.assoc_info.wmm_params);
wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event);
@@ -355,6 +363,13 @@ static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
event.assoc_info.freq = nl80211_get_assoc_freq(drv);
+#ifdef ANDROID
+ // When this connect event was initiated outside of wpa_supplicant,
+ // drv->ssid needs to be set here to satisfy later checking.
+ u8 ssid_len = nl80211_get_assoc_ssid(drv, drv->ssid);
+ if (ssid_len) drv->ssid_len = ssid_len;
+#endif /* ANDROID */
+
if (authorized && nla_get_u8(authorized)) {
event.assoc_info.authorized = 1;
wpa_printf(MSG_DEBUG, "nl80211: connection authorized");
diff --git a/src/drivers/driver_nl80211_scan.c b/src/drivers/driver_nl80211_scan.c
index c115b6b..3084695 100644
--- a/src/drivers/driver_nl80211_scan.c
+++ b/src/drivers/driver_nl80211_scan.c
@@ -621,15 +621,26 @@ int bss_info_handler(struct nl_msg *msg, void *arg)
MACSTR, MAC2STR(_arg->assoc_bssid));
}
}
- if (!res)
- return NL_SKIP;
if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) {
ie = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
ie_len = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]);
+ enum nl80211_bss_status status;
+ if (bss[NL80211_BSS_STATUS]) {
+ status = nla_get_u32(bss[NL80211_BSS_STATUS]);
+ if (status == NL80211_BSS_STATUS_ASSOCIATED && ie) {
+ const u8* ssid = get_ie(ie, ie_len, WLAN_EID_SSID);
+ if (ssid && ssid[1] > 0 && ssid[1] <= SSID_MAX_LEN) {
+ _arg->assoc_ssid_len = ssid[1];
+ os_memcpy(_arg->assoc_ssid, ssid + 2, ssid[1]);
+ }
+ }
+ }
} else {
ie = NULL;
ie_len = 0;
}
+ if (!res)
+ return NL_SKIP;
if (bss[NL80211_BSS_BEACON_IES]) {
beacon_ie = nla_data(bss[NL80211_BSS_BEACON_IES]);
beacon_ie_len = nla_len(bss[NL80211_BSS_BEACON_IES]);
--
2.8.0.rc3.226.g39d4020
More information about the Hostap
mailing list