1 #include "ace/Sock_Connect.h"
2 #include "ace/INET_Addr.h"
3 #include "ace/Log_Category.h"
4 #include "ace/Handle_Set.h"
5 #include "ace/Auto_Ptr.h"
6 #include "ace/SString.h"
7 #include "ace/OS_Memory.h"
8 #include "ace/OS_NS_stdio.h"
12 # include "ace/OS_NS_fcntl.h"
15 #include "ace/OS_NS_stdlib.h"
16 #include "ace/OS_NS_string.h"
17 #include "ace/OS_NS_sys_socket.h"
18 #include "ace/OS_NS_netdb.h"
19 #include "ace/OS_NS_unistd.h"
20 #include "ace/os_include/net/os_if.h"
22 #if defined (ACE_HAS_IPV6)
23 # include "ace/Guard_T.h"
24 # include "ace/Recursive_Thread_Mutex.h"
26 # include /**/ <netinet/in6_var.h>
28 #endif /* ACE_HAS_IPV6 */
30 #if defined (ACE_HAS_GETIFADDRS)
31 # include "ace/os_include/os_ifaddrs.h"
32 #endif /* ACE_HAS_GETIFADDRS */
34 #if defined (ACE_VXWORKS) && (ACE_VXWORKS <= 0x670) && defined (__RTP__) && defined (ACE_HAS_IPV6)
35 const struct in6_addr in6addr_any
= IN6ADDR_ANY_INIT
;
36 const struct in6_addr in6addr_nodelocal_allnodes
= IN6ADDR_NODELOCAL_ALLNODES_INIT
;
37 const struct in6_addr in6addr_linklocal_allnodes
= IN6ADDR_LINKLOCAL_ALLNODES_INIT
;
38 const struct in6_addr in6addr_linklocal_allrouters
= IN6ADDR_LINKLOCAL_ALLROUTERS_INIT
;
39 #endif /* ACE_VXWORKS <= 0x670 && __RTP__ && ACE_HAS_IPV6 */
41 #if defined (ACE_HAS_WINCE)
42 #include /**/ <iphlpapi.h>
43 # if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0) && (_WIN32_WCE < 0x600) && defined (ACE_HAS_IPV6)
44 # include /**/ <ws2tcpip.h>
45 const struct in6_addr in6addr_any
= IN6ADDR_ANY_INIT
;
46 const struct in6_addr in6addr_loopback
= IN6ADDR_LOOPBACK_INIT
;
48 #endif // ACE_HAS_WINCE
50 #if defined (ACE_WIN32) && defined (ACE_HAS_PHARLAP)
51 # include "ace/OS_NS_stdio.h"
54 #if defined (ACE_HAS_IPV6)
56 // These defines support a generic usage based on
57 // the various SIGCF*IF ioctl implementations
59 # if defined (SIOCGLIFCONF)
60 # define SIOCGIFCONF_CMD SIOCGLIFCONF
62 # define IFREQ if_laddrreq
63 # define IFCONF if_laddrconf
64 # define IFC_REQ iflc_req
65 # define IFC_LEN iflc_len
66 # define IFC_BUF iflc_buf
67 # define IFR_ADDR iflr_addr
68 # define IFR_NAME iflr_name
69 # define IFR_FLAGS iflr_flags
71 # define SA_FAMILY sa_family
74 # define IFCONF lifconf
75 # define IFC_REQ lifc_req
76 # define IFC_LEN lifc_len
77 # define IFC_BUF lifc_buf
78 # define IFR_ADDR lifr_addr
79 # define IFR_NAME lifr_name
80 # define IFR_FLAGS lifr_flags
82 # define IFC_FAMILY lifc_family
83 # define IFC_FLAGS lifc_flags
84 # define SA_FAMILY ss_family
87 # define SIOCGIFCONF_CMD SIOCGIFCONF
89 # define IFCONF ifconf
90 # define IFC_REQ ifc_req
91 # define IFC_LEN ifc_len
92 # define IFC_BUF ifc_buf
93 # define IFR_ADDR ifr_addr
94 # define IFR_NAME ifr_name
95 # define IFR_FLAGS ifr_flags
97 # define SA_FAMILY sa_family
98 # endif /* SIOCGLIFCONF */
100 # if defined (ACE_HAS_THREADS)
101 # include "ace/Object_Manager.h"
102 # endif /* ACE_HAS_THREADS */
107 // Used internally so not exported.
109 // Does this box have ipv4 turned on?
110 int ace_ipv4_enabled
= -1;
112 // Does this box have ipv6 turned on?
113 int ace_ipv6_enabled
= -1;
116 #else /* ACE_HAS_IPV6 */
117 # define SIOCGIFCONF_CMD SIOCGIFCONF
119 # define IFCONF ifconf
120 # define IFC_REQ ifc_req
121 # define IFC_LEN ifc_len
122 # define IFC_BUF ifc_buf
123 # define IFR_ADDR ifr_addr
124 # define IFR_NAME ifr_name
125 # define IFR_FLAGS ifr_flags
127 # define SA_FAMILY sa_family
128 #endif /* ACE_HAS_IPV6 */
130 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
132 // Bind socket to an unused port.
135 ACE::bind_port (ACE_HANDLE handle
, ACE_UINT32 ip_addr
, int address_family
)
137 ACE_TRACE ("ACE::bind_port");
141 #if defined (ACE_HAS_IPV6)
142 if (address_family
!= PF_INET6
)
143 // What do we do if it is PF_"INET6? Since it's 4 bytes, it must be an
144 // IPV4 address. Is there a difference? Why is this test done? dhinton
145 #else /* ACE_HAS_IPV6 */
146 ACE_UNUSED_ARG (address_family
);
147 #endif /* !ACE_HAS_IPV6 */
148 addr
= ACE_INET_Addr ((u_short
)0, ip_addr
);
149 #if defined (ACE_HAS_IPV6)
150 else if (ip_addr
!= INADDR_ANY
)
151 // address_family == PF_INET6 and a non default IP address means to bind
152 // to the IPv4-mapped IPv6 address
153 addr
.set ((u_short
)0, ip_addr
, 1, 1);
154 #endif /* ACE_HAS_IPV6 */
156 // The OS kernel should select a free port for us.
157 return ACE_OS::bind (handle
,
158 (sockaddr
*)addr
.get_addr(),
163 ACE::get_bcast_addr (ACE_UINT32
&bcast_addr
,
164 const ACE_TCHAR
*host_name
,
165 ACE_UINT32 host_addr
,
168 ACE_TRACE ("ACE::get_bcast_addr");
170 #if defined (ACE_LACKS_GET_BCAST_ADDR)
171 ACE_UNUSED_ARG (bcast_addr
);
172 ACE_UNUSED_ARG (host_name
);
173 ACE_UNUSED_ARG (host_addr
);
174 ACE_UNUSED_ARG (handle
);
175 ACE_NOTSUP_RETURN (-1);
176 #elif !defined(ACE_WIN32) && !defined(__INTERIX)
177 ACE_HANDLE s
= handle
;
179 if (s
== ACE_INVALID_HANDLE
)
180 s
= ACE_OS::socket (AF_INET
, SOCK_STREAM
, 0);
182 if (s
== ACE_INVALID_HANDLE
)
183 ACELIB_ERROR_RETURN ((LM_ERROR
,
185 ACE_TEXT ("ACE_OS::socket")),
191 ifc
.ifc_len
= sizeof buf
;
194 // Get interface structure and initialize the addresses using UNIX
196 if (ACE_OS::ioctl (s
, SIOCGIFCONF_CMD
, (char *) &ifc
) == -1)
197 ACELIB_ERROR_RETURN ((LM_ERROR
,
199 ACE_TEXT ("ACE::get_bcast_addr:")
200 ACE_TEXT ("ioctl (get interface configuration)")),
203 struct ifreq
*ifr
= ifc
.ifc_req
;
205 struct sockaddr_in ip_addr
;
207 // Get host ip address if necessary.
210 hostent
*hp
= ACE_OS::gethostbyname (ACE_TEXT_ALWAYS_CHAR (host_name
));
215 ACE_OS::memcpy ((char *) &ip_addr
.sin_addr
.s_addr
,
216 # ifdef ACE_HOSTENT_H_ADDR
217 (char *) hp
->ACE_HOSTENT_H_ADDR
,
225 ACE_OS::memset ((void *) &ip_addr
, 0, sizeof ip_addr
);
226 ACE_OS::memcpy ((void *) &ip_addr
.sin_addr
,
228 sizeof ip_addr
.sin_addr
);
231 #if !defined(AIX) && !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) && !defined (__Lynx__)
232 for (int n
= ifc
.ifc_len
/ sizeof (struct ifreq
) ; n
> 0;
235 // see mk_broadcast@SOCK_Dgram_Bcast.cpp
236 for (int nbytes
= ifc
.ifc_len
; nbytes
>= (int) sizeof (struct ifreq
) &&
237 ((ifr
->ifr_addr
.sa_len
> sizeof (struct sockaddr
)) ?
238 (nbytes
>= (int) sizeof (ifr
->ifr_name
) + ifr
->ifr_addr
.sa_len
) : 1);
239 ((ifr
->ifr_addr
.sa_len
> sizeof (struct sockaddr
)) ?
240 (nbytes
-= sizeof (ifr
->ifr_name
) + ifr
->ifr_addr
.sa_len
,
241 ifr
= (struct ifreq
*)
242 ((caddr_t
) &ifr
->ifr_addr
+ ifr
->ifr_addr
.sa_len
)) :
243 (nbytes
-= sizeof (struct ifreq
), ifr
++)))
244 #endif /* !defined(AIX) && !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) && !defined (__Lynx__) */
246 struct sockaddr_in if_addr
;
248 // Compare host ip address with interface ip address.
249 ACE_OS::memcpy (&if_addr
,
253 if (ip_addr
.sin_addr
.s_addr
!= if_addr
.sin_addr
.s_addr
)
256 if (ifr
->ifr_addr
.sa_family
!= AF_INET
)
258 ACELIB_ERROR ((LM_ERROR
,
260 ACE_TEXT ("ACE::get_bcast_addr:")
261 ACE_TEXT ("Not AF_INET")));
265 struct ifreq flags
= *ifr
;
266 struct ifreq if_req
= *ifr
;
268 if (ACE_OS::ioctl (s
, SIOCGIFFLAGS
, (char *) &flags
) == -1)
270 ACELIB_ERROR ((LM_ERROR
,
272 ACE_TEXT ("ACE::get_bcast_addr:")
273 ACE_TEXT (" ioctl (get interface flags)")));
277 if (ACE_BIT_DISABLED (flags
.ifr_flags
, IFF_UP
))
279 ACELIB_ERROR ((LM_ERROR
,
281 ACE_TEXT ("ACE::get_bcast_addr:")
282 ACE_TEXT ("Network interface is not up")));
286 if (ACE_BIT_ENABLED (flags
.ifr_flags
, IFF_LOOPBACK
))
289 if (ACE_BIT_ENABLED (flags
.ifr_flags
, IFF_BROADCAST
))
291 if (ACE_OS::ioctl (s
,
293 (char *) &if_req
) == -1)
294 ACELIB_ERROR ((LM_ERROR
,
296 ACE_TEXT ("ACE::get_bcast_addr:")
297 ACE_TEXT ("ioctl (get broadaddr)")));
300 ACE_OS::memcpy (&ip_addr
,
301 &if_req
.ifr_broadaddr
,
302 sizeof if_req
.ifr_broadaddr
);
304 ACE_OS::memcpy ((void *) &host_addr
,
305 (void *) &ip_addr
.sin_addr
,
308 if (handle
== ACE_INVALID_HANDLE
)
311 bcast_addr
= host_addr
;
316 ACELIB_ERROR ((LM_ERROR
,
318 ACE_TEXT ("ACE::get_bcast_addr:")
319 ACE_TEXT ("Broadcast is not enabled for this interface.")));
321 if (handle
== ACE_INVALID_HANDLE
)
324 bcast_addr
= host_addr
;
330 ACE_UNUSED_ARG (handle
);
331 ACE_UNUSED_ARG (host_addr
);
332 ACE_UNUSED_ARG (host_name
);
333 bcast_addr
= (ACE_UINT32 (INADDR_BROADCAST
));
335 #endif /* !ACE_WIN32 && !__INTERIX */
339 ACE::get_fqdn (ACE_INET_Addr
const & addr
,
343 #ifndef ACE_LACKS_GETNAMEINFO
345 const socklen_t addr_size
=
347 (addr
.get_type () == PF_INET6
) ? sizeof (sockaddr_in6
) :
349 sizeof (sockaddr_in
);
351 if (ACE_OS::getnameinfo ((const sockaddr
*) addr
.get_addr (),
353 static_cast<ACE_SOCKET_LEN
> (len
),
354 0, 0, NI_NAMEREQD
) != 0)
358 ACELIB_DEBUG ((LM_DEBUG
,
359 ACE_TEXT ("(%P|%t) - ACE::get_fqdn, ")
360 ACE_TEXT ("canonical host name is %C\n"),
364 #else // below, ACE_LACKS_GETNAMEINFO
365 int h_error
; // Not the same as errno!
367 ACE_HOSTENT_DATA buf
;
370 int ip_addr_size
= 0;
371 if (addr
.get_type () == AF_INET
)
373 sockaddr_in
* const sock_addr
=
374 reinterpret_cast<sockaddr_in
*> (addr
.get_addr ());
375 ip_addr_size
= sizeof sock_addr
->sin_addr
;
376 ip_addr
= (char*) &sock_addr
->sin_addr
;
381 sockaddr_in6
* sock_addr
=
382 reinterpret_cast<sockaddr_in6
*> (addr
.get_addr ());
384 ip_addr_size
= sizeof sock_addr
->sin6_addr
;
385 ip_addr
= (char*) &sock_addr
->sin6_addr
;
387 # endif /* ACE_HAS_IPV6 */
389 // get the host entry for the address in question
390 hostent
* const hp
= ACE_OS::gethostbyaddr_r (ip_addr
,
397 // if it's not found in the host file or the DNS datase, there is nothing
398 // much we can do. embed the IP address
399 if (hp
== 0 || hp
->h_name
== 0)
403 ACELIB_DEBUG ((LM_DEBUG
,
404 ACE_TEXT ("(%P|%t) - ACE::get_fqdn, ")
405 ACE_TEXT ("canonical host name is %C\n"),
408 // check if the canonical name is the FQDN
409 if (!ACE_OS::strchr(hp
->h_name
, '.'))
416 // for every address and for every alias within the address, check and
417 // see if we can locate a FQDN
418 for (p
= hp
->h_addr_list
; *p
!= 0; ++p
)
420 for (q
= hp
->h_aliases
; *q
!= 0; ++q
)
422 if (ACE_OS::strchr(*q
, '.'))
424 // we got an FQDN from an alias. use this
425 if (ACE_OS::strlen (*q
) >= len
)
426 // the hostname is too huge to fit into a
427 // buffer of size MAXHOSTNAMELEN
428 // should we check other aliases as well
429 // before bailing out prematurely?
430 // for right now, let's do it. this (short name)
431 // is atleast better than embedding the IP
432 // address in the profile
436 ACELIB_DEBUG ((LM_DEBUG
,
437 ACE_TEXT ("(%P|%t) - ACE::get_fqdn, ")
438 ACE_TEXT ("found fqdn within alias as %C\n"),
440 ACE_OS::strcpy (hostname
, *q
);
448 // The canonical name may be an FQDN when we reach here.
449 // Alternatively, the canonical name (a non FQDN) may be the best
451 if (ACE_OS::strlen (hp
->h_name
) >= len
)
453 // The hostname is too large to fit into a buffer of size
459 ACE_OS::strcpy (hostname
, hp
->h_name
);
463 #endif /* ACE_LACKS_GETNAMEINFO */
466 #if defined (ACE_WIN32)
469 get_ip_interfaces_win32 (size_t &count
,
470 ACE_INET_Addr
*&addrs
)
472 # if defined (ACE_HAS_WINCE) && defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
473 // moved the ACE_HAS_WINCE impl ahaid of ACE_HAS_WINSOCK2 because
474 // WINCE in fact has winsock2, but doesn't properly support the
475 // WSAIoctl for obtaining IPv6 address info.
476 PIP_ADAPTER_ADDRESSES AdapterAddresses
= 0;
477 ULONG OutBufferLength
= 0;
479 unsigned char *octet_buffer
= 0;
482 GetAdaptersAddresses(AF_UNSPEC
,
488 if (RetVal
!= ERROR_BUFFER_OVERFLOW
)
493 ACE_NEW_RETURN (octet_buffer
, unsigned char[OutBufferLength
],-1);
494 AdapterAddresses
= (IP_ADAPTER_ADDRESSES
*)octet_buffer
;
497 GetAdaptersAddresses(AF_UNSPEC
,
503 if (RetVal
!= NO_ERROR
)
505 delete [] octet_buffer
;
509 // If successful, output some information from the data we received
510 PIP_ADAPTER_ADDRESSES AdapterList
= AdapterAddresses
;
513 if (AdapterList
->OperStatus
== IfOperStatusUp
)
515 if (AdapterList
->IfIndex
!= 0)
517 if (AdapterList
->Ipv6IfIndex
!= 0)
520 AdapterList
= AdapterList
->Next
;
523 AdapterList
= AdapterAddresses
;
525 ACE_NEW_RETURN (addrs
, ACE_INET_Addr
[count
],-1);
527 for (AdapterList
= AdapterAddresses
;
529 AdapterList
= AdapterList
->Next
)
531 if (AdapterList
->OperStatus
!= IfOperStatusUp
)
534 IP_ADAPTER_UNICAST_ADDRESS
*uni
= 0;
535 if (AdapterList
->IfIndex
!= 0)
536 for (uni
= AdapterList
->FirstUnicastAddress
;
540 SOCKET_ADDRESS
*sa_addr
= &uni
->Address
;
541 if (sa_addr
->lpSockaddr
->sa_family
== AF_INET
)
543 sockaddr_in
*sin
= (sockaddr_in
*)sa_addr
->lpSockaddr
;
544 addrs
[count
].set(sin
,sa_addr
->iSockaddrLength
);
549 if (AdapterList
->Ipv6IfIndex
!= 0)
551 for (uni
= AdapterList
->FirstUnicastAddress
;
555 SOCKET_ADDRESS
*sa_addr
= &uni
->Address
;
556 if (sa_addr
->lpSockaddr
->sa_family
== AF_INET6
)
558 sockaddr_in
*sin
= (sockaddr_in
*)sa_addr
->lpSockaddr
;
559 addrs
[count
].set(sin
,sa_addr
->iSockaddrLength
);
567 delete [] octet_buffer
;
570 # elif defined (ACE_HAS_PHARLAP)
571 // PharLap ETS has its own kernel routines to rummage through the device
572 // configs and extract the interface info, but only for Pharlap RT.
573 # if !defined (ACE_HAS_PHARLAP_RT)
574 ACE_NOTSUP_RETURN (-1);
575 # endif /* ACE_HAS_PHARLAP_RT */
577 // Locate all of the IP devices in the system, saving a DEVHANDLE
578 // for each. Then allocate the ACE_INET_Addrs needed and fetch all
579 // the IP addresses. To locate the devices, try the available
580 // device name roots and increment the device number until the
581 // kernel says there are no more of that type.
582 const size_t ACE_MAX_ETS_DEVICES
= 64; // Arbitrary, but should be enough.
583 DEVHANDLE ip_dev
[ACE_MAX_ETS_DEVICES
];
584 EK_TCPIPCFG
*devp
= 0;
586 ACE_TCHAR dev_name
[16];
589 for (i
= 0; count
< ACE_MAX_ETS_DEVICES
; i
++, ++count
)
592 ACE_OS::sprintf (dev_name
,
595 ip_dev
[count
] = EtsTCPGetDeviceHandle (dev_name
);
596 if (ip_dev
[count
] == 0)
599 for (i
= 0; count
< ACE_MAX_ETS_DEVICES
; i
++, ++count
)
602 ACE_OS::sprintf (dev_name
,
605 ip_dev
[count
] = EtsTCPGetDeviceHandle (dev_name
);
606 if (ip_dev
[count
] == 0)
609 for (i
= 0; count
< ACE_MAX_ETS_DEVICES
; i
++, ++count
)
612 ACE_OS::sprintf (dev_name
,
615 ip_dev
[count
] = EtsTCPGetDeviceHandle (dev_name
);
616 if (ip_dev
[count
] == 0)
621 ACE_NEW_RETURN (addrs
,
622 ACE_INET_Addr
[count
],
627 for (i
= 0, j
= 0; i
< count
; i
++)
629 devp
= EtsTCPGetDeviceCfg (ip_dev
[i
]);
634 0); // Already in net order.
637 // There's no call to close the DEVHANDLE.
641 if (count
== 0 && addrs
!= 0)
651 // All non-CE, non-Pharlap Windows. Must support Winsock2.
653 int i
, n_interfaces
, status
;
655 INTERFACE_INFO info
[64];
658 // Get an (overlapped) DGRAM socket to test with
659 sock
= socket (AF_INET
, SOCK_DGRAM
, 0);
660 if (sock
== INVALID_SOCKET
)
664 status
= WSAIoctl(sock
,
665 SIO_GET_INTERFACE_LIST
,
674 if (status
== SOCKET_ERROR
)
677 n_interfaces
= bytes
/ sizeof(INTERFACE_INFO
);
679 // SIO_GET_INTERFACE_LIST does not work for IPv6
680 // Instead recent versions of Winsock2 add the new opcode
681 // SIO_ADDRESS_LIST_QUERY.
682 // If this is not available forget about IPv6 local interfaces:-/
683 int n_v6_interfaces
= 0;
685 # if defined (ACE_HAS_IPV6) && defined (SIO_ADDRESS_LIST_QUERY)
687 LPSOCKET_ADDRESS_LIST v6info
;
689 DWORD buflen
= sizeof (SOCKET_ADDRESS_LIST
) + (63 * sizeof (SOCKET_ADDRESS
));
690 ACE_NEW_RETURN (buffer
,
693 v6info
= reinterpret_cast<LPSOCKET_ADDRESS_LIST
> (buffer
);
695 // Get an (overlapped) DGRAM socket to test with.
696 // If it fails only return IPv4 interfaces.
697 sock
= socket (AF_INET6
, SOCK_DGRAM
, IPPROTO_UDP
);
698 if (sock
!= INVALID_SOCKET
)
700 status
= WSAIoctl(sock
,
701 SIO_ADDRESS_LIST_QUERY
,
710 if (status
!= SOCKET_ERROR
)
711 n_v6_interfaces
= v6info
->iAddressCount
;
713 # endif /* ACE_HAS_IPV6 */
715 ACE_NEW_RETURN (addrs
,
716 ACE_INET_Addr
[n_interfaces
+ n_v6_interfaces
],
719 // Now go through the list and transfer the good ones to the list of
720 // because they're down or don't have an IP address.
721 for (count
= 0, i
= 0; i
< n_interfaces
; ++i
)
723 LPINTERFACE_INFO lpii
;
724 struct sockaddr_in
*addrp
= 0;
727 if (!(lpii
->iiFlags
& IFF_UP
))
730 // We assume IPv4 addresses here
731 addrp
= reinterpret_cast<struct sockaddr_in
*> (&lpii
->iiAddress
.AddressIn
);
732 if (addrp
->sin_addr
.s_addr
== INADDR_ANY
)
735 // Set the address for the caller.
736 addrs
[count
].set(addrp
, sizeof(sockaddr_in
));
740 # if defined (ACE_HAS_IPV6) && defined (SIO_ADDRESS_LIST_QUERY)
741 // Now go through the list and transfer the good ones to the list of
742 // because they're down or don't have an IP address.
743 for (i
= 0; i
< n_v6_interfaces
; i
++)
745 struct sockaddr_in6
*addr6p
;
747 if (v6info
->Address
[i
].lpSockaddr
->sa_family
!= AF_INET6
)
750 addr6p
= reinterpret_cast<struct sockaddr_in6
*> (v6info
->Address
[i
].lpSockaddr
);
751 if (IN6_IS_ADDR_UNSPECIFIED(&addr6p
->sin6_addr
)) // IN6ADDR_ANY?
754 // Set the address for the caller.
755 addrs
[count
].set(reinterpret_cast<struct sockaddr_in
*> (addr6p
), sizeof(sockaddr_in6
));
759 delete [] buffer
; // Clean up
760 # endif /* ACE_HAS_IPV6 */
770 # endif /* ACE_HAS_WINCE */
773 #elif defined (ACE_HAS_GETIFADDRS)
775 get_ip_interfaces_getifaddrs (size_t &count
,
776 ACE_INET_Addr
*&addrs
)
778 // Take advantage of the BSD getifaddrs function that simplifies
779 // access to connected interfaces.
780 struct ifaddrs
*ifap
= 0;
781 struct ifaddrs
*p_if
= 0;
783 if (::getifaddrs (&ifap
) != 0)
786 // Count number of interfaces.
788 for (p_if
= ifap
; p_if
!= 0; p_if
= p_if
->ifa_next
)
791 // Now create and initialize output array.
792 ACE_NEW_RETURN (addrs
,
793 ACE_INET_Addr
[num_ifs
],
794 -1); // caller must free
796 // Pull the address out of each INET interface. Not every interface
797 // is for IP, so be careful to count properly. When setting the
798 // INET_Addr, note that the 3rd arg (0) says to leave the byte order
799 // (already in net byte order from the interface structure) as is.
804 p_if
= p_if
->ifa_next
)
806 if (p_if
->ifa_addr
== 0)
809 // Check to see if it's up.
810 if ((p_if
->ifa_flags
& IFF_UP
) != IFF_UP
)
813 if (p_if
->ifa_addr
->sa_family
== AF_INET
)
815 struct sockaddr_in
*addr
=
816 reinterpret_cast<sockaddr_in
*> (p_if
->ifa_addr
);
818 // Sometimes the kernel returns 0.0.0.0 as the interface
819 // address, skip those...
820 if (addr
->sin_addr
.s_addr
!= INADDR_ANY
)
822 addrs
[count
].set ((u_short
) 0,
823 addr
->sin_addr
.s_addr
,
828 # if defined (ACE_HAS_IPV6)
829 else if (p_if
->ifa_addr
->sa_family
== AF_INET6
)
831 struct sockaddr_in6
*addr
=
832 reinterpret_cast<sockaddr_in6
*> (p_if
->ifa_addr
);
834 // Skip the ANY address
835 if (!IN6_IS_ADDR_UNSPECIFIED(&addr
->sin6_addr
))
837 addrs
[count
].set(reinterpret_cast<struct sockaddr_in
*> (addr
),
838 sizeof(sockaddr_in6
));
842 # endif /* ACE_HAS_IPV6 */
845 ::freeifaddrs (ifap
);
849 #elif defined (__hpux)
851 get_ip_interfaces_hpux (size_t &count
,
852 ACE_INET_Addr
*&addrs
)
855 size_t num_ifs_found
= 0;
857 // Call specific routine as necessary.
858 ACE_HANDLE handle
= ACE_OS::socket (PF_INET
, SOCK_DGRAM
, 0);
859 ACE_HANDLE handle_ipv6
= ACE_INVALID_HANDLE
;
861 if (handle
== ACE_INVALID_HANDLE
)
862 ACELIB_ERROR_RETURN ((LM_ERROR
,
864 ACE_TEXT ("ACE::get_ip_interfaces:open")),
868 int tmp_how_many
= 0;
870 result
= ACE_OS::ioctl (handle
,
872 (caddr_t
) &tmp_how_many
);
874 num_ifs
= (size_t)tmp_how_many
;
876 # if defined (ACE_HAS_IPV6)
878 handle_ipv6
= ACE_OS::socket (PF_INET6
, SOCK_DGRAM
, 0);
879 result
= ACE_OS::ioctl (handle_ipv6
,
881 (caddr_t
) &tmp_how_many
);
883 num_ifs
+= (size_t)tmp_how_many
;
888 ACE_OS::close (handle
);
889 ACE_OS::close (handle_ipv6
);
893 // ioctl likes to have an extra IFREQ structure to mark the end of
894 // what it returned, so increase the num_ifs by one.
897 //HPUX requires two passes, First for IPv4, then for IPv6
899 struct ifreq
*ifs
= 0;
901 struct ifreq
[num_ifs
],
903 ACE_OS::memset (ifs
, 0, num_ifs
* sizeof (struct ifreq
));
905 ACE_Auto_Array_Ptr
<struct ifreq
> p_ifs (ifs
);
907 if (p_ifs
.get() == 0)
909 ACE_OS::close (handle
);
910 ACE_OS::close (handle_ipv6
);
916 ACE_OS::memset (&ifcfg
, 0, sizeof (struct ifconf
));
918 ifcfg
.ifc_req
= p_ifs
.get ();
919 ifcfg
.ifc_len
= num_ifs
* sizeof (struct ifreq
);
921 if (ACE_OS::ioctl (handle
,
923 (char *) &ifcfg
) == -1)
925 ACE_OS::close (handle
);
926 ACELIB_ERROR_RETURN ((LM_ERROR
,
928 ACE_TEXT ("ACE::get_ip_interfaces:")
929 ACE_TEXT ("ioctl - SIOCGIFCONF failed")),
933 ACE_OS::close (handle
);
935 // Now create and initialize output array.
937 ACE_NEW_RETURN (addrs
,
938 ACE_INET_Addr
[num_ifs
],
939 -1); // caller must free
941 struct ifreq
*pcur
= p_ifs
.get ();
942 num_ifs_found
= ifcfg
.ifc_len
/ sizeof (struct ifreq
); // get the number of returned ifs
948 struct sockaddr_in
*addr
=
949 reinterpret_cast<sockaddr_in
*> (&pcur
->ifr_addr
);
950 if (addr
->sin_addr
.s_addr
!= 0)
952 addrs
[count
].set ((u_short
) 0,
953 addr
->sin_addr
.s_addr
,
960 # if defined (ACE_HAS_IPV6)
962 if (handle_ipv6
!= ACE_INVALID_HANDLE
)
964 struct if_laddrreq
*lifs
= 0;
965 ACE_NEW_RETURN (lifs
,
966 struct if_laddrreq
[num_ifs
],
968 ACE_OS::memset (lifs
, 0, num_ifs
* sizeof (struct if_laddrreq
));
970 ACE_Auto_Array_Ptr
<struct if_laddrreq
> p_lifs (lifs
);
972 if (p_lifs
.get() == 0)
974 ACE_OS::close (handle
);
975 ACE_OS::close (handle_ipv6
);
980 struct if_laddrconf lifcfg
;
981 ACE_OS::memset (&lifcfg
, 0, sizeof (struct if_laddrconf
));
983 lifcfg
.iflc_req
= p_lifs
.get ();
984 lifcfg
.iflc_len
= num_ifs
* sizeof (struct if_laddrreq
);
986 if (ACE_OS::ioctl (handle_ipv6
,
988 (char *) &lifcfg
) == -1)
990 ACE_OS::close (handle
);
991 ACELIB_ERROR_RETURN ((LM_ERROR
,
993 ACE_TEXT ("ACE::get_ip_interfaces:")
994 ACE_TEXT ("ioctl - SIOCGLIFCONF failed")),
998 ACE_OS::close (handle_ipv6
);
1000 struct if_laddrreq
*plcur
= p_lifs
.get ();
1001 num_ifs_found
= lifcfg
.iflc_len
/ sizeof (struct if_laddrreq
);
1007 struct sockaddr_in
*addr
=
1008 reinterpret_cast<sockaddr_in
*> (&plcur
->iflr_addr
);
1009 if (!IN6_IS_ADDR_UNSPECIFIED(&reinterpret_cast<sockaddr_in6
*>(addr
)->sin6_addr
))
1011 addrs
[count
].set(addr
, sizeof(struct sockaddr_in6
));
1017 # endif /* ACE_HAS_IPV6 */
1020 #elif defined (_AIX)
1022 get_ip_interfaces_aix (size_t &count
,
1023 ACE_INET_Addr
*&addrs
)
1025 ACE_HANDLE handle
= ACE::get_handle();
1029 if (handle
== ACE_INVALID_HANDLE
)
1030 ACELIB_ERROR_RETURN ((LM_ERROR
,
1032 ACE_TEXT ("ACE::get_ip_interfaces_aix:")),
1035 if (ACE_OS::ioctl (handle
,
1037 (caddr_t
)&ifc
.ifc_len
) == -1)
1039 ACE_OS::close (handle
);
1040 ACELIB_ERROR_RETURN((LM_ERROR
,
1042 ACE_TEXT ("get ifconf size")),
1046 ACE_NEW_RETURN (ifc
.ifc_buf
,char [ifc
.ifc_len
], -1);
1048 ACE_Auto_Array_Ptr
<char> safe_buf (ifc
.ifc_buf
);
1049 ACE_OS::memset (safe_buf
.get(), 0, ifc
.ifc_len
);
1051 if (ACE_OS::ioctl(handle
, SIOCGIFCONF
, (caddr_t
)&ifc
) == -1)
1053 ACE_OS::close (handle
);
1054 ACELIB_ERROR_RETURN((LM_ERROR
,
1056 ACE_TEXT ("get ifconf")),
1060 ACE_OS::close (handle
);
1062 char *buf_start
= safe_buf
.get();
1063 char *buf_end
= buf_start
+ ifc
.ifc_len
;
1066 for (char *ptr
= buf_start
; ptr
< buf_end
; )
1068 struct ifreq
*req
= reinterpret_cast<struct ifreq
*>(ptr
);
1070 ptr
+= req
->ifr_addr
.sa_len
;
1071 if (req
->ifr_addr
.sa_family
== AF_INET
1072 # if defined (ACE_HAS_IPV6)
1073 || req
->ifr_addr
.sa_family
== AF_INET6
1078 ACE_NEW_RETURN (addrs
,ACE_INET_Addr
[num_ifs
], -1);
1080 for (char * ptr
= buf_start
; ptr
< buf_end
; )
1082 struct ifreq
*req
= reinterpret_cast<struct ifreq
*>(ptr
);
1083 // skip the interface name
1085 if (req
->ifr_addr
.sa_family
== AF_INET
1086 # if defined (ACE_HAS_IPV6)
1087 || req
->ifr_addr
.sa_family
== AF_INET6
1091 sockaddr_in
*addr
= (sockaddr_in
*)&req
->ifr_addr
;
1092 addrs
[count
++].set(addr
, addr
->sin_len
);
1094 ptr
+= req
->ifr_addr
.sa_len
;
1100 #endif // ACE_WIN32 || ACE_HAS_GETIFADDRS || __hpux || _AIX
1103 // return an array of all configured IP interfaces on this host, count
1104 // rc = 0 on success (count == number of interfaces else -1 caller is
1105 // responsible for calling delete [] on parray
1108 ACE::get_ip_interfaces (size_t &count
, ACE_INET_Addr
*&addrs
)
1110 ACE_TRACE ("ACE::get_ip_interfaces");
1115 #if defined (ACE_WIN32)
1116 return get_ip_interfaces_win32 (count
, addrs
);
1117 #elif defined (ACE_HAS_GETIFADDRS)
1118 return get_ip_interfaces_getifaddrs (count
, addrs
);
1119 #elif defined (__hpux)
1120 return get_ip_interfaces_hpux (count
, addrs
);
1121 #elif defined (_AIX)
1122 return get_ip_interfaces_aix (count
, addrs
);
1123 #elif (defined (__unix) || defined (__unix__) || defined (ACE_OPENVMS) || (defined (ACE_VXWORKS) && !defined (ACE_HAS_GETIFADDRS)) || defined (ACE_HAS_RTEMS)) && !defined (ACE_LACKS_NETWORKING)
1124 // COMMON (SVR4 and BSD) UNIX CODE
1126 // Call specific routine as necessary.
1127 ACE_HANDLE handle
= ACE::get_handle();
1129 if (handle
== ACE_INVALID_HANDLE
)
1130 ACELIB_ERROR_RETURN ((LM_ERROR
,
1132 ACE_TEXT ("ACE::get_ip_interfaces:open")),
1137 if (ACE::count_interfaces (handle
, num_ifs
))
1139 ACE_OS::close (handle
);
1143 // ioctl likes to have an extra ifreq structure to mark the end of
1144 // what it returned, so increase the num_ifs by one.
1147 struct IFREQ
*ifs
= 0;
1148 ACE_NEW_RETURN (ifs
,
1149 struct IFREQ
[num_ifs
],
1151 ACE_OS::memset (ifs
, 0, num_ifs
* sizeof (struct IFREQ
));
1153 ACE_Auto_Array_Ptr
<struct IFREQ
> p_ifs (ifs
);
1155 if (p_ifs
.get() == 0)
1157 ACE_OS::close (handle
);
1162 struct IFCONF ifcfg
;
1163 ACE_OS::memset (&ifcfg
, 0, sizeof (struct IFCONF
));
1166 ifcfg
.IFC_FAMILY
= AF_UNSPEC
; // request all families be returned
1167 ifcfg
.IFC_FLAGS
= 0;
1170 ifcfg
.IFC_REQ
= p_ifs
.get ();
1171 ifcfg
.IFC_LEN
= num_ifs
* sizeof (struct IFREQ
);
1173 if (ACE_OS::ioctl (handle
,
1175 (caddr_t
) &ifcfg
) == -1)
1177 ACE_OS::close (handle
);
1178 ACELIB_ERROR_RETURN ((LM_ERROR
,
1180 ACE_TEXT ("ACE::get_ip_interfaces:")
1181 ACE_TEXT ("ioctl - SIOCGIFCONF failed")),
1185 ACE_OS::close (handle
);
1187 // Now create and initialize output array.
1189 ACE_NEW_RETURN (addrs
,
1190 ACE_INET_Addr
[num_ifs
],
1191 -1); // caller must free
1193 struct IFREQ
*pcur
= p_ifs
.get ();
1194 size_t num_ifs_found
= ifcfg
.IFC_LEN
/ sizeof (struct IFREQ
); // get the number of returned ifs
1196 // Pull the address out of each INET interface. Not every interface
1197 // is for IP, so be careful to count properly. When setting the
1198 // INET_Addr, note that the 3rd arg (0) says to leave the byte order
1199 // (already in net byte order from the interface structure) as is.
1206 if (pcur
->IFR_ADDR
.SA_FAMILY
== AF_INET
1207 # if defined (ACE_HAS_IPV6)
1208 || pcur
->IFR_ADDR
.SA_FAMILY
== AF_INET6
1213 struct sockaddr_in
*addr
=
1214 reinterpret_cast<sockaddr_in
*> (&pcur
->IFR_ADDR
);
1216 // Sometimes the kernel returns 0.0.0.0 as an IPv4 interface
1217 // address; skip those...
1218 if (addr
->sin_addr
.s_addr
!= 0
1219 # if defined (ACE_HAS_IPV6)
1220 || (addr
->sin_family
== AF_INET6
&&
1221 !IN6_IS_ADDR_UNSPECIFIED(&reinterpret_cast<sockaddr_in6
*>(addr
)->sin6_addr
))
1225 int addrlen
= static_cast<int> (sizeof (struct sockaddr_in
));
1226 # if defined (ACE_HAS_IPV6)
1227 if (addr
->sin_family
== AF_INET6
)
1228 addrlen
= static_cast<int> (sizeof (struct sockaddr_in6
));
1230 addrs
[count
].set (addr
, addrlen
);
1235 #if !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) && !defined (ACE_HAS_RTEMS) && !defined (__Lynx__)
1238 if (pcur
->ifr_addr
.sa_len
<= sizeof (struct sockaddr
))
1244 pcur
= (struct ifreq
*)
1245 (pcur
->ifr_addr
.sa_len
+ (caddr_t
) &pcur
->ifr_addr
);
1247 #endif /* !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) && !defined (ACE_HAS_RTEMS) && !defined (__Lynx__) */
1250 # if defined (ACE_HAS_IPV6) && !defined (ACE_LACKS_FSCANF)
1251 // Retrieve IPv6 local interfaces by scanning /proc/net/if_inet6 if
1252 // it exists. If we cannot open it then ignore possible IPv6
1253 // interfaces, we did our best;-)
1258 struct addrinfo hints
, *res0
;
1261 ACE_OS::memset (&hints
, 0, sizeof (hints
));
1262 hints
.ai_flags
= AI_NUMERICHOST
;
1263 hints
.ai_family
= AF_INET6
;
1265 if ((fp
= ACE_OS::fopen (ACE_TEXT ("/proc/net/if_inet6"), ACE_TEXT ("r"))) != 0)
1268 "%4s%4s%4s%4s%4s%4s%4s%4s %02x %*02x %*02x %*02x %*8s\n",
1269 addr_p
[0], addr_p
[1], addr_p
[2], addr_p
[3],
1270 addr_p
[4], addr_p
[5], addr_p
[6], addr_p
[7], &scopeid
) != EOF
)
1272 // Format the address intoa proper IPv6 decimal address specification and
1273 // resolve the resulting text using getaddrinfo().
1275 const char* ip_fmt
= "%s:%s:%s:%s:%s:%s:%s:%s%%%d";
1276 ACE_OS::snprintf (s_ipaddr
, 64, ip_fmt
,
1277 addr_p
[0], addr_p
[1], addr_p
[2], addr_p
[3],
1278 addr_p
[4], addr_p
[5], addr_p
[6], addr_p
[7],
1281 error
= ACE_OS::getaddrinfo (s_ipaddr
, 0, &hints
, &res0
);
1285 if (res0
->ai_family
== AF_INET6
&&
1286 !IN6_IS_ADDR_UNSPECIFIED (&reinterpret_cast<sockaddr_in6
*> (res0
->ai_addr
)->sin6_addr
))
1288 addrs
[count
].set(reinterpret_cast<sockaddr_in
*> (res0
->ai_addr
), res0
->ai_addrlen
);
1291 ACE_OS::freeaddrinfo (res0
);
1294 ACE_OS::fclose (fp
);
1296 # endif /* ACE_HAS_IPV6 && !ACE_LACKS_FSCANF */
1300 ACE_UNUSED_ARG (count
);
1301 ACE_UNUSED_ARG (addrs
);
1302 ACE_NOTSUP_RETURN (-1); // no implementation
1303 #endif /* ACE_WIN32 */
1306 // Helper routine for get_ip_interfaces, differs by UNIX platform so
1307 // put into own subroutine. perform some ioctls to retrieve ifconf
1308 // list of ifreq structs.
1311 ACE::count_interfaces (ACE_HANDLE handle
, size_t &how_many
)
1313 #if defined (SIOCGIFNUM)
1314 # if defined (SIOCGLIFNUM) && !defined (ACE_LACKS_STRUCT_LIFNUM)
1315 int cmd
= SIOCGLIFNUM
;
1316 struct lifnum if_num
= {AF_UNSPEC
,0,0};
1318 int cmd
= SIOCGIFNUM
;
1320 # endif /* SIOCGLIFNUM */
1321 if (ACE_OS::ioctl (handle
, cmd
, (caddr_t
)&if_num
) == -1)
1322 ACELIB_ERROR_RETURN ((LM_ERROR
,
1324 ACE_TEXT ("ACE::count_interfaces:")
1325 ACE_TEXT ("ioctl - SIOCGLIFNUM failed")),
1327 # if defined (SIOCGLIFNUM) && !defined (ACE_LACKS_STRUCT_LIFNUM)
1328 how_many
= if_num
.lifn_count
;
1331 # endif /* SIOCGLIFNUM */
1334 #elif (defined (__unix) || defined (__unix__) || defined (ACE_OPENVMS) || defined (ACE_HAS_RTEMS) || (defined (ACE_VXWORKS) && !defined (ACE_HAS_GETIFADDRS))) && !defined (ACE_LACKS_NETWORKING)
1335 // Note: DEC CXX doesn't define "unix". BSD compatible OS: HP UX,
1336 // AIX, SunOS 4.x perform some ioctls to retrieve ifconf list of
1337 // ifreq structs no SIOCGIFNUM on SunOS 4.x, so use guess and scan
1340 // Probably hard to put this many ifs in a unix box..
1341 int const MAX_INTERFACES
= 50;
1343 // HACK - set to an unreasonable number
1344 int const num_ifs
= MAX_INTERFACES
;
1346 struct ifconf ifcfg
;
1347 size_t ifreq_size
= num_ifs
* sizeof (struct ifreq
);
1348 struct ifreq
*p_ifs
;
1350 #if defined (ACE_HAS_ALLOC_HOOKS)
1351 p_ifs
= (struct IFREQ
*)ACE_Allocator::instance()->malloc (ifreq_size
);
1353 p_ifs
= (struct ifreq
*) ACE_OS::malloc (ifreq_size
);
1354 #endif /* ACE_HAS_ALLOC_HOOKS */
1362 ACE_OS::memset (p_ifs
, 0, ifreq_size
);
1363 ACE_OS::memset (&ifcfg
, 0, sizeof (struct ifconf
));
1365 ifcfg
.ifc_req
= p_ifs
;
1366 ifcfg
.ifc_len
= ifreq_size
;
1368 if (ACE_OS::ioctl (handle
,
1370 (caddr_t
) &ifcfg
) == -1)
1372 #if defined (ACE_HAS_ALLOC_HOOKS)
1373 ACE_Allocator::instance()->free (ifcfg
.ifc_req
);
1375 ACE_OS::free (ifcfg
.ifc_req
);
1376 #endif /* ACE_HAS_ALLOC_HOOKS */
1378 ACELIB_ERROR_RETURN ((LM_ERROR
,
1380 ACE_TEXT ("ACE::count_interfaces:")
1381 ACE_TEXT ("ioctl - SIOCGIFCONF failed")),
1388 // get if address out of ifreq buffers. ioctl puts a blank-named
1389 // interface to mark the end of the returned interfaces.
1394 /* In OpenBSD, the length of the list is returned. */
1395 ifcfg
.ifc_len
-= sizeof (struct ifreq
);
1396 if (ifcfg
.ifc_len
< 0)
1400 # if !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) && !defined (ACE_HAS_RTEMS) && !defined (__Lynx__)
1403 if (p_ifs
->ifr_addr
.sa_len
<= sizeof (struct sockaddr
))
1409 p_ifs
= (struct ifreq
*)
1410 (p_ifs
->ifr_addr
.sa_len
+ (caddr_t
) &p_ifs
->ifr_addr
);
1412 # endif /* !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) && !defined (ACE_HAS_RTEMS) && !defined (__Lynx__) */
1415 #if defined (ACE_HAS_ALLOC_HOOKS)
1416 ACE_Allocator::instance()->free (ifcfg
.ifc_req
);
1418 ACE_OS::free (ifcfg
.ifc_req
);
1419 #endif /* ACE_HAS_ALLOC_HOOKS */
1421 # if defined (ACE_HAS_IPV6)
1424 if ((fp
= ACE_OS::fopen (ACE_TEXT ("/proc/net/if_inet6"), ACE_TEXT ("r"))) != 0)
1426 // Scan the lines according to the expected format but don't really read any input
1427 while (fscanf (fp
, "%*32s %*02x %*02x %*02x %*02x %*8s\n") != EOF
)
1431 ACE_OS::fclose (fp
);
1433 # endif /* ACE_HAS_IPV6 && !ACE_LACKS_FSCANF */
1435 how_many
= if_count
;
1438 ACE_UNUSED_ARG (handle
);
1439 ACE_UNUSED_ARG (how_many
);
1440 ACE_NOTSUP_RETURN (-1); // no implementation
1441 #endif /* sparc && SIOCGIFNUM */
1444 // Routine to return a handle from which ioctl() requests can be made.
1447 ACE::get_handle (void)
1450 ACE_HANDLE handle
= ACE_INVALID_HANDLE
;
1452 handle
= ACE_OS::open ("/dev/udp", O_RDONLY
);
1453 #elif defined (__unix) || defined (__unix__) || defined (_AIX) || defined (__hpux) || (defined (ACE_VXWORKS) && (ACE_VXWORKS >= 0x600)) || defined (ACE_OPENVMS) || defined (ACE_HAS_RTEMS)
1454 // Note: DEC CXX doesn't define "unix" BSD compatible OS: HP UX,
1457 handle
= ACE_OS::socket (PF_INET
, SOCK_DGRAM
, 0);
1463 #if defined (ACE_HAS_IPV6)
1465 ip_check (int &ipvn_enabled
, int pf
)
1467 // We only get to this point if ipvn_enabled was -1 in the caller.
1468 // Perform Double-Checked Locking Optimization.
1469 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex
, ace_mon
,
1470 *ACE_Static_Object_Lock::instance (), 0));
1472 if (ipvn_enabled
== -1)
1475 #if defined (ACE_WIN32)
1476 // as of the release of Windows 2008, even hosts that have IPv6 interfaces disabled
1477 // will still permit the creation of a PF_INET6 socket, thus rendering the socket
1478 // creation test inconsistent. The recommended solution is to get the list of
1479 // endpoint addresses and see if any match the desired family.
1480 ACE_INET_Addr
*if_addrs
= 0;
1483 ipvn_enabled
= 1; // assume enabled to avoid recursion during interface lookup.
1484 ACE::get_ip_interfaces (if_cnt
, if_addrs
);
1486 for (size_t i
= 0; ipvn_enabled
== 0 && i
< if_cnt
; i
++)
1488 ipvn_enabled
= (if_addrs
[i
].get_type () == pf
);
1492 // Determine if the kernel has IPv6 support by attempting to
1493 // create a PF_INET6 socket and see if it fails.
1494 ACE_HANDLE
const s
= ACE_OS::socket (pf
, SOCK_DGRAM
, 0);
1495 if (s
== ACE_INVALID_HANDLE
)
1502 ACE_OS::closesocket (s
);
1506 return ipvn_enabled
;
1508 #endif /* ACE_HAS_IPV6 */
1511 ACE::ipv4_enabled (void)
1513 #if defined (ACE_HAS_IPV6)
1514 return static_cast<bool> (ace_ipv4_enabled
== -1 ?
1515 ::ip_check (ace_ipv4_enabled
, PF_INET
) :
1518 // Assume it's always enabled since ACE requires some version of
1521 #endif /* ACE_HAS_IPV6*/
1525 ACE::ipv6_enabled (void)
1527 #if defined (ACE_HAS_IPV6)
1528 return ace_ipv6_enabled
== -1 ?
1529 ::ip_check (ace_ipv6_enabled
, PF_INET6
) :
1531 #else /* ACE_HAS_IPV6 */
1533 #endif /* !ACE_HAS_IPV6 */
1536 ACE_END_VERSIONED_NAMESPACE_DECL