[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