P2P MAC Randomization
Randomize the MAC address of p2p-discovery and group interfaces
Bug:151203962
Test: Tested from Android -R UI and verified on sniffer.a
Signed-off-by: Mir Ali <mir-khizer.ali@broadcom.com>
Change-Id: I1428cbe81d7bbf6126aa7a3b2d9af823bc18b9ae
diff --git a/src/common/brcm_vendor.h b/src/common/brcm_vendor.h
index cb5b348..b1bf397 100644
--- a/src/common/brcm_vendor.h
+++ b/src/common/brcm_vendor.h
@@ -27,6 +27,7 @@
*/
enum brcm_nl80211_vendor_subcmds {
BRCM_VENDOR_SUBCMD_UNSPEC = 0,
+ BRCM_VENDOR_SUBCMD_SET_MAC = 6,
BRCM_VENDOR_SCMD_ACS = 9,
BRCM_VENDOR_SCMD_MAX = 10
};
@@ -61,5 +62,12 @@
BRCM_VENDOR_ATTR_ACS_LAST
};
+
+enum brcm_wlan_vendor_attr {
+ BRCM_ATTR_DRIVER_CMD = 0,
+ BRCM_ATTR_DRIVER_MAC_ADDR = 3,
+ BRCM_ATTR_DRIVER_AFTER_LAST = 5,
+ BRCM_ATTR_DRIVER_MAX = BRCM_ATTR_DRIVER_AFTER_LAST - 1,
+};
#endif /* BRCM_VENDOR_H */
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index ca74d35..4295f0c 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -7689,8 +7689,10 @@
drv->global->if_add_wdevid = p2pdev_info.wdev_id;
drv->global->if_add_wdevid_set = p2pdev_info.wdev_id_set;
- if (!is_zero_ether_addr(p2pdev_info.macaddr))
+ if (!is_zero_ether_addr(p2pdev_info.macaddr)) {
os_memcpy(if_addr, p2pdev_info.macaddr, ETH_ALEN);
+ os_memcpy(drv->global->p2p_perm_addr, p2pdev_info.macaddr, ETH_ALEN);
+ }
wpa_printf(MSG_DEBUG, "nl80211: New P2P Device interface %s (0x%llx) created",
ifname,
(long long unsigned int) p2pdev_info.wdev_id);
@@ -10125,10 +10127,45 @@
struct i802_bss *bss = priv;
struct wpa_driver_nl80211_data *drv = bss->drv;
int new_addr = addr != NULL;
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+ struct nl_msg *msg;
+ struct nlattr *params;
+ int ret;
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
+ wpa_printf(MSG_DEBUG, "Enter: %s", __FUNCTION__);
if (TEST_FAIL())
return -1;
+ if (drv->nlmode == NL80211_IFTYPE_P2P_DEVICE) {
+#ifdef CONFIG_DRIVER_NL80211_BRCM
+ if (!addr ) {
+ addr = drv->global->p2p_perm_addr;
+ }
+ if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_VENDOR)) ||
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_BRCM) ||
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+ BRCM_VENDOR_SUBCMD_SET_MAC) ||
+ !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
+ nla_put(msg, BRCM_ATTR_DRIVER_MAC_ADDR, ETH_ALEN, addr)) {
+ wpa_printf(MSG_ERROR, "failed to put p2p randmac");
+ nl80211_nlmsg_clear(msg);
+ nlmsg_free(msg);
+ return -ENOBUFS;
+ }
+ nla_nest_end(msg, params);
+
+ ret = send_and_recv_msgs(drv, msg, NULL, (void *) -1, NULL, NULL);
+ if (ret) {
+ wpa_printf(MSG_ERROR, "nl80211: p2p set macaddr failed: ret=%d (%s)",
+ ret, strerror(-ret));
+ }
+ memcpy(bss->addr, addr, ETH_ALEN);
+ return ret;
+#else
+ return -ENOTSUP;
+#endif /* CONFIG_DRIVER_NL80211_BRCM */
+ }
if (!addr)
addr = drv->perm_addr;
@@ -10138,27 +10175,26 @@
if (linux_set_ifhwaddr(drv->global->ioctl_sock, bss->ifname, addr) < 0)
{
wpa_printf(MSG_DEBUG,
- "nl80211: failed to set_mac_addr for %s to " MACSTR,
- bss->ifname, MAC2STR(addr));
+ "nl80211: failed to set_mac_addr for %s to " MACSTR,
+ bss->ifname, MAC2STR(addr));
if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname,
- 1) < 0) {
+ 1) < 0) {
wpa_printf(MSG_DEBUG,
- "nl80211: Could not restore interface UP after failed set_mac_addr");
+ "nl80211: Could not restore interface UP after failed set_mac_addr");
}
return -1;
}
wpa_printf(MSG_DEBUG, "nl80211: set_mac_addr for %s to " MACSTR,
- bss->ifname, MAC2STR(addr));
+ bss->ifname, MAC2STR(addr));
drv->addr_changed = new_addr;
os_memcpy(bss->addr, addr, ETH_ALEN);
if (linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1) < 0)
{
wpa_printf(MSG_DEBUG,
- "nl80211: Could not restore interface UP after set_mac_addr");
+ "nl80211: Could not restore interface UP after set_mac_addr");
}
-
return 0;
}
diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
index 017c025..0db7d55 100644
--- a/src/drivers/driver_nl80211.h
+++ b/src/drivers/driver_nl80211.h
@@ -33,8 +33,8 @@
struct nl_sock *nl;
int nl80211_id;
int ioctl_sock; /* socket for ioctl() use */
-
struct nl_sock *nl_event;
+ u8 p2p_perm_addr[ETH_ALEN];
};
struct nl80211_wiphy_data {
diff --git a/wpa_supplicant/hidl/1.4/p2p_iface.cpp b/wpa_supplicant/hidl/1.4/p2p_iface.cpp
index d3d374e..8e1e264 100644
--- a/wpa_supplicant/hidl/1.4/p2p_iface.cpp
+++ b/wpa_supplicant/hidl/1.4/p2p_iface.cpp
@@ -1796,14 +1796,6 @@
bool currentEnabledState = !!wpa_s->conf->p2p_device_random_mac_addr;
u8 *addr = NULL;
- // A dedicated p2p device is not managed by supplicant,
- // supplicant could not change its MAC address.
- if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) {
- wpa_printf(MSG_ERROR,
- "Dedicated P2P device don't support MAC randomization");
- return {SupplicantStatusCode::FAILURE_ARGS_INVALID, "NotSupported"};
- }
-
// The same state, no change is needed.
if (currentEnabledState == enable) {
wpa_printf(MSG_DEBUG, "The random MAC is %s already.",
diff --git a/wpa_supplicant/hidl/1.4/p2p_iface.h b/wpa_supplicant/hidl/1.4/p2p_iface.h
index 4d07051..4a0e60a 100644
--- a/wpa_supplicant/hidl/1.4/p2p_iface.h
+++ b/wpa_supplicant/hidl/1.4/p2p_iface.h
@@ -30,6 +30,8 @@
#include "config.h"
}
+#define P2P_MGMT_DEVICE_PREFIX "p2p-dev-"
+
namespace android {
namespace hardware {
namespace wifi {
diff --git a/wpa_supplicant/hidl/1.4/supplicant.cpp b/wpa_supplicant/hidl/1.4/supplicant.cpp
index 5fea68d..6f4cde6 100644
--- a/wpa_supplicant/hidl/1.4/supplicant.cpp
+++ b/wpa_supplicant/hidl/1.4/supplicant.cpp
@@ -10,6 +10,7 @@
#include "hidl_manager.h"
#include "hidl_return_util.h"
#include "supplicant.h"
+#include "p2p_iface.h"
#include <android-base/file.h>
#include <fcntl.h>
@@ -254,6 +255,39 @@
}
std::pair<SupplicantStatus, sp<ISupplicantIface>>
+Supplicant::addP2pDevInterface(struct wpa_interface iface_params)
+{
+ char primary_ifname[IFNAMSIZ];
+ u32 primary_ifname_len =
+ strlen(iface_params.ifname) - strlen(P2P_MGMT_DEVICE_PREFIX);
+
+ if(primary_ifname_len > IFNAMSIZ) {
+ wpa_printf(MSG_DEBUG, "%s, Invalid primary iface name ", __FUNCTION__);
+ return {{SupplicantStatusCode::FAILURE_ARGS_INVALID, ""}, {}};
+ }
+
+ strncpy(primary_ifname, iface_params.ifname +
+ strlen(P2P_MGMT_DEVICE_PREFIX), primary_ifname_len);
+ wpa_printf(MSG_DEBUG, "%s, Initialize p2p-dev-wlan0 iface with"
+ "primary_iface = %s", __FUNCTION__, primary_ifname);
+ struct wpa_supplicant* wpa_s =
+ wpa_supplicant_get_iface(wpa_global_, primary_ifname);
+ if (!wpa_s) {
+ wpa_printf(MSG_DEBUG, "%s,NULL wpa_s for wlan0", __FUNCTION__);
+ return {{SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""},
+ nullptr};
+ }
+ if (wpas_p2p_add_p2pdev_interface(
+ wpa_s, wpa_s->global->params.conf_p2p_dev) < 0) {
+ wpa_printf(MSG_INFO,
+ "Failed to enable P2P Device");
+ return {{SupplicantStatusCode::FAILURE_UNKNOWN,
+ "Enable P2P Device failed"}, {}};
+ }
+ return {{SupplicantStatusCode::SUCCESS,""}, {}};
+}
+
+std::pair<SupplicantStatus, sp<ISupplicantIface>>
Supplicant::addInterfaceInternal(const IfaceInfo& iface_info)
{
android::sp<ISupplicantIface> iface;
@@ -305,10 +339,19 @@
}
}
iface_params.ifname = iface_info.name.c_str();
- struct wpa_supplicant* wpa_s =
- wpa_supplicant_add_iface(wpa_global_, &iface_params, NULL);
- if (!wpa_s) {
- return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
+ if (strncmp(iface_params.ifname, P2P_MGMT_DEVICE_PREFIX,
+ strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
+ std::tie(status, iface) = addP2pDevInterface(iface_params);
+ if (status.code != SupplicantStatusCode::SUCCESS) {
+ return {{status.code,
+ status.debugMessage.c_str()}, iface};
+ }
+ } else {
+ struct wpa_supplicant* wpa_s =
+ wpa_supplicant_add_iface(wpa_global_, &iface_params, NULL);
+ if (!wpa_s) {
+ return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
+ }
}
// The supplicant core creates a corresponding hidl object via
// HidlManager when |wpa_supplicant_add_iface| is called.
diff --git a/wpa_supplicant/hidl/1.4/supplicant.h b/wpa_supplicant/hidl/1.4/supplicant.h
index 8fd2033..2944c50 100644
--- a/wpa_supplicant/hidl/1.4/supplicant.h
+++ b/wpa_supplicant/hidl/1.4/supplicant.h
@@ -81,6 +81,8 @@
SupplicantStatus setDebugParamsInternal(
ISupplicant::DebugLevel level, bool show_timestamp, bool show_keys);
SupplicantStatus setConcurrencyPriorityInternal(IfaceType type);
+ std::pair<SupplicantStatus, sp<ISupplicantIface>> addP2pDevInterface(
+ struct wpa_interface iface_params);
// Raw pointer to the global structure maintained by the core.
struct wpa_global* wpa_global_;