[PATCH 3/5] scan: Add MAC address randomization in scan handling

Ilan Peer ilan.peer
Sun Dec 28 22:41:06 PST 2014


1. Supported MAC address randomization for scan.
2. Supported MAC address randomization for scheduled scan.
2. Supported MAC address randomization for pno.
4. Add functions to set and clear the MAC address randomization
   state variables.

Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
 wpa_supplicant/scan.c             | 123 ++++++++++++++++++++++++++++++++++++++
 wpa_supplicant/scan.h             |   4 ++
 wpa_supplicant/wpa_supplicant.c   |  10 ++++
 wpa_supplicant/wpa_supplicant_i.h |  18 ++++++
 4 files changed, 155 insertions(+)

diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 6f4ea08..8406d2f 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -938,6 +938,14 @@ ssid_list_set:
 	}
 #endif /* CONFIG_P2P */
 
+	if (wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCAN) {
+		params.mac_addr_rand = 1;
+		if (wpa_s->mac_addr_scan[0] && wpa_s->mac_addr_scan[1]) {
+			params.mac_addr = wpa_s->mac_addr_scan[0];
+			params.mac_addr_mask = wpa_s->mac_addr_scan[1];
+		}
+	}
+
 	scan_params = ¶ms;
 
 scan:
@@ -1281,6 +1289,15 @@ scan:
 
 	wpa_setband_scan_freqs(wpa_s, scan_params);
 
+	if (wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCHED_SCAN) {
+		params.mac_addr_rand = 1;
+		if (wpa_s->mac_addr_sched_scan[0] &&
+		    wpa_s->mac_addr_sched_scan[1]) {
+			params.mac_addr = wpa_s->mac_addr_sched_scan[0];
+			params.mac_addr_mask = wpa_s->mac_addr_sched_scan[1];
+		}
+	}
+
 	ret = wpa_supplicant_start_sched_scan(wpa_s, scan_params,
 					      wpa_s->sched_scan_interval);
 	wpabuf_free(extra_ie);
@@ -1926,6 +1943,26 @@ wpa_scan_clone_params(const struct wpa_driver_scan_params *src)
 	params->only_new_results = src->only_new_results;
 	params->low_priority = src->low_priority;
 
+	if (src->mac_addr_rand) {
+		params->mac_addr_rand = src->mac_addr_rand;
+
+		if (src->mac_addr && src->mac_addr_mask) {
+			u8 *mac_addr, *mac_addr_mask;
+
+			mac_addr = (u8 *)os_malloc(ETH_ALEN);
+			mac_addr_mask = (u8 *)os_malloc(ETH_ALEN);
+			if (!mac_addr || !mac_addr_mask) {
+				os_free(mac_addr);
+				os_free(mac_addr_mask);
+				goto failed;
+			}
+
+			os_memcpy(mac_addr, src->mac_addr, ETH_ALEN);
+			params->mac_addr = mac_addr;
+			os_memcpy(mac_addr_mask, src->mac_addr_mask, ETH_ALEN);
+			params->mac_addr_mask = mac_addr_mask;
+		}
+	}
 	return params;
 
 failed:
@@ -1946,6 +1983,9 @@ void wpa_scan_free_params(struct wpa_driver_scan_params *params)
 	os_free((u8 *) params->extra_ies);
 	os_free(params->freqs);
 	os_free(params->filter_ssids);
+	os_free((u8 *)params->mac_addr);
+	os_free((u8 *)params->mac_addr_mask);
+
 	os_free(params);
 }
 
@@ -2050,6 +2090,14 @@ int wpas_start_pno(struct wpa_supplicant *wpa_s)
 		params.freqs = wpa_s->manual_sched_scan_freqs;
 	}
 
+	if (wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_PNO) {
+		params.mac_addr_rand = 1;
+		if (wpa_s->mac_addr_pno[0] && wpa_s->mac_addr_pno[1]) {
+			params.mac_addr = wpa_s->mac_addr_pno[0];
+			params.mac_addr_mask = wpa_s->mac_addr_pno[1];
+		}
+	}
+
 	ret = wpa_supplicant_start_sched_scan(wpa_s, &params, interval);
 	os_free(params.filter_ssids);
 	if (ret == 0)
@@ -2077,3 +2125,78 @@ int wpas_stop_pno(struct wpa_supplicant *wpa_s)
 
 	return ret;
 }
