From 25b198cac8b46f3fabf19b3ba48c055e9c348e38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Thu, 19 Apr 2018 16:35:27 +0200 Subject: [PATCH] IOS/SO: Move default interface code into a separate function ...so that the function can be more easily reused. --- Source/Core/Core/IOS/Network/IP/Top.cpp | 133 +++++++++++++----------- 1 file changed, 72 insertions(+), 61 deletions(-) diff --git a/Source/Core/Core/IOS/Network/IP/Top.cpp b/Source/Core/Core/IOS/Network/IP/Top.cpp index 037cd95589..2081b3a595 100644 --- a/Source/Core/Core/IOS/Network/IP/Top.cpp +++ b/Source/Core/Core/IOS/Network/IP/Top.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -153,6 +154,75 @@ static s32 MapWiiSockOptNameToNative(u32 optname) return optname; } +struct DefaultInterface +{ + u32 inet; ///< IPv4 address + u32 netmask; ///< IPv4 subnet mask + u32 broadcast; ///< IPv4 broadcast address +}; + +static std::optional GetSystemDefaultInterface() +{ +#ifdef _WIN32 + DWORD forwardTableSize, ipTableSize, result; + NET_IFINDEX ifIndex = NET_IFINDEX_UNSPECIFIED; + std::unique_ptr forwardTable; + std::unique_ptr ipTable; + + forwardTableSize = 0; + if (GetIpForwardTable(nullptr, &forwardTableSize, FALSE) == ERROR_INSUFFICIENT_BUFFER) + { + forwardTable = + std::unique_ptr((PMIB_IPFORWARDTABLE) operator new(forwardTableSize)); + } + + ipTableSize = 0; + if (GetIpAddrTable(nullptr, &ipTableSize, FALSE) == ERROR_INSUFFICIENT_BUFFER) + { + ipTable = std::unique_ptr((PMIB_IPADDRTABLE) operator new(ipTableSize)); + } + + // find the interface IP used for the default route and use that + result = GetIpForwardTable(forwardTable.get(), &forwardTableSize, FALSE); + // can return ERROR_MORE_DATA on XP even after the first call + while (result == NO_ERROR || result == ERROR_MORE_DATA) + { + for (DWORD i = 0; i < forwardTable->dwNumEntries; ++i) + { + if (forwardTable->table[i].dwForwardDest == 0) + { + ifIndex = forwardTable->table[i].dwForwardIfIndex; + break; + } + } + + if (result == NO_ERROR || ifIndex != NET_IFINDEX_UNSPECIFIED) + break; + + result = GetIpForwardTable(forwardTable.get(), &forwardTableSize, FALSE); + } + + if (ifIndex != NET_IFINDEX_UNSPECIFIED && + GetIpAddrTable(ipTable.get(), &ipTableSize, FALSE) == NO_ERROR) + { + for (DWORD i = 0; i < ipTable->dwNumEntries; ++i) + { + const auto& entry = ipTable->table[i]; + if (entry.dwIndex == ifIndex) + return DefaultInterface{entry.dwAddr, entry.dwMask, entry.dwBCastAddr}; + } + } +#endif + return {}; +} + +static DefaultInterface GetSystemDefaultInterfaceOrFallback() +{ + static constexpr DefaultInterface FALLBACK_VALUES{ + inet_addr(10, 0, 1, 30), inet_addr(255, 255, 255, 0), inet_addr(10, 0, 255, 255)}; + return GetSystemDefaultInterface().value_or(FALLBACK_VALUES); +} + IPCCommandResult NetIPTop::IOCtl(const IOCtlRequest& request) { if (Core::WantsDeterminism()) @@ -433,67 +503,8 @@ IPCCommandResult NetIPTop::HandleGetPeerNameRequest(const IOCtlRequest& request) IPCCommandResult NetIPTop::HandleGetHostIDRequest(const IOCtlRequest& request) { request.Log(GetDeviceName(), LogTypes::IOS_WC24); - - s32 return_value = 0; - -#ifdef _WIN32 - DWORD forwardTableSize, ipTableSize, result; - NET_IFINDEX ifIndex = NET_IFINDEX_UNSPECIFIED; - std::unique_ptr forwardTable; - std::unique_ptr ipTable; - - forwardTableSize = 0; - if (GetIpForwardTable(nullptr, &forwardTableSize, FALSE) == ERROR_INSUFFICIENT_BUFFER) - { - forwardTable = - std::unique_ptr((PMIB_IPFORWARDTABLE) operator new(forwardTableSize)); - } - - ipTableSize = 0; - if (GetIpAddrTable(nullptr, &ipTableSize, FALSE) == ERROR_INSUFFICIENT_BUFFER) - { - ipTable = std::unique_ptr((PMIB_IPADDRTABLE) operator new(ipTableSize)); - } - - // find the interface IP used for the default route and use that - result = GetIpForwardTable(forwardTable.get(), &forwardTableSize, FALSE); - // can return ERROR_MORE_DATA on XP even after the first call - while (result == NO_ERROR || result == ERROR_MORE_DATA) - { - for (DWORD i = 0; i < forwardTable->dwNumEntries; ++i) - { - if (forwardTable->table[i].dwForwardDest == 0) - { - ifIndex = forwardTable->table[i].dwForwardIfIndex; - break; - } - } - - if (result == NO_ERROR || ifIndex != NET_IFINDEX_UNSPECIFIED) - break; - - result = GetIpForwardTable(forwardTable.get(), &forwardTableSize, FALSE); - } - - if (ifIndex != NET_IFINDEX_UNSPECIFIED && - GetIpAddrTable(ipTable.get(), &ipTableSize, FALSE) == NO_ERROR) - { - for (DWORD i = 0; i < ipTable->dwNumEntries; ++i) - { - if (ipTable->table[i].dwIndex == ifIndex) - { - return_value = Common::swap32(ipTable->table[i].dwAddr); - break; - } - } - } -#endif - - // default placeholder, in case of failure - if (return_value == 0) - return_value = 192 << 24 | 168 << 16 | 1 << 8 | 150; - - return GetDefaultReply(return_value); + const DefaultInterface interface = GetSystemDefaultInterfaceOrFallback(); + return GetDefaultReply(Common::swap32(interface.inet)); } IPCCommandResult NetIPTop::HandleInetAToNRequest(const IOCtlRequest& request)