Port networkTools.cpp to Mac OS X.

On Mac OS X the ioctl(SIOCGIFCONF) call will return all IPv4, IPv6
and MAC addresses, so we have to filter only the ones that have
sa_family equal to AF_INET.

I also added the common interface names for Mac OS X (en0 and en1),
to the getBestPublicIp() function. I refactored a bit the code so
that addition and reordering are easier.

Bugs: https://sourceforge.net/p/kiwix/bugs/658/
This commit is contained in:
Cristian Patrasciuc 2014-06-17 17:46:54 +02:00
parent 0bedd7ebc9
commit 5a695963d5
1 changed files with 28 additions and 23 deletions

View File

@ -65,18 +65,23 @@ std::map<std::string, std::string> kiwix::getNetworkInterfaces() {
int i; int i;
size_t len; size_t len;
struct ifreq *ifreq; struct ifreq *ifreq;
ifreq=ifconf.ifc_req; ifreq = ifconf.ifc_req;
for(i=0;i<ifconf.ifc_len;) { for (i = 0; i < ifconf.ifc_len; ) {
/* Get the network interface name */ if (ifreq->ifr_addr.sa_family == AF_INET) {
std::string interfaceName = std::string(ifreq->ifr_name); /* Get the network interface ip */
char host[128] = { 0 };
/* Get the network interface ip */ const int error = getnameinfo(&(ifreq->ifr_addr), sizeof ifreq->ifr_addr,
char host[128]; host, sizeof host,
getnameinfo(&(ifreq->ifr_addr), sizeof ifreq->ifr_addr, host, sizeof host, 0, 0, NI_NUMERICHOST); 0, 0, NI_NUMERICHOST);
std::string interfaceIp = std::string(host); if (!error) {
std::string interfaceName = std::string(ifreq->ifr_name);
/* Add to the map */ std::string interfaceIp = std::string(host);
interfaces.insert(std::pair<std::string, std::string>(interfaceName, interfaceIp)); /* Add to the map */
interfaces.insert(std::pair<std::string, std::string>(interfaceName, interfaceIp));
} else {
perror("getnameinfo()");
}
}
/* some systems have ifr_addr.sa_len and adjust the length that /* some systems have ifr_addr.sa_len and adjust the length that
* way, but not mine. weird */ * way, but not mine. weird */
@ -96,32 +101,32 @@ std::string kiwix::getBestPublicIp() {
std::map<std::string, std::string> interfaces = kiwix::getNetworkInterfaces(); std::map<std::string, std::string> interfaces = kiwix::getNetworkInterfaces();
#ifndef _WIN32 #ifndef _WIN32
if (interfaces.find("eth0") != interfaces.end()) { const char* const prioritizedNames[] =
return interfaces.find("eth0")->second; { "eth0", "eth1", "wlan0", "wlan1", "en0", "en1" };
} else if (interfaces.find("eth1") != interfaces.end()) { const int count = (sizeof prioritizedNames) / (sizeof prioritizedNames[0]);
return interfaces.find("eth1")->second; for (int i = 0; i < count; ++i) {
} else if (interfaces.find("wlan0") != interfaces.end()) { std::map<std::string, std::string>::const_iterator it =
return interfaces.find("wlan0")->second; interfaces.find(prioritizedNames[i]);
} else if (interfaces.find("wlan1") != interfaces.end()) { if (it != interfaces.end())
return interfaces.find("wlan1")->second; return it->second;
} }
#endif #endif
for(std::map<std::string, std::string>::iterator iter = interfaces.begin(); for (std::map<std::string, std::string>::iterator iter = interfaces.begin();
iter != interfaces.end(); ++iter) { iter != interfaces.end(); ++iter) {
std::string interfaceIp = iter->second; std::string interfaceIp = iter->second;
if (interfaceIp.length() >= 7 && interfaceIp.substr(0, 7) == "192.168") if (interfaceIp.length() >= 7 && interfaceIp.substr(0, 7) == "192.168")
return interfaceIp; return interfaceIp;
} }
for(std::map<std::string, std::string>::iterator iter = interfaces.begin(); for (std::map<std::string, std::string>::iterator iter = interfaces.begin();
iter != interfaces.end(); ++iter) { iter != interfaces.end(); ++iter) {
std::string interfaceIp = iter->second; std::string interfaceIp = iter->second;
if (interfaceIp.length() >= 7 && interfaceIp.substr(0, 7) == "172.16.") if (interfaceIp.length() >= 7 && interfaceIp.substr(0, 7) == "172.16.")
return interfaceIp; return interfaceIp;
} }
for(std::map<std::string, std::string>::iterator iter = interfaces.begin(); for (std::map<std::string, std::string>::iterator iter = interfaces.begin();
iter != interfaces.end(); ++iter) { iter != interfaces.end(); ++iter) {
std::string interfaceIp = iter->second; std::string interfaceIp = iter->second;
if (interfaceIp.length() >= 3 && interfaceIp.substr(0, 3) == "10.") if (interfaceIp.length() >= 3 && interfaceIp.substr(0, 3) == "10.")