From f8f3a0584535efecb92bf36a5d2a0066df3da1af Mon Sep 17 00:00:00 2001 From: Andrew Stitcher Date: Thu, 22 Apr 2010 04:30:44 +0000 Subject: QPID-1811: Applied patch from Andrey Kotrekhov with more portable code to enumerate the IP addresses of the local network interfaces git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@936610 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/src/qpid/sys/posix/SystemInfo.cpp | 55 ++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 20 deletions(-) (limited to 'cpp') diff --git a/cpp/src/qpid/sys/posix/SystemInfo.cpp b/cpp/src/qpid/sys/posix/SystemInfo.cpp index 55737fcfcc..3c11b04d29 100755 --- a/cpp/src/qpid/sys/posix/SystemInfo.cpp +++ b/cpp/src/qpid/sys/posix/SystemInfo.cpp @@ -24,11 +24,10 @@ #include #include -#include -#include -#include -#include -#include +#include // For FreeBSD +#include // For FreeBSD +#include // For FreeBSD +#include #include #include #include @@ -63,27 +62,43 @@ static const string LOCALHOST("127.0.0.1"); void SystemInfo::getLocalIpAddresses (uint16_t port, std::vector
&addrList) { - int s = ::socket(PF_INET, SOCK_STREAM, 0); - for (int i=1;;i++) { - ::ifreq ifr; - ifr.ifr_ifindex = i; - if (::ioctl (s, SIOCGIFNAME, &ifr) < 0) + ::ifaddrs* ifaddr = 0; + QPID_POSIX_CHECK(::getifaddrs(&ifaddr)); + for (::ifaddrs* ifap = ifaddr; ifap != 0; ifap = ifap->ifa_next) { + if (ifap->ifa_addr == 0) continue; + + int family = ifap->ifa_addr->sa_family; + switch (family) { + case AF_INET: { + char dispName[NI_MAXHOST]; + int rc = ::getnameinfo( + ifap->ifa_addr, + (family == AF_INET) + ? sizeof(struct sockaddr_in) + : sizeof(struct sockaddr_in6), + dispName, sizeof(dispName), + 0, 0, NI_NUMERICHOST); + if (rc != 0) { + throw QPID_POSIX_ERROR(rc); + } + string addr(dispName); + if (addr != LOCALHOST) { + addrList.push_back(TcpAddress(addr, port)); + } break; - /* now ifr.ifr_name is set */ - if (::ioctl (s, SIOCGIFADDR, &ifr) < 0) + } + // TODO: Url parsing currently can't cope with IPv6 addresses so don't return them + // when it can cope move this line to above "case AF_INET:" + case AF_INET6: + default: continue; - ::sockaddr *saddr = (::sockaddr *) &ifr.ifr_addr; - char dispName[NI_MAXHOST]; - if (int rc=::getnameinfo(saddr, sizeof(ifr.ifr_addr), dispName, sizeof(dispName), 0, 0, NI_NUMERICHOST) != 0) - throw QPID_POSIX_ERROR(rc); - string addr(dispName); - if (addr != LOCALHOST) - addrList.push_back(TcpAddress(addr, port)); + } } + freeifaddrs(ifaddr); + if (addrList.empty()) { addrList.push_back(TcpAddress(LOCALHOST, port)); } - close (s); } void SystemInfo::getSystemId (std::string &osName, -- cgit v1.2.1