DEV9: Unify GetAdapter code

This commit is contained in:
TheLastRar 2024-05-19 18:06:07 +01:00 committed by refractionpcsx2
parent 344cf6fffb
commit 3aff833b5c
4 changed files with 84 additions and 171 deletions

View File

@ -55,17 +55,15 @@ using namespace PacketReader::IP;
*/
#ifdef _WIN32
bool AdapterUtils::GetAdapter(const std::string& name, Adapter* adapter, AdapterBuffer* buffer)
AdapterUtils::Adapter* AdapterUtils::GetAllAdapters(AdapterBuffer* buffer, bool includeHidden)
{
int neededSize = 128;
int neededSize = includeHidden ? 256 : 128;
std::unique_ptr<IP_ADAPTER_ADDRESSES[]> adapterInfo = std::make_unique<IP_ADAPTER_ADDRESSES[]>(neededSize);
ULONG dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize;
PIP_ADAPTER_ADDRESSES pAdapterInfo;
DWORD dwStatus = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS | (includeHidden ? GAA_FLAG_INCLUDE_ALL_INTERFACES : 0),
NULL,
adapterInfo.get(),
&dwBufLen);
@ -80,66 +78,45 @@ bool AdapterUtils::GetAdapter(const std::string& name, Adapter* adapter, Adapter
dwStatus = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS | (includeHidden ? GAA_FLAG_INCLUDE_ALL_INTERFACES : 0),
NULL,
adapterInfo.get(),
&dwBufLen);
}
if (dwStatus != ERROR_SUCCESS)
return false;
return nullptr;
pAdapterInfo = adapterInfo.get();
buffer->swap(adapterInfo);
return buffer->get();
}
bool AdapterUtils::GetAdapter(const std::string& name, Adapter* adapter, AdapterBuffer* buffer)
{
std::unique_ptr<IP_ADAPTER_ADDRESSES[]> adapterInfo;
PIP_ADAPTER_ADDRESSES pAdapter = GetAllAdapters(&adapterInfo);
if (pAdapter == nullptr)
return false;
do
{
if (strcmp(pAdapterInfo->AdapterName, name.c_str()) == 0)
if (strcmp(pAdapter->AdapterName, name.c_str()) == 0)
{
*adapter = *pAdapterInfo;
*adapter = *pAdapter;
buffer->swap(adapterInfo);
return true;
}
pAdapterInfo = pAdapterInfo->Next;
} while (pAdapterInfo);
pAdapter = pAdapter->Next;
} while (pAdapter);
return false;
}
bool AdapterUtils::GetAdapterAuto(Adapter* adapter, AdapterBuffer* buffer)
{
int neededSize = 128;
std::unique_ptr<IP_ADAPTER_ADDRESSES[]> adapterInfo = std::make_unique<IP_ADAPTER_ADDRESSES[]>(neededSize);
ULONG dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize;
PIP_ADAPTER_ADDRESSES pAdapter;
DWORD dwStatus = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS,
NULL,
adapterInfo.get(),
&dwBufLen);
if (dwStatus == ERROR_BUFFER_OVERFLOW)
{
DevCon.WriteLn("DEV9: PCAPGetWin32Adapter() buffer too small, resizing");
//
neededSize = dwBufLen / sizeof(IP_ADAPTER_ADDRESSES) + 1;
adapterInfo = std::make_unique<IP_ADAPTER_ADDRESSES[]>(neededSize);
dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize;
DevCon.WriteLn("DEV9: New size %i", neededSize);
dwStatus = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS,
NULL,
adapterInfo.get(),
&dwBufLen);
}
if (dwStatus != ERROR_SUCCESS)
return 0;
pAdapter = adapterInfo.get();
std::unique_ptr<IP_ADAPTER_ADDRESSES[]> adapterInfo;
PIP_ADAPTER_ADDRESSES pAdapter = GetAllAdapters(&adapterInfo);
if (pAdapter == nullptr)
return false;
do
{
@ -181,19 +158,25 @@ bool AdapterUtils::GetAdapterAuto(Adapter* adapter, AdapterBuffer* buffer)
return false;
}
#elif defined(__POSIX__)
bool AdapterUtils::GetAdapter(const std::string& name, Adapter* adapter, AdapterBuffer* buffer)
AdapterUtils::Adapter* AdapterUtils::GetAllAdapters(AdapterBuffer* buffer)
{
ifaddrs* ifa;
ifaddrs* pAdapter;
int error = getifaddrs(&ifa);
if (error)
return nullptr;
buffer->reset(ifa);
return buffer->get();
}
bool AdapterUtils::GetAdapter(const std::string& name, Adapter* adapter, AdapterBuffer* buffer)
{
std::unique_ptr<ifaddrs, IfAdaptersDeleter> adapterInfo;
ifaddrs* pAdapter = GetAllAdapters(&adapterInfo);
if (pAdapter == nullptr)
return false;
std::unique_ptr<ifaddrs, IfAdaptersDeleter> adapterInfo(ifa, IfAdaptersDeleter());
pAdapter = adapterInfo.get();
do
{
if (pAdapter->ifa_addr != nullptr &&
@ -215,17 +198,11 @@ bool AdapterUtils::GetAdapter(const std::string& name, Adapter* adapter, Adapter
}
bool AdapterUtils::GetAdapterAuto(Adapter* adapter, AdapterBuffer* buffer)
{
ifaddrs* ifa;
ifaddrs* pAdapter;
int error = getifaddrs(&ifa);
if (error)
std::unique_ptr<ifaddrs, IfAdaptersDeleter> adapterInfo;
ifaddrs* pAdapter = GetAllAdapters(&adapterInfo);
if (pAdapter == nullptr)
return false;
std::unique_ptr<ifaddrs, IfAdaptersDeleter> adapterInfo(ifa, IfAdaptersDeleter());
pAdapter = adapterInfo.get();
do
{
if ((pAdapter->ifa_flags & IFF_LOOPBACK) == 0 &&

View File

@ -31,6 +31,15 @@ namespace AdapterUtils
void operator()(ifaddrs* buffer) const { freeifaddrs(buffer); }
};
typedef std::unique_ptr<ifaddrs, IfAdaptersDeleter> AdapterBuffer;
#endif
// Adapter is a structure that contains ptrs to data stored within AdapterBuffer.
// We need to return this buffer the caller can free it after it's finished with Adapter.
// AdapterBuffer is a unique_ptr, so will be freed when it leaves scope.
#ifdef _WIN32
// includeHidden sets GAA_FLAG_INCLUDE_ALL_INTERFACES, used by TAPAdapter
Adapter* GetAllAdapters(AdapterBuffer* buffer, bool includeHidden = false);
#elif defined(__POSIX__)
Adapter* GetAllAdapters(AdapterBuffer* buffer);
#endif
bool GetAdapter(const std::string& name, Adapter* adapter, AdapterBuffer* buffer);
bool GetAdapterAuto(Adapter* adapter, AdapterBuffer* buffer);

View File

@ -24,6 +24,7 @@
#include <wil/resource.h>
#include "DEV9/PacketReader/MAC_Address.h"
#include "DEV9/AdapterUtils.h"
//=============
// TAP IOCTLs
@ -272,80 +273,41 @@ PIP_ADAPTER_ADDRESSES FindAdapterViaIndex(PIP_ADAPTER_ADDRESSES adapterList, int
//IP_ADAPTER_ADDRESSES is a structure that contains ptrs to data in other regions
//of the buffer, se we need to return both so the caller can free the buffer
//after it's finished reading the needed data from IP_ADAPTER_ADDRESSES
bool TAPGetWin32Adapter(const std::string& name, PIP_ADAPTER_ADDRESSES adapter, std::unique_ptr<IP_ADAPTER_ADDRESSES[]>* buffer)
bool TAPGetWin32Adapter(const std::string& name, PIP_ADAPTER_ADDRESSES adapter, AdapterUtils::AdapterBuffer* buffer)
{
int neededSize = 256;
std::unique_ptr<IP_ADAPTER_ADDRESSES[]> AdapterInfo = std::make_unique<IP_ADAPTER_ADDRESSES[]>(neededSize);
ULONG dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize;
PIP_ADAPTER_ADDRESSES pAdapterInfo;
//GAA_FLAG_INCLUDE_ALL_INTERFACES needed to get Tap when bridged
DWORD dwStatus = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS | GAA_FLAG_INCLUDE_ALL_INTERFACES,
NULL,
AdapterInfo.get(),
&dwBufLen);
if (dwStatus == ERROR_BUFFER_OVERFLOW)
{
DevCon.WriteLn("DEV9: GetWin32Adapter() buffer too small, resizing");
//
neededSize = dwBufLen / sizeof(IP_ADAPTER_ADDRESSES) + 1;
AdapterInfo = std::make_unique<IP_ADAPTER_ADDRESSES[]>(neededSize);
dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize;
DevCon.WriteLn("DEV9: New size %i", neededSize);
dwStatus = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS | GAA_FLAG_INCLUDE_ALL_INTERFACES,
NULL,
AdapterInfo.get(),
&dwBufLen);
}
if (dwStatus != ERROR_SUCCESS)
return 0;
pAdapterInfo = AdapterInfo.get();
AdapterUtils::AdapterBuffer adapterInfo;
PIP_ADAPTER_ADDRESSES pAdapterFirst = AdapterUtils::GetAllAdapters(&adapterInfo, true);
if (pAdapterFirst == nullptr)
return false;
PIP_ADAPTER_ADDRESSES pAdapter = pAdapterFirst;
do
{
if (0 == strcmp(pAdapterInfo->AdapterName, name.c_str()))
if (0 == strcmp(pAdapter->AdapterName, name.c_str()))
break;
pAdapterInfo = pAdapterInfo->Next;
} while (pAdapterInfo);
pAdapter = pAdapter->Next;
} while (pAdapter);
if (pAdapterInfo == nullptr)
if (pAdapter == nullptr)
return false;
//If we are bridged, then we won't show up without GAA_FLAG_INCLUDE_ALL_INTERFACES
std::unique_ptr<IP_ADAPTER_ADDRESSES[]> AdapterInfoReduced = std::make_unique<IP_ADAPTER_ADDRESSES[]>(neededSize);
dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize;
dwStatus = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS,
NULL,
AdapterInfoReduced.get(),
&dwBufLen);
if (dwStatus != ERROR_SUCCESS)
return 0;
AdapterUtils::AdapterBuffer adapterInfoReduced;
PIP_ADAPTER_ADDRESSES pAdapterReducedFirst = AdapterUtils::GetAllAdapters(&adapterInfoReduced, false);
//If we find our adapter in the reduced list, we are not bridged
if (FindAdapterViaIndex(AdapterInfoReduced.get(), pAdapterInfo->IfIndex) != nullptr)
if (FindAdapterViaIndex(pAdapterReducedFirst, pAdapter->IfIndex) != nullptr)
{
*adapter = *pAdapterInfo;
buffer->swap(AdapterInfo);
*adapter = *pAdapter;
buffer->swap(adapterInfo);
return true;
}
//We must be bridged
Console.WriteLn("DEV9: Current adapter is probably bridged");
Console.WriteLn(fmt::format("DEV9: Adapter Display name: {}", StringUtil::WideStringToUTF8String(pAdapterInfo->FriendlyName)));
Console.WriteLn(fmt::format("DEV9: Adapter Display name: {}", StringUtil::WideStringToUTF8String(pAdapter->FriendlyName)));
//We will need to find the bridge adapter that out adapter is
//as the IP information of the tap adapter is null
@ -379,7 +341,7 @@ bool TAPGetWin32Adapter(const std::string& name, PIP_ADAPTER_ADDRESSES adapter,
//If multiple rows have our adapter, we check all of them
std::vector<NET_IFINDEX> potentialBridges;
std::vector<NET_IFINDEX> searchList;
searchList.push_back(pAdapterInfo->IfIndex);
searchList.push_back(pAdapter->IfIndex);
PMIB_IFSTACK_TABLE table;
GetIfStackTable(&table);
@ -392,7 +354,7 @@ bool TAPGetWin32Adapter(const std::string& name, PIP_ADAPTER_ADDRESSES adapter,
MIB_IFSTACK_ROW row = table->Table[i];
if (row.LowerLayerInterfaceIndex == targetIndex)
{
const PIP_ADAPTER_ADDRESSES potentialAdapter = FindAdapterViaIndex(AdapterInfoReduced.get(), row.HigherLayerInterfaceIndex);
const PIP_ADAPTER_ADDRESSES potentialAdapter = FindAdapterViaIndex(pAdapterReducedFirst, row.HigherLayerInterfaceIndex);
if (potentialAdapter != nullptr)
{
Console.WriteLn(fmt::format("DEV9: {} is possible bridge (Check 1 passed)", StringUtil::WideStringToUTF8String(potentialAdapter->Description)));
@ -406,7 +368,8 @@ bool TAPGetWin32Adapter(const std::string& name, PIP_ADAPTER_ADDRESSES adapter,
}
//Cleanup
FreeMibTable(table);
AdapterInfoReduced = nullptr;
pAdapterReducedFirst = nullptr;
adapterInfoReduced.reset();
//Step 2
//Init COM
@ -442,7 +405,7 @@ bool TAPGetWin32Adapter(const std::string& name, PIP_ADAPTER_ADDRESSES adapter,
//We need to match the adapter index to an INetCfgComponent
//We do this by matching IP_ADAPTER_ADDRESSES.AdapterName
//with the INetCfgComponent Instance GUID
PIP_ADAPTER_ADDRESSES cAdapterInfo = FindAdapterViaIndex(AdapterInfo.get(), index);
PIP_ADAPTER_ADDRESSES cAdapterInfo = FindAdapterViaIndex(pAdapterFirst, index);
if (cAdapterInfo == nullptr || cAdapterInfo->AdapterName == nullptr)
continue;
@ -514,7 +477,7 @@ bool TAPGetWin32Adapter(const std::string& name, PIP_ADAPTER_ADDRESSES adapter,
if (bridgeAdapter != nullptr)
{
*adapter = *bridgeAdapter;
buffer->swap(AdapterInfo);
buffer->swap(adapterInfo);
return true;
}
@ -551,7 +514,7 @@ TAPAdapter::TAPAdapter()
SetMACAddress(&newMAC);
IP_ADAPTER_ADDRESSES adapter;
std::unique_ptr<IP_ADAPTER_ADDRESSES[]> buffer;
AdapterUtils::AdapterBuffer buffer;
if (TAPGetWin32Adapter(EmuConfig.DEV9.EthDevice, &adapter, &buffer))
InitInternalServer(&adapter);
else
@ -646,7 +609,7 @@ bool TAPAdapter::send(NetPacket* pkt)
void TAPAdapter::reloadSettings()
{
IP_ADAPTER_ADDRESSES adapter;
std::unique_ptr<IP_ADAPTER_ADDRESSES[]> buffer;
AdapterUtils::AdapterBuffer buffer;
if (TAPGetWin32Adapter(EmuConfig.DEV9.EthDevice, &adapter, &buffer))
ReloadInternalServer(&adapter);
else

View File

@ -50,67 +50,33 @@ std::vector<AdapterEntry> SocketAdapter::GetAdapters()
nic.push_back(autoEntry);
#ifdef _WIN32
int neededSize = 128;
std::unique_ptr<IP_ADAPTER_ADDRESSES[]> AdapterInfo = std::make_unique<IP_ADAPTER_ADDRESSES[]>(neededSize);
ULONG dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize;
PIP_ADAPTER_ADDRESSES pAdapterInfo;
DWORD dwStatus = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS,
NULL,
AdapterInfo.get(),
&dwBufLen);
if (dwStatus == ERROR_BUFFER_OVERFLOW)
{
DevCon.WriteLn("DEV9: PCAPGetWin32Adapter() buffer too small, resizing");
//
neededSize = dwBufLen / sizeof(IP_ADAPTER_ADDRESSES) + 1;
AdapterInfo = std::make_unique<IP_ADAPTER_ADDRESSES[]>(neededSize);
dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize;
DevCon.WriteLn("DEV9: New size %i", neededSize);
dwStatus = GetAdaptersAddresses(
AF_UNSPEC,
GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS,
NULL,
AdapterInfo.get(),
&dwBufLen);
}
if (dwStatus != ERROR_SUCCESS)
AdapterUtils::AdapterBuffer adapterInfo;
PIP_ADAPTER_ADDRESSES pAdapter = AdapterUtils::GetAllAdapters(&adapterInfo);
if (pAdapter == nullptr)
return nic;
pAdapterInfo = AdapterInfo.get();
do
{
if (pAdapterInfo->IfType != IF_TYPE_SOFTWARE_LOOPBACK &&
pAdapterInfo->OperStatus == IfOperStatusUp)
if (pAdapter->IfType != IF_TYPE_SOFTWARE_LOOPBACK &&
pAdapter->OperStatus == IfOperStatusUp)
{
AdapterEntry entry;
entry.type = Pcsx2Config::DEV9Options::NetApi::Sockets;
entry.name = StringUtil::WideStringToUTF8String(pAdapterInfo->FriendlyName);
entry.guid = pAdapterInfo->AdapterName;
entry.name = StringUtil::WideStringToUTF8String(pAdapter->FriendlyName);
entry.guid = pAdapter->AdapterName;
nic.push_back(entry);
}
pAdapterInfo = pAdapterInfo->Next;
} while (pAdapterInfo);
pAdapter = pAdapter->Next;
} while (pAdapter);
#elif defined(__POSIX__)
ifaddrs* adapterInfo;
ifaddrs* pAdapter;
int error = getifaddrs(&adapterInfo);
if (error)
AdapterUtils::AdapterBuffer adapterInfo;
ifaddrs* pAdapter = GetAllAdapters(&adapterInfo);
if (pAdapter == nullptr)
return nic;
pAdapter = adapterInfo;
do
{
if ((pAdapter->ifa_flags & IFF_LOOPBACK) == 0 &&
@ -128,8 +94,6 @@ std::vector<AdapterEntry> SocketAdapter::GetAdapters()
pAdapter = pAdapter->ifa_next;
} while (pAdapter);
freeifaddrs(adapterInfo);
#endif
return nic;