mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-11-11 07:10:36 +00:00
273270916e
This commit reflects changes to clang-format rules. Unfortunately, these rule changes create a massive change to the codebase, which causes an apparent rewrite of git history. Git blame's --ignore-rev flag can be used to ignore this commit when attempting to `git blame` some code.
307 lines
8.9 KiB
C
307 lines
8.9 KiB
C
#if defined(__MINGW32__) && !defined(_WIN64)
|
|
/*
|
|
* Contains routines missing from WS2_32.DLL until 2006, if yer using
|
|
* Microsoft C/C++, then this code is irrelevant, as the official
|
|
* Platform SDK already links against these routines in the correct
|
|
* libraries.
|
|
*
|
|
* -despair86 30/07/18
|
|
*/
|
|
|
|
// these need to be in a specific order
|
|
#include <assert.h>
|
|
#include <stdbool.h>
|
|
#include <net/net.h>
|
|
#include <windows.h>
|
|
#include <iphlpapi.h>
|
|
#if WINNT_CROSS_COMPILE && !NTSTATUS
|
|
typedef LONG NTSTATUS;
|
|
#endif
|
|
#include "win32_intrnl.h"
|
|
|
|
const char*
|
|
inet_ntop(int af, const void* src, char* dst, size_t size)
|
|
{
|
|
int address_length;
|
|
DWORD string_length = size;
|
|
struct sockaddr_storage sa;
|
|
struct sockaddr_in* sin = (struct sockaddr_in*)&sa;
|
|
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)&sa;
|
|
|
|
memset(&sa, 0, sizeof(sa));
|
|
switch (af)
|
|
{
|
|
case AF_INET:
|
|
address_length = sizeof(struct sockaddr_in);
|
|
sin->sin_family = af;
|
|
memcpy(&sin->sin_addr, src, sizeof(struct in_addr));
|
|
break;
|
|
|
|
case AF_INET6:
|
|
address_length = sizeof(struct sockaddr_in6);
|
|
sin6->sin6_family = af;
|
|
memcpy(&sin6->sin6_addr, src, sizeof(struct in6_addr));
|
|
break;
|
|
|
|
default:
|
|
return NULL;
|
|
}
|
|
|
|
if (WSAAddressToString((LPSOCKADDR)&sa, address_length, NULL, dst, &string_length) == 0)
|
|
{
|
|
return dst;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int
|
|
inet_pton(int af, const char* src, void* dst)
|
|
{
|
|
int address_length;
|
|
struct sockaddr_storage sa;
|
|
struct sockaddr_in* sin = (struct sockaddr_in*)&sa;
|
|
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)&sa;
|
|
|
|
switch (af)
|
|
{
|
|
case AF_INET:
|
|
address_length = sizeof(struct sockaddr_in);
|
|
break;
|
|
|
|
case AF_INET6:
|
|
address_length = sizeof(struct sockaddr_in6);
|
|
break;
|
|
|
|
default:
|
|
return -1;
|
|
}
|
|
|
|
if (WSAStringToAddress((LPTSTR)src, af, NULL, (LPSOCKADDR)&sa, &address_length) == 0)
|
|
{
|
|
switch (af)
|
|
{
|
|
case AF_INET:
|
|
memcpy(dst, &sin->sin_addr, sizeof(struct in_addr));
|
|
break;
|
|
|
|
case AF_INET6:
|
|
memcpy(dst, &sin6->sin6_addr, sizeof(struct in6_addr));
|
|
break;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
typedef struct _InterfaceIndexTable
|
|
{
|
|
DWORD numIndexes;
|
|
IF_INDEX indexes[1];
|
|
} InterfaceIndexTable;
|
|
|
|
// windows 2000
|
|
// todo(despair86): implement IPv6 detection using
|
|
// the ipv6 preview stack/adv net pack from 1999/2001
|
|
DWORD FAR PASCAL
|
|
_GetAdaptersAddresses(
|
|
ULONG Family,
|
|
ULONG Flags,
|
|
PVOID Reserved,
|
|
PIP_ADAPTER_ADDRESSES pAdapterAddresses,
|
|
PULONG pOutBufLen)
|
|
{
|
|
InterfaceIndexTable* indexTable;
|
|
IFInfo ifInfo;
|
|
int i;
|
|
ULONG ret, requiredSize = 0;
|
|
PIP_ADAPTER_ADDRESSES currentAddress;
|
|
PUCHAR currentLocation;
|
|
HANDLE tcpFile;
|
|
|
|
(void)(Family);
|
|
if (!pOutBufLen)
|
|
return ERROR_INVALID_PARAMETER;
|
|
if (Reserved)
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
indexTable = getInterfaceIndexTable();
|
|
if (!indexTable)
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
ret = openTcpFile(&tcpFile, FILE_READ_DATA);
|
|
if (!NT_SUCCESS(ret))
|
|
return ERROR_NO_DATA;
|
|
|
|
for (i = indexTable->numIndexes; i >= 0; i--)
|
|
{
|
|
if (NT_SUCCESS(getIPAddrEntryForIf(tcpFile, NULL, indexTable->indexes[i], &ifInfo)))
|
|
{
|
|
/* The whole struct */
|
|
requiredSize += sizeof(IP_ADAPTER_ADDRESSES);
|
|
|
|
/* Friendly name */
|
|
if (!(Flags & GAA_FLAG_SKIP_FRIENDLY_NAME))
|
|
requiredSize += strlen((char*)ifInfo.if_info.ent.if_descr) + 1; // FIXME
|
|
|
|
/* Adapter name */
|
|
requiredSize += strlen((char*)ifInfo.if_info.ent.if_descr) + 1;
|
|
|
|
/* Unicast address */
|
|
if (!(Flags & GAA_FLAG_SKIP_UNICAST))
|
|
requiredSize += sizeof(IP_ADAPTER_UNICAST_ADDRESS);
|
|
|
|
/* FIXME: Implement multicast, anycast, and dns server stuff */
|
|
|
|
/* FIXME: Implement dns suffix and description */
|
|
requiredSize += 2 * sizeof(WCHAR);
|
|
|
|
/* We're only going to implement what's required for XP SP0 */
|
|
}
|
|
}
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "size: %ld, requiredSize: %ld\n", *pOutBufLen, requiredSize);
|
|
#endif
|
|
if (!pAdapterAddresses || *pOutBufLen < requiredSize)
|
|
{
|
|
*pOutBufLen = requiredSize;
|
|
closeTcpFile(tcpFile);
|
|
free(indexTable);
|
|
return ERROR_BUFFER_OVERFLOW;
|
|
}
|
|
|
|
RtlZeroMemory(pAdapterAddresses, requiredSize);
|
|
|
|
/* Let's set up the pointers */
|
|
currentAddress = pAdapterAddresses;
|
|
for (i = indexTable->numIndexes; i >= 0; i--)
|
|
{
|
|
if (NT_SUCCESS(getIPAddrEntryForIf(tcpFile, NULL, indexTable->indexes[i], &ifInfo)))
|
|
{
|
|
currentLocation = (PUCHAR)currentAddress + (ULONG_PTR)sizeof(IP_ADAPTER_ADDRESSES);
|
|
|
|
/* FIXME: Friendly name */
|
|
if (!(Flags & GAA_FLAG_SKIP_FRIENDLY_NAME))
|
|
{
|
|
currentAddress->FriendlyName = (PVOID)currentLocation;
|
|
currentLocation += sizeof(WCHAR);
|
|
}
|
|
|
|
/* Adapter name */
|
|
currentAddress->AdapterName = (PVOID)currentLocation;
|
|
currentLocation += strlen((char*)ifInfo.if_info.ent.if_descr) + 1;
|
|
|
|
/* Unicast address */
|
|
if (!(Flags & GAA_FLAG_SKIP_UNICAST))
|
|
{
|
|
currentAddress->FirstUnicastAddress = (PVOID)currentLocation;
|
|
currentLocation += sizeof(IP_ADAPTER_UNICAST_ADDRESS);
|
|
currentAddress->FirstUnicastAddress->Address.lpSockaddr = (PVOID)currentLocation;
|
|
currentLocation += sizeof(struct sockaddr);
|
|
}
|
|
|
|
/* FIXME: Implement multicast, anycast, and dns server stuff */
|
|
|
|
/* FIXME: Implement dns suffix and description */
|
|
currentAddress->DnsSuffix = (PVOID)currentLocation;
|
|
currentLocation += sizeof(WCHAR);
|
|
|
|
currentAddress->Description = (PVOID)currentLocation;
|
|
currentLocation += sizeof(WCHAR);
|
|
|
|
currentAddress->Next = (PVOID)currentLocation;
|
|
/* Terminate the last address correctly */
|
|
if (i == 0)
|
|
currentAddress->Next = NULL;
|
|
|
|
/* We're only going to implement what's required for XP SP0 */
|
|
|
|
currentAddress = currentAddress->Next;
|
|
}
|
|
}
|
|
|
|
/* Now again, for real this time */
|
|
|
|
currentAddress = pAdapterAddresses;
|
|
for (i = indexTable->numIndexes; i >= 0; i--)
|
|
{
|
|
if (NT_SUCCESS(getIPAddrEntryForIf(tcpFile, NULL, indexTable->indexes[i], &ifInfo)))
|
|
{
|
|
/* Make sure we're not looping more than we hoped for */
|
|
assert(currentAddress);
|
|
|
|
/* Alignment information */
|
|
currentAddress->Length = sizeof(IP_ADAPTER_ADDRESSES);
|
|
currentAddress->IfIndex = indexTable->indexes[i];
|
|
|
|
/* Adapter name */
|
|
strcpy(currentAddress->AdapterName, (char*)ifInfo.if_info.ent.if_descr);
|
|
|
|
if (!(Flags & GAA_FLAG_SKIP_UNICAST))
|
|
{
|
|
currentAddress->FirstUnicastAddress->Length = sizeof(IP_ADAPTER_UNICAST_ADDRESS);
|
|
currentAddress->FirstUnicastAddress->Flags = 0; // FIXME
|
|
currentAddress->FirstUnicastAddress->Next =
|
|
NULL; // FIXME: Support more than one address per adapter
|
|
currentAddress->FirstUnicastAddress->Address.lpSockaddr->sa_family = AF_INET;
|
|
memcpy(
|
|
currentAddress->FirstUnicastAddress->Address.lpSockaddr->sa_data,
|
|
&ifInfo.ip_addr.iae_addr,
|
|
sizeof(ifInfo.ip_addr.iae_addr));
|
|
currentAddress->FirstUnicastAddress->Address.iSockaddrLength =
|
|
sizeof(ifInfo.ip_addr.iae_addr) + sizeof(USHORT);
|
|
currentAddress->FirstUnicastAddress->PrefixOrigin = IpPrefixOriginOther; // FIXME
|
|
currentAddress->FirstUnicastAddress->SuffixOrigin = IpSuffixOriginOther; // FIXME
|
|
currentAddress->FirstUnicastAddress->DadState = IpDadStatePreferred; // FIXME
|
|
currentAddress->FirstUnicastAddress->ValidLifetime = 0xFFFFFFFF; // FIXME
|
|
currentAddress->FirstUnicastAddress->PreferredLifetime = 0xFFFFFFFF; // FIXME
|
|
currentAddress->FirstUnicastAddress->LeaseLifetime = 0xFFFFFFFF; // FIXME
|
|
}
|
|
|
|
/* FIXME: Implement multicast, anycast, and dns server stuff */
|
|
currentAddress->FirstAnycastAddress = NULL;
|
|
currentAddress->FirstMulticastAddress = NULL;
|
|
currentAddress->FirstDnsServerAddress = NULL;
|
|
|
|
/* FIXME: Implement dns suffix, description, and friendly name */
|
|
currentAddress->DnsSuffix[0] = UNICODE_NULL;
|
|
currentAddress->Description[0] = UNICODE_NULL;
|
|
currentAddress->FriendlyName[0] = UNICODE_NULL;
|
|
|
|
/* Physical Address */
|
|
memcpy(
|
|
currentAddress->PhysicalAddress,
|
|
ifInfo.if_info.ent.if_physaddr,
|
|
ifInfo.if_info.ent.if_physaddrlen);
|
|
currentAddress->PhysicalAddressLength = ifInfo.if_info.ent.if_physaddrlen;
|
|
|
|
/* Flags */
|
|
currentAddress->Flags = 0; // FIXME
|
|
|
|
/* MTU */
|
|
currentAddress->Mtu = ifInfo.if_info.ent.if_mtu;
|
|
|
|
/* Interface type */
|
|
currentAddress->IfType = ifInfo.if_info.ent.if_type;
|
|
|
|
/* Operational status */
|
|
if (ifInfo.if_info.ent.if_operstatus >= IF_OPER_STATUS_CONNECTING)
|
|
currentAddress->OperStatus = IfOperStatusUp;
|
|
else
|
|
currentAddress->OperStatus = IfOperStatusDown;
|
|
|
|
/* We're only going to implement what's required for XP SP0 */
|
|
|
|
/* Move to the next address */
|
|
currentAddress = currentAddress->Next;
|
|
}
|
|
}
|
|
|
|
closeTcpFile(tcpFile);
|
|
free(indexTable);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
#endif
|