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/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h
index f61f5ee..8304b39 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -2253,6 +2253,11 @@
#define CFG_ENABLE_DEAUTH_BEFORE_CONNECTION_MAX (1)
#define CFG_ENABLE_DEAUTH_BEFORE_CONNECTION_DEFAULT (0)
+#define CFG_ENABLE_MAC_ADDR_SPOOFING "gEnableMacAddrSpoof"
+#define CFG_ENABLE_MAC_ADDR_SPOOFING_MIN (0)
+#define CFG_ENABLE_MAC_ADDR_SPOOFING_MAX (1)
+#define CFG_ENABLE_MAC_ADDR_SPOOFING_DEFAULT (0)
+
#define CFG_ENABLE_CH_AVOID "gEnableChannelAvoidance"
#define CFG_ENABLE_CH_AVOID_MIN ( 0 )
#define CFG_ENABLE_CH_AVOID_MAX ( 1 )
@@ -2819,6 +2824,7 @@
#endif
v_U32_t deferImpsTime;
v_BOOL_t sendDeauthBeforeCon;
+ v_BOOL_t enableMacSpoofing;
v_BOOL_t fenableCHAvoidance;
v_U8_t gMaxConcurrentActiveSessions;
diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h
index bf65898..a0c9486 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg80211.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h
@@ -154,6 +154,7 @@
QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE = 35,
QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS = 36,
QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE = 37,
+ QCA_NL80211_VENDOR_SUBCMD_MAC_OUI = 39
};
enum qca_nl80211_vendor_subcmds_index {
@@ -779,6 +780,14 @@
};
#endif /* WLAN_FEATURE_EXTSCAN */
+enum qca_wlan_vendor_attr_set_scanning_mac_oui{
+ QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_INVALID = 0,
+ QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI = 1,
+ /* keep last */
+ QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_AFTER_LAST,
+ QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX =
+ QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_AFTER_LAST - 1,
+};
/* Vendor id to be used in vendor specific command and events
* to user space. Use QCA OUI 00:13:74 to match with define in
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index 8295885..7f2688d 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -1119,6 +1119,11 @@
tANI_U32 magic;
}bcnMissRateContext_t;
+typedef struct
+{
+ v_MACADDR_t randomMacAddr;
+}macAddrSpoof_t;
+
/** Adapter stucture definition */
struct hdd_context_s
@@ -1324,6 +1329,7 @@
v_BOOL_t btCoexModeSet;
v_BOOL_t isPnoEnable;
+ macAddrSpoof_t spoofMacAddr;
};
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 */
diff --git a/CORE/VOSS/inc/vos_api.h b/CORE/VOSS/inc/vos_api.h
index 258c848..3744a8b 100644
--- a/CORE/VOSS/inc/vos_api.h
+++ b/CORE/VOSS/inc/vos_api.h
@@ -329,4 +329,6 @@
v_U64_t vos_get_monotonic_boottime(void);
+VOS_STATUS vos_randomize_n_bytes(void *mac_addr, tANI_U32 n);
+
#endif // if !defined __VOS_NVITEM_H
diff --git a/CORE/VOSS/inc/vos_nvitem.h b/CORE/VOSS/inc/vos_nvitem.h
index 815a68e..43d053a 100644
--- a/CORE/VOSS/inc/vos_nvitem.h
+++ b/CORE/VOSS/inc/vos_nvitem.h
@@ -120,6 +120,8 @@
#define VOS_COUNTRY_CODE_LEN 2
#define VOS_MAC_ADDRESS_LEN 6
+#define VOS_MAC_ADDR_LAST_3_BYTES 3
+#define VOS_MAC_ADDR_FIRST_3_BYTES 3
#define VOS_NV_FREQUENCY_FOR_1_3V_SUPPLY_3P2MH 0 //3.2 Mhz
#define VOS_NV_FREQUENCY_FOR_1_3V_SUPPLY_1P6MH 1 //1.6 Mhz
diff --git a/CORE/VOSS/src/vos_api.c b/CORE/VOSS/src/vos_api.c
index 9df8d14..8535fc1 100644
--- a/CORE/VOSS/src/vos_api.c
+++ b/CORE/VOSS/src/vos_api.c
@@ -2205,3 +2205,26 @@
wcnss_get_monotonic_boottime(&ts);
return (((v_U64_t)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000));
}
+
+/**---------------------------------------------------------------------------
+
+ \brief vos_randomize_n_bytes() - HDD Random Mac Addr Generator
+
+ This generates the random mac address for WLAN interface
+
+ \param - mac_addr - pointer to Mac address
+
+ \return - 0 for success, < 0 for failure
+
+ --------------------------------------------------------------------------*/
+
+VOS_STATUS vos_randomize_n_bytes(void *start_addr, tANI_U32 n)
+{
+
+ if (start_addr == NULL )
+ return VOS_STATUS_E_FAILURE;
+
+ get_random_bytes( start_addr, n);
+
+ return eHAL_STATUS_SUCCESS;
+}