+
+
+void wpas_mac_addr_rand_scan_clear(struct wpa_supplicant *wpa_s,
+				    unsigned int type)
+{
+	type &= MAC_ADDR_RAND_ALL;
+	wpa_s->mac_addr_rand_enable &= ~type;
+
+	if (type & MAC_ADDR_RAND_SCAN) {
+		os_free(wpa_s->mac_addr_scan[0]);
+		wpa_s->mac_addr_scan[0] = NULL;
+		os_free(wpa_s->mac_addr_scan[1]);
+		wpa_s->mac_addr_scan[1] = NULL;
+	}
+
+	if (type & MAC_ADDR_RAND_SCHED_SCAN) {
+		os_free(wpa_s->mac_addr_sched_scan[0]);
+		wpa_s->mac_addr_sched_scan[0] = NULL;
+		os_free(wpa_s->mac_addr_sched_scan[1]);
+		wpa_s->mac_addr_sched_scan[1] = NULL;
+	}
+
+	if (type & MAC_ADDR_RAND_PNO) {
+		os_free(wpa_s->mac_addr_pno[0]);
+		wpa_s->mac_addr_pno[0] = NULL;
+		os_free(wpa_s->mac_addr_pno[1]);
+		wpa_s->mac_addr_pno[1] = NULL;
+	}
+}
+
+
+int wpas_mac_addr_rand_scan_set(struct wpa_supplicant *wpa_s,
+				unsigned int type, u8 *addr, u8 *mask)
+{
+	u8 *taddr, *tmask;
+
+	wpas_mac_addr_rand_scan_clear(wpa_s, type);
+
+	if (addr) {
+		taddr = os_malloc(ETH_ALEN);
+		if (!taddr)
+			return -1;
+
+		tmask = os_malloc(ETH_ALEN);
+		if (!tmask) {
+			os_free(taddr);
+			return -1;
+		}
+		os_memcpy(taddr, addr, ETH_ALEN);
+		os_memcpy(tmask, mask, ETH_ALEN);
+	} else {
+		taddr = NULL;
+		tmask = NULL;
+	}
+
+	if (type == MAC_ADDR_RAND_SCAN) {
+		wpa_s->mac_addr_scan[0] = taddr;
+		wpa_s->mac_addr_scan[1] = tmask;
+	} else if (type == MAC_ADDR_RAND_SCHED_SCAN) {
+		wpa_s->mac_addr_sched_scan[0] = taddr;
+		wpa_s->mac_addr_sched_scan[1] = tmask;
+	} else if (type == MAC_ADDR_RAND_PNO) {
+		wpa_s->mac_addr_pno[0] = taddr;
+		wpa_s->mac_addr_pno[1] = tmask;
+	} else {
+		wpa_printf(MSG_ERROR, "scan: invalid mac randomization type=%u",
+			   type);
+		os_free(taddr);
+		os_free(tmask);
+		return -1;
+	}
+
+	wpa_s->mac_addr_rand_enable |= type;
+	return 0;
+}
diff --git a/wpa_supplicant/scan.h b/wpa_supplicant/scan.h
index 946d2b3..1915dc4 100644
--- a/wpa_supplicant/scan.h
+++ b/wpa_supplicant/scan.h
@@ -49,4 +49,8 @@ void wpa_scan_free_params(struct wpa_driver_scan_params *params);
 int wpas_start_pno(struct wpa_supplicant *wpa_s);
 int wpas_stop_pno(struct wpa_supplicant *wpa_s);
 
+void wpas_mac_addr_rand_scan_clear(struct wpa_supplicant *wpa_s,
+				   unsigned int type);
+int wpas_mac_addr_rand_scan_set(struct wpa_supplicant *wpa_s,
+				unsigned int type, u8 *addr, u8 *mask);
 #endif /* SCAN_H */
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 995c8d8..f2f0006 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -484,6 +484,8 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
 	os_free(wpa_s->manual_sched_scan_freqs);
 	wpa_s->manual_sched_scan_freqs = NULL;
 
+	wpas_mac_addr_rand_scan_clear(wpa_s, MAC_ADDR_RAND_ALL);
+
 	gas_query_deinit(wpa_s->gas);
 	wpa_s->gas = NULL;
 
@@ -3818,7 +3820,15 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
 		wpa_s->num_multichan_concurrent =
 			capa.num_multichan_concurrent;
 		wpa_s->wmm_ac_supported = capa.wmm_ac_supported;
+
+		if (capa.mac_addr_rand_scan_supported)
+			wpa_s->mac_addr_rand_supported |= MAC_ADDR_RAND_SCAN;
+		if (wpa_s->sched_scan_supported &&
+		    capa.mac_addr_rand_sched_scan_supported)
+			wpa_s->mac_addr_rand_supported |=
+				(MAC_ADDR_RAND_SCHED_SCAN | MAC_ADDR_RAND_PNO);
 	}
+
 	if (wpa_s->max_remain_on_chan == 0)
 		wpa_s->max_remain_on_chan = 1000;
 
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index b0f3866..91b9764 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -893,6 +893,24 @@ struct wpa_supplicant {
 	unsigned int wmm_ac_supported:1;
 	unsigned int ext_work_in_progress:1;
 
+#define MAC_ADDR_RAND_SCAN       BIT(0)
+#define MAC_ADDR_RAND_SCHED_SCAN BIT(1)
+#define MAC_ADDR_RAND_PNO        BIT(2)
+#define MAC_ADDR_RAND_ALL        (MAC_ADDR_RAND_SCAN | \
+				  MAC_ADDR_RAND_SCHED_SCAN | \
+				  MAC_ADDR_RAND_PNO)
+	unsigned int mac_addr_rand_supported;
+	unsigned int mac_addr_rand_enable;
+
+	/*
+	 * array indexes:
+	 * [0] - mac address
+	 * [1] - mac address mask
+	 */
+	u8 *mac_addr_scan[2];
+	u8 *mac_addr_sched_scan[2];
+	u8 *mac_addr_pno[2];
+
 #ifdef CONFIG_WNM
 	u8 wnm_dialog_token;
 	u8 wnm_reply;
-- 
1.8.3.2




More information about the Hostap mailing list