summaryrefslogtreecommitdiff
path: root/cppe/src/IceE/Network.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cppe/src/IceE/Network.cpp')
-rw-r--r--cppe/src/IceE/Network.cpp117
1 files changed, 117 insertions, 0 deletions
diff --git a/cppe/src/IceE/Network.cpp b/cppe/src/IceE/Network.cpp
index 505468b3168..1c9b430d1cf 100644
--- a/cppe/src/IceE/Network.cpp
+++ b/cppe/src/IceE/Network.cpp
@@ -12,6 +12,18 @@
#include <IceE/LocalException.h>
#include <IceE/SafeStdio.h>
+#if defined(_WIN32)
+# include <winsock2.h>
+#elif defined(__linux) || defined(__APPLE__) || defined(__FreeBSD__)
+# include <ifaddrs.h>
+#else
+# include <sys/ioctl.h>
+# include <net/if.h>
+# ifdef __sun
+# include <sys/sockio.h>
+# endif
+#endif
+
using namespace std;
using namespace Ice;
using namespace IceInternal;
@@ -1002,6 +1014,111 @@ repeatListen:
#endif
+vector<string>
+IceInternal::getLocalHosts()
+{
+ vector<string> result;
+
+#if defined(_WIN32)
+ vector<struct sockaddr_in> addrs = getLocalAddresses();
+ for(unsigned int i = 0; i < addrs.size(); ++i)
+ {
+ result.push_back(inetAddrToString(addrs[i].sin_addr));
+ }
+#elif defined(__linux) || defined(__APPLE__) || defined(__FreeBSD__)
+ struct ifaddrs* ifap;
+ if(::getifaddrs(&ifap) == SOCKET_ERROR)
+ {
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+
+ struct ifaddrs* curr = ifap;
+ while(curr != 0)
+ {
+ if(curr->ifa_addr && curr->ifa_addr->sa_family == AF_INET)
+ {
+ struct sockaddr_in* addr = reinterpret_cast<struct sockaddr_in*>(curr->ifa_addr);
+ if(addr->sin_addr.s_addr != 0)
+ {
+ result.push_back(inetAddrToString((*addr).sin_addr));
+ }
+ }
+
+ curr = curr->ifa_next;
+ }
+
+ ::freeifaddrs(ifap);
+#else
+ SOCKET fd = createSocket(false);
+
+#ifdef _AIX
+ int cmd = CSIOCGIFCONF;
+#else
+ int cmd = SIOCGIFCONF;
+#endif
+ struct ifconf ifc;
+ int numaddrs = 10;
+ int old_ifc_len = 0;
+
+ //
+ // Need to call ioctl multiple times since we do not know up front
+ // how many addresses there will be, and thus how large a buffer we need.
+ // We keep increasing the buffer size until subsequent calls return
+ // the same length, meaning we have all the addresses.
+ //
+ while(true)
+ {
+ int bufsize = numaddrs * sizeof(struct ifreq);
+ ifc.ifc_len = bufsize;
+ ifc.ifc_buf = (char*)malloc(bufsize);
+
+ int rs = ioctl(fd, cmd, &ifc);
+ if(rs == SOCKET_ERROR)
+ {
+ closeSocketNoThrow(fd);
+ SocketException ex(__FILE__, __LINE__);
+ ex.error = getSocketErrno();
+ throw ex;
+ }
+ else if(ifc.ifc_len == old_ifc_len)
+ {
+ //
+ // Returned same length twice in a row, finished.
+ //
+ break;
+ }
+ else
+ {
+ old_ifc_len = ifc.ifc_len;
+ }
+
+ numaddrs += 10;
+ free(ifc.ifc_buf);
+ }
+
+ numaddrs = ifc.ifc_len / sizeof(struct ifreq);
+ struct ifreq* ifr = ifc.ifc_req;
+ for(int i = 0; i < numaddrs; ++i)
+ {
+ if(ifr[i].ifr_addr.sa_family == AF_INET)
+ {
+ struct sockaddr_in* addr = reinterpret_cast<struct sockaddr_in*>(&ifr[i].ifr_addr);
+ if(addr->sin_addr.s_addr != 0)
+ {
+ result.push_back(inetAddrToString((*addr).sin_addr));
+ }
+ }
+ }
+
+ free(ifc.ifc_buf);
+ closeSocket(fd);
+#endif
+
+ return result;
+}
+
#ifdef _WIN32
vector<struct sockaddr_in>