You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by as...@apache.org on 2012/11/16 15:27:14 UTC

svn commit: r1410362 - in /qpid/trunk/qpid/cpp: include/qpid/sys/SystemInfo.h src/qpid/sys/posix/SystemInfo.cpp

Author: astitcher
Date: Fri Nov 16 14:27:14 2012
New Revision: 1410362

URL: http://svn.apache.org/viewvc?rev=1410362&view=rev
Log:
QPID-3351: Provide ability to specify the network interfaces
Added functions to find machines network interface names and addresses

Modified:
    qpid/trunk/qpid/cpp/include/qpid/sys/SystemInfo.h
    qpid/trunk/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp

Modified: qpid/trunk/qpid/cpp/include/qpid/sys/SystemInfo.h
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/include/qpid/sys/SystemInfo.h?rev=1410362&r1=1410361&r2=1410362&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/include/qpid/sys/SystemInfo.h (original)
+++ qpid/trunk/qpid/cpp/include/qpid/sys/SystemInfo.h Fri Nov 16 14:27:14 2012
@@ -53,6 +53,25 @@ QPID_COMMON_EXTERN bool getLocalHostname
 QPID_COMMON_EXTERN void getLocalIpAddresses (uint16_t port, std::vector<Address> &addrList);
 
 /**
+ * Get the names of all the network interfaces connected to
+ * this host.
+ * @param names Receives the list of interface names
+ */
+QPID_COMMON_EXTERN void getInterfaceNames(std::vector<std::string>& names );
+
+/**
+ * Get strings for each of the IP addresses associated with a named network
+ * interface.
+ * If there is no interface of that name an empty list will be returned.
+ *
+ * @param interface The name of the network interface
+ * @param addresses The list of the strings for the IP addresses are pushed on the back of this parameter
+ *                  to get just the list you need to clear the vector before using it.
+ * @return true if an interface of the correct name was found, false otherwise
+ */
+QPID_COMMON_EXTERN bool getInterfaceAddresses(const std::string& interface, std::vector<std::string>& addresses);
+
+/**
  * Retrieve system identifiers and versions. This is information that can
  * generally be retrieved via POSIX uname().
  *

Modified: qpid/trunk/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp?rev=1410362&r1=1410361&r2=1410362&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/sys/posix/SystemInfo.cpp Fri Nov 16 14:27:14 2012
@@ -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 (ui
     }
 }
 
+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,



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org