wlan: HDD: Add mac spoofing support based on random mac OUI
This is done as per need to spoof scans. Only FW initialted
scans will use spoofed mac addr after this.
Add a way to pass first 3 bytes (OUI bytes) of mac addr from
cfg80211 and randomly generate last three bytes in driver
and send them to FW. Disable spoof scanning by set first 3 bytes
of mac addr to 00:00:00.
Change-Id: If862a2e28dccd7c9dc4d1ab6b6105148fc78cb0e
CRs-Fixed: 731655
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index 828a930..846b211 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -3091,6 +3091,13 @@
CFG_ENABLE_DEAUTH_BEFORE_CONNECTION_MIN,
CFG_ENABLE_DEAUTH_BEFORE_CONNECTION_MAX),
+ REG_VARIABLE(CFG_ENABLE_MAC_ADDR_SPOOFING, WLAN_PARAM_Integer,
+ hdd_config_t, enableMacSpoofing,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_ENABLE_MAC_ADDR_SPOOFING_DEFAULT,
+ CFG_ENABLE_MAC_ADDR_SPOOFING_MIN,
+ CFG_ENABLE_MAC_ADDR_SPOOFING_MAX),
+
REG_VARIABLE(CFG_ENABLE_CH_AVOID, WLAN_PARAM_Integer,
hdd_config_t, fenableCHAvoidance,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index b0918c1..1c3d228 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -3972,6 +3972,72 @@
[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
};
+
+static const struct nla_policy
+wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
+{
+ [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
+};
+
+static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ void *data,
+ int data_len)
+{
+
+ hdd_context_t *pHddCtx = wiphy_priv(wiphy);
+ struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
+
+ if (0 != wlan_hdd_validate_context(pHddCtx)){
+ hddLog(VOS_TRACE_LEVEL_ERROR, FL("hdd Ctx invalid while spoof macAddr"));
+ return -EINVAL;
+ }
+ if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
+ hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN disabled in ini"));
+ return -ENOTSUPP;
+ }
+ if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
+ hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN not supported by FW"));
+ return -ENOTSUPP;
+ }
+
+ if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
+ data, data_len, wlan_hdd_mac_config)) {
+ hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
+ return -EINVAL;
+ }
+
+ /* Parse and fetch mac address */
+ if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
+ hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
+ return -EINVAL;
+ }
+
+ memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
+ tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
+ VOS_MAC_ADDR_LAST_3_BYTES);
+
+ vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,nla_data(
+ tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
+ VOS_MAC_ADDR_FIRST_3_BYTES);
+
+ if (VOS_STATUS_SUCCESS != vos_randomize_n_bytes(
+ (void *)(&pHddCtx->spoofMacAddr.randomMacAddr.bytes[3]),
+ VOS_MAC_ADDR_LAST_3_BYTES)) {
+ hddLog(LOGE, FL("Failed to generate random Mac Addr"));
+ }
+ vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ pHddCtx->spoofMacAddr.randomMacAddr.bytes,
+ VOS_MAC_ADDR_SIZE);
+
+ if (eHAL_STATUS_SUCCESS != sme_SpoofMacAddrReq(pHddCtx->hHal,
+ &pHddCtx->spoofMacAddr.randomMacAddr)) {
+ hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
+ }
+
+ return 0;
+}
+
static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
struct wireless_dev *wdev,
void *data,
@@ -4358,6 +4424,13 @@
.doit = wlan_hdd_cfg80211_exttdls_get_status
},
+ {
+ .info.vendor_id = QCA_NL80211_VENDOR_ID,
+ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+ WIPHY_VENDOR_CMD_NEED_NETDEV,
+ .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
+ },
};
/* vendor specific events */