troubleshooter: detect lack of ipv4 (#447)

## Link to GitHub Issue, if one exists
#345 

## Description of change
Most games will fail show a network error if there is no network adapter
with a valid IPv4 address

Detect this case in netfix code and show a warning message in log +
deferred error message.

## Testing
Tested with no network adapters, with IPv6 only adapter, and a
disconnected NIC.
This commit is contained in:
bicarus-dev
2025-12-14 00:07:22 -08:00
committed by GitHub
parent 6f58d9ab68
commit f68a3439d3
+44 -1
View File
@@ -4,6 +4,7 @@
#include <iphlpapi.h> #include <iphlpapi.h>
#include <stdlib.h> #include <stdlib.h>
#include <string> #include <string>
#include <mutex>
#include "avs/core.h" #include "avs/core.h"
#include "avs/ea3.h" #include "avs/ea3.h"
@@ -12,6 +13,7 @@
#include "util/detour.h" #include "util/detour.h"
#include "util/fileutils.h" #include "util/fileutils.h"
#include "util/libutils.h" #include "util/libutils.h"
#include "util/deferlog.h"
// hooking related stuff // hooking related stuff
static decltype(GetAdaptersInfo) *GetAdaptersInfo_orig = nullptr; static decltype(GetAdaptersInfo) *GetAdaptersInfo_orig = nullptr;
@@ -27,6 +29,19 @@ static struct in_addr network;
static struct in_addr prefix; static struct in_addr prefix;
static struct in_addr subnet; static struct in_addr subnet;
static void defer_network_adapter_error() {
static std::once_flag printed;
std::call_once(printed, []() {
deferredlogs::defer_error_messages({
"network adapter issue detected!",
" ensure you have at least one network adapter with a valid IPv4 address",
" the IPv4 address can be external or internal, it just needs to be valid",
" the network adapter can be a wired or wireless connection",
" you still need to do this even if you are connecting to a local server!",
});
});
}
static ULONG WINAPI GetAdaptersInfo_hook(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen) { static ULONG WINAPI GetAdaptersInfo_hook(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen) {
// call orig // call orig
@@ -53,6 +68,15 @@ static ULONG WINAPI GetAdaptersInfo_hook(PIP_ADAPTER_INFO pAdapterInfo, PULONG p
free(pAdapterInfo2); free(pAdapterInfo2);
} }
if (ret != ERROR_SUCCESS) {
defer_network_adapter_error();
log_warning(
"network",
"GetAdaptersInfo failed with {}; "
"check if you have at least one network adapter with a valid IPv4 address!",
ret);
}
return ret; return ret;
} }
@@ -101,8 +125,13 @@ static ULONG WINAPI GetAdaptersInfo_hook(PIP_ADAPTER_INFO pAdapterInfo, PULONG p
free(pIpForwardTable); free(pIpForwardTable);
pIpForwardTable = (MIB_IPFORWARDTABLE *) malloc(dwSize); pIpForwardTable = (MIB_IPFORWARDTABLE *) malloc(dwSize);
} }
if (GetIpForwardTable(pIpForwardTable, &dwSize, 1) != NO_ERROR || pIpForwardTable->dwNumEntries == 0) if (GetIpForwardTable(pIpForwardTable, &dwSize, 1) != NO_ERROR || pIpForwardTable->dwNumEntries == 0) {
defer_network_adapter_error();
if (GetAdaptersInfo_log) {
log_warning("network", "GetIpForwardTable failed");
}
return ret; return ret;
}
// determine best interface // determine best interface
DWORD best = pIpForwardTable->table[0].dwForwardIfIndex; DWORD best = pIpForwardTable->table[0].dwForwardIfIndex;
@@ -134,6 +163,20 @@ static ULONG WINAPI GetAdaptersInfo_hook(PIP_ADAPTER_INFO pAdapterInfo, PULONG p
info = info->Next; info = info->Next;
} }
if (pAdapterInfo->IpAddressList.IpAddress.String[0] == 0 ||
pAdapterInfo->IpAddressList.IpAddress.String[0] == '0') {
defer_network_adapter_error();
if (GetAdaptersInfo_log) {
log_warning(
"network",
"invalid IPv4 address for adapter {}, {} = {}; "
"ensure you have at least one network adapter with valid IPv4 address!",
pAdapterInfo->AdapterName,
pAdapterInfo->Description,
pAdapterInfo->IpAddressList.IpAddress.String);
}
}
// return original value // return original value
GetAdaptersInfo_log = false; GetAdaptersInfo_log = false;
return ret; return ret;