00001 #include "ace_pch.h"
00002
00003
00004 #include "ace/Sock_Connect.h"
00005 #include "ace/OS.h"
00006 #include "ace/INET_Addr.h"
00007 #include "ace/Log_Msg.h"
00008 #include "ace/Handle_Set.h"
00009 #include "ace/Auto_Ptr.h"
00010 #include "ace/SString.h"
00011
00012 # if defined (ACE_HAS_GETIFADDRS)
00013 # include <ifaddrs.h>
00014 # endif
00015
00016 #if defined (VXWORKS)
00017 #include <inetLib.h>
00018 #include <netinet/in_var.h>
00019 extern "C" {
00020 extern struct in_ifaddr* in_ifaddr;
00021 }
00022 #endif
00023
00024 #if defined (ACE_HAS_WINCE)
00025 #include <Iphlpapi.h>
00026 #endif // ACE_HAS_WINCE
00027
00028 #if defined (ACE_HAS_IPV6)
00029 # if defined (ACE_HAS_THREADS)
00030 # include "ace/Synch.h"
00031 # include "ace/Object_Manager.h"
00032 # endif
00033
00034
00035 int ACE_Sock_Connect::ipv6_enabled_ = -1;
00036 #endif
00037
00038
00039
00040
00041
00042
00043
00044 #if defined (AIX) && defined (__IBMCPP__) && (__IBMCPP__ >= 500)
00045 # if (__IBMCPP__ >= 700)
00046 # error Recheck this hack to see if version 7 fixed it!
00047 # endif
00048 static ACE_Auto_Array_Ptr<sockaddr> force_compiler_to_include_socket_h;
00049 #endif
00050
00051
00052 #if defined (ACE_LACKS_INLINE_FUNCTIONS)
00053 #include "ace/Sock_Connect.i"
00054 #endif
00055
00056 ACE_RCSID(ace, Sock_Connect, "$Id: Sock_Connect.cpp,v 1.1.1.2.2.1 2003/03/13 19:44:22 chad Exp $")
00057
00058 #if defined (ACE_WIN32) && \
00059 (!defined (ACE_HAS_WINSOCK2) \
00060 || (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 == 0)))
00061
00062 static int
00063 get_reg_subkeys (const ACE_TCHAR *key,
00064 ACE_TCHAR *buffer,
00065 DWORD &buf_len)
00066 {
00067 HKEY hk;
00068 LONG rc = ACE_TEXT_RegOpenKeyEx (HKEY_LOCAL_MACHINE,
00069 key,
00070 0,
00071 KEY_READ,
00072 &hk);
00073
00074 if (rc != ERROR_SUCCESS)
00075 return -1;
00076
00077 ACE_TCHAR subkeyname[ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 1];
00078 DWORD subkeyname_len = ACE_MAX_FULLY_QUALIFIED_NAME_LEN;
00079 FILETIME update_dummy;
00080
00081 DWORD total = 0;
00082
00083 for (int i = 0;
00084 (rc = ACE_TEXT_RegEnumKeyEx (hk, i,
00085 subkeyname,
00086 &subkeyname_len,
00087 0, 0, 0,
00088 &update_dummy)) != ERROR_NO_MORE_ITEMS;
00089 ++i)
00090 {
00091 if (subkeyname_len < buf_len - total)
00092 {
00093 ACE_OS::strcpy(buffer + total, subkeyname);
00094 total += subkeyname_len + 1;
00095
00096 subkeyname_len = ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 1;
00097 }
00098 else
00099 return -1;
00100 }
00101
00102 buf_len = total;
00103
00104 ::RegCloseKey (hk);
00105 return 0;
00106 }
00107
00108
00109
00110
00111
00112 static int
00113 get_reg_value (const ACE_TCHAR *key,
00114 const ACE_TCHAR *name,
00115 ACE_TCHAR *buffer,
00116 DWORD &buf_len,
00117 int all_subkeys = 0)
00118 {
00119 HKEY hk;
00120 DWORD buf_type;
00121 LONG rc = ACE_TEXT_RegOpenKeyEx (HKEY_LOCAL_MACHINE,
00122 key,
00123 0,
00124 KEY_READ,
00125 &hk);
00126
00127 if (rc != ERROR_SUCCESS)
00128
00129 return -1;
00130
00131 if (all_subkeys)
00132 {
00133 ACE_TCHAR ifname[ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 1];
00134 DWORD ifname_len = ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 1;
00135 FILETIME update_dummy;
00136
00137 DWORD total = 0;
00138 DWORD size = buf_len;
00139
00140 for (int i = 0;
00141 (rc = ACE_TEXT_RegEnumKeyEx (hk, i, ifname, &ifname_len,
00142 0, 0, 0,
00143 &update_dummy)) != ERROR_NO_MORE_ITEMS;
00144 ++i)
00145 {
00146 HKEY ifkey;
00147 if (rc != ERROR_SUCCESS
00148 || ACE_TEXT_RegOpenKeyEx (hk, ifname, 0,
00149 KEY_READ, &ifkey) != ERROR_SUCCESS)
00150 continue;
00151
00152 if (ACE_TEXT_RegQueryValueEx (ifkey, name, 0, 0,
00153 (u_char*) (buffer + total),
00154 &size) != ERROR_SUCCESS)
00155 {
00156 RegCloseKey(ifkey);
00157 continue;
00158 }
00159 else
00160 {
00161 total += size;
00162 size = buf_len - total;
00163 }
00164
00165 ifname_len = ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 1;
00166 }
00167
00168 if (total == 0)
00169 {
00170 ::RegCloseKey (hk);
00171 return -2;
00172 }
00173 else
00174 {
00175 buf_len = total;
00176 }
00177 }
00178 else
00179 {
00180
00181 rc = ACE_TEXT_RegQueryValueEx (hk,
00182 name,
00183 0,
00184 &buf_type,
00185 (u_char *) buffer,
00186 &buf_len);
00187 if (rc != ERROR_SUCCESS)
00188 {
00189
00190 RegCloseKey (hk);
00191 return -2;
00192 }
00193 }
00194
00195 ::RegCloseKey (hk);
00196 return 0;
00197 }
00198
00199 enum ACE_WINDOWS_VERSION {
00200 ACE_WINDOWS_IS_UNKNOWN,
00201 ACE_WINDOWS_IS_WIN95,
00202 ACE_WINDOWS_IS_WIN98,
00203 ACE_WINDOWS_IS_WINME,
00204 ACE_WINDOWS_IS_WINNT,
00205 ACE_WINDOWS_IS_WIN2K,
00206 ACE_WINDOWS_IS_WINCE
00207 };
00208
00209 static ACE_WINDOWS_VERSION
00210 get_windows_version()
00211 {
00212 OSVERSIONINFO vinfo;
00213 vinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
00214 if (::GetVersionEx(&vinfo) == 0)
00215 {
00216 return ACE_WINDOWS_IS_UNKNOWN;
00217 }
00218
00219 switch (vinfo.dwPlatformId)
00220 {
00221 case VER_PLATFORM_WIN32_NT:
00222 if (vinfo.dwMajorVersion <= 4)
00223 return ACE_WINDOWS_IS_WINNT;
00224 else
00225 return ACE_WINDOWS_IS_WIN2K;
00226 case VER_PLATFORM_WIN32_WINDOWS:
00227 if (vinfo.dwMajorVersion == 4)
00228 {
00229 if (vinfo.dwMinorVersion == 0)
00230 return ACE_WINDOWS_IS_WIN95;
00231 else if (vinfo.dwMinorVersion == 10)
00232 return ACE_WINDOWS_IS_WIN98;
00233 else if (vinfo.dwMinorVersion == 90)
00234 return ACE_WINDOWS_IS_WINME;
00235 }
00236 case VER_PLATFORM_WIN32_CE:
00237 if (vinfo.dwMajorVersion >= 3) {
00238 return ACE_WINDOWS_IS_WINCE;
00239 }
00240 else {
00241 return ACE_WINDOWS_IS_UNKNOWN;
00242 }
00243
00244 default:
00245 return ACE_WINDOWS_IS_UNKNOWN;
00246 }
00247 }
00248
00249 #endif //(ACE_WIN32) && !(ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 == 0)
00250
00251
00252
00253 int
00254 ACE_Sock_Connect::bind_port (ACE_HANDLE handle,
00255 ACE_UINT32 ip_addr)
00256 {
00257 ACE_TRACE ("ACE_Sock_Connect::bind_port");
00258
00259 ACE_INET_Addr addr ((u_short)0, ip_addr);
00260
00261 #if !defined (ACE_LACKS_WILDCARD_BIND)
00262
00263 return ACE_OS::bind (handle,
00264 (sockaddr*)addr.get_addr(),
00265 addr.get_size());
00266 #else
00267 static u_short upper_limit = ACE_MAX_DEFAULT_PORT;
00268 int round_trip = upper_limit;
00269 int lower_limit = IPPORT_RESERVED;
00270
00271
00272
00273 for (;;)
00274 {
00275 addr.set((u_short)upper_limit,ip_addr);
00276
00277 if (ACE_OS::bind (handle,
00278 (sockaddr*)addr.get_addr()
00279 addr.get_size()) >= 0)
00280 {
00281 #if defined (ACE_WIN32)
00282 upper_limit--;
00283 #endif
00284 return 0;
00285 }
00286 else if (errno != EADDRINUSE)
00287 return -1;
00288 else
00289 {
00290 upper_limit--;
00291
00292
00293 if (upper_limit <= lower_limit)
00294 upper_limit = ACE_MAX_DEFAULT_PORT;
00295
00296
00297 if (upper_limit == round_trip)
00298 {
00299 errno = EAGAIN;
00300 return -1;
00301 }
00302 }
00303 }
00304 #endif
00305 }
00306
00307 int
00308 ACE_Sock_Connect::get_bcast_addr (ACE_UINT32 &bcast_addr,
00309 const ACE_TCHAR *host_name,
00310 ACE_UINT32 host_addr,
00311 ACE_HANDLE handle)
00312 {
00313 ACE_TRACE ("ACE_Sock_Connect::get_bcast_addr");
00314
00315 #if !defined(ACE_WIN32)
00316 ACE_HANDLE s = handle;
00317
00318 if (s == ACE_INVALID_HANDLE)
00319 s = ACE_OS::socket (AF_INET, SOCK_STREAM, 0);
00320
00321 if (s == ACE_INVALID_HANDLE)
00322 ACE_ERROR_RETURN ((LM_ERROR,
00323 ACE_LIB_TEXT ("%p\n"),
00324 ACE_LIB_TEXT ("ACE_OS::socket")),
00325 -1);
00326
00327 struct ifconf ifc;
00328 char buf[BUFSIZ];
00329
00330 ifc.ifc_len = sizeof buf;
00331 ifc.ifc_buf = buf;
00332
00333
00334
00335 #if defined (AIX)
00336 int cmd = CSIOCGIFCONF;
00337 #else
00338 int cmd = SIOCGIFCONF;
00339 #endif
00340 if (ACE_OS::ioctl (s, cmd, (char *) &ifc) == -1)
00341 ACE_ERROR_RETURN ((LM_ERROR,
00342 ACE_LIB_TEXT ("%p\n"),
00343 ACE_LIB_TEXT ("ACE_Sock_Connect::get_bcast_addr:")
00344 ACE_LIB_TEXT ("ioctl (get interface configuration)")),
00345 -1);
00346
00347 struct ifreq *ifr = ifc.ifc_req;
00348
00349 struct sockaddr_in ip_addr;
00350
00351
00352 if (host_name)
00353 {
00354 hostent *hp = ACE_OS::gethostbyname (host_name);
00355
00356 if (hp == 0)
00357 return -1;
00358 else
00359 #if !defined(_UNICOS)
00360 ACE_OS::memcpy ((char *) &ip_addr.sin_addr.s_addr,
00361 (char *) hp->h_addr,
00362 hp->h_length);
00363 #else
00364 {
00365 ACE_UINT64 haddr;
00366 char * haddrp = (char *) &haddr;
00367 ACE_OS::memcpy(haddrp,(char *) hp->h_addr,hp->h_length);
00368 ip_addr.sin_addr.s_addr = haddr;
00369 }
00370 #endif
00371 }
00372 else
00373 {
00374 ACE_OS::memset ((void *) &ip_addr, 0, sizeof ip_addr);
00375 #if !defined(_UNICOS)
00376 ACE_OS::memcpy ((void *) &ip_addr.sin_addr,
00377 (void*) &host_addr,
00378 sizeof ip_addr.sin_addr);
00379 #else
00380 ip_addr.sin_addr.s_addr = host_addr;
00381 #endif
00382 }
00383
00384 for (int n = ifc.ifc_len / sizeof (struct ifreq);
00385 n > 0;
00386 #if !defined (CHORUS_4) && !defined (__FreeBSD__)
00387 n--, ifr++)
00388 #else
00389 n--,
00390 ((ifr->ifr_addr.sa_len <= sizeof (struct sockaddr)) ?
00391 ifr++ :
00392 ifr = (struct ifreq *)
00393 (ifr->ifr_addr.sa_len + (caddr_t) &ifr->ifr_addr)))
00394 #endif
00395 {
00396 struct sockaddr_in if_addr;
00397
00398
00399 ACE_OS::memcpy (&if_addr,
00400 &ifr->ifr_addr,
00401 sizeof if_addr);
00402
00403 if (ip_addr.sin_addr.s_addr != if_addr.sin_addr.s_addr)
00404 continue;
00405
00406 if (ifr->ifr_addr.sa_family != AF_INET)
00407 {
00408 ACE_ERROR ((LM_ERROR,
00409 ACE_LIB_TEXT ("%p\n"),
00410 ACE_LIB_TEXT ("ACE_Sock_Connect::get_bcast_addr:")
00411 ACE_LIB_TEXT ("Not AF_INET")));
00412 continue;
00413 }
00414
00415 struct ifreq flags = *ifr;
00416 struct ifreq if_req = *ifr;
00417
00418 if (ACE_OS::ioctl (s, SIOCGIFFLAGS, (char *) &flags) == -1)
00419 {
00420 ACE_ERROR ((LM_ERROR,
00421 ACE_LIB_TEXT ("%p\n"),
00422 ACE_LIB_TEXT ("ACE_Sock_Connect::get_bcast_addr:")
00423 ACE_LIB_TEXT (" ioctl (get interface flags)")));
00424 continue;
00425 }
00426
00427 if (ACE_BIT_DISABLED (flags.ifr_flags, IFF_UP))
00428 {
00429 ACE_ERROR ((LM_ERROR,
00430 ACE_LIB_TEXT ("%p\n"),
00431 ACE_LIB_TEXT ("ACE_Sock_Connect::get_bcast_addr:")
00432 ACE_LIB_TEXT ("Network interface is not up")));
00433 continue;
00434 }
00435
00436 if (ACE_BIT_ENABLED (flags.ifr_flags, IFF_LOOPBACK))
00437 continue;
00438
00439 if (ACE_BIT_ENABLED (flags.ifr_flags, IFF_BROADCAST))
00440 {
00441 if (ACE_OS::ioctl (s,
00442 SIOCGIFBRDADDR,
00443 (char *) &if_req) == -1)
00444 ACE_ERROR ((LM_ERROR,
00445 ACE_LIB_TEXT ("%p\n"),
00446 ACE_LIB_TEXT ("ACE_Sock_Connect::get_bcast_addr:")
00447 ACE_LIB_TEXT ("ioctl (get broadaddr)")));
00448 else
00449 {
00450 ACE_OS::memcpy (ACE_reinterpret_cast(sockaddr_in *, &ip_addr),
00451 ACE_reinterpret_cast(sockaddr_in *, &if_req.ifr_broadaddr),
00452 sizeof if_req.ifr_broadaddr);
00453
00454 ACE_OS::memcpy ((void *) &host_addr,
00455 (void *) &ip_addr.sin_addr,
00456 sizeof host_addr);
00457
00458 if (handle == ACE_INVALID_HANDLE)
00459 ACE_OS::close (s);
00460
00461 bcast_addr = host_addr;
00462 return 0;
00463 }
00464 }
00465 else
00466 ACE_ERROR ((LM_ERROR,
00467 ACE_LIB_TEXT ("%p\n"),
00468 ACE_LIB_TEXT ("ACE_Sock_Connect::get_bcast_addr:")
00469 ACE_LIB_TEXT ("Broadcast is not enable for this interface.")));
00470
00471 if (handle == ACE_INVALID_HANDLE)
00472 ACE_OS::close (s);
00473
00474 bcast_addr = host_addr;
00475 return 0;
00476 }
00477
00478 return 0;
00479 #else
00480 ACE_UNUSED_ARG (handle);
00481 ACE_UNUSED_ARG (host_addr);
00482 ACE_UNUSED_ARG (host_name);
00483 bcast_addr = (ACE_UINT32 (INADDR_BROADCAST));
00484 return 0;
00485 #endif
00486 }
00487
00488
00489
00490
00491
00492 int
00493 ACE_Sock_Connect::get_ip_interfaces (size_t &count,
00494 ACE_INET_Addr *&addrs)
00495 {
00496 ACE_TRACE ("ACE_Sock_Connect::get_ip_interfaces");
00497
00498 count = 0;
00499 addrs = 0;
00500
00501 #if defined (ACE_WIN32)
00502
00503
00504 # if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
00505 int i, n_interfaces, status;
00506
00507 INTERFACE_INFO info[64];
00508 SOCKET sock;
00509
00510
00511 sock = socket (AF_INET, SOCK_DGRAM, 0);
00512 if (sock == INVALID_SOCKET)
00513 return -1;
00514
00515 DWORD bytes;
00516 status = WSAIoctl(sock,
00517 SIO_GET_INTERFACE_LIST,
00518 0,
00519 0,
00520 info,
00521 sizeof(info),
00522 &bytes,
00523 0,
00524 0);
00525 closesocket (sock);
00526 if (status == SOCKET_ERROR)
00527 return -1;
00528
00529 n_interfaces = bytes / sizeof(INTERFACE_INFO);
00530 if (n_interfaces == 0)
00531 return 0;
00532
00533 ACE_NEW_RETURN (addrs,
00534 ACE_INET_Addr[n_interfaces],
00535 -1);
00536
00537
00538
00539 for (count = 0, i = 0; i < n_interfaces; i++)
00540 {
00541 LPINTERFACE_INFO lpii;
00542 struct sockaddr_in *addrp;
00543
00544 lpii = &info[i];
00545 if (!(lpii->iiFlags & IFF_UP))
00546 continue;
00547
00548
00549 addrp = ACE_reinterpret_cast(struct sockaddr_in *, &(lpii->iiAddress));
00550 if (addrp->sin_addr.s_addr == INADDR_ANY)
00551 continue;
00552
00553
00554 addrs[count].set(addrp, sizeof(sockaddr_in));
00555 ++count;
00556 }
00557
00558 if (count == 0)
00559 {
00560 delete [] addrs;
00561 addrs = 0;
00562 }
00563
00564 return 0;
00565
00566 #else
00567
00568
00569
00570
00571
00572 # if defined (ACE_HAS_PHARLAP)
00573 # if !defined (ACE_HAS_PHARLAP_RT)
00574 ACE_NOTSUP_RETURN (-1);
00575 # endif
00576
00577
00578
00579
00580
00581
00582 const size_t ACE_MAX_ETS_DEVICES = 64;
00583 DEVHANDLE ip_dev[ACE_MAX_ETS_DEVICES];
00584 EK_TCPIPCFG *devp;
00585 size_t i, j;
00586 ACE_TCHAR dev_name[16];
00587
00588 count = 0;
00589 for (i = 0; count < ACE_MAX_ETS_DEVICES; i++, ++count)
00590 {
00591
00592 ACE_OS::sprintf (dev_name,
00593 "ether%d",
00594 i);
00595 ip_dev[count] = EtsTCPGetDeviceHandle (dev_name);
00596 if (ip_dev[count] == 0)
00597 break;
00598 }
00599 for (i = 0; count < ACE_MAX_ETS_DEVICES; i++, ++count)
00600 {
00601
00602 ACE_OS::sprintf (dev_name,
00603 "sl%d",
00604 i);
00605 ip_dev[count] = EtsTCPGetDeviceHandle (dev_name);
00606 if (ip_dev[count] == 0)
00607 break;
00608 }
00609 for (i = 0; count < ACE_MAX_ETS_DEVICES; i++, ++count)
00610 {
00611
00612 ACE_OS::sprintf (dev_name,
00613 "ppp%d",
00614 i);
00615 ip_dev[count] = EtsTCPGetDeviceHandle (dev_name);
00616 if (ip_dev[count] == 0)
00617 break;
00618 }
00619
00620 if (count > 0)
00621 ACE_NEW_RETURN (addrs,
00622 ACE_INET_Addr[count],
00623 -1);
00624 else
00625 addrs = 0;
00626
00627 for (i = 0, j = 0; i < count; i++)
00628 {
00629 devp = EtsTCPGetDeviceCfg (ip_dev[i]);
00630 if (devp != 0)
00631 {
00632 addrs[j].set (0,
00633 devp->nwIPAddress,
00634 0);
00635 j++;
00636 }
00637
00638 }
00639
00640 count = j;
00641 if (count == 0 && addrs != 0)
00642 {
00643 delete [] addrs;
00644 addrs = 0;
00645 }
00646
00647 return 0;
00648
00649 # else
00650
00651 # if defined (ACE_HAS_WINCE)
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662 IP_ADAPTER_INFO* adapterInfo = 0;
00663 ULONG sz = 0;
00664 DWORD result = ::GetAdaptersInfo(adapterInfo, &sz);
00665
00666 while (result != ERROR_SUCCESS)
00667 {
00668 switch (result)
00669 {
00670 case ERROR_BUFFER_OVERFLOW:
00671 adapterInfo = (PIP_ADAPTER_INFO)(new char[sz]);
00672
00673 result = ::GetAdaptersInfo(adapterInfo, &sz);
00674 if (result == ERROR_SUCCESS) {
00675 const char* invalid_IP = "0.0.0.0";
00676
00677
00678 {
00679 IP_ADAPTER_INFO* tempAdapterInfo = adapterInfo;
00680 int n_interfaces = 0;
00681 while (tempAdapterInfo != 0) {
00682 IP_ADDR_STRING* addr = &tempAdapterInfo->IpAddressList;
00683 while (addr != 0) {
00684 if (ACE_OS::strcmp(addr->IpAddress.String, invalid_IP) != 0) {
00685
00686 ++n_interfaces;
00687 }
00688 addr = addr->Next;
00689 }
00690 tempAdapterInfo = tempAdapterInfo->Next;
00691 }
00692 if (n_interfaces == 0) {
00693 ACE_ERROR_RETURN ((LM_ERROR,
00694 ACE_LIB_TEXT ("%p\nACE_Sock_Connect::get_ip_interfaces - ")
00695 ACE_LIB_TEXT ("No adapter found.")),
00696 -1);
00697 }
00698
00699 ACE_NEW_RETURN (addrs, ACE_INET_Addr[n_interfaces], -2);
00700 }
00701
00702
00703 while (adapterInfo != 0) {
00704 IP_ADDR_STRING* addr = &adapterInfo->IpAddressList;
00705 while (addr != 0) {
00706 if (ACE_OS::strcmp(addr->IpAddress.String, invalid_IP) != 0) {
00707 addrs[count++] = ACE_INET_Addr((u_short) 0, addr->IpAddress.String);
00708 }
00709 addr = addr->Next;
00710 }
00711 adapterInfo = adapterInfo->Next;
00712 }
00713 }
00714
00715 break;
00716
00717 case ERROR_NOT_SUPPORTED:
00718 ACE_ERROR_RETURN ((LM_ERROR,
00719 ACE_LIB_TEXT ("%p\nACE_Sock_Connect::get_ip_interfaces - ")
00720 ACE_LIB_TEXT ("This version of WinCE does not support GetAdapterInfo.")),
00721 -1);
00722 break;
00723
00724 case ERROR_NO_DATA:
00725 ACE_ERROR_RETURN ((LM_ERROR,
00726 ACE_LIB_TEXT ("%p\nACE_Sock_Connect::get_ip_interfaces - ")
00727 ACE_LIB_TEXT ("No network adapter installed.")),
00728 -1);
00729 break;
00730
00731 case ERROR_INVALID_PARAMETER:
00732 ACE_ERROR_RETURN ((LM_ERROR,
00733 ACE_LIB_TEXT ("%p\nACE_Sock_Connect::get_ip_interfaces - ")
00734 ACE_LIB_TEXT ("Invalid parameter.")),
00735 -1);
00736 break;
00737
00738 default:
00739 ACE_ERROR_RETURN ((LM_ERROR,
00740 ACE_LIB_TEXT ("%p\nACE_Sock_Connect::get_ip_interfaces - ")
00741 ACE_LIB_TEXT ("Adapter info access permission denied.")),
00742 -1);
00743 break;
00744 }
00745 }
00746
00747 delete [] adapterInfo;
00748 return 0;
00749
00750 # endif // ACE_HAS_WINCE
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764 const ACE_TCHAR *BASE_KEY1;
00765
00766
00767
00768
00769 const ACE_TCHAR *KEY1_NAME_ID;
00770
00771
00772
00773
00774 unsigned int s_offset;
00775 const ACE_TCHAR *PREFFIX_KEY2;
00776 const ACE_TCHAR *SUFFIX_KEY2;
00777
00778
00779
00780 int use_subkeys;
00781
00782
00783
00784
00785
00786 const ACE_TCHAR *IPADDR_NAME_ID[3] = {
00787 ACE_LIB_TEXT ("IPAddress"), 0, 0
00788 };
00789
00790
00791 const ACE_TCHAR *INVALID_TCPIP_DEVICE_ADDR = ACE_LIB_TEXT ("0.0.0.0");
00792
00793 ACE_WINDOWS_VERSION winver = get_windows_version();
00794
00795 switch (winver)
00796 {
00797 case ACE_WINDOWS_IS_WINNT:
00798 PREFFIX_KEY2 = ACE_LIB_TEXT ("SYSTEM\\CurrentControlSet\\Services\\");
00799 BASE_KEY1 =
00800 ACE_LIB_TEXT ("SYSTEM\\CurrentControlSet\\Services")
00801 ACE_LIB_TEXT ("\\Tcpip\\Linkage");
00802 SUFFIX_KEY2 = ACE_LIB_TEXT ("\\Parameters\\Tcpip");
00803 KEY1_NAME_ID = ACE_LIB_TEXT ("Bind");
00804 s_offset = 8;
00805 use_subkeys = 0;
00806 break;
00807
00808 case ACE_WINDOWS_IS_WIN2K:
00809 BASE_KEY1 =
00810 ACE_LIB_TEXT ("SYSTEM\\CurrentControlSet\\Services")
00811 ACE_LIB_TEXT ("\\Tcpip\\Parameters\\Interfaces\\");
00812 PREFFIX_KEY2 = BASE_KEY1;
00813 SUFFIX_KEY2 = ACE_LIB_TEXT ("");
00814 KEY1_NAME_ID = 0;
00815 s_offset = 0;
00816 use_subkeys = 1;
00817
00818 IPADDR_NAME_ID[1] = ACE_LIB_TEXT ("DhcpIPAddress");
00819 break;
00820
00821
00822
00823 # if !defined(ACE_HAS_WINNT4) || (ACE_HAS_WINNT4 == 0)
00824 case ACE_WINDOWS_IS_WIN95:
00825 case ACE_WINDOWS_IS_WIN98:
00826 case ACE_WINDOWS_IS_WINME:
00827 PREFFIX_KEY2 =
00828 ACE_LIB_TEXT ("SYSTEM\\CurrentControlSet\\Services\\Class\\");
00829 BASE_KEY1 = ACE_LIB_TEXT ("Enum\\Network\\MSTCP");
00830 SUFFIX_KEY2 = ACE_LIB_TEXT ("");
00831 KEY1_NAME_ID = ACE_LIB_TEXT ("Driver");
00832 use_subkeys = 1;
00833 s_offset = 0;
00834 break;
00835 # endif
00836
00837 default:
00838 return -1;
00839 }
00840
00841 ACE_TCHAR raw_buffer[ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 1];
00842 DWORD raw_buflen = ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 1;
00843
00844 if (KEY1_NAME_ID == 0)
00845 {
00846 if (::get_reg_subkeys (BASE_KEY1,
00847 raw_buffer,
00848 raw_buflen))
00849 return -1;
00850 }
00851 else
00852 {
00853 if (::get_reg_value (BASE_KEY1,
00854 KEY1_NAME_ID,
00855 raw_buffer,
00856 raw_buflen,
00857 use_subkeys))
00858 return -1;
00859 }
00860
00861
00862 ACE_Tokenizer dev_names (raw_buffer);
00863 dev_names.delimiter (ACE_LIB_TEXT ('\0'));
00864 int n_interfaces = 0;
00865
00866
00867 while (dev_names.next () != 0)
00868 n_interfaces ++;
00869
00870
00871 if (n_interfaces == 0)
00872 return 0;
00873
00874 ACE_NEW_RETURN (addrs,
00875 ACE_INET_Addr[n_interfaces],
00876 -2);
00877
00878 ACE_TCHAR buffer[ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 1];
00879 DWORD buf_len = ACE_MAX_FULLY_QUALIFIED_NAME_LEN + 1;
00880
00881 count = 0;
00882 for (int i = 0; i < n_interfaces; i++)
00883 {
00884 for (const ACE_TCHAR **ipaddr_name_id = IPADDR_NAME_ID;
00885 *ipaddr_name_id != 0;
00886 ++ipaddr_name_id)
00887 {
00888
00889 ACE_TString ifdevkey (PREFFIX_KEY2);
00890 ACE_TString the_dev = dev_names.next ();
00891
00892 if (the_dev.length() < s_offset)
00893 {
00894 return -3;
00895 }
00896
00897
00898 the_dev = the_dev.substring (s_offset);
00899
00900 ifdevkey += the_dev;
00901 ifdevkey += SUFFIX_KEY2;
00902
00903
00904
00905 buf_len = sizeof (buffer);
00906 if (get_reg_value (ifdevkey.fast_rep (),
00907 *ipaddr_name_id,
00908 buffer,
00909 buf_len))
00910 continue;
00911
00912 if (ACE_OS::strcmp (buffer,
00913 INVALID_TCPIP_DEVICE_ADDR) == 0)
00914 continue;
00915
00916
00917 addrs[count++] =
00918 ACE_INET_Addr ((u_short) 0, buffer);
00919 }
00920 }
00921
00922 return 0;
00923 # endif
00924 # endif
00925
00926 #elif defined (ACE_HAS_GETIFADDRS)
00927
00928
00929 struct ifaddrs *ifap;
00930 struct ifaddrs *p_if;
00931
00932 if (::getifaddrs (&ifap) != 0)
00933 return -1;
00934
00935
00936 size_t num_ifs = 0;
00937 for (p_if = ifap; p_if != 0; p_if = p_if->ifa_next)
00938 ++num_ifs;
00939
00940
00941 ACE_NEW_RETURN (addrs,
00942 ACE_INET_Addr[num_ifs],
00943 -1);
00944
00945
00946
00947
00948
00949 count = 0;
00950
00951 for (p_if = ifap;
00952 p_if != 0;
00953 p_if = p_if->ifa_next)
00954 {
00955 if (p_if->ifa_addr &&
00956 p_if->ifa_addr->sa_family == AF_INET)
00957 {
00958 struct sockaddr_in *addr =
00959 ACE_reinterpret_cast(sockaddr_in *, p_if->ifa_addr);
00960
00961
00962
00963 if (addr->sin_addr.s_addr != 0)
00964 {
00965 addrs[count].set ((u_short) 0,
00966 addr->sin_addr.s_addr,
00967 0);
00968 count++;
00969 }
00970 }
00971 }
00972
00973 ::freeifaddrs (ifap);
00974
00975 return 0;
00976
00977 #elif defined (__unix) || defined (__unix__) || defined (__Lynx__) || defined (_AIX)
00978
00979
00980 size_t num_ifs;
00981
00982
00983 ACE_HANDLE handle = get_handle();
00984
00985 if (handle == ACE_INVALID_HANDLE)
00986 ACE_ERROR_RETURN ((LM_ERROR,
00987 ACE_LIB_TEXT ("%p\n"),
00988 ACE_LIB_TEXT ("ACE_Sock_Connect::get_ip_interfaces:open")),
00989 -1);
00990 if (ACE_Sock_Connect::count_interfaces (handle, num_ifs))
00991 {
00992 ACE_OS::close (handle);
00993 return -1;
00994 }
00995
00996
00997
00998 ++num_ifs;
00999
01000 struct ifreq *ifs = 0;
01001 ACE_NEW_RETURN (ifs,
01002 struct ifreq[num_ifs],
01003 -1);
01004 ACE_OS::memset (ifs, 0, num_ifs * sizeof (struct ifreq));
01005
01006 ACE_Auto_Array_Ptr<struct ifreq> p_ifs (ifs);
01007
01008 if (p_ifs.get() == 0)
01009 {
01010 ACE_OS::close (handle);
01011 errno = ENOMEM;
01012 return -1;
01013 }
01014
01015 struct ifconf ifcfg;
01016 ACE_OS::memset (&ifcfg, 0, sizeof (struct ifconf));
01017 ifcfg.ifc_req = p_ifs.get ();
01018 ifcfg.ifc_len = num_ifs * sizeof (struct ifreq);
01019
01020 #if defined (AIX)
01021 int cmd = CSIOCGIFCONF;
01022 #else
01023 int cmd = SIOCGIFCONF;
01024 #endif
01025 if (ACE_OS::ioctl (handle,
01026 cmd,
01027 (caddr_t) &ifcfg) == -1)
01028 {
01029 ACE_OS::close (handle);
01030 ACE_ERROR_RETURN ((LM_ERROR,
01031 ACE_LIB_TEXT ("%p\n"),
01032 ACE_LIB_TEXT ("get_ip_interfaces:")
01033 ACE_LIB_TEXT ("ioctl - SIOCGIFCONF failed")),
01034 -1);
01035 }
01036
01037 ACE_OS::close (handle);
01038
01039
01040
01041 ACE_NEW_RETURN (addrs,
01042 ACE_INET_Addr[num_ifs],
01043 -1);
01044
01045 struct ifreq *pcur = p_ifs.get ();
01046
01047
01048
01049
01050 count = 0;
01051
01052 for (size_t i = 0;
01053 i < num_ifs;
01054 i++)
01055 {
01056 if (pcur->ifr_addr.sa_family == AF_INET)
01057 {
01058 #if !defined(_UNICOS)
01059 struct sockaddr_in *addr =
01060 ACE_reinterpret_cast(sockaddr_in *, &pcur->ifr_addr);
01061
01062
01063
01064 if (addr->sin_addr.s_addr != 0)
01065 {
01066 addrs[count].set ((u_short) 0,
01067 addr->sin_addr.s_addr,
01068 0);
01069 count++;
01070 }
01071 #else
01072
01073
01074 struct sockaddr_in inAddr;
01075
01076 inAddr.sin_len = pcur->ifr_addr.sa_len;
01077 inAddr.sin_family = pcur->ifr_addr.sa_family;
01078 memcpy((void *)&(inAddr.sin_addr),
01079 (const void *)&(pcur->ifr_addr.sa_data[8]),
01080 sizeof(struct in_addr));
01081
01082 if (inAddr.sin_addr.s_addr != 0)
01083 {
01084 addrs[count].set(&inAddr, sizeof(struct sockaddr_in));
01085 count++;
01086 }
01087 #endif
01088 }
01089
01090 #if !defined (CHORUS_4) && !defined (__FreeBSD__)
01091 pcur++;
01092 #else
01093 if (pcur->ifr_addr.sa_len <= sizeof (struct sockaddr))
01094 {
01095 pcur++;
01096 }
01097 else
01098 {
01099 pcur = (struct ifreq *)
01100 (pcur->ifr_addr.sa_len + (caddr_t) &pcur->ifr_addr);
01101 }
01102 #endif
01103 }
01104 return 0;
01105 #elif defined (VXWORKS)
01106 count = 0;
01107
01108 for (struct in_ifaddr* ia = in_ifaddr; ia != 0; ia = ia->ia_next)
01109 {
01110 ++count;
01111 }
01112
01113
01114 ACE_NEW_RETURN (addrs,
01115 ACE_INET_Addr[count],
01116 -1);
01117 count = 0;
01118 for (struct in_ifaddr* ia = in_ifaddr; ia != 0; ia = ia->ia_next)
01119 {
01120 struct ifnet* ifp = ia->ia_ifa.ifa_ifp;
01121 if (ifp != 0)
01122 {
01123
01124 char interface[64];
01125 ACE_OS::sprintf(interface, "%s%d", ifp->if_name, ifp->if_unit);
01126
01127
01128 char address [INET_ADDR_LEN];
01129 STATUS status = ifAddrGet(interface, address);
01130
01131 if (status == OK)
01132 {
01133
01134
01135
01136
01137
01138 ACE_OS::strcat (address, ":");
01139 addrs[count].set (address);
01140 }
01141 else
01142 {
01143 ACE_ERROR_RETURN ((LM_ERROR,
01144 ACE_LIB_TEXT ("ACE::get_ip_interface failed\n"),
01145 ACE_LIB_TEXT ("Couldnt get the IP Address\n")),
01146 -1);
01147 }
01148 ++count;
01149 }
01150 }
01151 return 0;
01152 #else
01153 ACE_UNUSED_ARG (count);
01154 ACE_UNUSED_ARG (addrs);
01155 ACE_NOTSUP_RETURN (-1);;
01156 #endif
01157 }
01158
01159
01160
01161
01162
01163 int
01164 ACE_Sock_Connect::count_interfaces (ACE_HANDLE handle, size_t &how_many)
01165 {
01166 #if defined (sparc) && defined (SIOCGIFNUM)
01167 int tmp_how_many;
01168 if (ACE_OS::ioctl (handle,
01169 SIOCGIFNUM,
01170 (caddr_t) &tmp_how_many) == -1)
01171 ACE_ERROR_RETURN ((LM_ERROR,
01172 ACE_LIB_TEXT ("ACE_Sock_Connect::get_ip_interfaces:")
01173 ACE_LIB_TEXT ("ioctl - SIOCGIFNUM failed")),
01174 -1);
01175 how_many = (size_t) tmp_how_many;
01176 return 0;
01177 #elif defined (ACE_HAS_GETIFADDRS)
01178 ACE_UNUSED_ARG (handle);
01179
01180 struct ifaddrs *ifap;
01181 struct ifaddrs *p_if;
01182
01183 if (::getifaddrs (&ifap) != 0)
01184 return -1;
01185
01186
01187 size_t num_ifs = 0;
01188 for (p_if = ifap; p_if != 0; p_if = p_if->ifa_next)
01189 ++num_ifs;
01190
01191 ::freeifaddrs (ifap);
01192
01193 how_many = num_ifs;
01194 return 0;
01195 #elif defined (__unix) || defined (__unix__) || defined (__Lynx__) || defined (_AIX)
01196
01197
01198
01199
01200
01201
01202 const int MAX_IF = 50;
01203
01204
01205 int num_ifs = MAX_IF;
01206
01207 struct ifconf ifcfg;
01208 size_t ifreq_size = num_ifs * sizeof (struct ifreq);
01209 struct ifreq *p_ifs =
01210 (struct ifreq *) ACE_OS::malloc (ifreq_size);
01211
01212 if (!p_ifs)
01213 {
01214 errno = ENOMEM;
01215 return -1;
01216 }
01217
01218 ACE_OS::memset (p_ifs, 0, ifreq_size);
01219 ACE_OS::memset (&ifcfg, 0, sizeof (struct ifconf));
01220
01221 ifcfg.ifc_req = p_ifs;
01222 ifcfg.ifc_len = ifreq_size;
01223
01224 #if defined (AIX)
01225 int cmd = CSIOCGIFCONF;
01226 #else
01227 int cmd = SIOCGIFCONF;
01228 #endif
01229 if (ACE_OS::ioctl (handle,
01230 cmd,
01231 (caddr_t) &ifcfg) == -1)
01232 {
01233 ACE_OS::free (ifcfg.ifc_req);
01234 ACE_ERROR_RETURN ((LM_ERROR,
01235 ACE_LIB_TEXT ("count_interfaces:ioctl:")
01236 ACE_LIB_TEXT ("SIOCGIFCONF failed")),
01237 -1);
01238 }
01239
01240 int if_count = 0, i;
01241
01242
01243
01244 for (i = 0;
01245 i < num_ifs;
01246 i++)
01247 {
01248
01249 ifcfg.ifc_len -= sizeof (struct ifreq);
01250 if (ifcfg.ifc_len < 0)
01251 break;
01252
01253 if_count++;
01254 #if !defined (CHORUS_4) && !defined (__FreeBSD__)
01255 p_ifs++;
01256 #else
01257 if (p_ifs->ifr_addr.sa_len <= sizeof (struct sockaddr))
01258 {
01259 p_ifs++;
01260 }
01261 else
01262 {
01263 p_ifs = (struct ifreq *)
01264 (p_ifs->ifr_addr.sa_len + (caddr_t) &p_ifs->ifr_addr);
01265 }
01266 #endif
01267 }
01268
01269 ACE_OS::free (ifcfg.ifc_req);
01270 how_many = if_count;
01271 return 0;
01272 #else
01273 ACE_UNUSED_ARG (handle);
01274 ACE_UNUSED_ARG (how_many);
01275 ACE_NOTSUP_RETURN (-1);;
01276 #endif
01277 }
01278
01279
01280
01281 ACE_HANDLE
01282 ACE_Sock_Connect::get_handle (void)
01283 {
01284
01285 ACE_HANDLE handle = ACE_INVALID_HANDLE;
01286 #if defined (sparc) && ! defined (CHORUS)
01287 handle = ACE_OS::open ("/dev/udp", O_RDONLY);
01288 #elif defined (__unix) || defined (__unix__) || defined (__Lynx__) || defined (_AIX)
01289
01290
01291
01292 handle = ACE_OS::socket (PF_INET, SOCK_DGRAM, 0);
01293 #endif
01294 return handle;
01295 }
01296
01297
01298 int
01299 ACE_Sock_Connect::ipv6_enabled (void)
01300 {
01301 #if defined (ACE_HAS_IPV6)
01302 if (ACE_Sock_Connect::ipv6_enabled_ == -1)
01303 {
01304
01305 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
01306 *ACE_Static_Object_Lock::instance (), 0));
01307
01308 if (ACE_Sock_Connect::ipv6_enabled_ == -1)
01309 {
01310
01311
01312 ACE_HANDLE s = ACE_OS::socket (PF_INET6, SOCK_DGRAM, 0);
01313 if (s == ACE_INVALID_HANDLE)
01314 {
01315 ACE_Sock_Connect::ipv6_enabled_ = 0;
01316 }
01317 else
01318 {
01319 ACE_Sock_Connect::ipv6_enabled_ = 1;
01320 ACE_OS::closesocket (s);
01321 }
01322 }
01323 }
01324
01325 return ACE_Sock_Connect::ipv6_enabled_;
01326 #else
01327 return 0;
01328 #endif
01329 }
01330
01331 #if defined (__unix) || defined (__unix__) || defined (__Lynx__) || \
01332 defined (_AIX)
01333 # if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
01334 template class ACE_Auto_Array_Ptr<struct ifreq>;
01335 template class ACE_Auto_Basic_Array_Ptr<struct ifreq>;
01336 # elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
01337 #pragma instantiate ACE_Auto_Array_Ptr<struct ifreq>
01338 #pragma instantiate ACE_Auto_Basic_Array_Ptr<struct ifreq>
01339 # endif
01340 #endif