aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlan Peer <ilan.peer@intel.com>2014-12-29 06:41:06 (GMT)
committerJouni Malinen <j@w1.fi>2015-01-04 21:06:31 (GMT)
commit56c76fa592d672198f9e58aec60818b92472db66 (patch)
treeeefd3d32007d079c63bf4b47f5b34ce555a6405b
parent86056fea63b7bc9bca170dd3c7daf6f2b699e535 (diff)
downloadhostap-56c76fa592d672198f9e58aec60818b92472db66.zip
hostap-56c76fa592d672198f9e58aec60818b92472db66.tar.gz
hostap-56c76fa592d672198f9e58aec60818b92472db66.tar.bz2
scan: Add MAC address randomization in scan handling
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@intel.com>
-rw-r--r--wpa_supplicant/scan.c107
-rw-r--r--wpa_supplicant/scan.h6
-rw-r--r--wpa_supplicant/wpa_supplicant.c9
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h14
4 files changed, 136 insertions, 0 deletions
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index b303760..cb2c8d6 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) {
+ params.mac_addr = wpa_s->mac_addr_scan;
+ params.mac_addr_mask = wpa_s->mac_addr_scan + ETH_ALEN;
+ }
+ }
+
scan_params = &params;
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) {
+ params.mac_addr = wpa_s->mac_addr_sched_scan;
+ params.mac_addr_mask = wpa_s->mac_addr_sched_scan +
+ ETH_ALEN;
+ }
+ }
+
ret = wpa_supplicant_start_sched_scan(wpa_s, scan_params,
wpa_s->sched_scan_interval);
wpabuf_free(extra_ie);
@@ -1926,6 +1943,23 @@ 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 = os_malloc(2 * ETH_ALEN);
+ if (!mac_addr)
+ goto failed;
+
+ os_memcpy(mac_addr, src->mac_addr, ETH_ALEN);
+ os_memcpy(mac_addr + ETH_ALEN, src->mac_addr_mask,
+ ETH_ALEN);
+ params->mac_addr = mac_addr;
+ params->mac_addr_mask = mac_addr + ETH_ALEN;
+ }
+ }
return params;
failed:
@@ -1946,6 +1980,13 @@ 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);
+
+ /*
+ * Note: params->mac_addr_mask points to same memory allocation and
+ * must not be freed separately.
+ */
+ os_free((u8 *) params->mac_addr);
+
os_free(params);
}
@@ -2050,6 +2091,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) {
+ params.mac_addr = wpa_s->mac_addr_pno;
+ params.mac_addr_mask = wpa_s->mac_addr_pno + ETH_ALEN;
+ }
+ }
+
ret = wpa_supplicant_start_sched_scan(wpa_s, &params, interval);
os_free(params.filter_ssids);
if (ret == 0)
@@ -2077,3 +2126,61 @@ 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);
+ wpa_s->mac_addr_scan = NULL;
+ }
+
+ if (type & MAC_ADDR_RAND_SCHED_SCAN) {
+ os_free(wpa_s->mac_addr_sched_scan);
+ wpa_s->mac_addr_sched_scan = NULL;
+ }
+
+ if (type & MAC_ADDR_RAND_PNO) {
+ os_free(wpa_s->mac_addr_pno);
+ wpa_s->mac_addr_pno = NULL;
+ }
+}
+
+
+int wpas_mac_addr_rand_scan_set(struct wpa_supplicant *wpa_s,
+ unsigned int type, const u8 *addr,
+ const u8 *mask)
+{
+ u8 *tmp = NULL;
+
+ wpas_mac_addr_rand_scan_clear(wpa_s, type);
+
+ if (addr) {
+ tmp = os_malloc(2 * ETH_ALEN);
+ if (!tmp)
+ return -1;
+ os_memcpy(tmp, addr, ETH_ALEN);
+ os_memcpy(tmp + ETH_ALEN, mask, ETH_ALEN);
+ }
+
+ if (type == MAC_ADDR_RAND_SCAN) {
+ wpa_s->mac_addr_scan = tmp;
+ } else if (type == MAC_ADDR_RAND_SCHED_SCAN) {
+ wpa_s->mac_addr_sched_scan = tmp;
+ } else if (type == MAC_ADDR_RAND_PNO) {
+ wpa_s->mac_addr_pno = tmp;
+ } else {
+ wpa_printf(MSG_INFO,
+ "scan: Invalid MAC randomization type=0x%x",
+ type);
+ os_free(tmp);
+ 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..7650f5a 100644
--- a/wpa_supplicant/scan.h
+++ b/wpa_supplicant/scan.h
@@ -49,4 +49,10 @@ 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, const u8 *addr,
+ const u8 *mask);
+
#endif /* SCAN_H */
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 32676cd..e5dc43f 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -488,6 +488,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;
@@ -3869,6 +3871,13 @@ 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 9d24b94..c541ccb 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -897,6 +897,20 @@ 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;
+
+ /* MAC Address followed by mask (2 * ETH_ALEN) */
+ u8 *mac_addr_scan;
+ u8 *mac_addr_sched_scan;
+ u8 *mac_addr_pno;
+
#ifdef CONFIG_WNM
u8 wnm_dialog_token;
u8 wnm_reply;