My first bet was GetIpAddrTable()
as there was sample code, but it only supports IPv4. Then I tried GetAdaptersInfo()
, but the document suggests it is obsoleted by GetAdaptersAddresses()
. Any code sample to get the netmask using GetAdaptersAdresses() or any other IP Helper API should I use?
Asked
Active
Viewed 991 times
0

Dyno Fu
- 8,753
- 4
- 39
- 64
1 Answers
1
For IPv4, you can call WSAIoctl with an AF_INET socket and SIO_GET_INTERFACE_LIST flag. This will return you back an array of INTERFACE_INFO structs that contain a set of IP, Netmask, and Broadcast addresses. See sample code below.
For IPv6, the concept of "NetMask" doesn't apply the same way as it does in IPv4. See here for more details. Did you notice that when you type "ipconfig" from the command line or try to manually set the IPv6 address from control panel, that there is no "netmask" field shown?
So you can go with SIO_GET_INTERFACE_LIST or GetIpAddrTable for the netmask of your IPv4 interfaces. But for IPv6, you'll probably have to elaborate on what you are really trying to do with that information.
int _tmain(int argc, _TCHAR* argv[])
{
WSAData data = {};
sockaddr_in addrLocal = {};
INTERFACE_INFO infolist[100] = {};
DWORD dwBytesReturned = 0;
DWORD dwNumInterfaces = 0;
::WSAStartup(MAKEWORD(2,2), &data);
int s = socket(AF_INET, SOCK_DGRAM, 0);
int result = WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, (void*)infolist, sizeof(infolist), &dwBytesReturned, NULL, NULL);
dwNumInterfaces = dwBytesReturned / sizeof(INTERFACE_INFO);
for (DWORD index = 0; index < dwNumInterfaces; index++)
{
char szIP[120]={};
char szBroadcast[120]={};
char szNetMask[120]={};
if (infolist[index].iiAddress.Address.sa_family == AF_INET)
{
// ipv4
sockaddr_in* pAddr4 = &infolist[index].iiAddress.AddressIn;
inet_ntop(AF_INET, &pAddr4->sin_addr, szIP, ARRAYSIZE(szIP));
pAddr4 = &infolist[index].iiBroadcastAddress.AddressIn;
inet_ntop(AF_INET, &pAddr4->sin_addr, szBroadcast, ARRAYSIZE(szBroadcast));
pAddr4 = &infolist[index].iiNetmask.AddressIn;
inet_ntop(AF_INET, &pAddr4->sin_addr, szNetMask, ARRAYSIZE(szNetMask));
}
else
{
continue;
}
printf("IP:%s NetMask:%s Broadcast:%s\n", szIP, szNetMask, szBroadcast);
}
return 0;
}
-
More details here: http://stackoverflow.com/questions/3679652/is-ip-address-on-the-same-subnet-as-the-local-machine-with-ipv6-support – selbie Jan 03 '13 at 10:04
-
thanks for the answer. netmask or prefix either will be ok for me. my current implementation is iterate over FirstPrefix and find the matching one i.e. "the host IP address prefix" per IP_ADAPTER_ADDRESSES and use its PrefixLen. http://msdn.microsoft.com/en-us/library/windows/desktop/aa366058%28v=vs.85%29.aspx. – Dyno Fu Jan 04 '13 at 07:38
-
That sounds reasonable. I didn't see FirstPrefix when I scanned the docs last night. – selbie Jan 04 '13 at 07:40