|
|
|
|
@ -236,30 +236,46 @@ public:
|
|
|
|
|
// Get IPv4 addresses for each device
|
|
|
|
|
if (ifnames.size() > 0) { |
|
|
|
|
const int controlfd = (int)socket(AF_INET,SOCK_DGRAM,0); |
|
|
|
|
if (controlfd >= 0) { |
|
|
|
|
for(std::set<std::string>::iterator devname(ifnames.begin());devname!=ifnames.end();++devname) { |
|
|
|
|
struct ifreq ifr; |
|
|
|
|
memset(&ifr,0,sizeof(ifr)); |
|
|
|
|
ifr.ifr_addr.sa_family = AF_INET; |
|
|
|
|
Utils::scopy(ifr.ifr_name,sizeof(ifr.ifr_name),devname->c_str()); |
|
|
|
|
if (ioctl(controlfd,SIOCGIFADDR,&ifr) >= 0) { |
|
|
|
|
InetAddress ip(&(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr),4,0); |
|
|
|
|
if (ifChecker.shouldBindInterface(devname->c_str(),ip)) { |
|
|
|
|
switch(ip.ipScope()) { |
|
|
|
|
default: break; |
|
|
|
|
case InetAddress::IP_SCOPE_PSEUDOPRIVATE: |
|
|
|
|
case InetAddress::IP_SCOPE_GLOBAL: |
|
|
|
|
case InetAddress::IP_SCOPE_SHARED: |
|
|
|
|
case InetAddress::IP_SCOPE_PRIVATE: |
|
|
|
|
ip.setPort(port); |
|
|
|
|
localIfAddrs.insert(std::pair<InetAddress,std::string>(ip,*devname)); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
struct ifconf configuration; |
|
|
|
|
configuration.ifc_len = 0; |
|
|
|
|
configuration.ifc_buf = nullptr; |
|
|
|
|
|
|
|
|
|
if (controlfd < 0) goto ip4_address_error; |
|
|
|
|
|
|
|
|
|
if (ioctl(controlfd, SIOCGIFCONF, &configuration) < 0) goto ip4_address_error; |
|
|
|
|
|
|
|
|
|
configuration.ifc_buf = (char*)malloc(configuration.ifc_len); |
|
|
|
|
|
|
|
|
|
if (ioctl(controlfd, SIOCGIFCONF, &configuration) < 0) goto ip4_address_error; |
|
|
|
|
|
|
|
|
|
for (int i=0; i < (int)(configuration.ifc_len / sizeof(ifreq)); i ++) { |
|
|
|
|
struct ifreq& request = configuration.ifc_req[i]; |
|
|
|
|
struct sockaddr* addr = &request.ifr_ifru.ifru_addr; |
|
|
|
|
if (addr->sa_family != AF_INET) continue; |
|
|
|
|
std::string ifname = request.ifr_ifrn.ifrn_name; |
|
|
|
|
// name can either be just interface name or interface name followed by ':' and arbitrary label
|
|
|
|
|
if (ifname.find(':') != std::string::npos) { |
|
|
|
|
ifname = ifname.substr(0, ifname.find(':')); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
InetAddress ip(&(((struct sockaddr_in *)addr)->sin_addr),4,0); |
|
|
|
|
if (ifChecker.shouldBindInterface(ifname.c_str(), ip)) { |
|
|
|
|
switch(ip.ipScope()) { |
|
|
|
|
default: break; |
|
|
|
|
case InetAddress::IP_SCOPE_PSEUDOPRIVATE: |
|
|
|
|
case InetAddress::IP_SCOPE_GLOBAL: |
|
|
|
|
case InetAddress::IP_SCOPE_SHARED: |
|
|
|
|
case InetAddress::IP_SCOPE_PRIVATE: |
|
|
|
|
ip.setPort(port); |
|
|
|
|
localIfAddrs.insert(std::pair<InetAddress,std::string>(ip, ifname)); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
close(controlfd); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ip4_address_error: |
|
|
|
|
free(configuration.ifc_buf); |
|
|
|
|
if (controlfd > 0) close(controlfd); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const bool gotViaProc = (localIfAddrs.size() > 0); |
|
|
|
|
|