[PATCH 3/3] Implement mac_addr_range option for same OUI randomization

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This deprecates option mac_addr=2 while maintaining compatibility.

Signed-off-by: João Lucas <jlucas@xxxxxxxxxxx>
---
 hostapd/main.c                     |  4 ++--
 src/utils/common.c                 | 14 +++++++-------
 src/utils/common.h                 |  2 +-
 wpa_supplicant/config.c            |  3 +++
 wpa_supplicant/config.h            | 10 ++++++++++
 wpa_supplicant/config_file.c       |  4 ++++
 wpa_supplicant/config_ssid.h       | 19 +++++++++++++++++++
 wpa_supplicant/gas_query.c         | 13 ++++---------
 wpa_supplicant/p2p_supplicant.c    |  4 ++--
 wpa_supplicant/wpa_supplicant.c    | 23 +++++++++++++++--------
 wpa_supplicant/wpa_supplicant.conf | 16 ++++++++++++++--
 wpa_supplicant/wpa_supplicant_i.h  |  1 +
 12 files changed, 82 insertions(+), 31 deletions(-)

diff --git a/hostapd/main.c b/hostapd/main.c
index a8bb9d4d6..e42b73dc6 100644
--- a/hostapd/main.c
+++ b/hostapd/main.c
@@ -190,7 +190,7 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
 		if (is_zero_ether_addr(b)) {
 			os_memcpy(hapd->own_addr, h_hapd->mld->mld_addr,
 				  ETH_ALEN);
-			random_mac_addr_keep_oui(hapd->own_addr);
+			random_mac_addr_wrapper(hapd->own_addr, 1, &random_mac_addr);
 		} else {
 			os_memcpy(hapd->own_addr, b, ETH_ALEN);
 		}
@@ -314,7 +314,7 @@ pre_setup_mld:
 		os_memcpy(hapd->mld->mld_addr, hapd->own_addr, ETH_ALEN);
 
 		if (!b)
-			random_mac_addr_keep_oui(hapd->own_addr);
+			random_mac_addr_wrapper(hapd->own_addr, 1, &random_mac_addr);
 		else
 			os_memcpy(hapd->own_addr, b, ETH_ALEN);
 
diff --git a/src/utils/common.c b/src/utils/common.c
index d62dec721..1e78de4e6 100644
--- a/src/utils/common.c
+++ b/src/utils/common.c
@@ -1022,22 +1022,22 @@ void bin_clear_free(void *bin, size_t len)
 }
 
 
