diff options
Diffstat (limited to 'windows')
20 files changed, 643 insertions, 330 deletions
diff --git a/windows/nsis-plugins/src/driverlogic/context.cpp b/windows/nsis-plugins/src/driverlogic/context.cpp index 42394e25e3..2598377091 100644 --- a/windows/nsis-plugins/src/driverlogic/context.cpp +++ b/windows/nsis-plugins/src/driverlogic/context.cpp @@ -1,9 +1,11 @@ #include "stdafx.h" #include "context.h" +#include <libcommon/guid.h> #include <libcommon/string.h> #include <libcommon/error.h> #include <libcommon/memory.h> +#include <libcommon/network/nci.h> #include <log/log.h> #include <winsock2.h> @@ -28,59 +30,6 @@ namespace const wchar_t TAP_HARDWARE_ID[] = L"tap0901"; -std::set<Context::NetworkAdapter> GetAllAdapters() -{ - ULONG bufferSize = 0; - - const ULONG flags = GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER; - - auto status = GetAdaptersAddresses(AF_INET, flags, nullptr, nullptr, &bufferSize); - - THROW_UNLESS(ERROR_BUFFER_OVERFLOW, status, "Probe for adapter listing buffer size"); - - // Memory is cheap, this avoids a looping construct. - bufferSize *= 2; - - std::vector<uint8_t> buffer(bufferSize); - - status = GetAdaptersAddresses(AF_INET, flags, nullptr, - reinterpret_cast<PIP_ADAPTER_ADDRESSES>(&buffer[0]), &bufferSize); - - THROW_UNLESS(ERROR_SUCCESS, status, "Retrieve adapter listing"); - - std::set<Context::NetworkAdapter> adapters; - - for (auto it = (PIP_ADAPTER_ADDRESSES)&buffer[0]; nullptr != it; it = it->Next) - { - adapters.emplace(Context::NetworkAdapter(common::string::ToWide(it->AdapterName), - it->Description, it->FriendlyName)); - } - - return adapters; -} - -std::set<Context::NetworkAdapter> GetTapAdapters(const std::set<Context::NetworkAdapter> &adapters) -{ - std::set<Context::NetworkAdapter> tapAdapters; - - for (const auto &adapter : adapters) - { - static const wchar_t name[] = L"TAP-Windows Adapter V9"; - - // - // Compare partial name, because once you start having more TAP adapters - // they're named "TAP-Windows Adapter V9 #2" and so on. - // - - if (0 == adapter.name.compare(0, _countof(name) - 1, name)) - { - tapAdapters.insert(adapter); - } - } - - return tapAdapters; -} - template<typename T> void LogAdapters(const std::wstring &description, const T &adapters) { @@ -143,6 +92,212 @@ std::wstring GetNetCfgInstanceId(HDEVINFO devInfo, const SP_DEVINFO_DATA &devInf return instanceId.data(); } +std::wstring GetDeviceInstanceId( + HDEVINFO devInfo, + SP_DEVINFO_DATA* devInfoData +) +{ + DWORD requiredSize = 0; + + SetupDiGetDeviceInstanceIdW( + devInfo, + devInfoData, + nullptr, + 0, + &requiredSize + ); + + std::vector<wchar_t> deviceInstanceId; + deviceInstanceId.resize(1 + requiredSize * sizeof(wchar_t)); + + const auto status = SetupDiGetDeviceInstanceIdW( + devInfo, + devInfoData, + &deviceInstanceId[0], + deviceInstanceId.size(), + nullptr + ); + THROW_GLE_IF(FALSE, status, "SetupDiGetDeviceInstanceIdW() failed"); + + return deviceInstanceId.data(); +} + +std::wstring GetDeviceStringProperty( + HDEVINFO devInfo, + SP_DEVINFO_DATA *devInfoData, + const DEVPROPKEY *property +) +{ + // + // Obtain required buffer size + // + + DWORD requiredSize = 0; + DEVPROPTYPE type; + + const auto sizeStatus = SetupDiGetDevicePropertyW( + devInfo, + devInfoData, + property, + &type, + nullptr, + 0, + &requiredSize, + 0 + ); + + const DWORD lastError = GetLastError(); + if (FALSE == sizeStatus && ERROR_INSUFFICIENT_BUFFER != lastError) + { + common::error::Throw( + "Error obtaining device property length", + lastError + ); + } + + std::vector<wchar_t> buffer; + buffer.resize(1 + requiredSize / sizeof(wchar_t)); + + // + // Read property + // + + const auto status = SetupDiGetDevicePropertyW( + devInfo, + devInfoData, + property, + &type, + reinterpret_cast<PBYTE>(&buffer[0]), + buffer.size() * sizeof(wchar_t), + nullptr, + 0 + ); + + THROW_GLE_IF(FALSE, status, "Failed to read device property"); + + return buffer.data(); +} + +std::optional<std::wstring> GetDeviceRegistryStringProperty( + HDEVINFO devInfo, + SP_DEVINFO_DATA *devInfoData, + DWORD property +) +{ + // + // Obtain required buffer size + // + + DWORD requiredSize = 0; + + const auto sizeStatus = SetupDiGetDeviceRegistryPropertyW( + devInfo, + devInfoData, + property, + nullptr, + nullptr, + 0, + &requiredSize + ); + + const DWORD lastError = GetLastError(); + if (FALSE == sizeStatus && ERROR_INSUFFICIENT_BUFFER != lastError) + { + if (ERROR_INVALID_DATA == lastError) + { + // ERROR_INVALID_DATA may mean that the property does not exist + // TODO: Check if there may be other causes. + return std::nullopt; + } + THROW_GLE("Error obtaining device property length"); + } + + // + // Read property + // + + std::vector<wchar_t> buffer; + buffer.resize(1 + requiredSize / sizeof(wchar_t)); + + const auto status = SetupDiGetDeviceRegistryPropertyW( + devInfo, + devInfoData, + property, + nullptr, + reinterpret_cast<PBYTE>(&buffer[0]), + buffer.size() * sizeof(wchar_t), + nullptr + ); + + THROW_GLE_IF(FALSE, status, "Failed to read device property"); + + return { buffer.data() }; +} + +std::set<Context::NetworkAdapter> GetTapAdapters() +{ + std::set<Context::NetworkAdapter> adapters; + + HDEVINFO devInfo = SetupDiGetClassDevs( + &GUID_DEVCLASS_NET, + nullptr, + nullptr, + DIGCF_PRESENT + ); + THROW_GLE_IF(INVALID_HANDLE_VALUE, devInfo, "SetupDiGetClassDevs() failed"); + + common::memory::ScopeDestructor scopeDestructor; + scopeDestructor += [devInfo]() + { + SetupDiDestroyDeviceInfoList(devInfo); + }; + + common::network::Nci nci; + + for (int memberIndex = 0; ; memberIndex++) + { + SP_DEVINFO_DATA devInfoData = { 0 }; + devInfoData.cbSize = sizeof(devInfoData); + + if (FALSE == SetupDiEnumDeviceInfo(devInfo, memberIndex, &devInfoData)) + { + if (ERROR_NO_MORE_ITEMS == GetLastError()) + { + // Done + break; + } + THROW_GLE("SetupDiEnumDeviceInfo() failed while enumerating network adapters"); + } + + // + // Check whether this is a TAP adapter + // + + const auto hardwareId = GetDeviceRegistryStringProperty(devInfo, &devInfoData, SPDRP_HARDWAREID); + if (!hardwareId.has_value() + || wcscmp(hardwareId.value().c_str(), TAP_HARDWARE_ID) != 0) + { + continue; + } + + // + // Construct NetworkAdapter + // + + const std::wstring guid = GetNetCfgInstanceId(devInfo, devInfoData); + GUID guidObj = common::Guid::FromString(guid); + + adapters.emplace(Context::NetworkAdapter( + guid, + GetDeviceStringProperty(devInfo, &devInfoData, &DEVPKEY_Device_DriverDesc), + nci.getConnectionName(guidObj), + GetDeviceInstanceId(devInfo, &devInfoData) + )); + } + + return adapters; +} + } // anonymous namespace //static @@ -201,15 +356,14 @@ std::optional<Context::NetworkAdapter> Context::FindMullvadAdapter(const std::se Context::BaselineStatus Context::establishBaseline() { - m_baseline = GetAllAdapters(); - const auto tapAdapters = GetTapAdapters(m_baseline); + m_baseline = GetTapAdapters(); - if (tapAdapters.empty()) + if (m_baseline.empty()) { return BaselineStatus::NO_TAP_ADAPTERS_PRESENT; } - if (FindMullvadAdapter(tapAdapters).has_value()) + if (FindMullvadAdapter(m_baseline).has_value()) { return BaselineStatus::MULLVAD_ADAPTER_PRESENT; } @@ -219,31 +373,50 @@ Context::BaselineStatus Context::establishBaseline() void Context::recordCurrentState() { - m_currentState = GetAllAdapters(); + m_currentState = GetTapAdapters(); +} + +void Context::rollbackTapAliases() +{ + common::network::Nci nci; + + for (const auto &adapter : m_currentState) + { + const auto oldInfo = m_baseline.find(adapter); + if (m_baseline.end() != oldInfo) + { + GUID guidObj = common::Guid::FromString(&adapter.guid[0]); + + nci.setConnectionName(guidObj, oldInfo->alias.c_str()); + } + } } Context::NetworkAdapter Context::getNewAdapter() { std::list<NetworkAdapter> added; - const auto baselineTaps = GetTapAdapters(m_baseline); - const auto currentTaps = GetTapAdapters(m_currentState); - - for (const auto &adapter : currentTaps) + for (const auto &adapter : m_currentState) { - if (baselineTaps.end() == baselineTaps.find(adapter)) + if (m_baseline.end() == m_baseline.find(adapter)) { added.push_back(adapter); } } - if (added.size() != 1) + if (added.size() == 0) { - LogAdapters(L"Enumerable network adapters", m_currentState); - LogAdapters(L"Added TAP adapters", added); + LogAdapters(L"Enumerable network TAP adapters", m_currentState); throw std::runtime_error("Unable to identify recently added TAP adapter"); } + else if (added.size() > 1) + { + LogAdapters(L"Enumerable network TAP adapters", m_currentState); + LogAdapters(L"New TAP adapters:", added); + + throw std::runtime_error("Identified more TAP adapters than expected"); + } return *added.begin(); } @@ -251,7 +424,7 @@ Context::NetworkAdapter Context::getNewAdapter() //static Context::DeletionResult Context::DeleteMullvadAdapter() { - auto tapAdapters = GetTapAdapters(GetAllAdapters()); + auto tapAdapters = GetTapAdapters(); std::optional<NetworkAdapter> mullvadAdapter = FindMullvadAdapter(tapAdapters); if (!mullvadAdapter.has_value()) @@ -276,71 +449,28 @@ Context::DeletionResult Context::DeleteMullvadAdapter() SetupDiDestroyDeviceInfoList(devInfo); }; - SP_DEVINFO_DATA devInfoData; - - std::vector<wchar_t> buffer; - DWORD nameLen; - int numRemainingAdapters = 0; for (int memberIndex = 0; ; memberIndex++) { - devInfoData = { 0 }; + SP_DEVINFO_DATA devInfoData = { 0 }; devInfoData.cbSize = sizeof(devInfoData); if (FALSE == SetupDiEnumDeviceInfo(devInfo, memberIndex, &devInfoData)) { - if (GetLastError() == ERROR_NO_MORE_ITEMS) + if (ERROR_NO_MORE_ITEMS == GetLastError()) { - /* done */ break; } THROW_GLE("Error enumerating network adapters"); } - if (FALSE == SetupDiGetDeviceRegistryPropertyW( - devInfo, - &devInfoData, - SPDRP_HARDWAREID, - nullptr, - nullptr, - 0, - &nameLen - )) - { - const auto status = GetLastError(); - if (ERROR_INSUFFICIENT_BUFFER != status) - { - /* ERROR_INSUFFICIENT_BUFFER is expected */ - if (ERROR_INVALID_DATA == status) - { - /* ERROR_INVALID_DATA may mean that the property does not exist */ - continue; - } - THROW_GLE("Error obtaining network adapter hardware ID length"); - } - } - - buffer.resize(nameLen / sizeof(wchar_t) + 1); - buffer[nameLen / sizeof(wchar_t)] = L'\0'; - - if (FALSE == SetupDiGetDeviceRegistryPropertyW( - devInfo, - &devInfoData, - SPDRP_HARDWAREID, - nullptr, - reinterpret_cast<PBYTE>(buffer.data()), - (buffer.size() - 1) * sizeof(wchar_t), - nullptr - )) - { - THROW_GLE("Error obtaining network adapter hardware ID"); - } + const auto hardwareId = GetDeviceRegistryStringProperty(devInfo, &devInfoData, SPDRP_HARDWAREID); - if (wcscmp(TAP_HARDWARE_ID, buffer.data()) == 0) + if (hardwareId.has_value() + && wcscmp(TAP_HARDWARE_ID, hardwareId.value().data()) == 0) { - std::wstring netCfgInstanceId = GetNetCfgInstanceId(devInfo, devInfoData); - if (netCfgInstanceId.compare(mullvadGuid) != 0) + if (0 != GetNetCfgInstanceId(devInfo, devInfoData).compare(mullvadGuid)) { numRemainingAdapters++; continue; @@ -356,10 +486,7 @@ Context::DeletionResult Context::DeleteMullvadAdapter() } } - if (numRemainingAdapters > 0) - { - return DeletionResult::SOME_REMAINING_TAP_ADAPTERS; - } - - return DeletionResult::NO_REMAINING_TAP_ADAPTERS; + return (numRemainingAdapters > 0) + ? DeletionResult::SOME_REMAINING_TAP_ADAPTERS + : DeletionResult::NO_REMAINING_TAP_ADAPTERS; } diff --git a/windows/nsis-plugins/src/driverlogic/context.h b/windows/nsis-plugins/src/driverlogic/context.h index eabf884ba8..9c0b19d62f 100644 --- a/windows/nsis-plugins/src/driverlogic/context.h +++ b/windows/nsis-plugins/src/driverlogic/context.h @@ -17,17 +17,19 @@ public: std::wstring guid; std::wstring name; std::wstring alias; + std::wstring deviceInstanceId; - NetworkAdapter(std::wstring _guid, std::wstring _name, std::wstring _alias) - : guid(_guid) - , name(_name) - , alias(_alias) + NetworkAdapter(std::wstring guid, std::wstring name, std::wstring alias, std::wstring deviceInstanceId) + : guid(guid) + , name(name) + , alias(alias) + , deviceInstanceId(deviceInstanceId) { } bool operator<(const NetworkAdapter &rhs) const { - return _wcsicmp(guid.c_str(), rhs.guid.c_str()) < 0; + return _wcsicmp(deviceInstanceId.c_str(), rhs.deviceInstanceId.c_str()) < 0; } }; @@ -43,6 +45,11 @@ public: void recordCurrentState(); // + // Restore TAP aliases to baseline state + // + void rollbackTapAliases(); + + // // Identify a single new TAP adapter // NetworkAdapter getNewAdapter(); diff --git a/windows/nsis-plugins/src/driverlogic/driverlogic.cpp b/windows/nsis-plugins/src/driverlogic/driverlogic.cpp index 82259c015d..1e1ecc0fc7 100644 --- a/windows/nsis-plugins/src/driverlogic/driverlogic.cpp +++ b/windows/nsis-plugins/src/driverlogic/driverlogic.cpp @@ -126,6 +126,7 @@ void __declspec(dllexport) NSISCALL EstablishBaseline { pushstring(L"Initialize() function was not called or was not successful"); pushint(EstablishBaselineStatus::GENERAL_ERROR); + return; } try @@ -247,7 +248,8 @@ void __declspec(dllexport) NSISCALL IdentifyNewAdapter if (nullptr == g_context) { pushstring(L"Initialize() function was not called or was not successful"); - pushint(EstablishBaselineStatus::GENERAL_ERROR); + pushint(IdentifyNewAdapterStatus::GENERAL_ERROR); + return; } try @@ -272,6 +274,57 @@ void __declspec(dllexport) NSISCALL IdentifyNewAdapter } // +// RollbackTapAliases +// +// Updating the TAP driver may replace GUIDs and aliases. +// Use this to restore the aliases to their baseline state. +// +enum class RollbackTapAliasesStatus +{ + GENERAL_ERROR = 0, + SUCCESS +}; + +void __declspec(dllexport) NSISCALL RollbackTapAliases +( + HWND hwndParent, + int string_size, + LPTSTR variables, + stack_t** stacktop, + extra_parameters* extra, + ... +) +{ + EXDLL_INIT(); + + if (nullptr == g_context) + { + pushstring(L"Initialize() function was not called or was not successful"); + pushint(RollbackTapAliasesStatus::GENERAL_ERROR); + return; + } + + try + { + g_context->recordCurrentState(); + g_context->rollbackTapAliases(); + + pushstring(L""); + pushint(RollbackTapAliasesStatus::SUCCESS); + } + catch (std::exception & err) + { + pushstring(common::string::ToWide(err.what()).c_str()); + pushint(RollbackTapAliasesStatus::GENERAL_ERROR); + } + catch (...) + { + pushstring(L"Unspecified error"); + pushint(RollbackTapAliasesStatus::GENERAL_ERROR); + } +} + +// // Deinitialize // // Call this function once during shutdown. diff --git a/windows/nsis-plugins/src/driverlogic/driverlogic.def b/windows/nsis-plugins/src/driverlogic/driverlogic.def index b8735f1ada..f7982c513d 100644 --- a/windows/nsis-plugins/src/driverlogic/driverlogic.def +++ b/windows/nsis-plugins/src/driverlogic/driverlogic.def @@ -6,4 +6,5 @@ Initialize EstablishBaseline IdentifyNewAdapter RemoveMullvadTap +RollbackTapAliases Deinitialize diff --git a/windows/nsis-plugins/src/driverlogic/driverlogic.vcxproj b/windows/nsis-plugins/src/driverlogic/driverlogic.vcxproj index 0bcb1a2179..5a4e4b18c4 100644 --- a/windows/nsis-plugins/src/driverlogic/driverlogic.vcxproj +++ b/windows/nsis-plugins/src/driverlogic/driverlogic.vcxproj @@ -70,7 +70,7 @@ <GenerateDebugInformation>true</GenerateDebugInformation> <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> <AdditionalLibraryDirectories>$(ProjectDir)../../../../dist-assets/binaries/x86_64-pc-windows-msvc/nsis/;$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories> - <AdditionalDependencies>setupapi.lib;iphlpapi.lib;log.lib;libcommon.lib;pluginapi-x86-unicode.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>setupapi.lib;log.lib;libcommon.lib;pluginapi-x86-unicode.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> <IgnoreSpecificDefaultLibraries>libc.lib</IgnoreSpecificDefaultLibraries> <ModuleDefinitionFile>driverlogic.def</ModuleDefinitionFile> </Link> @@ -96,7 +96,7 @@ <GenerateDebugInformation>true</GenerateDebugInformation> <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> <AdditionalLibraryDirectories>$(ProjectDir)../../../../dist-assets/binaries/x86_64-pc-windows-msvc/nsis/;$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories> - <AdditionalDependencies>setupapi.lib;iphlpapi.lib;log.lib;libcommon.lib;pluginapi-x86-unicode.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>setupapi.lib;log.lib;libcommon.lib;pluginapi-x86-unicode.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> <IgnoreSpecificDefaultLibraries>libc.lib</IgnoreSpecificDefaultLibraries> <ModuleDefinitionFile>driverlogic.def</ModuleDefinitionFile> </Link> diff --git a/windows/shared/shared.sln b/windows/shared/shared.sln index d735b2d82d..d664af8399 100644 --- a/windows/shared/shared.sln +++ b/windows/shared/shared.sln @@ -3,6 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00 VisualStudioVersion = 16.0.29324.140 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shared", "src\shared\shared.vcxproj", "{EE69EA4A-CF71-4B88-866B-957F60C4CE0D}" + ProjectSection(ProjectDependencies) = postProject + {B52E2D10-A94A-4605-914A-2DCEF6A757EF} = {B52E2D10-A94A-4605-914A-2DCEF6A757EF} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcommon", "..\windows-libraries\src\libcommon\libcommon.vcxproj", "{B52E2D10-A94A-4605-914A-2DCEF6A757EF}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -24,6 +29,14 @@ Global {EE69EA4A-CF71-4B88-866B-957F60C4CE0D}.Release|x86.ActiveCfg = Release|Win32 {EE69EA4A-CF71-4B88-866B-957F60C4CE0D}.Release|x86.Build.0 = Release|Win32 {EE69EA4A-CF71-4B88-866B-957F60C4CE0D}.Release|x86.Deploy.0 = Release|Win32 + {B52E2D10-A94A-4605-914A-2DCEF6A757EF}.Debug|x64.ActiveCfg = Debug|x64 + {B52E2D10-A94A-4605-914A-2DCEF6A757EF}.Debug|x64.Build.0 = Debug|x64 + {B52E2D10-A94A-4605-914A-2DCEF6A757EF}.Debug|x86.ActiveCfg = Debug|Win32 + {B52E2D10-A94A-4605-914A-2DCEF6A757EF}.Debug|x86.Build.0 = Debug|Win32 + {B52E2D10-A94A-4605-914A-2DCEF6A757EF}.Release|x64.ActiveCfg = Release|x64 + {B52E2D10-A94A-4605-914A-2DCEF6A757EF}.Release|x64.Build.0 = Release|x64 + {B52E2D10-A94A-4605-914A-2DCEF6A757EF}.Release|x86.ActiveCfg = Release|Win32 + {B52E2D10-A94A-4605-914A-2DCEF6A757EF}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/windows/shared/src/shared/network/interfaceutils.cpp b/windows/shared/src/shared/network/interfaceutils.cpp new file mode 100644 index 0000000000..6d56ec82d2 --- /dev/null +++ b/windows/shared/src/shared/network/interfaceutils.cpp @@ -0,0 +1,177 @@ +#include "stdafx.h" +#include <sstream> +#include <algorithm> +#include "interfaceutils.h" +#include <libcommon/error.h> +#include <libcommon/string.h> + +namespace shared::network +{ + +InterfaceUtils::NetworkAdapter::NetworkAdapter( + const common::network::Nci &nci, + const std::shared_ptr<std::vector<uint8_t>> addressesBuffer, + const IP_ADAPTER_ADDRESSES &entry +) + : m_addressesBuffer(addressesBuffer) + , m_entry(entry) +{ + m_guid = common::string::ToWide(entry.AdapterName); + + try + { + // + // FIXME: + // Work around incorrect alias sometimes + // being returned on Windows 8. + // + // Steps to reproduce: + // 1. Install NDIS 6 TAP driver v9.00.00.21. + // 2. Update driver to v9.24.2.601. + // 3. Rename TAP adapter. + // + // GetAdaptersAddresses() returns a generic name + // for the *first* adapter instead of the correct + // one, whereas ConvertInterfaceAliasToLuid() and + // ConvertInterfaceLuidToAlias() yield correct values. + // + + IID guidObj = { 0 }; + if (S_OK != IIDFromString(&m_guid[0], &guidObj)) + { + throw std::runtime_error("IIDFromString() failed"); + } + + m_alias = nci.getConnectionName(guidObj); + } + catch (const std::exception &) + { + m_alias = entry.FriendlyName; + } + + m_name = entry.Description; +} + +//static +std::set<InterfaceUtils::NetworkAdapter> InterfaceUtils::GetAllAdapters(ULONG family, ULONG flags) +{ + ULONG bufferSize = 0; + + auto status = GetAdaptersAddresses(family, flags, nullptr, nullptr, &bufferSize); + + THROW_UNLESS(ERROR_BUFFER_OVERFLOW, status, "Probe for adapter listing buffer size"); + + // Memory is cheap, this avoids a looping construct. + bufferSize *= 2; + + auto buffer = std::make_shared<std::vector<uint8_t>>(bufferSize); + auto addresses = reinterpret_cast<PIP_ADAPTER_ADDRESSES>(&(*buffer)[0]); + + status = GetAdaptersAddresses(family, flags, nullptr, addresses, &bufferSize); + + THROW_UNLESS(ERROR_SUCCESS, status, "Retrieve adapter listing"); + + std::set<NetworkAdapter> adapters; + + common::network::Nci nci; + + for (auto it = addresses; nullptr != it; it = it->Next) + { + adapters.emplace(NetworkAdapter(nci, buffer, *it)); + } + + return adapters; +} + +//static +void InterfaceUtils::AddDeviceIpAddresses(NET_LUID device, const std::vector<SOCKADDR_INET> &addresses) +{ + for (const auto &address : addresses) + { + MIB_UNICASTIPADDRESS_ROW row; + InitializeUnicastIpAddressEntry(&row); + + row.InterfaceLuid = device; + row.Address = address; + + THROW_UNLESS(NO_ERROR, CreateUnicastIpAddressEntry(&row), "Assign IP address on network interface"); + } +} + +//static +std::set<InterfaceUtils::NetworkAdapter> +InterfaceUtils::GetTapAdapters(const std::set<NetworkAdapter>& adapters) +{ + std::set<NetworkAdapter> tapAdapters; + + for (const auto& adapter : adapters) + { + static const wchar_t name[] = L"TAP-Windows Adapter V9"; + + // + // Compare partial name, because once you start having more TAP adapters + // they're named "TAP-Windows Adapter V9 #2" and so on. + // + + if (0 == adapter.name().compare(0, _countof(name) - 1, name)) + { + tapAdapters.insert(adapter); + } + } + + return tapAdapters; +} + +//static +std::wstring InterfaceUtils::GetTapInterfaceAlias() +{ + // + // Look for TAP adapter with alias "Mullvad". + // + + using shared::network::InterfaceUtils; + + auto adapters = InterfaceUtils::GetTapAdapters(InterfaceUtils::GetAllAdapters( + AF_INET, + GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST + )); + + auto findByAlias = [](const std::set<InterfaceUtils::NetworkAdapter>& adapters, const std::wstring& alias) + { + const auto it = std::find_if(adapters.begin(), adapters.end(), [&alias](const InterfaceUtils::NetworkAdapter& candidate) + { + return 0 == _wcsicmp(candidate.alias().c_str(), alias.c_str()); + }); + + return it != adapters.end(); + }; + + static const wchar_t baseAlias[] = L"Mullvad"; + + if (findByAlias(adapters, baseAlias)) + { + return baseAlias; + } + + // + // Look for TAP adapter with alias "Mullvad-1", "Mullvad-2", etc. + // + + for (auto i = 0; i < 10; ++i) + { + std::wstringstream ss; + + ss << baseAlias << L"-" << i; + + const auto alias = ss.str(); + + if (findByAlias(adapters, alias)) + { + return alias; + } + } + + throw std::runtime_error("Unable to find TAP adapter"); +} + +} diff --git a/windows/shared/src/shared/network/interfaceutils.h b/windows/shared/src/shared/network/interfaceutils.h new file mode 100644 index 0000000000..85a243d591 --- /dev/null +++ b/windows/shared/src/shared/network/interfaceutils.h @@ -0,0 +1,79 @@ +#pragma once + +#include <string> +#include <set> +#include <vector> +#include <memory> +#include <cstdint> + +// Secret include order to get most common networking structs/apis +// And avoiding compilation errors +#include <winsock2.h> +#include <windows.h> +#include <ws2def.h> +#include <ws2ipdef.h> +#include <iphlpapi.h> +#include <netioapi.h> +// end + +#include <libcommon/network/nci.h> + +namespace shared::network +{ + +class InterfaceUtils +{ + InterfaceUtils() = delete; + +public: + + class NetworkAdapter + { + + public: + + const std::wstring &guid() const { return m_guid; } + const std::wstring &name() const { return m_name; } + const std::wstring &alias() const { return m_alias; } + + bool operator<(const NetworkAdapter &rhs) const + { + return _wcsicmp(m_guid.c_str(), rhs.m_guid.c_str()) < 0; + } + + const IP_ADAPTER_ADDRESSES &raw() const + { + return m_entry; + } + + private: + + NetworkAdapter( + const common::network::Nci &nci, + const std::shared_ptr<std::vector<uint8_t>> addressesBuffer, + const IP_ADAPTER_ADDRESSES &entry + ); + + friend class InterfaceUtils; + + const IP_ADAPTER_ADDRESSES &m_entry; + std::shared_ptr<std::vector<uint8_t>> m_addressesBuffer; + + std::wstring m_guid; + std::wstring m_name; + std::wstring m_alias; + }; + + static std::set<NetworkAdapter> GetAllAdapters(ULONG family, ULONG flags); + + static void AddDeviceIpAddresses(NET_LUID device, const std::vector<SOCKADDR_INET> &addresses); + + static std::set<NetworkAdapter> GetTapAdapters(const std::set<NetworkAdapter> &adapters); + + // + // Determines alias of primary TAP adapter. + // + static std::wstring GetTapInterfaceAlias(); +}; + +} diff --git a/windows/shared/src/shared/shared.vcxproj b/windows/shared/src/shared/shared.vcxproj index 771aaa14bd..a5dc7cf4f2 100644 --- a/windows/shared/src/shared/shared.vcxproj +++ b/windows/shared/src/shared/shared.vcxproj @@ -178,10 +178,12 @@ <ItemGroup> <ClInclude Include="logsink.h" /> <ClInclude Include="ilogsink.h" /> + <ClInclude Include="network\interfaceutils.h" /> <ClInclude Include="stdafx.h" /> <ClInclude Include="targetver.h" /> </ItemGroup> <ItemGroup> + <ClCompile Include="network\interfaceutils.cpp" /> <ClCompile Include="stdafx.cpp"> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader> diff --git a/windows/shared/src/shared/shared.vcxproj.filters b/windows/shared/src/shared/shared.vcxproj.filters index 00c566d6e6..61b48a6937 100644 --- a/windows/shared/src/shared/shared.vcxproj.filters +++ b/windows/shared/src/shared/shared.vcxproj.filters @@ -5,8 +5,19 @@ <ClInclude Include="logsink.h" /> <ClInclude Include="stdafx.h" /> <ClInclude Include="targetver.h" /> + <ClInclude Include="network\interfaceutils.h"> + <Filter>network</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="stdafx.cpp" /> + <ClCompile Include="network\interfaceutils.cpp"> + <Filter>network</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <Filter Include="network"> + <UniqueIdentifier>{c36884fc-7afc-42a8-b852-c0aafcfcc1c2}</UniqueIdentifier> + </Filter> </ItemGroup> </Project>
\ No newline at end of file diff --git a/windows/shared/src/shared/stdafx.h b/windows/shared/src/shared/stdafx.h index fc6b905b83..59e4616a97 100644 --- a/windows/shared/src/shared/stdafx.h +++ b/windows/shared/src/shared/stdafx.h @@ -10,3 +10,6 @@ #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #include <windows.h> +#include <string> +#include <sstream> +#include <algorithm> diff --git a/windows/windns/src/windns/windns.cpp b/windows/windns/src/windns/windns.cpp index eae828973c..1ea10f0f08 100644 --- a/windows/windns/src/windns/windns.cpp +++ b/windows/windns/src/windns/windns.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" +#include <libcommon/guid.h> #include <libcommon/string.h> -#include <libcommon/network/adapters.h> +#include <shared/network/interfaceutils.h> #include "windns.h" #include "confineoperation.h" #include "netsh.h" @@ -92,20 +93,25 @@ struct AdapterDnsAddresses // AdapterDnsAddresses GetAdapterDnsAddresses(const std::wstring &adapterAlias) { - common::network::Adapters adapters(AF_UNSPEC, GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST); + using shared::network::InterfaceUtils; - const IP_ADAPTER_ADDRESSES *adapter; + const auto adapters = InterfaceUtils::GetAllAdapters( + AF_UNSPEC, + GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST + ); - while (nullptr != (adapter = adapters.next())) + for (const auto adapter : adapters) { - if (0 != _wcsicmp(adapter->FriendlyName, adapterAlias.c_str())) + const auto guidObj = common::Guid::FromString(adapter.guid()); + + if (0 != _wcsicmp(adapter.alias().c_str(), adapterAlias.c_str())) { continue; } AdapterDnsAddresses out; - for (auto server = adapter->FirstDnsServerAddress; nullptr != server; server = server->Next) + for (auto server = adapter.raw().FirstDnsServerAddress; nullptr != server; server = server->Next) { if (AF_INET == server->Address.lpSockaddr->sa_family) { diff --git a/windows/windns/src/windns/windns.vcxproj b/windows/windns/src/windns/windns.vcxproj index b2b68a999f..31a74eab87 100644 --- a/windows/windns/src/windns/windns.vcxproj +++ b/windows/windns/src/windns/windns.vcxproj @@ -98,7 +98,7 @@ <SDLCheck>true</SDLCheck> <PreprocessorDefinitions>_DEBUG;WINDNS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <ConformanceMode>true</ConformanceMode> - <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../../../windows-libraries/src/</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../../../windows-libraries/src/;$(ProjectDir)../../../shared/src/</AdditionalIncludeDirectories> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <LanguageStandard>stdcpplatest</LanguageStandard> </ClCompile> @@ -106,7 +106,7 @@ <SubSystem>Windows</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> <AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories> - <AdditionalDependencies>libcommon.lib;Iphlpapi.lib;wbemuuid.lib;comsuppw.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>shared.lib;libcommon.lib;Iphlpapi.lib;wbemuuid.lib;comsuppw.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> @@ -117,7 +117,7 @@ <SDLCheck>true</SDLCheck> <PreprocessorDefinitions>WIN32;_DEBUG;WINDNS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <ConformanceMode>true</ConformanceMode> - <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../../../windows-libraries/src/</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../../../windows-libraries/src/;$(ProjectDir)../../../shared/src/</AdditionalIncludeDirectories> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <LanguageStandard>stdcpplatest</LanguageStandard> </ClCompile> @@ -125,7 +125,7 @@ <SubSystem>Windows</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> <AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories> - <AdditionalDependencies>libcommon.lib;Iphlpapi.lib;wbemuuid.lib;comsuppw.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>shared.lib;libcommon.lib;Iphlpapi.lib;wbemuuid.lib;comsuppw.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> @@ -138,7 +138,7 @@ <SDLCheck>true</SDLCheck> <PreprocessorDefinitions>WIN32;NDEBUG;WINDNS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <ConformanceMode>true</ConformanceMode> - <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../../../windows-libraries/src/</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../../../windows-libraries/src/;$(ProjectDir)../../../shared/src/</AdditionalIncludeDirectories> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <LanguageStandard>stdcpplatest</LanguageStandard> </ClCompile> @@ -148,7 +148,7 @@ <OptimizeReferences>true</OptimizeReferences> <GenerateDebugInformation>true</GenerateDebugInformation> <AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories> - <AdditionalDependencies>libcommon.lib;Iphlpapi.lib;wbemuuid.lib;comsuppw.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>shared.lib;libcommon.lib;Iphlpapi.lib;wbemuuid.lib;comsuppw.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> @@ -161,7 +161,7 @@ <SDLCheck>true</SDLCheck> <PreprocessorDefinitions>NDEBUG;WINDNS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <ConformanceMode>true</ConformanceMode> - <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../../../windows-libraries/src/</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>$(ProjectDir)../;$(ProjectDir)../../../windows-libraries/src/;$(ProjectDir)../../../shared/src/</AdditionalIncludeDirectories> <RuntimeLibrary>MultiThreaded</RuntimeLibrary> <LanguageStandard>stdcpplatest</LanguageStandard> </ClCompile> @@ -171,7 +171,7 @@ <OptimizeReferences>true</OptimizeReferences> <GenerateDebugInformation>true</GenerateDebugInformation> <AdditionalLibraryDirectories>$(SolutionDir)bin\$(Platform)-$(Configuration)\</AdditionalLibraryDirectories> - <AdditionalDependencies>libcommon.lib;Iphlpapi.lib;wbemuuid.lib;comsuppw.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>shared.lib;libcommon.lib;Iphlpapi.lib;wbemuuid.lib;comsuppw.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemGroup> diff --git a/windows/windns/windns.sln b/windows/windns/windns.sln index 41811271f9..13f072ff31 100644 --- a/windows/windns/windns.sln +++ b/windows/windns/windns.sln @@ -7,8 +7,11 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "windns", "src\windns\windns.vcxproj", "{A5344205-FC37-4572-9C63-8564ECC410AC}" ProjectSection(ProjectDependencies) = postProject {B52E2D10-A94A-4605-914A-2DCEF6A757EF} = {B52E2D10-A94A-4605-914A-2DCEF6A757EF} + {EE69EA4A-CF71-4B88-866B-957F60C4CE0D} = {EE69EA4A-CF71-4B88-866B-957F60C4CE0D} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shared", "..\shared\src\shared\shared.vcxproj", "{EE69EA4A-CF71-4B88-866B-957F60C4CE0D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -37,6 +40,14 @@ Global {A5344205-FC37-4572-9C63-8564ECC410AC}.Release|x86.ActiveCfg = Release|Win32 {A5344205-FC37-4572-9C63-8564ECC410AC}.Release|x86.Build.0 = Release|Win32 {A5344205-FC37-4572-9C63-8564ECC410AC}.Release|x86.Deploy.0 = Release|Win32 + {EE69EA4A-CF71-4B88-866B-957F60C4CE0D}.Debug|x64.ActiveCfg = Debug|x64 + {EE69EA4A-CF71-4B88-866B-957F60C4CE0D}.Debug|x64.Build.0 = Debug|x64 + {EE69EA4A-CF71-4B88-866B-957F60C4CE0D}.Debug|x86.ActiveCfg = Debug|Win32 + {EE69EA4A-CF71-4B88-866B-957F60C4CE0D}.Debug|x86.Build.0 = Debug|Win32 + {EE69EA4A-CF71-4B88-866B-957F60C4CE0D}.Release|x64.ActiveCfg = Release|x64 + {EE69EA4A-CF71-4B88-866B-957F60C4CE0D}.Release|x64.Build.0 = Release|x64 + {EE69EA4A-CF71-4B88-866B-957F60C4CE0D}.Release|x86.ActiveCfg = Release|Win32 + {EE69EA4A-CF71-4B88-866B-957F60C4CE0D}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/windows/windows-libraries b/windows/windows-libraries -Subproject 05e4625383d8521a42da7a2b327fa257061e96f +Subproject 19889be7a7e3555a03b9678dc486b429d5fad10 diff --git a/windows/winnet/src/winnet/interfaceutils.cpp b/windows/winnet/src/winnet/interfaceutils.cpp deleted file mode 100644 index 202d9d0724..0000000000 --- a/windows/winnet/src/winnet/interfaceutils.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include "stdafx.h" -#include "interfaceutils.h" -#include "libcommon/error.h" -#include "libcommon/string.h" -#include <cstdint> -#include <algorithm> - -//static -std::set<InterfaceUtils::NetworkAdapter> InterfaceUtils::GetAllAdapters() -{ - ULONG bufferSize = 0; - - const ULONG flags = GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER; - - auto status = GetAdaptersAddresses(AF_INET, flags, nullptr, nullptr, &bufferSize); - - THROW_UNLESS(ERROR_BUFFER_OVERFLOW, status, "Probe for adapter listing buffer size"); - - // Memory is cheap, this avoids a looping construct. - bufferSize *= 2; - - std::vector<uint8_t> buffer(bufferSize); - - status = GetAdaptersAddresses(AF_INET, flags, nullptr, - reinterpret_cast<PIP_ADAPTER_ADDRESSES>(&buffer[0]), &bufferSize); - - THROW_UNLESS(ERROR_SUCCESS, status, "Retrieve adapter listing"); - - std::set<NetworkAdapter> adapters; - - for (auto it = (PIP_ADAPTER_ADDRESSES)&buffer[0]; nullptr != it; it = it->Next) - { - adapters.emplace(NetworkAdapter(common::string::ToWide(it->AdapterName), - it->Description, it->FriendlyName)); - } - - return adapters; -} - -//static -std::set<InterfaceUtils::NetworkAdapter> -InterfaceUtils::GetTapAdapters(const std::set<InterfaceUtils::NetworkAdapter> &adapters) -{ - std::set<NetworkAdapter> tapAdapters; - - for (const auto &adapter : adapters) - { - static const wchar_t name[] = L"TAP-Windows Adapter V9"; - - // - // Compare partial name, because once you start having more TAP adapters - // they're named "TAP-Windows Adapter V9 #2" and so on. - // - - if (0 == adapter.name.compare(0, _countof(name) - 1, name)) - { - tapAdapters.insert(adapter); - } - } - - return tapAdapters; -} - -//static -std::wstring InterfaceUtils::GetTapInterfaceAlias() -{ - // - // Look for TAP adapter with alias "Mullvad". - // - - auto adapters = GetTapAdapters(GetAllAdapters()); - - auto findByAlias = [](const std::set<NetworkAdapter> &adapters, const std::wstring &alias) - { - const auto it = std::find_if(adapters.begin(), adapters.end(), [&alias](const NetworkAdapter &candidate) - { - return 0 == _wcsicmp(candidate.alias.c_str(), alias.c_str()); - }); - - return it != adapters.end(); - }; - - static const wchar_t baseAlias[] = L"Mullvad"; - - if (findByAlias(adapters, baseAlias)) - { - return baseAlias; - } - - // - // Look for TAP adapter with alias "Mullvad-1", "Mullvad-2", etc. - // - - for (auto i = 0; i < 10; ++i) - { - std::wstringstream ss; - - ss << baseAlias << L"-" << i; - - const auto alias = ss.str(); - - if (findByAlias(adapters, alias)) - { - return alias; - } - } - - throw std::runtime_error("Unable to find TAP adapter"); -} - -//static -void InterfaceUtils::AddDeviceIpAddresses(NET_LUID device, const std::vector<SOCKADDR_INET> &addresses) -{ - for (const auto &address : addresses) - { - MIB_UNICASTIPADDRESS_ROW row; - InitializeUnicastIpAddressEntry(&row); - - row.InterfaceLuid = device; - row.Address = address; - - THROW_UNLESS(NO_ERROR, CreateUnicastIpAddressEntry(&row), "Assign IP address on network interface"); - } -} diff --git a/windows/winnet/src/winnet/interfaceutils.h b/windows/winnet/src/winnet/interfaceutils.h deleted file mode 100644 index 8ab1249a50..0000000000 --- a/windows/winnet/src/winnet/interfaceutils.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include <string> -#include <set> -#include <vector> - -// Secret include order to get most common networking structs/apis -// And avoiding compilation errors -#include <winsock2.h> -#include <windows.h> -#include <ws2def.h> -#include <ws2ipdef.h> -#include <iphlpapi.h> -#include <netioapi.h> -// end - -class InterfaceUtils -{ - InterfaceUtils() = delete; - -public: - - struct NetworkAdapter - { - std::wstring guid; - std::wstring name; - std::wstring alias; - - NetworkAdapter(std::wstring _guid, std::wstring _name, std::wstring _alias) - : guid(_guid) - , name(_name) - , alias(_alias) - { - } - - bool operator<(const NetworkAdapter &rhs) const - { - return _wcsicmp(guid.c_str(), rhs.guid.c_str()) < 0; - } - }; - - static std::set<NetworkAdapter> GetAllAdapters(); - static std::set<NetworkAdapter> GetTapAdapters(const std::set<NetworkAdapter> &adapters); - - // - // Determines alias of primary TAP adapter. - // - static std::wstring GetTapInterfaceAlias(); - - static void AddDeviceIpAddresses(NET_LUID device, const std::vector<SOCKADDR_INET> &addresses); -}; diff --git a/windows/winnet/src/winnet/winnet.cpp b/windows/winnet/src/winnet/winnet.cpp index 690af747f2..c94970b863 100644 --- a/windows/winnet/src/winnet/winnet.cpp +++ b/windows/winnet/src/winnet/winnet.cpp @@ -1,10 +1,10 @@ #include "stdafx.h"
#include "winnet.h"
#include "NetworkInterfaces.h"
-#include "interfaceutils.h"
#include "offlinemonitor.h"
#include "routing/routemanager.h"
#include <shared/logsinkadapter.h>
+#include <shared/network/interfaceutils.h>
#include <libcommon/error.h>
#include <libcommon/network.h>
#include <cstdint>
@@ -14,7 +14,9 @@ #include <mutex>
using namespace winnet::routing;
+using namespace common::network;
using AutoLockType = std::scoped_lock<std::mutex>;
+using namespace shared::network;
namespace
{
diff --git a/windows/winnet/src/winnet/winnet.vcxproj b/windows/winnet/src/winnet/winnet.vcxproj index def37bc67d..5fb0a50ec5 100644 --- a/windows/winnet/src/winnet/winnet.vcxproj +++ b/windows/winnet/src/winnet/winnet.vcxproj @@ -30,7 +30,6 @@ <ClCompile Include="networkadaptermonitor.cpp" /> <ClCompile Include="dllmain.cpp" /> <ClCompile Include="InterfacePair.cpp" /> - <ClCompile Include="interfaceutils.cpp" /> <ClCompile Include="offlinemonitor.cpp" /> <ClCompile Include="NetworkInterfaces.cpp" /> <ClCompile Include="routing\defaultroutemonitor.cpp" /> @@ -43,7 +42,6 @@ <ItemGroup> <ClInclude Include="networkadaptermonitor.h" /> <ClInclude Include="InterfacePair.h" /> - <ClInclude Include="interfaceutils.h" /> <ClInclude Include="offlinemonitor.h" /> <ClInclude Include="NetworkInterfaces.h" /> <ClInclude Include="routing\defaultroutemonitor.h" /> @@ -179,7 +177,7 @@ <GenerateDebugInformation>true</GenerateDebugInformation> <ModuleDefinitionFile>winnet.def</ModuleDefinitionFile> <AdditionalLibraryDirectories>$(SolutionDir)/bin/$(Platform)-$(Configuration)</AdditionalLibraryDirectories> - <AdditionalDependencies>libcommon.lib;Iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>shared.lib;libcommon.lib;Iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Static|Win32'"> @@ -203,7 +201,7 @@ </Link> <Lib> <AdditionalLibraryDirectories>$(SolutionDir)/bin/$(Platform)-Debug</AdditionalLibraryDirectories> - <AdditionalDependencies>libcommon.lib;Iphlpapi.lib</AdditionalDependencies> + <AdditionalDependencies>shared.lib;libcommon.lib;Iphlpapi.lib</AdditionalDependencies> </Lib> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> @@ -221,7 +219,7 @@ <Link> <SubSystem>Windows</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalDependencies>libcommon.lib;Iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>shared.lib;libcommon.lib;Iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>$(SolutionDir)/bin/$(Platform)-$(Configuration)</AdditionalLibraryDirectories> <ModuleDefinitionFile>winnet.def</ModuleDefinitionFile> </Link> @@ -246,7 +244,7 @@ <ModuleDefinitionFile>winnet.def</ModuleDefinitionFile> </Link> <Lib> - <AdditionalDependencies>libcommon.lib;Iphlpapi.lib</AdditionalDependencies> + <AdditionalDependencies>shared.lib;libcommon.lib;Iphlpapi.lib</AdditionalDependencies> <AdditionalLibraryDirectories>$(SolutionDir)/bin/$(Platform)-Debug</AdditionalLibraryDirectories> </Lib> </ItemDefinitionGroup> @@ -271,7 +269,7 @@ <GenerateDebugInformation>true</GenerateDebugInformation> <ModuleDefinitionFile>winnet.def</ModuleDefinitionFile> <AdditionalLibraryDirectories>$(SolutionDir)/bin/$(Platform)-$(Configuration)</AdditionalLibraryDirectories> - <AdditionalDependencies>libcommon.lib;Iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>shared.lib;libcommon.lib;Iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> @@ -295,7 +293,7 @@ <GenerateDebugInformation>true</GenerateDebugInformation> <ModuleDefinitionFile>winnet.def</ModuleDefinitionFile> <AdditionalLibraryDirectories>$(SolutionDir)/bin/$(Platform)-$(Configuration)</AdditionalLibraryDirectories> - <AdditionalDependencies>libcommon.lib;Iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>shared.lib;libcommon.lib;Iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> </ItemDefinitionGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> diff --git a/windows/winnet/src/winnet/winnet.vcxproj.filters b/windows/winnet/src/winnet/winnet.vcxproj.filters index dfe6d29ec7..db5a7c8b3a 100644 --- a/windows/winnet/src/winnet/winnet.vcxproj.filters +++ b/windows/winnet/src/winnet/winnet.vcxproj.filters @@ -6,7 +6,6 @@ <ClCompile Include="winnet.cpp" /> <ClCompile Include="NetworkInterfaces.cpp" /> <ClCompile Include="InterfacePair.cpp" /> - <ClCompile Include="interfaceutils.cpp" /> <ClCompile Include="networkadaptermonitor.cpp" /> <ClCompile Include="offlinemonitor.cpp" /> <ClCompile Include="routing\types.cpp"> @@ -28,7 +27,6 @@ <ClInclude Include="winnet.h" /> <ClInclude Include="NetworkInterfaces.h" /> <ClInclude Include="InterfacePair.h" /> - <ClInclude Include="interfaceutils.h" /> <ClInclude Include="networkadaptermonitor.h" /> <ClInclude Include="offlinemonitor.h" /> <ClInclude Include="routing\types.h"> |
