diff options
| author | Andrew Stitcher <astitcher@apache.org> | 2010-04-22 04:30:44 +0000 |
|---|---|---|
| committer | Andrew Stitcher <astitcher@apache.org> | 2010-04-22 04:30:44 +0000 |
| commit | f8f3a0584535efecb92bf36a5d2a0066df3da1af (patch) | |
| tree | 09fdbffa77dfdc2d64cc9da5f0a9c6db23dbdaec /cpp/src | |
| parent | 49902715d753ef740af36a47e9ee9e98c3735227 (diff) | |
| download | qpid-python-f8f3a0584535efecb92bf36a5d2a0066df3da1af.tar.gz | |
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
Diffstat (limited to 'cpp/src')
| -rwxr-xr-x | cpp/src/qpid/sys/posix/SystemInfo.cpp | 55 |
1 files changed, 35 insertions, 20 deletions
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 <sys/ioctl.h> #include <sys/utsname.h> -#include <net/if.h> -#include <unistd.h> -#include <arpa/inet.h> -#include <stdio.h> -#include <unistd.h> +#include <sys/types.h> // For FreeBSD +#include <sys/socket.h> // For FreeBSD +#include <netinet/in.h> // For FreeBSD +#include <ifaddrs.h> #include <iostream> #include <fstream> #include <sstream> @@ -63,27 +62,43 @@ static const string LOCALHOST("127.0.0.1"); void SystemInfo::getLocalIpAddresses (uint16_t port, std::vector<Address> &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, |
