summaryrefslogtreecommitdiff
path: root/ace/Sock_Connect.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ace/Sock_Connect.cpp')
-rw-r--r--ace/Sock_Connect.cpp1383
1 files changed, 0 insertions, 1383 deletions
diff --git a/ace/Sock_Connect.cpp b/ace/Sock_Connect.cpp
deleted file mode 100644
index 138f0150d09..00000000000
--- a/ace/Sock_Connect.cpp
+++ /dev/null
@@ -1,1383 +0,0 @@
-// $Id$
-
-#include "ace/Sock_Connect.h"
-#include "ace/INET_Addr.h"
-#include "ace/Log_Msg.h"
-#include "ace/Handle_Set.h"
-#include "ace/Auto_Ptr.h"
-#include "ace/SString.h"
-#include "ace/OS_Memory.h"
-
-#if defined (sparc) && ! defined (CHORUS)
-# include "ace/OS_NS_fcntl.h"
-#endif // sparc && !CHORUS
-
-#include "ace/OS_NS_stdlib.h"
-#include "ace/OS_NS_string.h"
-#include "ace/OS_NS_sys_socket.h"
-#include "ace/OS_NS_netdb.h"
-#include "ace/OS_NS_unistd.h"
-#include "ace/os_include/net/os_if.h"
-
-#if defined (ACE_HAS_IPV6)
-# include "ace/Guard_T.h"
-# include "ace/Recursive_Thread_Mutex.h"
-#endif /* ACE_HAS_IPV6 */
-
-# if defined (ACE_HAS_GETIFADDRS)
-# include /**/ <ifaddrs.h>
-# endif /* ACE_HAS_GETIFADDRS */
-
-#if defined (VXWORKS)
-#include /**/ <inetLib.h>
-#include /**/ <netinet/in_var.h>
-extern "C" {
- extern struct in_ifaddr* in_ifaddr;
-}
-#include "ace/OS_NS_stdio.h"
-#endif /* VXWORKS */
-
-#if defined (ACE_HAS_WINCE)
-#include /**/ <Iphlpapi.h>
-#endif // ACE_HAS_WINCE
-
-#if defined (ACE_HAS_IPV6)
-# if defined (ACE_HAS_THREADS)
-# include "ace/Object_Manager.h"
-# endif /* ACE_HAS_THREADS */
-
-namespace ACE
-{
- // private:
- // Used internally so not exported.
-
- /// Does this box have ipv6 turned on?
- int ipv6_enabled_ = -1;
-}
-#endif /* ACE_HAS_IPV6 */
-
-// This is a hack to work around a problem with Visual Age C++ 5 and 6 on AIX.
-// Without this, the compiler auto-instantiates the ACE_Auto_Array_Ptr for
-// ifreq (contained in this module) but only adds the #include for <net/if.h>
-// and not the one for <sys/socket.h> which is also needed. Although we
-// don't need the template defined here, it makes the compiler pull in
-// <sys/socket.h> and the build runs clean.
-#if defined (AIX) && defined (__IBMCPP__) && (__IBMCPP__ >= 500)
-# if (__IBMCPP__ >= 700)
-# error Recheck this hack to see if version 7 fixed it!
-# endif
-static ACE_Auto_Array_Ptr<sockaddr> force_compiler_to_include_socket_h;
-#endif /* AIX && __IBMCPP__ >= 500 */
-
-
-ACE_RCSID (ace,
- Sock_Connect,
- "$Id$")
-
-
-#if defined (ACE_WIN32) && \
- (!defined (ACE_HAS_WINSOCK2) \
- || (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 == 0)))
-
-static int
-get_reg_subkeys (const ACE_TCHAR *key,
- ACE_TCHAR *buffer,
- DWORD &buf_len)
-{
- HKEY hk;
- LONG rc = ACE_TEXT_RegOpenKeyEx (HKEY_LOCAL_MACHINE,
- key,
- 0,
- KEY_READ,
- &hk);
-
- if (rc != ERROR_SUCCESS)
- return -1;
-
- ACE_TCHAR subkeyname[ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 1];
- DWORD subkeyname_len = ACE_MAX_FULLY_QUALIFIED_NAME_LEN;
- FILETIME update_dummy;
-
- DWORD total = 0;
-
- for (int i = 0;
- (rc = ACE_TEXT_RegEnumKeyEx (hk, i,
- subkeyname,
- &subkeyname_len,
- 0, 0, 0,
- &update_dummy)) != ERROR_NO_MORE_ITEMS;
- ++i)
- {
- if (subkeyname_len < buf_len - total)
- {
- ACE_OS::strcpy(buffer + total, subkeyname);
- total += subkeyname_len + 1;
- // Reset: was changed by RegEnumKeyEx call.
- subkeyname_len = ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 1;
- }
- else
- return -1;
- }
-
- buf_len = total;
-
- ::RegCloseKey (hk);
- return 0;
-}
-
-// Return value in buffer for a key/name pair from the Windows
-// Registry up to buf_len size.
-// If all_subkeys == 1, look for name under all subkeys of key.
-
-static int
-get_reg_value (const ACE_TCHAR *key,
- const ACE_TCHAR *name,
- ACE_TCHAR *buffer,
- DWORD &buf_len,
- int all_subkeys = 0)
-{
- HKEY hk;
- DWORD buf_type;
- LONG rc = ACE_TEXT_RegOpenKeyEx (HKEY_LOCAL_MACHINE,
- key,
- 0,
- KEY_READ,
- &hk);
-
- if (rc != ERROR_SUCCESS)
- // print_error_string(ACE_LIB_TEXT ("RegOpenKeyEx"), rc);
- return -1;
-
- if (all_subkeys)
- {
- ACE_TCHAR ifname[ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 1];
- DWORD ifname_len = ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 1;
- FILETIME update_dummy;
-
- DWORD total = 0;
- DWORD size = buf_len;
-
- for (int i = 0;
- (rc = ACE_TEXT_RegEnumKeyEx (hk, i, ifname, &ifname_len,
- 0, 0, 0,
- &update_dummy)) != ERROR_NO_MORE_ITEMS;
- ++i)
- {
- HKEY ifkey;
- if (rc != ERROR_SUCCESS
- || ACE_TEXT_RegOpenKeyEx (hk, ifname, 0,
- KEY_READ, &ifkey) != ERROR_SUCCESS)
- continue;
-
- if (ACE_TEXT_RegQueryValueEx (ifkey, name, 0, 0,
- (u_char*) (buffer + total),
- &size) != ERROR_SUCCESS)
- {
- RegCloseKey(ifkey);
- continue;
- }
- else
- {
- total += size;
- size = buf_len - total;
- }
- // Needs to be reset.
- ifname_len = ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 1;
- }
-
- if (total == 0)
- {
- ::RegCloseKey (hk);
- return -2;
- }
- else
- {
- buf_len = total;
- }
- }
- else
- {
-
- rc = ACE_TEXT_RegQueryValueEx (hk,
- name,
- 0,
- &buf_type,
- (u_char *) buffer,
- &buf_len);
- if (rc != ERROR_SUCCESS)
- {
- // print_error_string(ACE_LIB_TEXT ("RegEnumKeyEx"), rc);
- RegCloseKey (hk);
- return -2;
- }
- }
-
- ::RegCloseKey (hk);
- return 0;
-}
-
-enum ACE_WINDOWS_VERSION {
- ACE_WINDOWS_IS_UNKNOWN,
- ACE_WINDOWS_IS_WIN95,
- ACE_WINDOWS_IS_WIN98,
- ACE_WINDOWS_IS_WINME,
- ACE_WINDOWS_IS_WINNT,
- ACE_WINDOWS_IS_WIN2K,
- ACE_WINDOWS_IS_WINCE
-};
-
-static ACE_WINDOWS_VERSION
-get_windows_version()
-{
- OSVERSIONINFO vinfo;
- vinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- if (::GetVersionEx(&vinfo) == 0)
- {
- return ACE_WINDOWS_IS_UNKNOWN;
- }
-
- switch (vinfo.dwPlatformId)
- {
- case VER_PLATFORM_WIN32_NT:
- if (vinfo.dwMajorVersion <= 4)
- return ACE_WINDOWS_IS_WINNT;
- else
- return ACE_WINDOWS_IS_WIN2K;
- case VER_PLATFORM_WIN32_WINDOWS:
- if (vinfo.dwMajorVersion == 4)
- {
- if (vinfo.dwMinorVersion == 0)
- return ACE_WINDOWS_IS_WIN95;
- else if (vinfo.dwMinorVersion == 10)
- return ACE_WINDOWS_IS_WIN98;
- else if (vinfo.dwMinorVersion == 90)
- return ACE_WINDOWS_IS_WINME;
- }
-#if defined (VER_PLATFORM_WIN32_CE)
- case VER_PLATFORM_WIN32_CE:
- if (vinfo.dwMajorVersion >= 3) {
- return ACE_WINDOWS_IS_WINCE;
- }
- else {
- return ACE_WINDOWS_IS_UNKNOWN;
- }
-#endif /* VER_PLATFORM_WIN32_CE */
- // If no match we fall throu.
- default:
- return ACE_WINDOWS_IS_UNKNOWN;
- }
-}
-
-#endif //(ACE_WIN32) && !(ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 == 0)
-
-// Bind socket to an unused port.
-
-int
-ACE::bind_port (ACE_HANDLE handle,
- ACE_UINT32 ip_addr,
- int address_family)
-{
- ACE_TRACE ("ACE::bind_port");
-
- ACE_INET_Addr addr;
-
-#if defined (ACE_HAS_IPV6)
- if (address_family != PF_INET6)
- // What do we do if it is PF_"INET6? Since it's 4 bytes, it must be an
- // IPV4 address. Is there a difference? Why is this test done? dhinton
-#else
- ACE_UNUSED_ARG (address_family);
-#endif /* ACE_HAS_IPV6 */
- addr = ACE_INET_Addr ((u_short)0, ip_addr);
-#if defined (ACE_HAS_IPV6)
- else if (ip_addr != INADDR_ANY)
- // address_family == PF_INET6 and a non default IP address means to bind
- // to the IPv4-mapped IPv6 address
- addr.set ((u_short)0, ip_addr, 1, 1);
-#endif /* ACE_HAS_IPV6 */
-
-#if !defined (ACE_LACKS_WILDCARD_BIND)
- // The OS kernel should select a free port for us.
- return ACE_OS::bind (handle,
- (sockaddr*)addr.get_addr(),
- addr.get_size());
-#else
- static u_short upper_limit = ACE_MAX_DEFAULT_PORT;
- int round_trip = upper_limit;
- int lower_limit = IPPORT_RESERVED;
-
- // We have to select the port explicitly.
-
- for (;;)
- {
- addr.set((u_short)upper_limit,ip_addr);
-
- if (ACE_OS::bind (handle,
- (sockaddr*)addr.get_addr()
- addr.get_size()) >= 0)
- {
-#if defined (ACE_WIN32)
- upper_limit--;
-#endif /* ACE_WIN32 */
- return 0;
- }
- else if (errno != EADDRINUSE)
- return -1;
- else
- {
- upper_limit--;
-
- // Wrap back around when we reach the bottom.
- if (upper_limit <= lower_limit)
- upper_limit = ACE_MAX_DEFAULT_PORT;
-
- // See if we have already gone around once!
- if (upper_limit == round_trip)
- {
- errno = EAGAIN;
- return -1;
- }
- }
- }
-#endif /* ACE_HAS_WILDCARD_BIND */
-}
-
-int
-ACE::get_bcast_addr (ACE_UINT32 &bcast_addr,
- const ACE_TCHAR *host_name,
- ACE_UINT32 host_addr,
- ACE_HANDLE handle)
-{
- ACE_TRACE ("ACE::get_bcast_addr");
-
-#if !defined(ACE_WIN32) && !defined(__INTERIX)
- ACE_HANDLE s = handle;
-
- if (s == ACE_INVALID_HANDLE)
- s = ACE_OS::socket (AF_INET, SOCK_STREAM, 0);
-
- if (s == ACE_INVALID_HANDLE)
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_LIB_TEXT ("%p\n"),
- ACE_LIB_TEXT ("ACE_OS::socket")),
- -1);
-
- struct ifconf ifc;
- char buf[BUFSIZ];
-
- ifc.ifc_len = sizeof buf;
- ifc.ifc_buf = buf;
-
- // Get interface structure and initialize the addresses using UNIX
- // techniques
-#if defined (AIX)
- int cmd = CSIOCGIFCONF;
-#else
- int cmd = SIOCGIFCONF;
-#endif /* AIX */
- if (ACE_OS::ioctl (s, cmd, (char *) &ifc) == -1)
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_LIB_TEXT ("%p\n"),
- ACE_LIB_TEXT ("ACE::get_bcast_addr:")
- ACE_LIB_TEXT ("ioctl (get interface configuration)")),
- -1);
-
- struct ifreq *ifr = ifc.ifc_req;
-
- struct sockaddr_in ip_addr;
-
- // Get host ip address if necessary.
- if (host_name)
- {
- hostent *hp = ACE_OS::gethostbyname (ACE_TEXT_ALWAYS_CHAR (host_name));
-
- if (hp == 0)
- return -1;
- else
-#if !defined(_UNICOS)
- ACE_OS::memcpy ((char *) &ip_addr.sin_addr.s_addr,
- (char *) hp->h_addr,
- hp->h_length);
-#else /* _UNICOS */
- {
- ACE_UINT64 haddr; // a place to put the address
- char * haddrp = (char *) &haddr; // convert to char pointer
- ACE_OS::memcpy(haddrp,(char *) hp->h_addr,hp->h_length);
- ip_addr.sin_addr.s_addr = haddr;
- }
-#endif /* ! _UNICOS */
- }
- else
- {
- ACE_OS::memset ((void *) &ip_addr, 0, sizeof ip_addr);
-#if !defined(_UNICOS)
- ACE_OS::memcpy ((void *) &ip_addr.sin_addr,
- (void*) &host_addr,
- sizeof ip_addr.sin_addr);
-#else /* _UNICOS */
- ip_addr.sin_addr.s_addr = host_addr; // just copy to the bitfield
-#endif /* ! _UNICOS */
- }
-
-#if !defined(CHORUS_4) && !defined(AIX) && !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__)
- for (int n = ifc.ifc_len / sizeof (struct ifreq) ; n > 0;
- n--, ifr++)
-#else
- // see mk_broadcast@SOCK_Dgram_Bcast.cpp
- for (int nbytes = ifc.ifc_len; nbytes >= (int) sizeof (struct ifreq) &&
- ((ifr->ifr_addr.sa_len > sizeof (struct sockaddr)) ?
- (nbytes >= (int) sizeof (ifr->ifr_name) + ifr->ifr_addr.sa_len) : 1);
- ((ifr->ifr_addr.sa_len > sizeof (struct sockaddr)) ?
- (nbytes -= sizeof (ifr->ifr_name) + ifr->ifr_addr.sa_len,
- ifr = (struct ifreq *)
- ((caddr_t) &ifr->ifr_addr + ifr->ifr_addr.sa_len)) :
- (nbytes -= sizeof (struct ifreq), ifr++)))
-#endif /* !defined(CHORUS_4) && !defined(AIX) && !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) */
- {
- struct sockaddr_in if_addr;
-
- // Compare host ip address with interface ip address.
- ACE_OS::memcpy (&if_addr,
- &ifr->ifr_addr,
- sizeof if_addr);
-
- if (ip_addr.sin_addr.s_addr != if_addr.sin_addr.s_addr)
- continue;
-
- if (ifr->ifr_addr.sa_family != AF_INET)
- {
- ACE_ERROR ((LM_ERROR,
- ACE_LIB_TEXT ("%p\n"),
- ACE_LIB_TEXT ("ACE::get_bcast_addr:")
- ACE_LIB_TEXT ("Not AF_INET")));
- continue;
- }
-
- struct ifreq flags = *ifr;
- struct ifreq if_req = *ifr;
-
- if (ACE_OS::ioctl (s, SIOCGIFFLAGS, (char *) &flags) == -1)
- {
- ACE_ERROR ((LM_ERROR,
- ACE_LIB_TEXT ("%p\n"),
- ACE_LIB_TEXT ("ACE::get_bcast_addr:")
- ACE_LIB_TEXT (" ioctl (get interface flags)")));
- continue;
- }
-
- if (ACE_BIT_DISABLED (flags.ifr_flags, IFF_UP))
- {
- ACE_ERROR ((LM_ERROR,
- ACE_LIB_TEXT ("%p\n"),
- ACE_LIB_TEXT ("ACE::get_bcast_addr:")
- ACE_LIB_TEXT ("Network interface is not up")));
- continue;
- }
-
- if (ACE_BIT_ENABLED (flags.ifr_flags, IFF_LOOPBACK))
- continue;
-
- if (ACE_BIT_ENABLED (flags.ifr_flags, IFF_BROADCAST))
- {
- if (ACE_OS::ioctl (s,
- SIOCGIFBRDADDR,
- (char *) &if_req) == -1)
- ACE_ERROR ((LM_ERROR,
- ACE_LIB_TEXT ("%p\n"),
- ACE_LIB_TEXT ("ACE::get_bcast_addr:")
- ACE_LIB_TEXT ("ioctl (get broadaddr)")));
- else
- {
- ACE_OS::memcpy (ACE_reinterpret_cast(sockaddr_in *, &ip_addr),
- ACE_reinterpret_cast(sockaddr_in *, &if_req.ifr_broadaddr),
- sizeof if_req.ifr_broadaddr);
-
- ACE_OS::memcpy ((void *) &host_addr,
- (void *) &ip_addr.sin_addr,
- sizeof host_addr);
-
- if (handle == ACE_INVALID_HANDLE)
- ACE_OS::close (s);
-
- bcast_addr = host_addr;
- return 0;
- }
- }
- else
- ACE_ERROR ((LM_ERROR,
- ACE_LIB_TEXT ("%p\n"),
- ACE_LIB_TEXT ("ACE::get_bcast_addr:")
- ACE_LIB_TEXT ("Broadcast is not enable for this interface.")));
-
- if (handle == ACE_INVALID_HANDLE)
- ACE_OS::close (s);
-
- bcast_addr = host_addr;
- return 0;
- }
-
- return 0;
-#else
- ACE_UNUSED_ARG (handle);
- ACE_UNUSED_ARG (host_addr);
- ACE_UNUSED_ARG (host_name);
- bcast_addr = (ACE_UINT32 (INADDR_BROADCAST));
- return 0;
-#endif /* !ACE_WIN32 && !__INTERIX */
-}
-
-// return an array of all configured IP interfaces on this host, count
-// rc = 0 on success (count == number of interfaces else -1 caller is
-// responsible for calling delete [] on parray
-
-int
-ACE::get_ip_interfaces (size_t &count,
- ACE_INET_Addr *&addrs)
-{
- ACE_TRACE ("ACE::get_ip_interfaces");
-
- count = 0;
- addrs = 0;
-
-#if defined (ACE_WIN32)
- // Win32 can do this by a simple API call if MSVC 5 or later is the compiler.
- // Not sure if Borland supplies the needed header/lib, but it might.
-# if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
- int i, n_interfaces, status;
-
- INTERFACE_INFO info[64];
- SOCKET sock;
-
- // Get an (overlapped) DGRAM socket to test with
- sock = socket (AF_INET, SOCK_DGRAM, 0);
- if (sock == INVALID_SOCKET)
- return -1;
-
- DWORD bytes;
- status = WSAIoctl(sock,
- SIO_GET_INTERFACE_LIST,
- 0,
- 0,
- info,
- sizeof(info),
- &bytes,
- 0,
- 0);
- closesocket (sock);
- if (status == SOCKET_ERROR)
- return -1;
-
- n_interfaces = bytes / sizeof(INTERFACE_INFO);
- if (n_interfaces == 0)
- return 0;
-
- ACE_NEW_RETURN (addrs,
- ACE_INET_Addr[n_interfaces],
- -1);
-
- // Now go through the list and transfer the good ones to the list of
- // because they're down or don't have an IP address.
- for (count = 0, i = 0; i < n_interfaces; i++)
- {
- LPINTERFACE_INFO lpii;
- struct sockaddr_in *addrp;
-
- lpii = &info[i];
- if (!(lpii->iiFlags & IFF_UP))
- continue;
-
- // We assume IPv4 addresses here
- addrp = ACE_reinterpret_cast(struct sockaddr_in *, &(lpii->iiAddress));
- if (addrp->sin_addr.s_addr == INADDR_ANY)
- continue;
-
- // Set the address for the caller.
- addrs[count].set(addrp, sizeof(sockaddr_in));
- ++count;
- }
-
- if (count == 0)
- {
- delete [] addrs;
- addrs = 0;
- }
-
- return 0;
-
-#else /* Winsock 2 && MSVC 5 or later */
-
- // PharLap ETS has kernel routines to rummage through the device
- // configs and extract the interface info. Sort of a pain in the
- // butt, but better than trying to figure out where it moved to in
- // the registry... :-|
-# if defined (ACE_HAS_PHARLAP)
-# if !defined (ACE_HAS_PHARLAP_RT)
- ACE_NOTSUP_RETURN (-1);
-# endif /* ACE_HAS_PHARLAP_RT */
-
- // Locate all of the IP devices in the system, saving a DEVHANDLE
- // for each. Then allocate the ACE_INET_Addrs needed and fetch all
- // the IP addresses. To locate the devices, try the available
- // device name roots and increment the device number until the
- // kernel says there are no more of that type.
- const size_t ACE_MAX_ETS_DEVICES = 64; // Arbitrary, but should be enough.
- DEVHANDLE ip_dev[ACE_MAX_ETS_DEVICES];
- EK_TCPIPCFG *devp;
- size_t i, j;
- ACE_TCHAR dev_name[16];
-
- count = 0;
- for (i = 0; count < ACE_MAX_ETS_DEVICES; i++, ++count)
- {
- // Ethernet.
- ACE_OS::sprintf (dev_name,
- "ether%d",
- i);
- ip_dev[count] = EtsTCPGetDeviceHandle (dev_name);
- if (ip_dev[count] == 0)
- break;
- }
- for (i = 0; count < ACE_MAX_ETS_DEVICES; i++, ++count)
- {
- // SLIP.
- ACE_OS::sprintf (dev_name,
- "sl%d",
- i);
- ip_dev[count] = EtsTCPGetDeviceHandle (dev_name);
- if (ip_dev[count] == 0)
- break;
- }
- for (i = 0; count < ACE_MAX_ETS_DEVICES; i++, ++count)
- {
- // PPP.
- ACE_OS::sprintf (dev_name,
- "ppp%d",
- i);
- ip_dev[count] = EtsTCPGetDeviceHandle (dev_name);
- if (ip_dev[count] == 0)
- break;
- }
-
- if (count > 0)
- ACE_NEW_RETURN (addrs,
- ACE_INET_Addr[count],
- -1);
- else
- addrs = 0;
-
- for (i = 0, j = 0; i < count; i++)
- {
- devp = EtsTCPGetDeviceCfg (ip_dev[i]);
- if (devp != 0)
- {
- addrs[j].set (0,
- devp->nwIPAddress,
- 0); // Already in net order.
- j++;
- }
- // There's no call to close the DEVHANDLE.
- }
-
- count = j;
- if (count == 0 && addrs != 0)
- {
- delete [] addrs;
- addrs = 0;
- }
-
- return 0;
-
-# else /* ACE_HAS_PHARLAP */
-
-# if defined (ACE_HAS_WINCE)
-
- // CE does not support Winsock2 (yet) and has many variations on registry setting.
- // Thus, it is better to use GetAdapterInfo defined in iphlpapi.h, which is a
- // standard library for CE. iphlpapi.lib should come with the CE SDK and should
- // be included in the machine.
- // Note: This call is supported only in WinCE 3.0 or later. Also, even though
- // "iphlpapi.dll" may not be found in the /Windows directory on some machines,
- // it will (must) support iphlpapi API's because it is part of the standard
- // library for WinCE.
-
- IP_ADAPTER_INFO* adapterInfo = 0;
- ULONG sz = 0;
- DWORD result = ::GetAdaptersInfo(adapterInfo, &sz);
-
- while (result != ERROR_SUCCESS)
- {
- switch (result)
- {
- case ERROR_BUFFER_OVERFLOW: // MUST come here at the first run because sz = 0
- adapterInfo = (PIP_ADAPTER_INFO)(new char[sz]); // I know, I know, this is ugly.
-
- result = ::GetAdaptersInfo(adapterInfo, &sz);
- if (result == ERROR_SUCCESS) {
- const char* invalid_IP = "0.0.0.0";
-
- // find out how many interfaces are there
- {
- IP_ADAPTER_INFO* tempAdapterInfo = adapterInfo;
- int n_interfaces = 0;
- while (tempAdapterInfo != 0) {
- IP_ADDR_STRING* addr = &tempAdapterInfo->IpAddressList;
- while (addr != 0) {
- if (ACE_OS::strcmp(addr->IpAddress.String, invalid_IP) != 0) {
- // skip invalid IP address
- ++n_interfaces;
- }
- addr = addr->Next;
- }
- tempAdapterInfo = tempAdapterInfo->Next;
- }
- if (n_interfaces == 0) {
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_LIB_TEXT ("%p\nACE::get_ip_interfaces - "),
- ACE_LIB_TEXT ("No adapter found.")),
- -1);
- }
-
- ACE_NEW_RETURN (addrs, ACE_INET_Addr[n_interfaces], -2);
- }
-
- // find out valid IP addresses and put them into the addr
- while (adapterInfo != 0) {
- IP_ADDR_STRING* addr = &adapterInfo->IpAddressList;
- while (addr != 0) {
- if (ACE_OS::strcmp(addr->IpAddress.String, invalid_IP) != 0) {
- addrs[count++] = ACE_INET_Addr((u_short) 0, addr->IpAddress.String);
- }
- addr = addr->Next;
- }
- adapterInfo = adapterInfo->Next;
- }
- }
- // if second GetAdaptersInfo call fails, let other cases take care of it
- break;
-
- case ERROR_NOT_SUPPORTED: // OS does not support this method
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_LIB_TEXT ("%p\nACE::get_ip_interfaces - "),
- ACE_LIB_TEXT ("This version of WinCE does not support GetAdapterInfo.")),
- -1);
- break;
-
- case ERROR_NO_DATA: // no adapter installed
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_LIB_TEXT ("%p\nACE::get_ip_interfaces - "),
- ACE_LIB_TEXT ("No network adapter installed.")),
- -1);
- break;
-
- case ERROR_INVALID_PARAMETER:
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_LIB_TEXT ("%p\nACE::get_ip_interfaces - "),
- ACE_LIB_TEXT ("Invalid parameter.")),
- -1);
- break;
-
- default:
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_LIB_TEXT ("%p\nACE::get_ip_interfaces - "),
- ACE_LIB_TEXT ("Adapter info access permission denied.")),
- -1);
- break;
- }
- }
-
- delete [] adapterInfo;
- return 0;
-
-# endif // ACE_HAS_WINCE
-
- //
- // No Winsock2.
- // Get interface information from the registry.
- // As this information is in different locations of the registry
- // on different windows versions, we need to ask at runtime.
- //
-
- // Normally we have to look under one key for interfaces name,
- // and under a second key for ip address of those interfaces.
- // Exact values and the way to search depend on windows version.
-
- // This is the first key we have to look for.
- const ACE_TCHAR *BASE_KEY1;
-
- // This is the name we have to look for under the first key.
- // If this is == 0, we need to look for subkeys, not the values from
- // a name.
- const ACE_TCHAR *KEY1_NAME_ID;
-
- // The second key is normally constructed concatenating a prefix,
- // the value found on KEY1_NAME_ID stripped from the first s_offset
- // characters, and a suffix.
- unsigned int s_offset;
- const ACE_TCHAR *PREFFIX_KEY2;
- const ACE_TCHAR *SUFFIX_KEY2;
-
- // If != 0, look for the value of KEY1_NAME_ID not directly under
- // BASE_KEY1, but on every subkey of BASE_KEY1.
- int use_subkeys;
-
- // When we search for IP Addresses below, we look for a key with a
- // name in this array (null terminated).
- // For some windows versions, there is an
- // aditional key for ppp interfaces that will be stored on [1].
- const ACE_TCHAR *IPADDR_NAME_ID[3] = {
- ACE_LIB_TEXT ("IPAddress"), 0, 0
- };
-
- // Skip addresses that match this.
- const ACE_TCHAR *INVALID_TCPIP_DEVICE_ADDR = ACE_LIB_TEXT ("0.0.0.0");
-
- ACE_WINDOWS_VERSION winver = get_windows_version();
-
- switch (winver)
- {
- case ACE_WINDOWS_IS_WINNT:
- PREFFIX_KEY2 = ACE_LIB_TEXT ("SYSTEM\\CurrentControlSet\\Services\\");
- BASE_KEY1 =
- ACE_LIB_TEXT ("SYSTEM\\CurrentControlSet\\Services")
- ACE_LIB_TEXT ("\\Tcpip\\Linkage");
- SUFFIX_KEY2 = ACE_LIB_TEXT ("\\Parameters\\Tcpip");
- KEY1_NAME_ID = ACE_LIB_TEXT ("Bind");
- s_offset = 8;
- use_subkeys = 0;
- break;
-
- case ACE_WINDOWS_IS_WIN2K:
- BASE_KEY1 =
- ACE_LIB_TEXT ("SYSTEM\\CurrentControlSet\\Services")
- ACE_LIB_TEXT ("\\Tcpip\\Parameters\\Interfaces\\");
- PREFFIX_KEY2 = BASE_KEY1;
- SUFFIX_KEY2 = ACE_LIB_TEXT ("");
- KEY1_NAME_ID = 0;
- s_offset = 0;
- use_subkeys = 1;
- // PPP.
- IPADDR_NAME_ID[1] = ACE_LIB_TEXT ("DhcpIPAddress");
- break;
-
- // If ACE_HAS_WINNT4 we can safely assume the ones below will
- // not be needed.
-# if !defined(ACE_HAS_WINNT4) || (ACE_HAS_WINNT4 == 0)
- case ACE_WINDOWS_IS_WIN95:
- case ACE_WINDOWS_IS_WIN98:
- case ACE_WINDOWS_IS_WINME:
- PREFFIX_KEY2 =
- ACE_LIB_TEXT ("SYSTEM\\CurrentControlSet\\Services\\Class\\");
- BASE_KEY1 = ACE_LIB_TEXT ("Enum\\Network\\MSTCP");
- SUFFIX_KEY2 = ACE_LIB_TEXT ("");
- KEY1_NAME_ID = ACE_LIB_TEXT ("Driver");
- use_subkeys = 1;
- s_offset = 0;
- break;
-# endif /* !ACE_HAS_WINNT4 */
-
- default:
- return -1;
- }
-
- ACE_TCHAR raw_buffer[ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 1];
- DWORD raw_buflen = ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 1;
-
- if (KEY1_NAME_ID == 0)
- {
- if (::get_reg_subkeys (BASE_KEY1,
- raw_buffer,
- raw_buflen))
- return -1;
- }
- else
- {
- if (::get_reg_value (BASE_KEY1,
- KEY1_NAME_ID,
- raw_buffer,
- raw_buflen,
- use_subkeys))
- return -1;
- }
- // return buffer contains 0 delimited strings
-
- ACE_Tokenizer dev_names (raw_buffer);
- dev_names.delimiter (ACE_LIB_TEXT ('\0'));
- int n_interfaces = 0;
-
- // Count the number of interfaces
- while (dev_names.next () != 0)
- n_interfaces ++;
-
- // case 1. no interfaces present, empty string? OS version change?
- if (n_interfaces == 0)
- return 0;
-
- ACE_NEW_RETURN (addrs,
- ACE_INET_Addr[n_interfaces],
- -2);
-
- ACE_TCHAR buffer[ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 1];
- DWORD buf_len = ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 1;
-
- count = 0;
- for (int i = 0; i < n_interfaces; i++)
- {
- for (const ACE_TCHAR **ipaddr_name_id = IPADDR_NAME_ID;
- *ipaddr_name_id != 0;
- ++ipaddr_name_id)
- {
- // a. construct name to access IP Address for this interface
- ACE_TString ifdevkey (PREFFIX_KEY2);
- ACE_TString the_dev = dev_names.next ();
-
- if (the_dev.length() < s_offset)
- {
- return -3; // Something's wrong
- }
-
- // rest of string from offset.
- the_dev = the_dev.substring (s_offset);
-
- ifdevkey += the_dev;
- ifdevkey += SUFFIX_KEY2;
-
- // b. extract value
- // Gets overwritten on each call
- buf_len = sizeof (buffer);
- if (get_reg_value (ifdevkey.fast_rep (),
- *ipaddr_name_id,
- buffer,
- buf_len))
- continue; // Skip unknown devices.
-
- if (ACE_OS::strcmp (buffer,
- INVALID_TCPIP_DEVICE_ADDR) == 0)
- continue; // Don't count this device
-
- // c. store in hostinfo object array and up the counter
- addrs[count++] =
- ACE_INET_Addr ((u_short) 0, buffer);
- }
- }
-
- return 0;
-# endif /* ACE_HAS_PHARLAP */
-# endif /* Winsock 2 && MSVC 5 or later */
-
-#elif defined (ACE_HAS_GETIFADDRS)
- // Take advantage of the BSD getifaddrs function that simplifies
- // access to connected interfaces.
- struct ifaddrs *ifap;
- struct ifaddrs *p_if;
-
- if (::getifaddrs (&ifap) != 0)
- return -1;
-
- // Count number of interfaces.
- size_t num_ifs = 0;
- for (p_if = ifap; p_if != 0; p_if = p_if->ifa_next)
- ++num_ifs;
-
- // Now create and initialize output array.
- ACE_NEW_RETURN (addrs,
- ACE_INET_Addr[num_ifs],
- -1); // caller must free
-
- // Pull the address out of each INET interface. Not every interface
- // is for IP, so be careful to count properly. When setting the
- // INET_Addr, note that the 3rd arg (0) says to leave the byte order
- // (already in net byte order from the interface structure) as is.
- count = 0;
-
- for (p_if = ifap;
- p_if != 0;
- p_if = p_if->ifa_next)
- {
- if (p_if->ifa_addr &&
- p_if->ifa_addr->sa_family == AF_INET)
- {
- struct sockaddr_in *addr =
- ACE_reinterpret_cast(sockaddr_in *, p_if->ifa_addr);
-
- // Sometimes the kernel returns 0.0.0.0 as the interface
- // address, skip those...
- if (addr->sin_addr.s_addr != 0)
- {
- addrs[count].set ((u_short) 0,
- addr->sin_addr.s_addr,
- 0);
- count++;
- }
- }
- }
-
- ::freeifaddrs (ifap);
-
- return 0;
-
-#elif defined (__unix) || defined (__unix__) || defined (__Lynx__) || defined (_AIX)
- // COMMON (SVR4 and BSD) UNIX CODE
-
- size_t num_ifs;
-
- // Call specific routine as necessary.
- ACE_HANDLE handle = get_handle();
-
- if (handle == ACE_INVALID_HANDLE)
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_LIB_TEXT ("%p\n"),
- ACE_LIB_TEXT ("ACE::get_ip_interfaces:open")),
- -1);
- if (ACE::count_interfaces (handle, num_ifs))
- {
- ACE_OS::close (handle);
- return -1;
- }
-
- // ioctl likes to have an extra ifreq structure to mark the end of
- // what it returned, so increase the num_ifs by one.
- ++num_ifs;
-
- struct ifreq *ifs = 0;
- ACE_NEW_RETURN (ifs,
- struct ifreq[num_ifs],
- -1);
- ACE_OS::memset (ifs, 0, num_ifs * sizeof (struct ifreq));
-
- ACE_Auto_Array_Ptr<struct ifreq> p_ifs (ifs);
-
- if (p_ifs.get() == 0)
- {
- ACE_OS::close (handle);
- errno = ENOMEM;
- return -1;
- }
-
- struct ifconf ifcfg;
- ACE_OS::memset (&ifcfg, 0, sizeof (struct ifconf));
- ifcfg.ifc_req = p_ifs.get ();
- ifcfg.ifc_len = num_ifs * sizeof (struct ifreq);
-
-#if defined (AIX)
- int cmd = CSIOCGIFCONF;
-#else
- int cmd = SIOCGIFCONF;
-#endif /* AIX */
- if (ACE_OS::ioctl (handle,
- cmd,
- (caddr_t) &ifcfg) == -1)
- {
- ACE_OS::close (handle);
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_LIB_TEXT ("%p\n"),
- ACE_LIB_TEXT ("ACE::get_ip_interfaces:")
- ACE_LIB_TEXT ("ioctl - SIOCGIFCONF failed")),
- -1);
- }
-
- ACE_OS::close (handle);
-
- // Now create and initialize output array.
-
- ACE_NEW_RETURN (addrs,
- ACE_INET_Addr[num_ifs],
- -1); // caller must free
-
- struct ifreq *pcur = p_ifs.get ();
- // Pull the address out of each INET interface. Not every interface
- // is for IP, so be careful to count properly. When setting the
- // INET_Addr, note that the 3rd arg (0) says to leave the byte order
- // (already in net byte order from the interface structure) as is.
- count = 0;
-
- for (size_t i = 0;
- i < num_ifs;
- i++)
- {
- if (pcur->ifr_addr.sa_family == AF_INET)
- {
-#if !defined(_UNICOS)
- struct sockaddr_in *addr =
- ACE_reinterpret_cast(sockaddr_in *, &pcur->ifr_addr);
-
- // Sometimes the kernel returns 0.0.0.0 as the interface
- // address, skip those...
- if (addr->sin_addr.s_addr != 0)
- {
- addrs[count].set ((u_short) 0,
- addr->sin_addr.s_addr,
- 0);
- count++;
- }
-#else /* ! _UNICOS */
- // need to explicitly copy on the Cray, since the bitfields kinda
- // screw things up here
- struct sockaddr_in inAddr;
-
- inAddr.sin_len = pcur->ifr_addr.sa_len;
- inAddr.sin_family = pcur->ifr_addr.sa_family;
- memcpy((void *)&(inAddr.sin_addr),
- (const void *)&(pcur->ifr_addr.sa_data[8]),
- sizeof(struct in_addr));
-
- if (inAddr.sin_addr.s_addr != 0)
- {
- addrs[count].set(&inAddr, sizeof(struct sockaddr_in));
- count++;
- }
-#endif /* ! _UNICOS */
- }
-
-#if !defined(CHORUS_4) && !defined(AIX) && !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__)
- pcur++;
-#else
- if (pcur->ifr_addr.sa_len <= sizeof (struct sockaddr))
- {
- pcur++;
- }
- else
- {
- pcur = (struct ifreq *)
- (pcur->ifr_addr.sa_len + (caddr_t) &pcur->ifr_addr);
- }
-#endif /* !defined(CHORUS_4) && !defined(AIX) && !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) */
- }
- return 0;
-#elif defined (VXWORKS)
- count = 0;
- // Loop through each address structure
- for (struct in_ifaddr* ia = in_ifaddr; ia != 0; ia = ia->ia_next)
- {
- ++count;
- }
-
- // Now create and initialize output array.
- ACE_NEW_RETURN (addrs,
- ACE_INET_Addr[count],
- -1); // caller must free
- count = 0;
- for (struct in_ifaddr* ia = in_ifaddr; ia != 0; ia = ia->ia_next)
- {
- struct ifnet* ifp = ia->ia_ifa.ifa_ifp;
- if (ifp != 0)
- {
- // Get the current interface name
- char interface[64];
- ACE_OS::sprintf(interface, "%s%d", ifp->if_name, ifp->if_unit);
-
- // Get the address for the current interface
- char address [INET_ADDR_LEN];
- STATUS status = ifAddrGet(interface, address);
-
- if (status == OK)
- {
- // Concatenate a ':' at the end. This is because in
- // ACE_INET_Addr::string_to_addr, the ip_address is
- // obtained using ':' as the delimiter. Since, using
- // ifAddrGet(), we just get the IP address, I am adding
- // a ":" to get with the general case.
- ACE_OS::strcat (address, ":");
- addrs[count].set (address);
- }
- else
- {
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_LIB_TEXT ("ACE::get_ip_interface failed\n")
- ACE_LIB_TEXT ("Couldnt get the IP Address\n")),
- -1);
- }
- ++count;
- }
- }
- return 0;
-#else
- ACE_UNUSED_ARG (count);
- ACE_UNUSED_ARG (addrs);
- ACE_NOTSUP_RETURN (-1);; // no implementation
-#endif /* ACE_WIN32 */
-}
-
-// Helper routine for get_ip_interfaces, differs by UNIX platform so
-// put into own subroutine. perform some ioctls to retrieve ifconf
-// list of ifreq structs.
-
-int
-ACE::count_interfaces (ACE_HANDLE handle, size_t &how_many)
-{
-#if defined (sparc) && defined (SIOCGIFNUM)
- int tmp_how_many; // For 64 bit Solaris
- if (ACE_OS::ioctl (handle,
- SIOCGIFNUM,
- (caddr_t) &tmp_how_many) == -1)
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_LIB_TEXT ("%p\n"),
- ACE_LIB_TEXT ("ACE::count_interfaces:")
- ACE_LIB_TEXT ("ioctl - SIOCGIFNUM failed")),
- -1);
- how_many = (size_t) tmp_how_many;
- return 0;
-#elif defined (ACE_HAS_GETIFADDRS)
- ACE_UNUSED_ARG (handle);
-
- struct ifaddrs *ifap;
- struct ifaddrs *p_if;
-
- if (::getifaddrs (&ifap) != 0)
- return -1;
-
- // Count number of interfaces.
- size_t num_ifs = 0;
- for (p_if = ifap; p_if != 0; p_if = p_if->ifa_next)
- ++num_ifs;
-
- ::freeifaddrs (ifap);
-
- how_many = num_ifs;
- return 0;
-#elif defined (__unix) || defined (__unix__) || defined (__Lynx__) || defined (_AIX)
- // Note: DEC CXX doesn't define "unix". BSD compatible OS: HP UX,
- // AIX, SunOS 4.x perform some ioctls to retrieve ifconf list of
- // ifreq structs no SIOCGIFNUM on SunOS 4.x, so use guess and scan
- // algorithm
-
- // Probably hard to put this many ifs in a unix box..
- const int MAX_IF = 50;
-
- // HACK - set to an unreasonable number
- int num_ifs = MAX_IF;
-
- struct ifconf ifcfg;
- size_t ifreq_size = num_ifs * sizeof (struct ifreq);
- struct ifreq *p_ifs =
- (struct ifreq *) ACE_OS::malloc (ifreq_size);
-
- if (!p_ifs)
- {
- errno = ENOMEM;
- return -1;
- }
-
- ACE_OS::memset (p_ifs, 0, ifreq_size);
- ACE_OS::memset (&ifcfg, 0, sizeof (struct ifconf));
-
- ifcfg.ifc_req = p_ifs;
- ifcfg.ifc_len = ifreq_size;
-
-#if defined (AIX)
- int cmd = CSIOCGIFCONF;
-#else
- int cmd = SIOCGIFCONF;
-#endif /* AIX */
- if (ACE_OS::ioctl (handle,
- cmd,
- (caddr_t) &ifcfg) == -1)
- {
- ACE_OS::free (ifcfg.ifc_req);
- ACE_ERROR_RETURN ((LM_ERROR,
- ACE_LIB_TEXT ("%p\n"),
- ACE_LIB_TEXT ("ACE::count_interfaces:")
- ACE_LIB_TEXT ("ioctl - SIOCGIFCONF failed")),
- -1);
- }
-
- int if_count = 0, i;
-
- // get if address out of ifreq buffers. ioctl puts a blank-named
- // interface to mark the end of the returned interfaces.
- for (i = 0;
- i < num_ifs;
- i++)
- {
- /* In OpenBSD, the length of the list is returned. */
- ifcfg.ifc_len -= sizeof (struct ifreq);
- if (ifcfg.ifc_len < 0)
- break;
-
- if_count++;
-#if !defined(CHORUS_4) && !defined(AIX) && !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__)
- p_ifs++;
-#else
- if (p_ifs->ifr_addr.sa_len <= sizeof (struct sockaddr))
- {
- p_ifs++;
- }
- else
- {
- p_ifs = (struct ifreq *)
- (p_ifs->ifr_addr.sa_len + (caddr_t) &p_ifs->ifr_addr);
- }
-#endif /* !defined(CHORUS_4) && !defined(AIX) && !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) */
- }
-
- ACE_OS::free (ifcfg.ifc_req);
- how_many = if_count;
- return 0;
-#else
- ACE_UNUSED_ARG (handle);
- ACE_UNUSED_ARG (how_many);
- ACE_NOTSUP_RETURN (-1);; // no implmentation
-#endif /* sparc && SIOCGIFNUM */
-}
-
-// Routine to return a handle from which ioctl() requests can be made.
-
-ACE_HANDLE
-ACE::get_handle (void)
-{
- // Solaris 2.x
- ACE_HANDLE handle = ACE_INVALID_HANDLE;
-#if defined (sparc) && ! defined (CHORUS)
- handle = ACE_OS::open ("/dev/udp", O_RDONLY);
-#elif defined (__unix) || defined (__unix__) || defined (__Lynx__) || defined (_AIX)
- // Note: DEC CXX doesn't define "unix" BSD compatible OS: HP UX,
- // AIX, SunOS 4.x
-
- handle = ACE_OS::socket (PF_INET, SOCK_DGRAM, 0);
-#endif /* sparc */
- return handle;
-}
-
-
-int
-ACE::ipv6_enabled (void)
-{
-#if defined (ACE_HAS_IPV6)
- if (ACE::ipv6_enabled_ == -1)
- {
- // Perform Double-Checked Locking Optimization.
- ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
- *ACE_Static_Object_Lock::instance (), 0));
-
- if (ACE::ipv6_enabled_ == -1)
- {
- // Determine if the kernel has IPv6 support by attempting to
- // create a PF_INET6 socket and see if it fails.
- ACE_HANDLE s = ACE_OS::socket (PF_INET6, SOCK_DGRAM, 0);
- if (s == ACE_INVALID_HANDLE)
- {
- ACE::ipv6_enabled_ = 0;
- }
- else
- {
- ACE::ipv6_enabled_ = 1;
- ACE_OS::closesocket (s);
- }
- }
- }
-
- return ACE::ipv6_enabled_;
-#else
- return 0;
-#endif /* ACE_HAS_IPV6 */
-}
-
-#if defined (__unix) || defined (__unix__) || defined (__Lynx__) || \
- defined (_AIX)
-# if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
-template class ACE_Auto_Array_Ptr<struct ifreq>;
-template class ACE_Auto_Basic_Array_Ptr<struct ifreq>;
-# elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
-#pragma instantiate ACE_Auto_Array_Ptr<struct ifreq>
-#pragma instantiate ACE_Auto_Basic_Array_Ptr<struct ifreq>
-# endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
-#endif /* (__unix || __Lynx_ || AIX ) */