Add VPN detection by mac-address for Windows
This patch adds VPN detection for windows
based on known MAC addresses.
- Cisco AnyConnect
- GlobalProtect Virtual Ethernet
Bug: webrtc:13097
Change-Id: Ia90ee50be0dc2dcd2e6e9de1493fdd2c5e7d9d3a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/230245
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Jonas Oreland <jonaso@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#34997}
diff --git a/rtc_base/network.cc b/rtc_base/network.cc
index b485077..a9352d8 100644
--- a/rtc_base/network.cc
+++ b/rtc_base/network.cc
@@ -40,6 +40,14 @@
namespace rtc {
namespace {
+// List of MAC addresses of known VPN (for windows).
+constexpr uint8_t kVpns[2][6] = {
+ // Cisco AnyConnect.
+ {0x0, 0x5, 0x9A, 0x3C, 0x7A, 0x0},
+ // GlobalProtect Virtual Ethernet.
+ {0x2, 0x50, 0x41, 0x0, 0x0, 0x1},
+};
+
const uint32_t kUpdateNetworksMessage = 1;
const uint32_t kSignalNetworksMessage = 2;
@@ -486,6 +494,20 @@
return nullptr;
}
+bool NetworkManagerBase::IsVpnMacAddress(
+ rtc::ArrayView<const uint8_t> address) {
+ if (address.data() == nullptr && address.size() == 0) {
+ return false;
+ }
+ for (const auto& vpn : kVpns) {
+ if (sizeof(vpn) == address.size() &&
+ memcmp(vpn, address.data(), address.size()) == 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
BasicNetworkManager::BasicNetworkManager() : BasicNetworkManager(nullptr) {}
BasicNetworkManager::BasicNetworkManager(
@@ -781,6 +803,15 @@
vpn_underlying_adapter_type = adapter_type;
adapter_type = ADAPTER_TYPE_VPN;
}
+ if (adapter_type != ADAPTER_TYPE_VPN &&
+ IsVpnMacAddress(rtc::ArrayView<const uint8_t>(
+ reinterpret_cast<const uint8_t*>(
+ adapter_addrs->PhysicalAddress),
+ adapter_addrs->PhysicalAddressLength))) {
+ vpn_underlying_adapter_type = adapter_type;
+ adapter_type = ADAPTER_TYPE_VPN;
+ }
+
std::unique_ptr<Network> network(new Network(
name, description, prefix, prefix_length, adapter_type));
network->set_underlying_type_for_vpn(vpn_underlying_adapter_type);
diff --git a/rtc_base/network.h b/rtc_base/network.h
index 94350e0..d97b07f 100644
--- a/rtc_base/network.h
+++ b/rtc_base/network.h
@@ -19,6 +19,7 @@
#include <string>
#include <vector>
+#include "api/array_view.h"
#include "api/sequence_checker.h"
#include "rtc_base/ip_address.h"
#include "rtc_base/mdns_responder_interface.h"
@@ -194,6 +195,10 @@
bool GetDefaultLocalAddress(int family, IPAddress* ipaddr) const override;
+ // Check if MAC address in |bytes| is one of the pre-defined
+ // MAC addresses for know VPNs.
+ static bool IsVpnMacAddress(rtc::ArrayView<const uint8_t> address);
+
protected:
typedef std::map<std::string, Network*> NetworkMap;
// Updates `networks_` with the networks listed in `list`. If
diff --git a/rtc_base/network_unittest.cc b/rtc_base/network_unittest.cc
index e7b9982..b4f1f31 100644
--- a/rtc_base/network_unittest.cc
+++ b/rtc_base/network_unittest.cc
@@ -1434,4 +1434,19 @@
}
#endif // defined(WEBRTC_POSIX)
+TEST_F(NetworkTest, HardcodedVpn) {
+ const uint8_t cisco[] = {0x0, 0x5, 0x9A, 0x3C, 0x7A, 0x0};
+ const uint8_t global[] = {0x2, 0x50, 0x41, 0x0, 0x0, 0x1};
+ const uint8_t unknown[] = {0x2, 0x50, 0x41, 0x0, 0x0, 0x0};
+ const uint8_t five_bytes[] = {0x2, 0x50, 0x41, 0x0, 0x0};
+ EXPECT_TRUE(NetworkManagerBase::IsVpnMacAddress(cisco));
+ EXPECT_TRUE(NetworkManagerBase::IsVpnMacAddress(global));
+
+ EXPECT_FALSE(NetworkManagerBase::IsVpnMacAddress(
+ rtc::ArrayView<const uint8_t>(cisco, 5)));
+ EXPECT_FALSE(NetworkManagerBase::IsVpnMacAddress(five_bytes));
+ EXPECT_FALSE(NetworkManagerBase::IsVpnMacAddress(unknown));
+ EXPECT_FALSE(NetworkManagerBase::IsVpnMacAddress(nullptr));
+}
+
} // namespace rtc