Since I got no answer on my previous question, I will rephrase it.
What order of IP addresses (in case when IP addresses are bound to one interface) is used when doing gethostbyname() using PC name (NetBIOS name)?
I have this code:
#include <iostream>
#include <winsock.h>
#pragma comment(lib, "Ws2_32.lib")
int main()
{
char hostname[255];
struct hostent *he;
struct in_addr **addr_list;
WSAData data;
WSAStartup(MAKEWORD(2, 2), &data);
gethostname(hostname, 255);
std::cout << "Host name: " << hostname << std::endl;
if ((he = gethostbyname(hostname)) == NULL) {
std::cout << "gethostbyname error" << std::endl;
} else {
std::cout << "IP addresses: " << std::endl;
addr_list = (struct in_addr **)he->h_addr_list;
for(int i = 0; addr_list[i] != NULL; i++) {
std::cout << inet_ntoa(*addr_list[i]) << std::endl;
}
}
std::cin.get();
}
And it gives me different results on Windows Server 2012 and Windows Server 2008 / Windows 7. On my home PC with Windows 7, ascending order is used:
Host name: SplattWin
IP addresses:
192.168.1.140
192.168.3.1
192.168.3.2
192.168.3.3
192.168.3.4
However, on Windows server 2012 it gives me IP addresses in descending order:
Host name: WinServ
IP addresses:
1.1.1.4
1.1.1.3
1.1.1.2
1.1.1.1
Is there any way to reorder it? I tried skipassource flag when I added these IP addresses but it doesn't seem to work in this case.
I have third party software that is using gethostname() followed by gethostbyname() to determine it's own IP address (it takes first from the list). And it's really frustrating that you need to change settings and client side every time you add new IP address to your system.
The order of the IPs is determined by Windows based on interface priorities and such. There is no standard rule that spans across machine boundaries or Windows version boundaries. You have to treat the output list as random, and re-order the IPs yourself to your particular needs. For example:
That being said, don't use
gethostbyname()
(orgetaddrinfo()
) to enumerate a machine's local interfaces. Such functions are not intended for that purpose. UseGetAdaptersInfo()
orGetAdaptersAddresses()
instead. They are specifically intended to enumerate local interfaces, and they give you much more detailed information about the interfaces.