CharlesLiuChina CharlesLiuChina - 1 month ago 20
Linux Question

I get wrong ip address with getifaddrs

Function to get ethernet specified ip address:

char *get_ethernet_ip(const char *ethernet, char *ip, size_t len) {
struct ifaddrs *ips;
int rc = getifaddrs(&ips);
if (rc == -1) {
SYSLOG("getifaddrs() failed (%s)", strerror(errno));
return NULL;
}

for (; ips != NULL; ips = ips->ifa_next) {
if (strcasecmp(ethernet, ips->ifa_name) == 0) {
in_addr local_ip = ((sockaddr_in *)ips->ifa_addr)->sin_addr;
const char *p = inet_ntop(AF_INET, &local_ip, ip, len);
if (p == NULL) {
SYSLOG("inet_ntop() failed (%s)", strerror(errno));
return NULL;
}

return ip;
}
}

return NULL;
}


Used in main:

char ip[32];
SYSLOG("ethernet lo ip: %s", get_ethernet_ip("lo", ip, 32));
SYSLOG("ethernet eth0 ip: %s", get_ethernet_ip("eth0", ip, 32));


Result:

[ 2016-10-26 04:37:52 UTC ] [ server_info.cpp:90 ] [ main ] ethernet lo ip: 1.0.0.0

[ 2016-10-26 04:37:52 UTC ] [ server_info.cpp:91 ] [ main ] ethernet eth0 ip: 2.0.0.0


Question:

The ip for
lo
should be
127.0.0.1
, and for
eth0
it should not be
2.0.0.0
, am I right?

Answer

You have assumed that the first entry you encounter for a name will be in the AF_INET family, but you did not check.

Use ips->ifa_addr->sa_family to check that it's AF_INET.

Chances are that the first lo and eth0 devices you encounter will be in the AF_PACKET family.

Comments