// Based on example code from https://msdn.microsoft.com/en-us/library/windows/desktop/aa365947(v=vs.85).aspx
|
// and http://www.nynaeve.net/Code/GetInterfaceMetric.cpp.
|
|
#include <winsock2.h>
|
#include <ws2ipdef.h>
|
#include <iphlpapi.h>
|
#include <stdio.h>
|
#include <objbase.h>
|
|
#pragma comment(lib, "iphlpapi.lib")
|
#pragma comment(lib, "Ole32.lib")
|
|
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
|
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
|
|
/* Note: could also use malloc() and free() */
|
|
//
|
// Suspected prototype of NsiGetParameter, via reverse engineering.
|
//
|
|
typedef DWORD (__stdcall *NsiGetParameterProc)(
|
DWORD Argument1,
|
CONST UCHAR* Argument2,
|
DWORD Argument3,
|
PNET_LUID Argument4,
|
DWORD Argument5,
|
DWORD Argument6,
|
PUCHAR Argument7,
|
DWORD Argument8,
|
DWORD Argument9
|
);
|
|
/*
|
0:000> db NPI_MS_IPV4_MODULEID l14
|
751b3364 18 00 00 00 01 00 00 00-00 4a 00 eb 1a 9b d4 11
|
751b3374 91 23 00 50 04 77 59 BC
|
*/
|
|
const unsigned char NPI_MS_IPV4_MODULEID[0x18] =
|
{
|
0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4A, 0x00, 0xEB, 0x1A, 0x9B, 0xD4, 0x11,
|
0x91, 0x23, 0x00, 0x50, 0x04, 0x77, 0x59, 0xBC
|
};
|
|
VOID PrintHex(PBYTE Data, ULONG dwBytes) {
|
for (ULONG i = 0; i < dwBytes; i += 16) {
|
printf("%.8x: ", i);
|
|
for (ULONG j = 0; j < 16; j++) {
|
if (i + j < dwBytes) {
|
printf("%.2x ", Data[i + j]);
|
}
|
else {
|
printf("?? ");
|
}
|
}
|
|
for (ULONG j = 0; j < 16; j++) {
|
if (i + j < dwBytes && Data[i + j] >= 0x20 && Data[i + j] <= 0x7e) {
|
printf("%c", Data[i + j]);
|
}
|
else {
|
printf(".");
|
}
|
}
|
|
printf("\n");
|
}
|
}
|
|
int main() {
|
HMODULE hNsi = LoadLibraryW(L"Nsi.dll");
|
NsiGetParameterProc _NsiGetParameter = (NsiGetParameterProc)GetProcAddress(hNsi, "NsiGetParameter");
|
|
// Declare and initialize variables
|
PIP_INTERFACE_INFO pInfo = NULL;
|
ULONG ulOutBufLen = 0;
|
|
DWORD dwRetVal = 0;
|
int iReturn = 1;
|
|
int i;
|
|
// Make an initial call to GetInterfaceInfo to get
|
// the necessary size in the ulOutBufLen variable
|
dwRetVal = GetInterfaceInfo(NULL, &ulOutBufLen);
|
if (dwRetVal == ERROR_INSUFFICIENT_BUFFER) {
|
pInfo = (IP_INTERFACE_INFO *)MALLOC(ulOutBufLen);
|
if (pInfo == NULL) {
|
printf
|
("Unable to allocate memory needed to call GetInterfaceInfo\n");
|
return 1;
|
}
|
}
|
// Make a second call to GetInterfaceInfo to get
|
// the actual data we need
|
dwRetVal = GetInterfaceInfo(pInfo, &ulOutBufLen);
|
if (dwRetVal == NO_ERROR) {
|
printf("Number of Adapters: %ld\n\n", pInfo->NumAdapters);
|
for (i = 0; i < pInfo->NumAdapters; i++) {
|
printf("Adapter Index[%d]: %ld\n", i,
|
pInfo->Adapter[i].Index);
|
|
NET_LUID Luid;
|
NETIO_STATUS st = ConvertInterfaceIndexToLuid(pInfo->Adapter[i].Index, &Luid);
|
if (st == NO_ERROR) {
|
BYTE OutputBuffer[0xB8] = { /* zero padding */ };
|
DWORD nsi_st = _NsiGetParameter(1, NPI_MS_IPV4_MODULEID, 7, &Luid, sizeof(Luid), 0, OutputBuffer, sizeof(OutputBuffer), 0);
|
if (nsi_st == NO_ERROR) {
|
PrintHex(OutputBuffer, sizeof(OutputBuffer));
|
}
|
}
|
}
|
iReturn = 0;
|
}
|
else if (dwRetVal == ERROR_NO_DATA) {
|
printf
|
("There are no network adapters with IPv4 enabled on the local system\n");
|
iReturn = 0;
|
}
|
else {
|
printf("GetInterfaceInfo failed with error: %d\n", dwRetVal);
|
iReturn = 1;
|
}
|
|
FREE(pInfo);
|
return (iReturn);
|
}
|