summaryrefslogtreecommitdiff
path: root/qpid/cpp/src/qpid/sys/posix
diff options
context:
space:
mode:
authorAndrew Stitcher <astitcher@apache.org>2012-11-16 14:27:14 +0000
committerAndrew Stitcher <astitcher@apache.org>2012-11-16 14:27:14 +0000
commit039e634984f5dbcf1d9271b2e9a364b8a2c228c1 (patch)
treeab359a95feed13af86c5062cb34809b420870d91 /qpid/cpp/src/qpid/sys/posix
parent9d277505a7640b1f03039009f5dd41c9a3678e5c (diff)
downloadqpid-python-039e634984f5dbcf1d9271b2e9a364b8a2c228c1.tar.gz
QPID-3351: Provide ability to specify the network interfaces
Added functions to find machines network interface names and addresses git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1410362 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp/src/qpid/sys/posix')
-rwxr-xr-xqpid/cpp/src/qpid/sys/posix/SystemInfo.cpp67
1 files changed, 67 insertions, 0 deletions
diff --git a/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp b/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp
index 0f29f511b1..cbff1effac 100755
--- a/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp
+++ b/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp
@@ -32,6 +32,7 @@
#include <iostream>
#include <fstream>
#include <sstream>
+#include <map>
#include <netdb.h>
#include <string.h>
@@ -121,6 +122,72 @@ void SystemInfo::getLocalIpAddresses (uint16_t port,
}
}
+namespace {
+ inline socklen_t sa_len(::sockaddr* sa)
+ {
+ switch (sa->sa_family) {
+ case AF_INET:
+ return sizeof(struct sockaddr_in);
+ case AF_INET6:
+ return sizeof(struct sockaddr_in6);
+ default:
+ return sizeof(struct sockaddr_storage);
+ }
+ }
+
+ inline bool isInetOrInet6(::sockaddr* sa) {
+ switch (sa->sa_family) {
+ case AF_INET:
+ case AF_INET6:
+ return true;
+ default:
+ return false;
+ }
+ }
+ typedef std::map<std::string, std::vector<std::string> > InterfaceInfo;
+ std::map<std::string, std::vector<std::string> > cachedInterfaces;
+
+ void cacheInterfaceInfo() {
+ // Get interface info
+ ::ifaddrs* interfaceInfo;
+ QPID_POSIX_CHECK( ::getifaddrs(&interfaceInfo) );
+
+ char name[NI_MAXHOST];
+ for (::ifaddrs* info = interfaceInfo; info != 0; info = info->ifa_next) {
+
+ // Only use IPv4/IPv6 interfaces
+ if (!isInetOrInet6(info->ifa_addr)) continue;
+
+ int rc=::getnameinfo(info->ifa_addr, sa_len(info->ifa_addr),
+ name, sizeof(name), 0, 0,
+ NI_NUMERICHOST);
+ if (rc >= 0) {
+ std::string address(name);
+ cachedInterfaces[info->ifa_name].push_back(address);
+ } else {
+ throw qpid::Exception(QPID_MSG(gai_strerror(rc)));
+ }
+ }
+ ::freeifaddrs(interfaceInfo);
+ }
+}
+
+bool SystemInfo::getInterfaceAddresses(const std::string& interface, std::vector<std::string>& addresses) {
+ if ( cachedInterfaces.empty() ) cacheInterfaceInfo();
+ InterfaceInfo::iterator i = cachedInterfaces.find(interface);
+ if ( i==cachedInterfaces.end() ) return false;
+ std::copy(i->second.begin(), i->second.end(), std::back_inserter(addresses));
+ return true;
+}
+
+void SystemInfo::getInterfaceNames(std::vector<std::string>& names ) {
+ if ( cachedInterfaces.empty() ) cacheInterfaceInfo();
+
+ for (InterfaceInfo::const_iterator i = cachedInterfaces.begin(); i!=cachedInterfaces.end(); ++i) {
+ names.push_back(i->first);
+ }
+}
+
void SystemInfo::getSystemId (std::string &osName,
std::string &nodeName,
std::string &release,