Skip to content

Instantly share code, notes, and snippets.

@trollcop
Created October 8, 2024 04:55
Show Gist options
  • Save trollcop/c5bb9b08ec7344ff08aa861a08a8be9f to your computer and use it in GitHub Desktop.
Save trollcop/c5bb9b08ec7344ff08aa861a08a8be9f to your computer and use it in GitHub Desktop.
get IP address(es), gateway(s) and metric of all currently enabled network interfaces on windows
#define _WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <Windows.h>
#include <stdio.h>
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "Ws2_32.lib")
#define BUFFER_SIZE 15000
#define RETRIES 3
static const char *printAddress(SOCKET_ADDRESS *in)
{
/* BUG this returns static string, is not re-entrant, and assumes printing SOCKET_ADDRESS is ipv4 */
static char buf[MAX_PATH];
return inet_ntop(AF_INET, &((SOCKADDR_IN *)in->lpSockaddr)->sin_addr, buf, sizeof(buf));
}
static const char *printFriendlyName(WCHAR *in)
{
/* BUG this returns static string, is not re-entrant, and will fail if input string is longer than MAX_PATH
* however it's sufficient for demo purposes */
static char buf[MAX_PATH];
memset(buf, 0, sizeof(buf));
WideCharToMultiByte(CP_UTF8, 0, in, -1, buf, MAX_PATH, NULL, NULL);
return buf;
}
int listInterfaces(void)
{
ULONG flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS, family = AF_INET;
PIP_ADAPTER_ADDRESSES addrs = NULL;
ULONG bufsiz = BUFFER_SIZE;
DWORD rv = 0;
int i = 0;
PIP_ADAPTER_ADDRESSES addr = NULL;
PIP_ADAPTER_GATEWAY_ADDRESS gateway = NULL;
PIP_ADAPTER_UNICAST_ADDRESS unicast = NULL;
do {
addrs = (IP_ADAPTER_ADDRESSES *)malloc(bufsiz);
/* all broken */
if (addrs == NULL)
return -1;
/* actually get all adapters info */
rv = GetAdaptersAddresses(family, flags, NULL, addrs, &bufsiz);
if (rv == ERROR_BUFFER_OVERFLOW) {
free(addrs);
addrs = NULL;
/* try to increase buffer by 2x */
bufsiz += BUFFER_SIZE;
} else
break;
} while ((rv == ERROR_BUFFER_OVERFLOW) && (++i < RETRIES));
/* walk the returned structure */
addr = addrs;
while (addr) {
/* skip useless interfaces: not running/up, no gateway, no ip assigned */
if ((addr->OperStatus != IfOperStatusUp) || !addr->FirstGatewayAddress || !addr->FirstUnicastAddress) {
addr = addr->Next;
continue;
}
/* pretty print */
printf("{\n interface: '%s',\n", printFriendlyName(addr->FriendlyName));
printf(" metric: %u,\n", addr->Ipv4Metric);
printf(" gateway: { ");
gateway = addr->FirstGatewayAddress;
for (i = 0; gateway != NULL; i++) {
printf("'%s'", printAddress(&gateway->Address));
gateway = gateway->Next;
if (gateway != NULL)
printf(", ");
else
printf(" ");
}
printf("},\n");
printf(" ip: { ");
unicast = addr->FirstUnicastAddress;
for (i = 0; unicast != NULL; i++) {
printf("'%s'", printAddress(&unicast->Address));
unicast = unicast->Next;
if (unicast != NULL)
printf(", ");
else
printf(" ");
}
printf("},\n");
printf(" model: '%wS',\n", addr->Description);
if (addr->PhysicalAddressLength != 0) {
printf(" mac_address: '");
for (i = 0; i < (int)addr->PhysicalAddressLength; i++) {
if (i == (addr->PhysicalAddressLength - 1))
printf("%.2X", (int)addr->PhysicalAddress[i]);
else
printf("%.2X:", (int)addr->PhysicalAddress[i]);
}
printf("',\n");
}
printf("}\n");
addr = addr->Next;
}
return 0;
}
int main(int argc, char **argv)
{
SetConsoleOutputCP(65001);
listInterfaces();
}
{
interface: 'イーサネット',
metric: 25,
gateway: { '192.168.14.1' },
ip: { '192.168.14.88' },
model: 'Intel(R) 82574L Gigabit Network Connection',
mac_address: '00:0C:29:XX:XX:XX',
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment