summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichał Zieliński <michal@zielinscy.org.pl>2017-01-01 11:49:35 +0100
committerMichał Zieliński <michal@zielinscy.org.pl>2017-01-01 23:57:15 +0100
commit203b7e17de09c9f19b51be1435b326fb56ea3d8d (patch)
treefbdb63a961a48074732bc4e451145d621f96e102
parent9a2b766aad60b25e76777bd6bbf226701a311d43 (diff)
downloadinfinitytier-203b7e17de09c9f19b51be1435b326fb56ea3d8d.tar.gz
infinitytier-203b7e17de09c9f19b51be1435b326fb56ea3d8d.zip
Binder.hpp: gather all IPv4 interface addresses
-rw-r--r--osdep/Binder.hpp58
1 files changed, 37 insertions, 21 deletions
diff --git a/osdep/Binder.hpp b/osdep/Binder.hpp
index d017f6d4..9829f170 100644
--- a/osdep/Binder.hpp
+++ b/osdep/Binder.hpp
@@ -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);