00001
00002
00003 #include "ace/Sock_Connect.h"
00004 #include "ace/INET_Addr.h"
00005 #include "ace/Log_Msg.h"
00006 #include "ace/Handle_Set.h"
00007 #include "ace/Auto_Ptr.h"
00008 #include "ace/SString.h"
00009 #include "ace/OS_Memory.h"
00010 #include "ace/OS_NS_stdio.h"
00011 #include "ace/ACE.h"
00012
00013 #if defined (sparc)
00014 # include "ace/OS_NS_fcntl.h"
00015 #endif // sparc
00016
00017 #include "ace/OS_NS_stdlib.h"
00018 #include "ace/OS_NS_string.h"
00019 #include "ace/OS_NS_sys_socket.h"
00020 #include "ace/OS_NS_netdb.h"
00021 #include "ace/OS_NS_unistd.h"
00022 #include "ace/os_include/net/os_if.h"
00023
00024 #if defined (ACE_HAS_IPV6)
00025 # include "ace/Guard_T.h"
00026 # include "ace/Recursive_Thread_Mutex.h"
00027 # if defined (_AIX)
00028 # include <netinet/in6_var.h>
00029 # endif
00030 #endif
00031
00032 # if defined (ACE_HAS_GETIFADDRS)
00033 # if defined (ACE_VXWORKS)
00034 # include <net/ifaddrs.h>
00035 # else
00036 # include <ifaddrs.h>
00037 # endif
00038 # endif
00039
00040 #if defined (ACE_VXWORKS) && (ACE_VXWORKS < 0x600)
00041 #include <inetLib.h>
00042 #include <netinet/in_var.h>
00043 #if defined (ACE_HAS_IPV6)
00044 #include <ifLib.h>
00045 extern "C" {
00046 extern struct in_ifaddr* in_ifaddr;
00047 extern LIST_HEAD(in_ifaddrhashhead, in_ifaddr) *in_ifaddrhashtbl;
00048 }
00049 #endif
00050 #include "ace/OS_NS_stdio.h"
00051 #endif
00052
00053 #if defined (ACE_VXWORKS) && ((ACE_VXWORKS >= 0x630) && (ACE_VXWORKS <= 0x670)) && defined (__RTP__) && defined (ACE_HAS_IPV6)
00054 const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
00055 const struct in6_addr in6addr_nodelocal_allnodes = IN6ADDR_NODELOCAL_ALLNODES_INIT;
00056 const struct in6_addr in6addr_linklocal_allnodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT;
00057 const struct in6_addr in6addr_linklocal_allrouters = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT;
00058 #endif
00059
00060 #if defined (ACE_HAS_WINCE)
00061 #include <iphlpapi.h>
00062 # if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) && (_WIN32_WCE < 0x600) && defined (ACE_HAS_IPV6)
00063 # include <ws2tcpip.h>
00064 const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
00065 const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
00066 # endif
00067 #endif // ACE_HAS_WINCE
00068
00069 #if defined (ACE_WIN32) && defined (ACE_HAS_PHARLAP)
00070 # include "ace/OS_NS_stdio.h"
00071 #endif
00072
00073 #if defined (ACE_HAS_IPV6)
00074
00075
00076
00077
00078 # if defined (SIOCGLIFCONF)
00079 # define SIOCGIFCONF_CMD SIOCGLIFCONF
00080 # if defined (__hpux)
00081 # define IFREQ if_laddrreq
00082 # define IFCONF if_laddrconf
00083 # define IFC_REQ iflc_req
00084 # define IFC_LEN iflc_len
00085 # define IFC_BUF iflc_buf
00086 # define IFR_ADDR iflr_addr
00087 # define IFR_NAME iflr_name
00088 # define IFR_FLAGS iflr_flags
00089 # undef SETFAMILY
00090 # define SA_FAMILY sa_family
00091 # else
00092 # define IFREQ lifreq
00093 # define IFCONF lifconf
00094 # define IFC_REQ lifc_req
00095 # define IFC_LEN lifc_len
00096 # define IFC_BUF lifc_buf
00097 # define IFR_ADDR lifr_addr
00098 # define IFR_NAME lifr_name
00099 # define IFR_FLAGS lifr_flags
00100 # define SETFAMILY
00101 # define IFC_FAMILY lifc_family
00102 # define IFC_FLAGS lifc_flags
00103 # define SA_FAMILY ss_family
00104 # endif
00105 # else
00106 # define SIOCGIFCONF_CMD SIOCGIFCONF
00107 # define IFREQ ifreq
00108 # define IFCONF ifconf
00109 # define IFC_REQ ifc_req
00110 # define IFC_LEN ifc_len
00111 # define IFC_BUF ifc_buf
00112 # define IFR_ADDR ifr_addr
00113 # define IFR_NAME ifr_name
00114 # define IFR_FLAGS ifr_flags
00115 # undef SETFAMILY
00116 # define SA_FAMILY sa_family
00117 # endif
00118
00119 # if defined (ACE_HAS_THREADS)
00120 # include "ace/Object_Manager.h"
00121 # endif
00122
00123 namespace
00124 {
00125
00126
00127
00128
00129 int ace_ipv4_enabled = -1;
00130
00131
00132 int ace_ipv6_enabled = -1;
00133
00134 }
00135 #else
00136 # define SIOCGIFCONF_CMD SIOCGIFCONF
00137 # define IFREQ ifreq
00138 # define IFCONF ifconf
00139 # define IFC_REQ ifc_req
00140 # define IFC_LEN ifc_len
00141 # define IFC_BUF ifc_buf
00142 # define IFR_ADDR ifr_addr
00143 # define IFR_NAME ifr_name
00144 # define IFR_FLAGS ifr_flags
00145 # undef SETFAMILY
00146 # define SA_FAMILY sa_family
00147 #endif
00148
00149
00150
00151
00152
00153
00154
00155 #if defined (AIX) && defined (__IBMCPP__) && (__IBMCPP__ >= 500) && (__IBMCPP__ < 700)
00156 static ACE_Auto_Array_Ptr<sockaddr> force_compiler_to_include_socket_h;
00157 #endif
00158
00159
00160 ACE_RCSID (ace,
00161 Sock_Connect,
00162 "$Id: Sock_Connect.cpp 90399 2010-06-03 21:35:20Z mesnier_p $")
00163
00164
00165 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00166
00167
00168
00169 int
00170 ACE::bind_port (ACE_HANDLE handle, ACE_UINT32 ip_addr, int address_family)
00171 {
00172 ACE_TRACE ("ACE::bind_port");
00173
00174 ACE_INET_Addr addr;
00175
00176 #if defined (ACE_HAS_IPV6)
00177 if (address_family != PF_INET6)
00178
00179
00180 #else
00181 ACE_UNUSED_ARG (address_family);
00182 #endif
00183 addr = ACE_INET_Addr ((u_short)0, ip_addr);
00184 #if defined (ACE_HAS_IPV6)
00185 else if (ip_addr != INADDR_ANY)
00186
00187
00188 addr.set ((u_short)0, ip_addr, 1, 1);
00189 #endif
00190
00191
00192 return ACE_OS::bind (handle,
00193 (sockaddr*)addr.get_addr(),
00194 addr.get_size());
00195 }
00196
00197 int
00198 ACE::get_bcast_addr (ACE_UINT32 &bcast_addr,
00199 const ACE_TCHAR *host_name,
00200 ACE_UINT32 host_addr,
00201 ACE_HANDLE handle)
00202 {
00203 ACE_TRACE ("ACE::get_bcast_addr");
00204
00205 #if defined (ACE_LACKS_GET_BCAST_ADDR)
00206 ACE_UNUSED_ARG (bcast_addr);
00207 ACE_UNUSED_ARG (host_name);
00208 ACE_UNUSED_ARG (host_addr);
00209 ACE_UNUSED_ARG (handle);
00210 ACE_NOTSUP_RETURN (-1);
00211 #elif !defined(ACE_WIN32) && !defined(__INTERIX)
00212 ACE_HANDLE s = handle;
00213
00214 if (s == ACE_INVALID_HANDLE)
00215 s = ACE_OS::socket (AF_INET, SOCK_STREAM, 0);
00216
00217 if (s == ACE_INVALID_HANDLE)
00218 ACE_ERROR_RETURN ((LM_ERROR,
00219 ACE_TEXT ("%p\n"),
00220 ACE_TEXT ("ACE_OS::socket")),
00221 -1);
00222
00223 struct ifconf ifc;
00224 char buf[BUFSIZ];
00225
00226 ifc.ifc_len = sizeof buf;
00227 ifc.ifc_buf = buf;
00228
00229
00230
00231 if (ACE_OS::ioctl (s, SIOCGIFCONF_CMD, (char *) &ifc) == -1)
00232 ACE_ERROR_RETURN ((LM_ERROR,
00233 ACE_TEXT ("%p\n"),
00234 ACE_TEXT ("ACE::get_bcast_addr:")
00235 ACE_TEXT ("ioctl (get interface configuration)")),
00236 -1);
00237
00238 struct ifreq *ifr = ifc.ifc_req;
00239
00240 struct sockaddr_in ip_addr;
00241
00242
00243 if (host_name)
00244 {
00245 hostent *hp = ACE_OS::gethostbyname (ACE_TEXT_ALWAYS_CHAR (host_name));
00246
00247 if (hp == 0)
00248 return -1;
00249 else
00250 #if !defined(_UNICOS)
00251 ACE_OS::memcpy ((char *) &ip_addr.sin_addr.s_addr,
00252 (char *) hp->h_addr,
00253 hp->h_length);
00254 #else
00255 {
00256 ACE_UINT64 haddr;
00257 char * haddrp = (char *) &haddr;
00258 ACE_OS::memcpy(haddrp,(char *) hp->h_addr,hp->h_length);
00259 ip_addr.sin_addr.s_addr = haddr;
00260 }
00261 #endif
00262 }
00263 else
00264 {
00265 ACE_OS::memset ((void *) &ip_addr, 0, sizeof ip_addr);
00266 #if !defined(_UNICOS)
00267 ACE_OS::memcpy ((void *) &ip_addr.sin_addr,
00268 (void*) &host_addr,
00269 sizeof ip_addr.sin_addr);
00270 #else
00271 ip_addr.sin_addr.s_addr = host_addr;
00272 #endif
00273 }
00274
00275 #if !defined(AIX) && !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) && !defined (__Lynx__)
00276 for (int n = ifc.ifc_len / sizeof (struct ifreq) ; n > 0;
00277 n--, ifr++)
00278 #else
00279
00280 for (int nbytes = ifc.ifc_len; nbytes >= (int) sizeof (struct ifreq) &&
00281 ((ifr->ifr_addr.sa_len > sizeof (struct sockaddr)) ?
00282 (nbytes >= (int) sizeof (ifr->ifr_name) + ifr->ifr_addr.sa_len) : 1);
00283 ((ifr->ifr_addr.sa_len > sizeof (struct sockaddr)) ?
00284 (nbytes -= sizeof (ifr->ifr_name) + ifr->ifr_addr.sa_len,
00285 ifr = (struct ifreq *)
00286 ((caddr_t) &ifr->ifr_addr + ifr->ifr_addr.sa_len)) :
00287 (nbytes -= sizeof (struct ifreq), ifr++)))
00288 #endif
00289 {
00290 struct sockaddr_in if_addr;
00291
00292
00293 ACE_OS::memcpy (&if_addr,
00294 &ifr->ifr_addr,
00295 sizeof if_addr);
00296
00297 if (ip_addr.sin_addr.s_addr != if_addr.sin_addr.s_addr)
00298 continue;
00299
00300 if (ifr->ifr_addr.sa_family != AF_INET)
00301 {
00302 ACE_ERROR ((LM_ERROR,
00303 ACE_TEXT ("%p\n"),
00304 ACE_TEXT ("ACE::get_bcast_addr:")
00305 ACE_TEXT ("Not AF_INET")));
00306 continue;
00307 }
00308
00309 struct ifreq flags = *ifr;
00310 struct ifreq if_req = *ifr;
00311
00312 if (ACE_OS::ioctl (s, SIOCGIFFLAGS, (char *) &flags) == -1)
00313 {
00314 ACE_ERROR ((LM_ERROR,
00315 ACE_TEXT ("%p\n"),
00316 ACE_TEXT ("ACE::get_bcast_addr:")
00317 ACE_TEXT (" ioctl (get interface flags)")));
00318 continue;
00319 }
00320
00321 if (ACE_BIT_DISABLED (flags.ifr_flags, IFF_UP))
00322 {
00323 ACE_ERROR ((LM_ERROR,
00324 ACE_TEXT ("%p\n"),
00325 ACE_TEXT ("ACE::get_bcast_addr:")
00326 ACE_TEXT ("Network interface is not up")));
00327 continue;
00328 }
00329
00330 if (ACE_BIT_ENABLED (flags.ifr_flags, IFF_LOOPBACK))
00331 continue;
00332
00333 if (ACE_BIT_ENABLED (flags.ifr_flags, IFF_BROADCAST))
00334 {
00335 if (ACE_OS::ioctl (s,
00336 SIOCGIFBRDADDR,
00337 (char *) &if_req) == -1)
00338 ACE_ERROR ((LM_ERROR,
00339 ACE_TEXT ("%p\n"),
00340 ACE_TEXT ("ACE::get_bcast_addr:")
00341 ACE_TEXT ("ioctl (get broadaddr)")));
00342 else
00343 {
00344 ACE_OS::memcpy (&ip_addr,
00345 &if_req.ifr_broadaddr,
00346 sizeof if_req.ifr_broadaddr);
00347
00348 ACE_OS::memcpy ((void *) &host_addr,
00349 (void *) &ip_addr.sin_addr,
00350 sizeof host_addr);
00351
00352 if (handle == ACE_INVALID_HANDLE)
00353 ACE_OS::close (s);
00354
00355 bcast_addr = host_addr;
00356 return 0;
00357 }
00358 }
00359 else
00360 ACE_ERROR ((LM_ERROR,
00361 ACE_TEXT ("%p\n"),
00362 ACE_TEXT ("ACE::get_bcast_addr:")
00363 ACE_TEXT ("Broadcast is not enable for this interface.")));
00364
00365 if (handle == ACE_INVALID_HANDLE)
00366 ACE_OS::close (s);
00367
00368 bcast_addr = host_addr;
00369 return 0;
00370 }
00371
00372 return 0;
00373 #else
00374 ACE_UNUSED_ARG (handle);
00375 ACE_UNUSED_ARG (host_addr);
00376 ACE_UNUSED_ARG (host_name);
00377 bcast_addr = (ACE_UINT32 (INADDR_BROADCAST));
00378 return 0;
00379 #endif
00380 }
00381
00382 int
00383 ACE::get_fqdn (ACE_INET_Addr const & addr,
00384 char hostname[],
00385 size_t len)
00386 {
00387 int h_error;
00388 hostent hentry;
00389 ACE_HOSTENT_DATA buf;
00390
00391 char * ip_addr = 0;
00392 int ip_addr_size = 0;
00393 if (addr.get_type () == AF_INET)
00394 {
00395 sockaddr_in * const sock_addr =
00396 reinterpret_cast<sockaddr_in *> (addr.get_addr ());
00397 ip_addr_size = sizeof sock_addr->sin_addr;
00398 ip_addr = (char*) &sock_addr->sin_addr;
00399 }
00400 #ifdef ACE_HAS_IPV6
00401 else
00402 {
00403 sockaddr_in6 * sock_addr =
00404 reinterpret_cast<sockaddr_in6 *> (addr.get_addr ());
00405
00406 ip_addr_size = sizeof sock_addr->sin6_addr;
00407 ip_addr = (char*) &sock_addr->sin6_addr;
00408 }
00409 #endif
00410
00411
00412 hostent * const hp = ACE_OS::gethostbyaddr_r (ip_addr,
00413 ip_addr_size,
00414 addr.get_type (),
00415 &hentry,
00416 buf,
00417 &h_error);
00418
00419
00420
00421 if (hp == 0 || hp->h_name == 0)
00422 return -1;
00423
00424 if (ACE::debug())
00425 ACE_DEBUG ((LM_DEBUG,
00426 ACE_TEXT ("(%P|%t) - ACE::get_fqdn, ")
00427 ACE_TEXT ("canonical host name is %C\n"),
00428 hp->h_name));
00429
00430
00431 if (!ACE_OS::strchr(hp->h_name, '.'))
00432 {
00433
00434 char** p;
00435
00436 char** q;
00437
00438
00439
00440 for (p = hp->h_addr_list; *p != 0; ++p)
00441 {
00442 for (q = hp->h_aliases; *q != 0; ++q)
00443 {
00444 if (ACE_OS::strchr(*q, '.'))
00445 {
00446
00447 if (ACE_OS::strlen (*q) >= len)
00448
00449
00450
00451
00452
00453
00454
00455 continue;
00456
00457 if (ACE::debug ())
00458 ACE_DEBUG ((LM_DEBUG,
00459 ACE_TEXT ("(%P|%t) - ACE::get_fqdn, ")
00460 ACE_TEXT ("found fqdn within alias as %C\n"),
00461 *q));
00462 ACE_OS::strcpy (hostname, *q);
00463
00464 return 0;
00465 }
00466 }
00467 }
00468 }
00469
00470
00471
00472
00473 if (ACE_OS::strlen (hp->h_name) >= len)
00474 {
00475
00476
00477 return -2;
00478 }
00479 else
00480 {
00481 ACE_OS::strcpy (hostname, hp->h_name);
00482 }
00483
00484 return 0;
00485 }
00486
00487 #if defined (ACE_WIN32)
00488
00489 static int
00490 get_ip_interfaces_win32 (size_t &count,
00491 ACE_INET_Addr *&addrs)
00492 {
00493 # if defined (ACE_HAS_WINCE) && defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
00494
00495
00496
00497 PIP_ADAPTER_ADDRESSES AdapterAddresses = 0;
00498 ULONG OutBufferLength = 0;
00499 ULONG RetVal = 0;
00500 unsigned char *octet_buffer = 0;
00501
00502 RetVal =
00503 GetAdaptersAddresses(AF_UNSPEC,
00504 0,
00505 0,
00506 AdapterAddresses,
00507 &OutBufferLength);
00508
00509 if (RetVal != ERROR_BUFFER_OVERFLOW)
00510 {
00511 return -1;
00512 }
00513
00514 ACE_NEW_RETURN (octet_buffer, unsigned char[OutBufferLength],-1);
00515 AdapterAddresses = (IP_ADAPTER_ADDRESSES *)octet_buffer;
00516
00517 RetVal =
00518 GetAdaptersAddresses(AF_UNSPEC,
00519 0,
00520 0,
00521 AdapterAddresses,
00522 &OutBufferLength);
00523
00524 if (RetVal != NO_ERROR)
00525 {
00526 delete [] octet_buffer;
00527 return -1;
00528 }
00529
00530
00531 PIP_ADAPTER_ADDRESSES AdapterList = AdapterAddresses;
00532 while (AdapterList)
00533 {
00534 if (AdapterList->OperStatus == IfOperStatusUp)
00535 {
00536 if (AdapterList->IfIndex != 0)
00537 ++count;
00538 if (AdapterList->Ipv6IfIndex != 0)
00539 ++count;
00540 }
00541 AdapterList = AdapterList->Next;
00542 }
00543
00544 AdapterList = AdapterAddresses;
00545
00546 ACE_NEW_RETURN (addrs, ACE_INET_Addr[count],-1);
00547 count = 0;
00548 for (AdapterList = AdapterAddresses;
00549 AdapterList != 0;
00550 AdapterList = AdapterList->Next)
00551 {
00552 if (AdapterList->OperStatus != IfOperStatusUp)
00553 continue;
00554
00555 IP_ADAPTER_UNICAST_ADDRESS *uni = 0;
00556 if (AdapterList->IfIndex != 0)
00557 for (uni = AdapterList->FirstUnicastAddress;
00558 uni != 0;
00559 uni = uni->Next)
00560 {
00561 SOCKET_ADDRESS *sa_addr = &uni->Address;
00562 if (sa_addr->lpSockaddr->sa_family == AF_INET)
00563 {
00564 sockaddr_in *sin = (sockaddr_in*)sa_addr->lpSockaddr;
00565 addrs[count].set(sin,sa_addr->iSockaddrLength);
00566 ++count;
00567 break;
00568 }
00569 }
00570 if (AdapterList->Ipv6IfIndex != 0)
00571 {
00572 for (uni = AdapterList->FirstUnicastAddress;
00573 uni != 0;
00574 uni = uni->Next)
00575 {
00576 SOCKET_ADDRESS *sa_addr = &uni->Address;
00577 if (sa_addr->lpSockaddr->sa_family == AF_INET6)
00578 {
00579 sockaddr_in *sin = (sockaddr_in*)sa_addr->lpSockaddr;
00580 addrs[count].set(sin,sa_addr->iSockaddrLength);
00581 ++count;
00582 break;
00583 }
00584 }
00585 }
00586 }
00587
00588 delete [] octet_buffer;
00589 return 0;
00590
00591 # elif defined (ACE_HAS_PHARLAP)
00592
00593
00594 # if !defined (ACE_HAS_PHARLAP_RT)
00595 ACE_NOTSUP_RETURN (-1);
00596 # endif
00597
00598
00599
00600
00601
00602
00603 const size_t ACE_MAX_ETS_DEVICES = 64;
00604 DEVHANDLE ip_dev[ACE_MAX_ETS_DEVICES];
00605 EK_TCPIPCFG *devp = 0;
00606 size_t i, j;
00607 ACE_TCHAR dev_name[16];
00608
00609 count = 0;
00610 for (i = 0; count < ACE_MAX_ETS_DEVICES; i++, ++count)
00611 {
00612
00613 ACE_OS::sprintf (dev_name,
00614 "ether%d",
00615 i);
00616 ip_dev[count] = EtsTCPGetDeviceHandle (dev_name);
00617 if (ip_dev[count] == 0)
00618 break;
00619 }
00620 for (i = 0; count < ACE_MAX_ETS_DEVICES; i++, ++count)
00621 {
00622
00623 ACE_OS::sprintf (dev_name,
00624 "sl%d",
00625 i);
00626 ip_dev[count] = EtsTCPGetDeviceHandle (dev_name);
00627 if (ip_dev[count] == 0)
00628 break;
00629 }
00630 for (i = 0; count < ACE_MAX_ETS_DEVICES; i++, ++count)
00631 {
00632
00633 ACE_OS::sprintf (dev_name,
00634 "ppp%d",
00635 i);
00636 ip_dev[count] = EtsTCPGetDeviceHandle (dev_name);
00637 if (ip_dev[count] == 0)
00638 break;
00639 }
00640
00641 if (count > 0)
00642 ACE_NEW_RETURN (addrs,
00643 ACE_INET_Addr[count],
00644 -1);
00645 else
00646 addrs = 0;
00647
00648 for (i = 0, j = 0; i < count; i++)
00649 {
00650 devp = EtsTCPGetDeviceCfg (ip_dev[i]);
00651 if (devp != 0)
00652 {
00653 addrs[j].set (0,
00654 devp->nwIPAddress,
00655 0);
00656 ++j;
00657 }
00658
00659 }
00660
00661 count = j;
00662 if (count == 0 && addrs != 0)
00663 {
00664 delete [] addrs;
00665 addrs = 0;
00666 }
00667
00668 return 0;
00669
00670
00671 # else
00672
00673
00674 int i, n_interfaces, status;
00675
00676 INTERFACE_INFO info[64];
00677 SOCKET sock;
00678
00679
00680 sock = socket (AF_INET, SOCK_DGRAM, 0);
00681 if (sock == INVALID_SOCKET)
00682 return -1;
00683
00684 DWORD bytes;
00685 status = WSAIoctl(sock,
00686 SIO_GET_INTERFACE_LIST,
00687 0,
00688 0,
00689 info,
00690 sizeof(info),
00691 &bytes,
00692 0,
00693 0);
00694 closesocket (sock);
00695 if (status == SOCKET_ERROR)
00696 return -1;
00697
00698 n_interfaces = bytes / sizeof(INTERFACE_INFO);
00699
00700
00701
00702
00703
00704 int n_v6_interfaces = 0;
00705
00706 # if defined (ACE_HAS_IPV6) && defined (SIO_ADDRESS_LIST_QUERY)
00707
00708 LPSOCKET_ADDRESS_LIST v6info;
00709 char *buffer;
00710 DWORD buflen = sizeof (SOCKET_ADDRESS_LIST) + (63 * sizeof (SOCKET_ADDRESS));
00711 ACE_NEW_RETURN (buffer,
00712 char[buflen],
00713 -1);
00714 v6info = reinterpret_cast<LPSOCKET_ADDRESS_LIST> (buffer);
00715
00716
00717
00718 sock = socket (AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
00719 if (sock != INVALID_SOCKET)
00720 {
00721 status = WSAIoctl(sock,
00722 SIO_ADDRESS_LIST_QUERY,
00723 0,
00724 0,
00725 v6info,
00726 buflen,
00727 &bytes,
00728 0,
00729 0);
00730 closesocket (sock);
00731 if (status != SOCKET_ERROR)
00732 n_v6_interfaces = v6info->iAddressCount;
00733 }
00734 # endif
00735
00736 ACE_NEW_RETURN (addrs,
00737 ACE_INET_Addr[n_interfaces + n_v6_interfaces],
00738 -1);
00739
00740
00741
00742 for (count = 0, i = 0; i < n_interfaces; ++i)
00743 {
00744 LPINTERFACE_INFO lpii;
00745 struct sockaddr_in *addrp = 0;
00746
00747 lpii = &info[i];
00748 if (!(lpii->iiFlags & IFF_UP))
00749 continue;
00750
00751
00752 addrp = reinterpret_cast<struct sockaddr_in *> (&lpii->iiAddress.AddressIn);
00753 if (addrp->sin_addr.s_addr == INADDR_ANY)
00754 continue;
00755
00756
00757 addrs[count].set(addrp, sizeof(sockaddr_in));
00758 ++count;
00759 }
00760
00761 # if defined (ACE_HAS_IPV6) && defined (SIO_ADDRESS_LIST_QUERY)
00762
00763
00764 for (i = 0; i < n_v6_interfaces; i++)
00765 {
00766 struct sockaddr_in6 *addr6p;
00767
00768 if (v6info->Address[i].lpSockaddr->sa_family != AF_INET6)
00769 continue;
00770
00771 addr6p = reinterpret_cast<struct sockaddr_in6 *> (v6info->Address[i].lpSockaddr);
00772 if (IN6_IS_ADDR_UNSPECIFIED(&addr6p->sin6_addr))
00773 continue;
00774
00775
00776 addrs[count].set(reinterpret_cast<struct sockaddr_in *> (addr6p), sizeof(sockaddr_in6));
00777 ++count;
00778 }
00779
00780 delete [] buffer;
00781 # endif
00782
00783 if (count == 0)
00784 {
00785 delete [] addrs;
00786 addrs = 0;
00787 }
00788
00789 return 0;
00790
00791 # endif
00792 }
00793 #elif defined (ACE_HAS_GETIFADDRS)
00794 static int
00795 get_ip_interfaces_getifaddrs (size_t &count,
00796 ACE_INET_Addr *&addrs)
00797 {
00798
00799
00800 struct ifaddrs *ifap = 0;
00801 struct ifaddrs *p_if = 0;
00802
00803 if (::getifaddrs (&ifap) != 0)
00804 return -1;
00805
00806
00807 size_t num_ifs = 0;
00808 for (p_if = ifap; p_if != 0; p_if = p_if->ifa_next)
00809 ++num_ifs;
00810
00811
00812 ACE_NEW_RETURN (addrs,
00813 ACE_INET_Addr[num_ifs],
00814 -1);
00815
00816
00817
00818
00819
00820 count = 0;
00821
00822 for (p_if = ifap;
00823 p_if != 0;
00824 p_if = p_if->ifa_next)
00825 {
00826 if (p_if->ifa_addr &&
00827 p_if->ifa_addr->sa_family == AF_INET)
00828 {
00829 struct sockaddr_in *addr =
00830 reinterpret_cast<sockaddr_in *> (p_if->ifa_addr);
00831
00832
00833
00834 if (addr->sin_addr.s_addr != INADDR_ANY)
00835 {
00836 addrs[count].set ((u_short) 0,
00837 addr->sin_addr.s_addr,
00838 0);
00839 ++count;
00840 }
00841 }
00842 # if defined (ACE_HAS_IPV6)
00843 else if (p_if->ifa_addr &&
00844 p_if->ifa_addr->sa_family == AF_INET6)
00845 {
00846 struct sockaddr_in6 *addr =
00847 reinterpret_cast<sockaddr_in6 *> (p_if->ifa_addr);
00848
00849
00850 if (!IN6_IS_ADDR_UNSPECIFIED(&addr->sin6_addr))
00851 {
00852 addrs[count].set(reinterpret_cast<struct sockaddr_in *> (addr),
00853 sizeof(sockaddr_in6));
00854 ++count;
00855 }
00856 }
00857 # endif
00858 }
00859
00860 ::freeifaddrs (ifap);
00861
00862 return 0;
00863 }
00864 #elif defined (__hpux)
00865 static int
00866 get_ip_interfaces_hpux (size_t &count,
00867 ACE_INET_Addr *&addrs)
00868 {
00869 size_t num_ifs = 0;
00870 size_t num_ifs_found = 0;
00871
00872
00873 ACE_HANDLE handle = ACE_OS::socket (PF_INET, SOCK_DGRAM, 0);
00874 ACE_HANDLE handle_ipv6 = ACE_INVALID_HANDLE;
00875
00876 if (handle == ACE_INVALID_HANDLE)
00877 ACE_ERROR_RETURN ((LM_ERROR,
00878 ACE_TEXT ("%p\n"),
00879 ACE_TEXT ("ACE::get_ip_interfaces:open")),
00880 -1);
00881
00882 int result = 0;
00883 int tmp_how_many = 0;
00884
00885 result = ACE_OS::ioctl (handle,
00886 SIOCGIFNUM,
00887 (caddr_t) &tmp_how_many);
00888 if (result != -1)
00889 num_ifs = (size_t)tmp_how_many;
00890
00891 # if defined (ACE_HAS_IPV6)
00892 tmp_how_many = 0;
00893 handle_ipv6 = ACE_OS::socket (PF_INET6, SOCK_DGRAM, 0);
00894 result = ACE_OS::ioctl (handle_ipv6,
00895 SIOCGLIFNUM,
00896 (caddr_t) &tmp_how_many);
00897 if (result != -1)
00898 num_ifs += (size_t)tmp_how_many;
00899 # endif
00900
00901 if (num_ifs == 0)
00902 {
00903 ACE_OS::close (handle);
00904 ACE_OS::close (handle_ipv6);
00905 return -1;
00906 }
00907
00908
00909
00910 ++num_ifs;
00911
00912
00913
00914 struct ifreq *ifs = 0;
00915 ACE_NEW_RETURN (ifs,
00916 struct ifreq[num_ifs],
00917 -1);
00918 ACE_OS::memset (ifs, 0, num_ifs * sizeof (struct ifreq));
00919
00920 ACE_Auto_Array_Ptr<struct ifreq> p_ifs (ifs);
00921
00922 if (p_ifs.get() == 0)
00923 {
00924 ACE_OS::close (handle);
00925 ACE_OS::close (handle_ipv6);
00926 errno = ENOMEM;
00927 return -1;
00928 }
00929
00930 struct ifconf ifcfg;
00931 ACE_OS::memset (&ifcfg, 0, sizeof (struct ifconf));
00932
00933 ifcfg.ifc_req = p_ifs.get ();
00934 ifcfg.ifc_len = num_ifs * sizeof (struct ifreq);
00935
00936 if (ACE_OS::ioctl (handle,
00937 SIOCGIFCONF,
00938 (char *) &ifcfg) == -1)
00939 {
00940 ACE_OS::close (handle);
00941 ACE_ERROR_RETURN ((LM_ERROR,
00942 ACE_TEXT ("%p\n"),
00943 ACE_TEXT ("ACE::get_ip_interfaces:")
00944 ACE_TEXT ("ioctl - SIOCGIFCONF failed")),
00945 -1);
00946 }
00947
00948 ACE_OS::close (handle);
00949
00950
00951
00952 ACE_NEW_RETURN (addrs,
00953 ACE_INET_Addr[num_ifs],
00954 -1);
00955
00956 struct ifreq *pcur = p_ifs.get ();
00957 num_ifs_found = ifcfg.ifc_len / sizeof (struct ifreq);
00958
00959 for (size_t i = 0;
00960 i < num_ifs_found;
00961 i++)
00962 {
00963 struct sockaddr_in *addr =
00964 reinterpret_cast<sockaddr_in *> (&pcur->ifr_addr);
00965 if (addr->sin_addr.s_addr != 0)
00966 {
00967 addrs[count].set ((u_short) 0,
00968 addr->sin_addr.s_addr,
00969 0);
00970 ++count;
00971 }
00972 ++pcur;
00973 }
00974
00975 # if defined (ACE_HAS_IPV6)
00976
00977 if (handle_ipv6 != ACE_INVALID_HANDLE)
00978 {
00979 struct if_laddrreq *lifs = 0;
00980 ACE_NEW_RETURN (lifs,
00981 struct if_laddrreq[num_ifs],
00982 -1);
00983 ACE_OS::memset (lifs, 0, num_ifs * sizeof (struct if_laddrreq));
00984
00985 ACE_Auto_Array_Ptr<struct if_laddrreq> p_lifs (lifs);
00986
00987 if (p_lifs.get() == 0)
00988 {
00989 ACE_OS::close (handle);
00990 ACE_OS::close (handle_ipv6);
00991 errno = ENOMEM;
00992 return -1;
00993 }
00994
00995 struct if_laddrconf lifcfg;
00996 ACE_OS::memset (&lifcfg, 0, sizeof (struct if_laddrconf));
00997
00998 lifcfg.iflc_req = p_lifs.get ();
00999 lifcfg.iflc_len = num_ifs * sizeof (struct if_laddrreq);
01000
01001 if (ACE_OS::ioctl (handle_ipv6,
01002 SIOCGLIFCONF,
01003 (char *) &lifcfg) == -1)
01004 {
01005 ACE_OS::close (handle);
01006 ACE_ERROR_RETURN ((LM_ERROR,
01007 ACE_TEXT ("%p\n"),
01008 ACE_TEXT ("ACE::get_ip_interfaces:")
01009 ACE_TEXT ("ioctl - SIOCGLIFCONF failed")),
01010 -1);
01011 }
01012
01013 ACE_OS::close (handle_ipv6);
01014
01015 struct if_laddrreq *plcur = p_lifs.get ();
01016 num_ifs_found = lifcfg.iflc_len / sizeof (struct if_laddrreq);
01017
01018 for (size_t i = 0;
01019 i < num_ifs_found;
01020 i++)
01021 {
01022 struct sockaddr_in *addr =
01023 reinterpret_cast<sockaddr_in *> (&plcur->iflr_addr);
01024 if (!IN6_IS_ADDR_UNSPECIFIED(&reinterpret_cast<sockaddr_in6 *>(addr)->sin6_addr))
01025 {
01026 addrs[count].set(addr, sizeof(struct sockaddr_in6));
01027 ++count;
01028 }
01029 ++plcur;
01030 }
01031 }
01032 # endif
01033 return 0;
01034 }
01035 #elif defined (_AIX)
01036 static int
01037 get_ip_interfaces_aix (size_t &count,
01038 ACE_INET_Addr *&addrs)
01039 {
01040 ACE_HANDLE handle = ACE::get_handle();
01041 size_t num_ifs = 0;
01042 struct ifconf ifc;
01043
01044 if (handle == ACE_INVALID_HANDLE)
01045 ACE_ERROR_RETURN ((LM_ERROR,
01046 ACE_TEXT ("%p\n"),
01047 ACE_TEXT ("ACE::get_ip_interfaces_aix:")),
01048 -1);
01049
01050 if (ACE_OS::ioctl (handle,
01051 SIOCGSIZIFCONF,
01052 (caddr_t)&ifc.ifc_len) == -1)
01053 {
01054 ACE_OS::close (handle);
01055 ACE_ERROR_RETURN((LM_ERROR,
01056 ACE_TEXT ("%p\n"),
01057 ACE_TEXT ("get ifconf size")),
01058 -1);
01059 }
01060
01061 ACE_NEW_RETURN (ifc.ifc_buf,char [ifc.ifc_len], -1);
01062
01063 ACE_Auto_Array_Ptr<char> safe_buf (ifc.ifc_buf);
01064 ACE_OS::memset (safe_buf.get(), 0, ifc.ifc_len);
01065
01066 if (ACE_OS::ioctl(handle, SIOCGIFCONF, (caddr_t)&ifc) == -1)
01067 {
01068 ACE_OS::close (handle);
01069 ACE_ERROR_RETURN((LM_ERROR,
01070 ACE_TEXT ("%p\n"),
01071 ACE_TEXT ("get ifconf")),
01072 -1);
01073 }
01074
01075 ACE_OS::close (handle);
01076
01077 char *buf_start = safe_buf.get();
01078 char *buf_end = buf_start + ifc.ifc_len;
01079
01080 num_ifs = 0;
01081 for (char *ptr = buf_start; ptr < buf_end; )
01082 {
01083 struct ifreq *req = reinterpret_cast<struct ifreq *>(ptr);
01084 ptr += IFNAMSIZ;
01085 ptr += req->ifr_addr.sa_len;
01086 if (req->ifr_addr.sa_family == AF_INET
01087 # if defined (ACE_HAS_IPV6)
01088 || req->ifr_addr.sa_family == AF_INET6
01089 # endif
01090 )
01091 ++num_ifs;
01092 }
01093 ACE_NEW_RETURN (addrs,ACE_INET_Addr[num_ifs], -1);
01094
01095 for (char * ptr = buf_start; ptr < buf_end; )
01096 {
01097 struct ifreq *req = reinterpret_cast<struct ifreq *>(ptr);
01098
01099 ptr += IFNAMSIZ;
01100 if (req->ifr_addr.sa_family == AF_INET
01101 # if defined (ACE_HAS_IPV6)
01102 || req->ifr_addr.sa_family == AF_INET6
01103 # endif
01104 )
01105 {
01106 sockaddr_in *addr = (sockaddr_in*)&req->ifr_addr;
01107 addrs[count++].set(addr, addr->sin_len);
01108 }
01109 ptr += req->ifr_addr.sa_len;
01110 }
01111
01112 return 0;
01113 }
01114
01115 #elif defined (ACE_VXWORKS) && (ACE_VXWORKS < 0x600) && !defined (ACE_HAS_VXWORKS551_MEDUSA)
01116 int
01117 get_ip_interfaces_vxworks_lt600 (size_t &count,
01118 ACE_INET_Addr *&addrs)
01119 {
01120 count = 0;
01121
01122
01123 # if defined (ACE_HAS_IPV6) && defined (TAILQ_ENTRY)
01124 # define ia_next ia_link.tqe_next
01125 # endif
01126
01127 for (struct in_ifaddr* ia = in_ifaddr; ia != 0; ia = ia->ia_next)
01128 {
01129 ++count;
01130 }
01131
01132
01133 ACE_NEW_RETURN (addrs,
01134 ACE_INET_Addr[count],
01135 -1);
01136 count = 0;
01137 for (struct in_ifaddr* ia = in_ifaddr; ia != 0; ia = ia->ia_next)
01138 {
01139 struct ifnet* ifp = ia->ia_ifa.ifa_ifp;
01140 if (ifp != 0)
01141 {
01142
01143 char interface[64];
01144 ACE_OS::sprintf(interface, "%s%d", ifp->if_name, ifp->if_unit);
01145
01146
01147 char address [INET_ADDR_LEN];
01148 STATUS status = ifAddrGet(interface, address);
01149
01150 if (status == OK)
01151 {
01152
01153
01154
01155
01156
01157 ACE_OS::strcat (address, ":");
01158 addrs[count].set (address);
01159 }
01160 else
01161 {
01162 ACE_ERROR_RETURN ((LM_ERROR,
01163 ACE_TEXT ("ACE::get_ip_interface failed\n")
01164 ACE_TEXT ("Couldnt get the IP Address\n")),
01165 -1);
01166 }
01167 ++count;
01168 }
01169 }
01170 return 0;
01171 }
01172 #endif // ACE_WIN32 || ACE_HAS_GETIFADDRS || __hpux || _AIX || ACE_VXWORKS < 0x600
01173
01174
01175
01176
01177
01178
01179 int
01180 ACE::get_ip_interfaces (size_t &count, ACE_INET_Addr *&addrs)
01181 {
01182 ACE_TRACE ("ACE::get_ip_interfaces");
01183
01184 count = 0;
01185 addrs = 0;
01186
01187 #if defined (ACE_WIN32)
01188 return get_ip_interfaces_win32 (count, addrs);
01189 #elif defined (ACE_HAS_GETIFADDRS)
01190 return get_ip_interfaces_getifaddrs (count, addrs);
01191 #elif defined (__hpux)
01192 return get_ip_interfaces_hpux (count, addrs);
01193 #elif defined (_AIX)
01194 return get_ip_interfaces_aix (count, addrs);
01195 #elif defined (ACE_VXWORKS) && (ACE_VXWORKS < 0x600) && !defined (ACE_HAS_VXWORKS551_MEDUSA)
01196 return get_ip_interfaces_vxworks_lt600 (count, addrs);
01197 #elif (defined (__unix) || defined (__unix__) || defined (ACE_OPENVMS) || (defined (ACE_VXWORKS) && !defined (ACE_HAS_GETIFADDRS)) || defined (ACE_HAS_RTEMS)) && !defined (ACE_LACKS_NETWORKING)
01198
01199
01200
01201 ACE_HANDLE handle = ACE::get_handle();
01202
01203 if (handle == ACE_INVALID_HANDLE)
01204 ACE_ERROR_RETURN ((LM_ERROR,
01205 ACE_TEXT ("%p\n"),
01206 ACE_TEXT ("ACE::get_ip_interfaces:open")),
01207 -1);
01208
01209 size_t num_ifs = 0;
01210
01211 if (ACE::count_interfaces (handle, num_ifs))
01212 {
01213 ACE_OS::close (handle);
01214 return -1;
01215 }
01216
01217
01218
01219 ++num_ifs;
01220
01221 struct IFREQ *ifs = 0;
01222 ACE_NEW_RETURN (ifs,
01223 struct IFREQ[num_ifs],
01224 -1);
01225 ACE_OS::memset (ifs, 0, num_ifs * sizeof (struct IFREQ));
01226
01227 ACE_Auto_Array_Ptr<struct IFREQ> p_ifs (ifs);
01228
01229 if (p_ifs.get() == 0)
01230 {
01231 ACE_OS::close (handle);
01232 errno = ENOMEM;
01233 return -1;
01234 }
01235
01236 struct IFCONF ifcfg;
01237 ACE_OS::memset (&ifcfg, 0, sizeof (struct IFCONF));
01238
01239 # ifdef SETFAMILY
01240 ifcfg.IFC_FAMILY = AF_UNSPEC;
01241 ifcfg.IFC_FLAGS = 0;
01242 # endif
01243
01244 ifcfg.IFC_REQ = p_ifs.get ();
01245 ifcfg.IFC_LEN = num_ifs * sizeof (struct IFREQ);
01246
01247 if (ACE_OS::ioctl (handle,
01248 SIOCGIFCONF_CMD,
01249 (caddr_t) &ifcfg) == -1)
01250 {
01251 ACE_OS::close (handle);
01252 ACE_ERROR_RETURN ((LM_ERROR,
01253 ACE_TEXT ("%p\n"),
01254 ACE_TEXT ("ACE::get_ip_interfaces:")
01255 ACE_TEXT ("ioctl - SIOCGIFCONF failed")),
01256 -1);
01257 }
01258
01259 ACE_OS::close (handle);
01260
01261
01262
01263 ACE_NEW_RETURN (addrs,
01264 ACE_INET_Addr[num_ifs],
01265 -1);
01266
01267 struct IFREQ *pcur = p_ifs.get ();
01268 size_t num_ifs_found = ifcfg.IFC_LEN / sizeof (struct IFREQ);
01269
01270
01271
01272
01273
01274 count = 0;
01275
01276 for (size_t i = 0;
01277 i < num_ifs_found;
01278 i++)
01279 {
01280 if (pcur->IFR_ADDR.SA_FAMILY == AF_INET
01281 # if defined (ACE_HAS_IPV6)
01282 || pcur->IFR_ADDR.SA_FAMILY == AF_INET6
01283 # endif
01284 )
01285
01286 {
01287 # if !defined(_UNICOS)
01288 struct sockaddr_in *addr =
01289 reinterpret_cast<sockaddr_in *> (&pcur->IFR_ADDR);
01290
01291
01292
01293 if (addr->sin_addr.s_addr != 0
01294 # if defined (ACE_HAS_IPV6)
01295 || (addr->sin_family == AF_INET6 &&
01296 !IN6_IS_ADDR_UNSPECIFIED(&reinterpret_cast<sockaddr_in6 *>(addr)->sin6_addr))
01297 # endif
01298 )
01299 {
01300 int addrlen = static_cast<int> (sizeof (struct sockaddr_in));
01301 # if defined (ACE_HAS_IPV6)
01302 if (addr->sin_family == AF_INET6)
01303 addrlen = static_cast<int> (sizeof (struct sockaddr_in6));
01304 # endif
01305 addrs[count].set (addr, addrlen);
01306 ++count;
01307 }
01308 # else
01309
01310
01311 struct sockaddr_in inAddr;
01312
01313 inAddr.sin_len = pcur->IFR_ADDR.sa_len;
01314 inAddr.sin_family = pcur->IFR_ADDR.sa_family;
01315 memcpy((void *)&(inAddr.sin_addr),
01316 (const void *)&(pcur->IFR_ADDR.sa_data[8]),
01317 sizeof(struct in_addr));
01318
01319 if (inAddr.sin_addr.s_addr != 0)
01320 {
01321 addrs[count].set(&inAddr, sizeof(struct sockaddr_in));
01322 ++count;
01323 }
01324 # endif
01325 }
01326
01327 #if !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) && !defined (ACE_HAS_RTEMS) && !defined (__Lynx__)
01328 ++pcur;
01329 #else
01330 if (pcur->ifr_addr.sa_len <= sizeof (struct sockaddr))
01331 {
01332 ++pcur;
01333 }
01334 else
01335 {
01336 pcur = (struct ifreq *)
01337 (pcur->ifr_addr.sa_len + (caddr_t) &pcur->ifr_addr);
01338 }
01339 #endif
01340 }
01341
01342 # if defined (ACE_HAS_IPV6)
01343
01344
01345
01346 FILE* fp = 0;
01347 char addr_p[8][5];
01348 char s_ipaddr[64];
01349 int scopeid;
01350 struct addrinfo hints, *res0;
01351 int error;
01352
01353 ACE_OS::memset (&hints, 0, sizeof (hints));
01354 hints.ai_flags = AI_NUMERICHOST;
01355 hints.ai_family = AF_INET6;
01356
01357 if ((fp = ACE_OS::fopen (ACE_TEXT ("/proc/net/if_inet6"), ACE_TEXT ("r"))) != 0)
01358 {
01359 while (fscanf (fp,
01360 "%4s%4s%4s%4s%4s%4s%4s%4s %02x %*02x %*02x %*02x %*8s\n",
01361 addr_p[0], addr_p[1], addr_p[2], addr_p[3],
01362 addr_p[4], addr_p[5], addr_p[6], addr_p[7], &scopeid) != EOF)
01363 {
01364
01365
01366
01367 const char* ip_fmt = "%s:%s:%s:%s:%s:%s:%s:%s%%%d";
01368 ACE_OS::sprintf (s_ipaddr,
01369 ip_fmt,
01370 addr_p[0], addr_p[1], addr_p[2], addr_p[3],
01371 addr_p[4], addr_p[5], addr_p[6], addr_p[7], scopeid);
01372
01373 error = getaddrinfo (s_ipaddr, 0, &hints, &res0);
01374 if (error)
01375 continue;
01376
01377 if (res0->ai_family == AF_INET6 &&
01378 !IN6_IS_ADDR_UNSPECIFIED (&reinterpret_cast<sockaddr_in6 *> (res0->ai_addr)->sin6_addr))
01379 {
01380 addrs[count].set(reinterpret_cast<sockaddr_in *> (res0->ai_addr), res0->ai_addrlen);
01381 ++count;
01382 }
01383 freeaddrinfo (res0);
01384
01385 }
01386 ACE_OS::fclose (fp);
01387 }
01388 # endif
01389
01390 return 0;
01391 #else
01392 ACE_UNUSED_ARG (count);
01393 ACE_UNUSED_ARG (addrs);
01394 ACE_NOTSUP_RETURN (-1);
01395 #endif
01396 }
01397
01398
01399
01400
01401
01402 int
01403 ACE::count_interfaces (ACE_HANDLE handle, size_t &how_many)
01404 {
01405 #if defined (SIOCGIFNUM)
01406 # if defined (SIOCGLIFNUM) && !defined (ACE_LACKS_STRUCT_LIFNUM)
01407 int cmd = SIOCGLIFNUM;
01408 struct lifnum if_num = {AF_UNSPEC,0,0};
01409 # else
01410 int cmd = SIOCGIFNUM;
01411 int if_num = 0;
01412 # endif
01413 if (ACE_OS::ioctl (handle, cmd, (caddr_t)&if_num) == -1)
01414 ACE_ERROR_RETURN ((LM_ERROR,
01415 ACE_TEXT ("%p\n"),
01416 ACE_TEXT ("ACE::count_interfaces:")
01417 ACE_TEXT ("ioctl - SIOCGLIFNUM failed")),
01418 -1);
01419 # if defined (SIOCGLIFNUM) && !defined (ACE_LACKS_STRUCT_LIFNUM)
01420 how_many = if_num.lifn_count;
01421 # else
01422 how_many = if_num;
01423 # endif
01424 return 0;
01425
01426 #elif (defined (__unix) || defined (__unix__) || defined (ACE_OPENVMS) || defined (ACE_HAS_RTEMS) || (defined (ACE_VXWORKS) && !defined (ACE_HAS_GETIFADDRS))) && !defined (ACE_LACKS_NETWORKING)
01427
01428
01429
01430
01431
01432
01433 int const MAX_IF = 50;
01434
01435
01436 int const num_ifs = MAX_IF;
01437
01438 struct ifconf ifcfg;
01439 size_t ifreq_size = num_ifs * sizeof (struct ifreq);
01440 struct ifreq *p_ifs = (struct ifreq *) ACE_OS::malloc (ifreq_size);
01441
01442 if (!p_ifs)
01443 {
01444 errno = ENOMEM;
01445 return -1;
01446 }
01447
01448 ACE_OS::memset (p_ifs, 0, ifreq_size);
01449 ACE_OS::memset (&ifcfg, 0, sizeof (struct ifconf));
01450
01451 ifcfg.ifc_req = p_ifs;
01452 ifcfg.ifc_len = ifreq_size;
01453
01454 if (ACE_OS::ioctl (handle,
01455 SIOCGIFCONF_CMD,
01456 (caddr_t) &ifcfg) == -1)
01457 {
01458 ACE_OS::free (ifcfg.ifc_req);
01459 ACE_ERROR_RETURN ((LM_ERROR,
01460 ACE_TEXT ("%p\n"),
01461 ACE_TEXT ("ACE::count_interfaces:")
01462 ACE_TEXT ("ioctl - SIOCGIFCONF failed")),
01463 -1);
01464 }
01465
01466 int if_count = 0;
01467 int i = 0;
01468
01469
01470
01471 for (i = 0;
01472 i < num_ifs;
01473 i++)
01474 {
01475
01476 ifcfg.ifc_len -= sizeof (struct ifreq);
01477 if (ifcfg.ifc_len < 0)
01478 break;
01479
01480 ++if_count;
01481 #if !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) && !defined (ACE_HAS_RTEMS) && !defined (__Lynx__)
01482 ++p_ifs;
01483 #else
01484 if (p_ifs->ifr_addr.sa_len <= sizeof (struct sockaddr))
01485 {
01486 ++p_ifs;
01487 }
01488 else
01489 {
01490 p_ifs = (struct ifreq *)
01491 (p_ifs->ifr_addr.sa_len + (caddr_t) &p_ifs->ifr_addr);
01492 }
01493 #endif
01494 }
01495
01496 ACE_OS::free (ifcfg.ifc_req);
01497
01498 # if defined (ACE_HAS_IPV6)
01499 FILE* fp = 0;
01500
01501 if ((fp = ACE_OS::fopen (ACE_TEXT ("/proc/net/if_inet6"), ACE_TEXT ("r"))) != 0)
01502 {
01503
01504 while (fscanf (fp, "%*32s %*02x %*02x %*02x %*02x %*8s\n") != EOF)
01505 {
01506 ++if_count;
01507 }
01508 ACE_OS::fclose (fp);
01509 }
01510 # endif
01511
01512 how_many = if_count;
01513 return 0;
01514 #else
01515 ACE_UNUSED_ARG (handle);
01516 ACE_UNUSED_ARG (how_many);
01517 ACE_NOTSUP_RETURN (-1);
01518 #endif
01519 }
01520
01521
01522
01523 ACE_HANDLE
01524 ACE::get_handle (void)
01525 {
01526
01527 ACE_HANDLE handle = ACE_INVALID_HANDLE;
01528 #if defined (sparc)
01529 handle = ACE_OS::open ("/dev/udp", O_RDONLY);
01530 #elif defined (__unix) || defined (__unix__) || defined (_AIX) || defined (__hpux) || (defined (ACE_VXWORKS) && (ACE_VXWORKS >= 0x600)) || defined (ACE_OPENVMS) || defined (ACE_HAS_RTEMS)
01531
01532
01533
01534 handle = ACE_OS::socket (PF_INET, SOCK_DGRAM, 0);
01535 #endif
01536 return handle;
01537 }
01538
01539
01540 #if defined (ACE_HAS_IPV6)
01541 static int
01542 ip_check (int &ipvn_enabled, int pf)
01543 {
01544
01545
01546 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
01547 *ACE_Static_Object_Lock::instance (), 0));
01548
01549 if (ipvn_enabled == -1)
01550 {
01551
01552
01553 ACE_HANDLE const s = ACE_OS::socket (pf, SOCK_DGRAM, 0);
01554 if (s == ACE_INVALID_HANDLE)
01555 {
01556 ipvn_enabled = 0;
01557 }
01558 else
01559 {
01560 ipvn_enabled = 1;
01561 ACE_OS::closesocket (s);
01562 }
01563 }
01564 return ipvn_enabled;
01565 }
01566 #endif
01567
01568 bool
01569 ACE::ipv4_enabled (void)
01570 {
01571 #if defined (ACE_HAS_IPV6)
01572 return static_cast<bool> (ace_ipv4_enabled == -1 ?
01573 ::ip_check (ace_ipv4_enabled, PF_INET) :
01574 ace_ipv4_enabled);
01575 #else
01576
01577
01578 return true;
01579 #endif
01580 }
01581
01582 int
01583 ACE::ipv6_enabled (void)
01584 {
01585 #if defined (ACE_HAS_IPV6)
01586 return ace_ipv6_enabled == -1 ?
01587 ::ip_check (ace_ipv6_enabled, PF_INET6) :
01588 ace_ipv6_enabled;
01589 #else
01590 return 0;
01591 #endif
01592 }
01593
01594 ACE_END_VERSIONED_NAMESPACE_DECL