-int random_mac_addr(u8 *addr)
-{
-	if (os_get_random(addr, ETH_ALEN) < 0)
+int random_mac_addr_wrapper(u8 *addr, int range, int (*func)(u8*)) {
+	u8 rand[ETH_ALEN];
+	int offset = (range == 1) ? 3 : 0;
+	if (func(rand) < 0)
 		return -1;
+	os_memcpy(addr + offset, rand + offset, ETH_ALEN - offset);
 	addr[0] &= 0xfe; /* unicast */
 	addr[0] |= 0x02; /* locally administered */
 	return 0;
 }
 
 
-int random_mac_addr_keep_oui(u8 *addr)
+int random_mac_addr(u8 *addr)
 {
-	if (os_get_random(addr + 3, 3) < 0)
+	if (os_get_random(addr, ETH_ALEN) < 0)
 		return -1;
-	addr[0] &= 0xfe; /* unicast */
-	addr[0] |= 0x02; /* locally administered */
 	return 0;
 }
 
diff --git a/src/utils/common.h b/src/utils/common.h
index 1dc2ea5aa..513b4a0cf 100644
--- a/src/utils/common.h
+++ b/src/utils/common.h
@@ -601,8 +601,8 @@ bool int_array_includes(int *arr, int val);
 void str_clear_free(char *str);
 void bin_clear_free(void *bin, size_t len);
 
+int random_mac_addr_wrapper(u8 *addr, int range, int (*func)(u8*));
 int random_mac_addr(u8 *addr);
-int random_mac_addr_keep_oui(u8 *addr);
 
 const char * cstr_token(const char *str, const char *delim, const char **last);
 char * str_token(char *str, const char *delim, char **context);
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index c07e61930..e834598a6 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2760,6 +2760,7 @@ static const struct parse_data ssid_fields[] = {
 	{ STR_RANGE(roaming_consortium_selection, 0, MAX_ROAMING_CONS_OI_LEN) },
 #endif /* CONFIG_HS20 */
 	{ INT_RANGE(mac_addr, 0, 4) },
+	{ INT_RANGE(mac_addr_range, 0, 1) },
 	{ FUNC_KEY(mac_value) },
 	{ INT_RANGE(pbss, 0, 2) },
 	{ INT_RANGE(wps_disabled, 0, 1) },
@@ -3352,6 +3353,7 @@ void wpa_config_set_network_defaults(struct wpa_ssid *ssid)
 	ssid->mka_priority = DEFAULT_PRIO_NOT_KEY_SERVER;
 #endif /* CONFIG_MACSEC */
 	ssid->mac_addr = WPAS_MAC_ADDR_STYLE_NOT_SET;
+	ssid->mac_addr_range = WPAS_MAC_ADDR_RANGE_NOT_SET;
 	ssid->max_oper_chwidth = DEFAULT_MAX_OPER_CHWIDTH;
 	ssid->rsn_overriding = RSN_OVERRIDING_NOT_SET;
 }
@@ -5623,6 +5625,7 @@ static const struct global_parse_data global_fields[] = {
 	{ STR(wowlan_triggers), CFG_CHANGED_WOWLAN_TRIGGERS },
 	{ INT(p2p_search_delay), 0},
 	{ INT_RANGE(mac_addr, 0, 4), 0 },
+	{ INT_RANGE(mac_addr_range, 0, 1), 0 },
 	{ INT(rand_addr_lifetime), 0 },
 	{ INT_RANGE(preassoc_mac_addr, 0, 2), 0 },
 	{ INT(key_mgmt_offload), 0},
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index ca227a82e..ced9cf122 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -1474,6 +1474,16 @@ struct wpa_config {
 	 */
 	enum wpas_mac_addr_style mac_addr;
 
+	/**
+	 * mac_addr_range - Whether MAC addresses should maintain OUI octets
+	 *
+	 * 0 = full randomization (default)
+	 * 1 = keep OUI octets of permanent address
+	 *
+	 * Locally administered bit will be set regardless (unless mac_addr <= 0).
+	 */
+	enum wpas_mac_addr_range mac_addr_range;
+
 	/**
 	 * rand_addr_lifetime - Lifetime of random MAC address in seconds
 	 */
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 9b75fc989..d3e34c18a 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -918,6 +918,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
 	STR(roaming_consortium_selection);
 #endif /* CONFIG_HS20 */
 	INT_DEF(mac_addr, -1);
+	INT_DEF(mac_addr_range, -1);
 #ifdef CONFIG_MESH
 	STR(mesh_basic_rates);
 	INT_DEF(dot11MeshMaxRetries, DEFAULT_MESH_MAX_RETRIES);
@@ -1611,6 +1612,9 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
 	if (config->mac_addr)
 		fprintf(f, "mac_addr=%d\n", config->mac_addr);
 
+	if (config->mac_addr_range)
+		fprintf(f, "mac_addr_range=%d\n", config->mac_addr_range);
+
 	if (config->rand_addr_lifetime != DEFAULT_RAND_ADDR_LIFETIME)
 		fprintf(f, "rand_addr_lifetime=%u\n",
 			config->rand_addr_lifetime);
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index 01b3fde8e..ec563cd5b 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -80,6 +80,12 @@ enum wpas_mac_addr_style {
 	WPAS_MAC_ADDR_STYLE_DERIVED_FROM_ESS = 4,
 };
 
+enum wpas_mac_addr_range {
+	WPAS_MAC_ADDR_RANGE_NOT_SET = -1,
+	WPAS_MAC_ADDR_RANGE_FULL = 0,
+	WPAS_MAC_ADDR_RANGE_KEEP_OUI = 1,
+};
+
 /**
  * rsn_overriding - RSN overriding
  *
@@ -1048,6 +1054,19 @@ struct wpa_ssid {
 	 */
 	enum wpas_mac_addr_style mac_addr;
 
+	/**
+	 * mac_addr_range - Whether MAC addresses should maintain OUI octets
+	 *
+	 * 0 = full randomization (default)
+	 * 1 = keep OUI octets of permanent address
+	 *
+	 * Locally administered bit will be set regardless (unless mac_addr <= 0).
+	 * Internally, special value -1 is used to indicate that the parameter
+	 * was not specified in the configuration (i.e., default behavior is
+	 * followed).
+	 */
+	enum wpas_mac_addr_range mac_addr_range;
+
 	/**
 	 * mac_value - Specific MAC address to be used
 	 *
diff --git a/wpa_supplicant/gas_query.c b/wpa_supplicant/gas_query.c
index 7d2993179..bb444a48a 100644
--- a/wpa_supplicant/gas_query.c
+++ b/wpa_supplicant/gas_query.c
@@ -798,19 +798,14 @@ static int gas_query_set_sa(struct gas_query *gas,
 		return 0;
 	}
 
-	if (wpa_s->conf->gas_rand_mac_addr == 1 &&
-	    random_mac_addr(gas->rand_addr) < 0) {
+	if (wpa_s->conf->gas_rand_mac_addr <= 1 &&
+	    random_mac_addr_wrapper(gas->rand_addr,
+	                            wpa_s->conf->gas_rand_mac_addr - 1,
+	                            &random_mac_addr) < 0) {
 		wpa_printf(MSG_ERROR, "GAS: Failed to get random address");
 		return -1;
 	}
 
-	if (wpa_s->conf->gas_rand_mac_addr == 2 &&
-	    random_mac_addr_keep_oui(gas->rand_addr) < 0) {
-		wpa_printf(MSG_ERROR,
-			   "GAS: Failed to get random address with same OUI");
-		return -1;
-	}
-
 	wpa_printf(MSG_DEBUG, "GAS: Use a new random transmitter address "
 		   MACSTR, MAC2STR(gas->rand_addr));
 	os_memcpy(query->sa, gas->rand_addr, ETH_ALEN);
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index b589707e6..1a3fa3b1f 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -2691,7 +2691,7 @@ static int wpas_p2p_add_group_interface(struct wpa_supplicant *wpa_s,
 	}
 
 	if (wpa_s->conf->p2p_interface_random_mac_addr) {
-		random_mac_addr(wpa_s->pending_interface_addr);
+		random_mac_addr_wrapper(wpa_s->pending_interface_addr, 0, &random_mac_addr);
 		wpa_printf(MSG_DEBUG, "P2P: Generate random MAC address " MACSTR
 			   " for the group",
 			   MAC2STR(wpa_s->pending_interface_addr));
@@ -5623,7 +5623,7 @@ int wpas_p2p_mac_setup(struct wpa_supplicant *wpa_s)
 	}
 
 	if (!wpa_s->conf->ssid) {
-		if (random_mac_addr(addr) < 0) {
+		if (random_mac_addr_wrapper(addr, 0, &random_mac_addr) < 0) {
 			wpa_msg(wpa_s, MSG_INFO,
 				"Failed to generate random MAC address");
 			return -EINVAL;
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index fae00ede7..bf83ed738 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -2591,10 +2591,12 @@ int random_mac_addr_from_ssid(u8 *addr, struct wpa_supplicant *wpa_s,
 
 int wpas_update_random_addr(struct wpa_supplicant *wpa_s,
 			    enum wpas_mac_addr_style style,
+			    enum wpas_mac_addr_range range,
 			    struct wpa_ssid *ssid)
 {
 	struct os_reltime now;
 	u8 addr[ETH_ALEN];
+	os_memcpy(addr, wpa_s->perm_addr, ETH_ALEN);
 
 	os_get_reltime(&now);
 	/* Random addresses are valid within a given ESS so check
@@ -2618,13 +2620,12 @@ int wpas_update_random_addr(struct wpa_supplicant *wpa_s,
 	}
 
 	switch (style) {
-	case WPAS_MAC_ADDR_STYLE_RANDOM:
-		if (random_mac_addr(addr) < 0)
-			return -1;
-		break;
 	case WPAS_MAC_ADDR_STYLE_RANDOM_SAME_OUI:
-		os_memcpy(addr, wpa_s->perm_addr, ETH_ALEN);
-		if (random_mac_addr_keep_oui(addr) < 0)
+		range = WPAS_MAC_ADDR_RANGE_KEEP_OUI;
+		wpa_msg(wpa_s, MSG_WARNING,
+			"mac_addr=2 is deprecated, use mac_addr=1 with mac_addr_range=1 instead");
+	case WPAS_MAC_ADDR_STYLE_RANDOM:
+		if (random_mac_addr_wrapper(addr, range, &random_mac_addr) < 0)
 			return -1;
 		break;
 	case WPAS_MAC_ADDR_STYLE_DEDICATED_PER_ESS:
@@ -2680,7 +2681,7 @@ int wpas_update_random_addr_disassoc(struct wpa_supplicant *wpa_s)
 		return 0;
 
 	return wpas_update_random_addr(wpa_s, wpa_s->conf->preassoc_mac_addr,
-				       NULL);
+				       wpa_s->conf->mac_addr_range, NULL);
 }
 
 
@@ -2784,6 +2785,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
 	bool clear_rejected = true;
 	struct wpa_connect_work *cwork;
 	enum wpas_mac_addr_style rand_style;
+	enum wpas_mac_addr_range rand_range;
 
 	wpa_s->own_disconnect_req = 0;
 	wpa_s->own_reconnect_req = 0;
@@ -2800,6 +2802,11 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
 	else
 		rand_style = ssid->mac_addr;
 
+	if (ssid->mac_addr_range == WPAS_MAC_ADDR_RANGE_NOT_SET)
+		rand_range = wpa_s->conf->mac_addr_range;
+	else
+		rand_range = ssid->mac_addr_range;
+
 	wpa_s->eapol_failed = 0;
 	wpa_s->multi_ap_ie = 0;
 #ifndef CONFIG_NO_WMM_AC
@@ -2837,7 +2844,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
 #endif /* CONFIG_SAE */
 
 	if (rand_style > WPAS_MAC_ADDR_STYLE_PERMANENT) {
-		int status = wpas_update_random_addr(wpa_s, rand_style, ssid);
+		int status = wpas_update_random_addr(wpa_s, rand_style, rand_range, ssid);
 
 		if (status < 0)
 			return;
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index 40c5ff57d..4200c9659 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -546,7 +546,8 @@ fast_reauth=1
 # MAC address policy default
 # 0 = use permanent MAC address
 # 1 = use random MAC address for each ESS connection
-# 2 = like 1, but maintain OUI (with local admin bit set)
+# 2 = like 1, but maintain OUI (with local admin bit set; deprecated, use
+#     mac_addr=1 with mac_addr_range=1 instead)
 # 3 = use dedicated/pregenerated MAC address (see mac_value)
 #
 # By default, permanent MAC address is used unless policy is changed by
@@ -554,6 +555,11 @@ fast_reauth=1
 # change this default behavior.
 #mac_addr=0
 
+# MAC address policy range
+# 0 = full randomization (default)
+# 1 = keep OUI octets of permanent address
+#mac_addr_range=0
+
 # Local MAC address to use whenever connecting with this network profile
 # This is used with mac_addr=3.
 #mac_value=02:12:34:56:78:9a
@@ -1711,9 +1717,15 @@ fast_reauth=1
 # MAC address policy
 # 0 = use permanent MAC address
 # 1 = use random MAC address for each ESS connection
-# 2 = like 1, but maintain OUI (with local admin bit set)
+# 2 = like 1, but maintain OUI (with local admin bit set; deprecated, use
+#     mac_addr=1 with mac_addr_range=1 instead)
 #mac_addr=0
 
+# MAC address policy range
+# 0 = full randomization (default)
+# 1 = keep OUI octets of permanent address
+#mac_addr_range=0
+
 # disable_ht: Whether HT (802.11n) should be disabled.
 # 0 = HT enabled (if AP supports it)
 # 1 = HT disabled
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index d5e951f06..1f6bdbee3 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1770,6 +1770,7 @@ int wpas_populate_wfa_capa(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
 			   size_t max_wpa_ie_len);
 int wpas_update_random_addr(struct wpa_supplicant *wpa_s,
 			    enum wpas_mac_addr_style style,
+			    enum wpas_mac_addr_range range,
 			    struct wpa_ssid *ssid);
 int wpas_update_random_addr_disassoc(struct wpa_supplicant *wpa_s);
 void add_freq(int *freqs, int *num_freqs, int freq);
-- 
2.45.3


--g2aje6mts3ohlv5y
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Hostap mailing list
Hostap@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/hostap

--g2aje6mts3ohlv5y--




[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux