diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 78f0e68f3..d4570d6af 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -4528,6 +4528,21 @@ static int wpa_config_process_p2p_no_go_freq( return 0; } + +static int wpa_config_process_p2p_device_persistent_mac_addr( + const struct global_parse_data *data, + struct wpa_config *config, int line, const char *pos) +{ + if (hwaddr_aton2(pos, config->p2p_device_persistent_mac_addr) < 0) { + wpa_printf(MSG_ERROR, + "Line %d: Invalid p2p_device_persistent_mac_addr '%s'", + line, pos); + return -1; + } + + return 0; +} + #endif /* CONFIG_P2P */ @@ -4770,6 +4785,8 @@ static const struct global_parse_data global_fields[] = { { IPV4(ip_addr_start), 0 }, { IPV4(ip_addr_end), 0 }, { INT_RANGE(p2p_cli_probe, 0, 1), 0 }, + { INT(p2p_device_random_mac_addr), 0 }, + { FUNC(p2p_device_persistent_mac_addr), 0 }, #endif /* CONFIG_P2P */ { FUNC(country), CFG_CHANGED_COUNTRY }, { INT(bss_max_count), 0 }, diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 2e8e05733..0d0282755 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -1488,6 +1488,25 @@ struct wpa_config { * 1 = enabled (true) */ int coloc_intf_reporting; + + /** + * p2p_device_random_mac_addr - P2P Device MAC address policy default + * + * 0 = use permanent MAC address + * 1 = use random MAC address on creating the interface if there is no + * persistent groups. + * + * By default, permanent MAC address is used. + */ + int p2p_device_random_mac_addr; + + /** + * p2p_device_persistent_mac_addr - Record last used MAC address + * + * If there are saved persistent groups, P2P cannot generate another + * random MAC address, and need to restore to last used MAC address. + */ + u8 p2p_device_persistent_mac_addr[ETH_ALEN]; }; diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 72252a29f..57d8afcf0 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -1529,6 +1529,12 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) if (config->coloc_intf_reporting) fprintf(f, "coloc_intf_reporting=%d\n", config->coloc_intf_reporting); + if (config->p2p_device_random_mac_addr) + fprintf(f, "p2p_device_random_mac_addr=%d\n", + config->p2p_device_random_mac_addr); + if (!is_zero_ether_addr(config->p2p_device_persistent_mac_addr)) + fprintf(f, "p2p_device_persistent_mac_addr=" MACSTR "\n", + MAC2STR(config->p2p_device_persistent_mac_addr)); } #endif /* CONFIG_NO_CONFIG_WRITE */ diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 570c09b59..6df4f763d 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -4330,6 +4330,54 @@ static int wpas_p2p_get_pref_freq_list(void *ctx, int go, } +int wpas_p2p_mac_setup(struct wpa_supplicant *wpa_s) +{ + u8 addr[ETH_ALEN] = {0}; + + if (wpa_s->conf->p2p_device_random_mac_addr == 0) + return 0; + + if (!wpa_s->conf->ssid) { + if (random_mac_addr(addr) < 0) { + wpa_msg(wpa_s, MSG_INFO, + "Failed to generate random MAC address"); + return -EINVAL; + } + + /* Store generated MAC address. */ + os_memcpy(wpa_s->conf->p2p_device_persistent_mac_addr, addr, + ETH_ALEN); + } else { + /* If there are existing saved groups, restore last MAC address. + * if there is no last used MAC address, the last one is + * factory MAC. */ + if (is_zero_ether_addr( + wpa_s->conf->p2p_device_persistent_mac_addr)) + return 0; + os_memcpy(addr, wpa_s->conf->p2p_device_persistent_mac_addr, + ETH_ALEN); + wpa_msg(wpa_s, MSG_DEBUG, "Restore last used MAC address."); + } + + if (wpa_drv_set_mac_addr(wpa_s, addr) < 0) { + wpa_msg(wpa_s, MSG_INFO, + "Failed to set random MAC address"); + return -EINVAL; + } + + if (wpa_supplicant_update_mac_addr(wpa_s) < 0) { + wpa_msg(wpa_s, MSG_INFO, + "Could not update MAC address information"); + return -EINVAL; + } + + wpa_msg(wpa_s, MSG_DEBUG, "Using random MAC address " MACSTR, + MAC2STR(addr)); + + return 0; +} + + /** * wpas_p2p_init - Initialize P2P module for %wpa_supplicant * @global: Pointer to global data from wpa_supplicant_init() @@ -4350,6 +4398,12 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s) if (global->p2p) return 0; + if (wpas_p2p_mac_setup(wpa_s) < 0) { + wpa_msg(wpa_s, MSG_ERROR, + "Failed to initialize P2P random MAC address."); + return -1; + } + os_memset(&p2p, 0, sizeof(p2p)); p2p.cb_ctx = wpa_s; p2p.debug_print = wpas_p2p_debug_print; diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index 128dfb767..24ec2cafc 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -211,6 +211,7 @@ int wpas_p2p_lo_start(struct wpa_supplicant *wpa_s, unsigned int freq, unsigned int period, unsigned int interval, unsigned int count); int wpas_p2p_lo_stop(struct wpa_supplicant *wpa_s); +int wpas_p2p_mac_setup(struct wpa_supplicant *wpa_s); #else /* CONFIG_P2P */