diff --git a/src/lib/gui/core/NetworkMonitor.cpp b/src/lib/gui/core/NetworkMonitor.cpp index 2b8688176..3b13993af 100644 --- a/src/lib/gui/core/NetworkMonitor.cpp +++ b/src/lib/gui/core/NetworkMonitor.cpp @@ -9,31 +9,20 @@ #include #include #include +#include #include #include namespace deskflow::gui { -bool NetworkMonitor::isVirtualInterface(const QString &interfaceName) const +bool NetworkMonitor::isVirtualInterface(const QString &interfaceName) { // Common virtual network interface patterns - static const QStringList virtualPatterns = { - QStringLiteral("vboxnet"), // VirtualBox host-only networks - QStringLiteral("vmnet"), // VMware virtual networks - QStringLiteral("docker"), // Docker bridge networks - QStringLiteral("virbr"), // libvirt bridge networks - QStringLiteral("veth"), // Virtual ethernet - QStringLiteral("br-"), // Bridge interfaces (some are virtual) - QStringLiteral("tun"), // Tunnel interfaces - QStringLiteral("tap"), // TAP interfaces - QStringLiteral("utun"), // User tunnel (macOS) - QStringLiteral("awdl"), // Apple Wireless Direct Link - QStringLiteral("p2p"), // Peer-to-peer - QStringLiteral("llw"), // Link-local wireless - QStringLiteral("anpi"), // Apple network interface - }; - - return virtualPatterns.contains(interfaceName, Qt::CaseInsensitive); + static const auto virtualRegEx = QRegularExpression( + QStringLiteral("^vboxnet|vmnet|docker|virbr|veth|br\\-|tun|utun|awdl|p2p|llw|anpi|tap"), + QRegularExpression::CaseInsensitiveOption + ); + return virtualRegEx.match(interfaceName).hasMatch(); } NetworkMonitor::NetworkMonitor(QObject *parent) : QObject(parent), m_checkTimer(new QTimer(this)) diff --git a/src/lib/gui/core/NetworkMonitor.h b/src/lib/gui/core/NetworkMonitor.h index 1994457d7..338e2f154 100644 --- a/src/lib/gui/core/NetworkMonitor.h +++ b/src/lib/gui/core/NetworkMonitor.h @@ -52,6 +52,13 @@ public: */ QStringList getAvailableIPv4Addresses() const; + /** + * @brief Check if a network interface is virtual + * @param interfaceName Network interface name + * @return true if it's a virtual interface + */ + static bool isVirtualInterface(const QString &interfaceName); + Q_SIGNALS: /** * @brief Emitted when IP addresses change @@ -62,13 +69,6 @@ Q_SIGNALS: private: void setIpAddresses(const QStringList &newAddresses); - /** - * @brief Check if a network interface is virtual - * @param interfaceName Network interface name - * @return true if it's a virtual interface - */ - bool isVirtualInterface(const QString &interfaceName) const; - /** * @brief Update current network status */ diff --git a/src/unittests/gui/core/CMakeLists.txt b/src/unittests/gui/core/CMakeLists.txt index a2550ac49..73da17091 100644 --- a/src/unittests/gui/core/CMakeLists.txt +++ b/src/unittests/gui/core/CMakeLists.txt @@ -14,3 +14,12 @@ create_test( SOURCE ServerConnectionTests.cpp WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/src/lib/gui" ) + + +create_test( + NAME NetworkMonitorTests + DEPENDS gui + SOURCE NetworkMonitorTests.cpp + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/src/lib/gui" +) + diff --git a/src/unittests/gui/core/NetworkMonitorTests.cpp b/src/unittests/gui/core/NetworkMonitorTests.cpp new file mode 100644 index 000000000..25b56c99e --- /dev/null +++ b/src/unittests/gui/core/NetworkMonitorTests.cpp @@ -0,0 +1,36 @@ +/* + * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2026 Chris Rizzitello + * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception + */ + +#include "NetworkMonitorTests.h" + +#include "gui/core/NetworkMonitor.h" + +#include + +using namespace deskflow::gui; +void NetworkMonitorTests::testVirtualInterface() +{ + QVERIFY(NetworkMonitor::isVirtualInterface(QStringLiteral("vboxnet0"))); + QVERIFY(NetworkMonitor::isVirtualInterface(QStringLiteral("vboXnet0"))); + QVERIFY(NetworkMonitor::isVirtualInterface(QStringLiteral("vmnet0"))); + QVERIFY(NetworkMonitor::isVirtualInterface(QStringLiteral("docker-bridge"))); + QVERIFY(NetworkMonitor::isVirtualInterface(QStringLiteral("virbr0"))); + QVERIFY(NetworkMonitor::isVirtualInterface(QStringLiteral("veth0"))); + QVERIFY(NetworkMonitor::isVirtualInterface(QStringLiteral("br-0"))); + QVERIFY(NetworkMonitor::isVirtualInterface(QStringLiteral("tun0"))); + QVERIFY(NetworkMonitor::isVirtualInterface(QStringLiteral("utun0"))); + QVERIFY(NetworkMonitor::isVirtualInterface(QStringLiteral("awdl0"))); + QVERIFY(NetworkMonitor::isVirtualInterface(QStringLiteral("p2p0"))); + QVERIFY(NetworkMonitor::isVirtualInterface(QStringLiteral("llw0"))); + QVERIFY(NetworkMonitor::isVirtualInterface(QStringLiteral("anpi5"))); + QVERIFY(NetworkMonitor::isVirtualInterface(QStringLiteral("tap1"))); + + QVERIFY(!NetworkMonitor::isVirtualInterface(QStringLiteral("eth0"))); + QVERIFY(!NetworkMonitor::isVirtualInterface(QStringLiteral("enp0s0f"))); + QVERIFY(!NetworkMonitor::isVirtualInterface(QStringLiteral("wifi"))); + QVERIFY(!NetworkMonitor::isVirtualInterface(QStringLiteral("wlan0"))); +} +QTEST_MAIN(NetworkMonitorTests) diff --git a/src/unittests/gui/core/NetworkMonitorTests.h b/src/unittests/gui/core/NetworkMonitorTests.h new file mode 100644 index 000000000..a9e4c4c0f --- /dev/null +++ b/src/unittests/gui/core/NetworkMonitorTests.h @@ -0,0 +1,15 @@ +/* + * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2026 Chris Rizzitello + * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception + */ + +#include + +class NetworkMonitorTests : public QObject +{ + Q_OBJECT +private Q_SLOTS: + // Test are run in order top to bottom + void testVirtualInterface(); +};