1 // $Id: Sock_Connect.cpp 82276 2008-07-09 17:35:49Z jtc $
3 #include "ace/Sock_Connect.h"
4 #include "ace/INET_Addr.h"
5 #include "ace/Log_Msg.h"
6 #include "ace/Handle_Set.h"
7 #include "ace/Auto_Ptr.h"
8 #include "ace/SString.h"
9 #include "ace/OS_Memory.h"
10 #include "ace/OS_NS_stdio.h"
14 # include "ace/OS_NS_fcntl.h"
17 #include "ace/OS_NS_stdlib.h"
18 #include "ace/OS_NS_string.h"
19 #include "ace/OS_NS_sys_socket.h"
20 #include "ace/OS_NS_netdb.h"
21 #include "ace/OS_NS_unistd.h"
22 #include "ace/os_include/net/os_if.h"
24 #if defined (ACE_HAS_IPV6)
25 # include "ace/Guard_T.h"
26 # include "ace/Recursive_Thread_Mutex.h"
28 # include /**/ <netinet/in6_var.h>
30 #endif /* ACE_HAS_IPV6 */
32 # if defined (ACE_HAS_GETIFADDRS)
33 # if defined (ACE_VXWORKS)
34 # include /**/ <net/ifaddrs.h>
36 # include /**/ <ifaddrs.h>
37 # endif /*ACE_VXWORKS */
38 # endif /* ACE_HAS_GETIFADDRS */
40 #if defined (ACE_VXWORKS) && (ACE_VXWORKS < 0x600)
41 #include /**/ <inetLib.h>
42 #include /**/ <netinet/in_var.h>
43 #if defined (ACE_HAS_IPV6)
44 #include /**/ <ifLib.h>
46 extern struct in_ifaddr
* in_ifaddr
;
47 extern LIST_HEAD(in_ifaddrhashhead
, in_ifaddr
) *in_ifaddrhashtbl
;
49 #endif /* ACE_HAS_IPV6 */
50 #include "ace/OS_NS_stdio.h"
51 #endif /* ACE_VXWORKS < 0x600 */
53 #if defined (ACE_VXWORKS) && ((ACE_VXWORKS == 0x630) || (ACE_VXWORKS == 0x640)) && defined (__RTP__) && defined (ACE_HAS_IPV6)
54 const struct in6_addr in6addr_any
= IN6ADDR_ANY_INIT
;
55 const struct in6_addr in6addr_nodelocal_allnodes
= IN6ADDR_NODELOCAL_ALLNODES_INIT
;
56 const struct in6_addr in6addr_linklocal_allnodes
= IN6ADDR_LINKLOCAL_ALLNODES_INIT
;
57 const struct in6_addr in6addr_linklocal_allrouters
= IN6ADDR_LINKLOCAL_ALLROUTERS_INIT
;
58 #endif /* ACE_VXWORKS == 0x630 && __RTP__ && ACE_HAS_IPV6 */
60 #if defined (ACE_HAS_WINCE)
61 #include /**/ <Iphlpapi.h>
62 // The following code is suggested by microsoft as a workaround to the fact
63 // that on Windows CE, these constants are exported as function addresses
64 // rather than simply values.
65 # include /**/ <ws2tcpip.h>
66 const struct in6_addr in6addr_any
= IN6ADDR_ANY_INIT
;
67 const struct in6_addr in6addr_loopback
= IN6ADDR_LOOPBACK_INIT
;
68 #endif // ACE_HAS_WINCE
70 #if defined (ACE_WIN32) && defined (ACE_HAS_PHARLAP)
71 # include "ace/OS_NS_stdio.h"
74 #if defined (ACE_HAS_IPV6)
76 // These defines support a generic usage based on
77 // the various SIGCF*IF ioctl implementations
79 # if defined (SIOCGLIFCONF)
80 # define SIOCGIFCONF_CMD SIOCGLIFCONF
82 # define IFREQ if_laddrreq
83 # define IFCONF if_laddrconf
84 # define IFC_REQ iflc_req
85 # define IFC_LEN iflc_len
86 # define IFC_BUF iflc_buf
87 # define IFR_ADDR iflr_addr
88 # define IFR_NAME iflr_name
89 # define IFR_FLAGS iflr_flags
91 # define SA_FAMILY sa_family
94 # define IFCONF lifconf
95 # define IFC_REQ lifc_req
96 # define IFC_LEN lifc_len
97 # define IFC_BUF lifc_buf
98 # define IFR_ADDR lifr_addr
99 # define IFR_NAME lifr_name
100 # define IFR_FLAGS lifr_flags
102 # define IFC_FAMILY lifc_family
103 # define IFC_FLAGS lifc_flags
104 # define SA_FAMILY ss_family
107 # define SIOCGIFCONF_CMD SIOCGIFCONF
109 # define IFCONF ifconf
110 # define IFC_REQ ifc_req
111 # define IFC_LEN ifc_len
112 # define IFC_BUF ifc_buf
113 # define IFR_ADDR ifr_addr
114 # define IFR_NAME ifr_name
115 # define IFR_FLAGS ifr_flags
117 # define SA_FAMILY sa_family
118 # endif /* SIOCGLIFCONF */
120 # if defined (ACE_HAS_THREADS)
121 # include "ace/Object_Manager.h"
122 # endif /* ACE_HAS_THREADS */
127 // Used internally so not exported.
129 // Does this box have ipv4 turned on?
130 int ace_ipv4_enabled
= -1;
132 // Does this box have ipv6 turned on?
133 int ace_ipv6_enabled
= -1;
136 #else /* ACE_HAS_IPV6 */
137 # define SIOCGIFCONF_CMD SIOCGIFCONF
139 # define IFCONF ifconf
140 # define IFC_REQ ifc_req
141 # define IFC_LEN ifc_len
142 # define IFC_BUF ifc_buf
143 # define IFR_ADDR ifr_addr
144 # define IFR_NAME ifr_name
145 # define IFR_FLAGS ifr_flags
147 # define SA_FAMILY sa_family
148 #endif /* ACE_HAS_IPV6 */
150 // This is a hack to work around a problem with Visual Age C++ 5 and 6 on AIX.
151 // Without this, the compiler auto-instantiates the ACE_Auto_Array_Ptr for
152 // ifreq (contained in this module) but only adds the #include for <net/if.h>
153 // and not the one for <sys/socket.h> which is also needed. Although we
154 // don't need the template defined here, it makes the compiler pull in
155 // <sys/socket.h> and the build runs clean.
156 #if defined (AIX) && defined (__IBMCPP__) && (__IBMCPP__ >= 500) && (__IBMCPP__ < 700)
157 static ACE_Auto_Array_Ptr
<sockaddr
> force_compiler_to_include_socket_h
;
158 #endif /* AIX && __IBMCPP__ >= 500 */
163 "$Id: Sock_Connect.cpp 82276 2008-07-09 17:35:49Z jtc $")
166 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
168 // Bind socket to an unused port.
171 ACE::bind_port (ACE_HANDLE handle
, ACE_UINT32 ip_addr
, int address_family
)
173 ACE_TRACE ("ACE::bind_port");
177 #if defined (ACE_HAS_IPV6)
178 if (address_family
!= PF_INET6
)
179 // What do we do if it is PF_"INET6? Since it's 4 bytes, it must be an
180 // IPV4 address. Is there a difference? Why is this test done? dhinton
181 #else /* ACE_HAS_IPV6 */
182 ACE_UNUSED_ARG (address_family
);
183 #endif /* !ACE_HAS_IPV6 */
184 addr
= ACE_INET_Addr ((u_short
)0, ip_addr
);
185 #if defined (ACE_HAS_IPV6)
186 else if (ip_addr
!= INADDR_ANY
)
187 // address_family == PF_INET6 and a non default IP address means to bind
188 // to the IPv4-mapped IPv6 address
189 addr
.set ((u_short
)0, ip_addr
, 1, 1);
190 #endif /* ACE_HAS_IPV6 */
192 // The OS kernel should select a free port for us.
193 return ACE_OS::bind (handle
,
194 (sockaddr
*)addr
.get_addr(),
199 ACE::get_bcast_addr (ACE_UINT32
&bcast_addr
,
200 const ACE_TCHAR
*host_name
,
201 ACE_UINT32 host_addr
,
204 ACE_TRACE ("ACE::get_bcast_addr");
206 #if defined (ACE_LACKS_GET_BCAST_ADDR)
207 ACE_UNUSED_ARG (bcast_addr
);
208 ACE_UNUSED_ARG (host_name
);
209 ACE_UNUSED_ARG (host_addr
);
210 ACE_UNUSED_ARG (handle
);
211 ACE_NOTSUP_RETURN (-1);
212 #elif !defined(ACE_WIN32) && !defined(__INTERIX)
213 ACE_HANDLE s
= handle
;
215 if (s
== ACE_INVALID_HANDLE
)
216 s
= ACE_OS::socket (AF_INET
, SOCK_STREAM
, 0);
218 if (s
== ACE_INVALID_HANDLE
)
219 ACE_ERROR_RETURN ((LM_ERROR
,
221 ACE_TEXT ("ACE_OS::socket")),
227 ifc
.ifc_len
= sizeof buf
;
230 // Get interface structure and initialize the addresses using UNIX
232 if (ACE_OS::ioctl (s
, SIOCGIFCONF_CMD
, (char *) &ifc
) == -1)
233 ACE_ERROR_RETURN ((LM_ERROR
,
235 ACE_TEXT ("ACE::get_bcast_addr:")
236 ACE_TEXT ("ioctl (get interface configuration)")),
239 struct ifreq
*ifr
= ifc
.ifc_req
;
241 struct sockaddr_in ip_addr
;
243 // Get host ip address if necessary.
246 hostent
*hp
= ACE_OS::gethostbyname (ACE_TEXT_ALWAYS_CHAR (host_name
));
251 #if !defined(_UNICOS)
252 ACE_OS::memcpy ((char *) &ip_addr
.sin_addr
.s_addr
,
257 ACE_UINT64 haddr
; // a place to put the address
258 char * haddrp
= (char *) &haddr
; // convert to char pointer
259 ACE_OS::memcpy(haddrp
,(char *) hp
->h_addr
,hp
->h_length
);
260 ip_addr
.sin_addr
.s_addr
= haddr
;
262 #endif /* ! _UNICOS */
266 ACE_OS::memset ((void *) &ip_addr
, 0, sizeof ip_addr
);
267 #if !defined(_UNICOS)
268 ACE_OS::memcpy ((void *) &ip_addr
.sin_addr
,
270 sizeof ip_addr
.sin_addr
);
272 ip_addr
.sin_addr
.s_addr
= host_addr
; // just copy to the bitfield
273 #endif /* ! _UNICOS */
276 #if !defined(AIX) && !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__)
277 for (int n
= ifc
.ifc_len
/ sizeof (struct ifreq
) ; n
> 0;
280 // see mk_broadcast@SOCK_Dgram_Bcast.cpp
281 for (int nbytes
= ifc
.ifc_len
; nbytes
>= (int) sizeof (struct ifreq
) &&
282 ((ifr
->ifr_addr
.sa_len
> sizeof (struct sockaddr
)) ?
283 (nbytes
>= (int) sizeof (ifr
->ifr_name
) + ifr
->ifr_addr
.sa_len
) : 1);
284 ((ifr
->ifr_addr
.sa_len
> sizeof (struct sockaddr
)) ?
285 (nbytes
-= sizeof (ifr
->ifr_name
) + ifr
->ifr_addr
.sa_len
,
286 ifr
= (struct ifreq
*)
287 ((caddr_t
) &ifr
->ifr_addr
+ ifr
->ifr_addr
.sa_len
)) :
288 (nbytes
-= sizeof (struct ifreq
), ifr
++)))
289 #endif /* !defined(AIX) && !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) */
291 struct sockaddr_in if_addr
;
293 // Compare host ip address with interface ip address.
294 ACE_OS::memcpy (&if_addr
,
298 if (ip_addr
.sin_addr
.s_addr
!= if_addr
.sin_addr
.s_addr
)
301 if (ifr
->ifr_addr
.sa_family
!= AF_INET
)
303 ACE_ERROR ((LM_ERROR
,
305 ACE_TEXT ("ACE::get_bcast_addr:")
306 ACE_TEXT ("Not AF_INET")));
310 struct ifreq flags
= *ifr
;
311 struct ifreq if_req
= *ifr
;
313 if (ACE_OS::ioctl (s
, SIOCGIFFLAGS
, (char *) &flags
) == -1)
315 ACE_ERROR ((LM_ERROR
,
317 ACE_TEXT ("ACE::get_bcast_addr:")
318 ACE_TEXT (" ioctl (get interface flags)")));
322 if (ACE_BIT_DISABLED (flags
.ifr_flags
, IFF_UP
))
324 ACE_ERROR ((LM_ERROR
,
326 ACE_TEXT ("ACE::get_bcast_addr:")
327 ACE_TEXT ("Network interface is not up")));
331 if (ACE_BIT_ENABLED (flags
.ifr_flags
, IFF_LOOPBACK
))
334 if (ACE_BIT_ENABLED (flags
.ifr_flags
, IFF_BROADCAST
))
336 if (ACE_OS::ioctl (s
,
338 (char *) &if_req
) == -1)
339 ACE_ERROR ((LM_ERROR
,
341 ACE_TEXT ("ACE::get_bcast_addr:")
342 ACE_TEXT ("ioctl (get broadaddr)")));
345 ACE_OS::memcpy (&ip_addr
,
346 &if_req
.ifr_broadaddr
,
347 sizeof if_req
.ifr_broadaddr
);
349 ACE_OS::memcpy ((void *) &host_addr
,
350 (void *) &ip_addr
.sin_addr
,
353 if (handle
== ACE_INVALID_HANDLE
)
356 bcast_addr
= host_addr
;
361 ACE_ERROR ((LM_ERROR
,
363 ACE_TEXT ("ACE::get_bcast_addr:")
364 ACE_TEXT ("Broadcast is not enable for this interface.")));
366 if (handle
== ACE_INVALID_HANDLE
)
369 bcast_addr
= host_addr
;
375 ACE_UNUSED_ARG (handle
);
376 ACE_UNUSED_ARG (host_addr
);
377 ACE_UNUSED_ARG (host_name
);
378 bcast_addr
= (ACE_UINT32 (INADDR_BROADCAST
));
380 #endif /* !ACE_WIN32 && !__INTERIX */
384 ACE::get_fqdn (ACE_INET_Addr
const & addr
,
388 int h_error
; // Not the same as errno!
390 ACE_HOSTENT_DATA buf
;
393 int ip_addr_size
= 0;
394 if (addr
.get_type () == AF_INET
)
396 sockaddr_in
* const sock_addr
=
397 reinterpret_cast<sockaddr_in
*> (addr
.get_addr ());
398 ip_addr_size
= sizeof sock_addr
->sin_addr
;
399 ip_addr
= (char*) &sock_addr
->sin_addr
;
404 sockaddr_in6
* sock_addr
=
405 reinterpret_cast<sockaddr_in6
*> (addr
.get_addr ());
407 ip_addr_size
= sizeof sock_addr
->sin6_addr
;
408 ip_addr
= (char*) &sock_addr
->sin6_addr
;
410 #endif /* ACE_HAS_IPV6 */
412 // get the host entry for the address in question
413 hostent
* const hp
= ACE_OS::gethostbyaddr_r (ip_addr
,
420 // if it's not found in the host file or the DNS datase, there is nothing
421 // much we can do. embed the IP address
422 if (hp
== 0 || hp
->h_name
== 0)
426 ACE_DEBUG ((LM_DEBUG
,
427 ACE_TEXT ("(%P|%t) - ACE::get_fqdn, ")
428 ACE_TEXT ("canonical host name is %s\n"),
429 ACE_TEXT_CHAR_TO_TCHAR (hp
->h_name
)));
431 // check if the canonical name is the FQDN
432 if (!ACE_OS::strchr(hp
->h_name
, '.'))
439 // for every address and for every alias within the address, check and
440 // see if we can locate a FQDN
441 for (p
= hp
->h_addr_list
; *p
!= 0; ++p
)
443 for (q
= hp
->h_aliases
; *q
!= 0; ++q
)
445 if (ACE_OS::strchr(*q
, '.'))
447 // we got an FQDN from an alias. use this
448 if (ACE_OS::strlen (*q
) >= len
)
449 // the hostname is too huge to fit into a
450 // buffer of size MAXHOSTNAMELEN
451 // should we check other aliases as well
452 // before bailing out prematurely?
453 // for right now, let's do it. this (short name)
454 // is atleast better than embedding the IP
455 // address in the profile
459 ACE_DEBUG ((LM_DEBUG
,
460 ACE_TEXT ("(%P|%t) - ACE::get_fqdn, ")
461 ACE_TEXT ("found fqdn within alias as %s\n"),
462 ACE_TEXT_CHAR_TO_TCHAR(*q
)));
463 ACE_OS::strcpy (hostname
, *q
);
471 // The canonical name may be an FQDN when we reach here.
472 // Alternatively, the canonical name (a non FQDN) may be the best
474 if (ACE_OS::strlen (hp
->h_name
) >= len
)
476 // The hostname is too large to fit into a buffer of size
482 ACE_OS::strcpy (hostname
, hp
->h_name
);
488 #if defined (ACE_WIN32)
491 get_ip_interfaces_win32 (size_t &count
,
492 ACE_INET_Addr
*&addrs
)
494 # if defined (ACE_HAS_WINCE)
495 // moved the ACE_HAS_WINCE impl ahaid of ACE_HAS_WINSOCK2 because
496 // WINCE in fact has winsock2, but doesn't properly support the
497 // WSAIoctl for obtaining IPv6 address info.
498 PIP_ADAPTER_ADDRESSES AdapterAddresses
= 0;
499 ULONG OutBufferLength
= 0;
501 unsigned char *octet_buffer
= 0;
504 GetAdaptersAddresses(AF_UNSPEC
,
510 if (RetVal
!= ERROR_BUFFER_OVERFLOW
)
515 ACE_NEW_RETURN (octet_buffer
, unsigned char[OutBufferLength
],-1);
516 AdapterAddresses
= (IP_ADAPTER_ADDRESSES
*)octet_buffer
;
519 GetAdaptersAddresses(AF_UNSPEC
,
525 if (RetVal
!= NO_ERROR
)
527 delete [] octet_buffer
;
531 // If successful, output some information from the data we received
532 PIP_ADAPTER_ADDRESSES AdapterList
= AdapterAddresses
;
535 if (AdapterList
->OperStatus
== IfOperStatusUp
)
537 if (AdapterList
->IfIndex
!= 0)
539 if (AdapterList
->Ipv6IfIndex
!= 0)
542 AdapterList
= AdapterList
->Next
;
545 AdapterList
= AdapterAddresses
;
547 ACE_NEW_RETURN (addrs
, ACE_INET_Addr
[count
],-1);
549 for (AdapterList
= AdapterAddresses
;
551 AdapterList
= AdapterList
->Next
)
553 if (AdapterList
->OperStatus
!= IfOperStatusUp
)
556 IP_ADAPTER_UNICAST_ADDRESS
*uni
= 0;
557 if (AdapterList
->IfIndex
!= 0)
558 for (uni
= AdapterList
->FirstUnicastAddress
;
562 SOCKET_ADDRESS
*sa_addr
= &uni
->Address
;
563 if (sa_addr
->lpSockaddr
->sa_family
== AF_INET
)
565 sockaddr_in
*sin
= (sockaddr_in
*)sa_addr
->lpSockaddr
;
566 addrs
[count
].set(sin
,sa_addr
->iSockaddrLength
);
571 if (AdapterList
->Ipv6IfIndex
!= 0)
573 for (uni
= AdapterList
->FirstUnicastAddress
;
577 SOCKET_ADDRESS
*sa_addr
= &uni
->Address
;
578 if (sa_addr
->lpSockaddr
->sa_family
== AF_INET6
)
580 sockaddr_in
*sin
= (sockaddr_in
*)sa_addr
->lpSockaddr
;
581 addrs
[count
].set(sin
,sa_addr
->iSockaddrLength
);
589 delete [] octet_buffer
;
592 # elif defined (ACE_HAS_PHARLAP)
593 // PharLap ETS has its own kernel routines to rummage through the device
594 // configs and extract the interface info, but only for Pharlap RT.
595 # if !defined (ACE_HAS_PHARLAP_RT)
596 ACE_NOTSUP_RETURN (-1);
597 # endif /* ACE_HAS_PHARLAP_RT */
599 // Locate all of the IP devices in the system, saving a DEVHANDLE
600 // for each. Then allocate the ACE_INET_Addrs needed and fetch all
601 // the IP addresses. To locate the devices, try the available
602 // device name roots and increment the device number until the
603 // kernel says there are no more of that type.
604 const size_t ACE_MAX_ETS_DEVICES
= 64; // Arbitrary, but should be enough.
605 DEVHANDLE ip_dev
[ACE_MAX_ETS_DEVICES
];
608 ACE_TCHAR dev_name
[16];
611 for (i
= 0; count
< ACE_MAX_ETS_DEVICES
; i
++, ++count
)
614 ACE_OS::sprintf (dev_name
,
617 ip_dev
[count
] = EtsTCPGetDeviceHandle (dev_name
);
618 if (ip_dev
[count
] == 0)
621 for (i
= 0; count
< ACE_MAX_ETS_DEVICES
; i
++, ++count
)
624 ACE_OS::sprintf (dev_name
,
627 ip_dev
[count
] = EtsTCPGetDeviceHandle (dev_name
);
628 if (ip_dev
[count
] == 0)
631 for (i
= 0; count
< ACE_MAX_ETS_DEVICES
; i
++, ++count
)
634 ACE_OS::sprintf (dev_name
,
637 ip_dev
[count
] = EtsTCPGetDeviceHandle (dev_name
);
638 if (ip_dev
[count
] == 0)
643 ACE_NEW_RETURN (addrs
,
644 ACE_INET_Addr
[count
],
649 for (i
= 0, j
= 0; i
< count
; i
++)
651 devp
= EtsTCPGetDeviceCfg (ip_dev
[i
]);
656 0); // Already in net order.
659 // There's no call to close the DEVHANDLE.
663 if (count
== 0 && addrs
!= 0)
673 // All non-CE, non-Pharlap Windows. Must support Winsock2.
675 int i
, n_interfaces
, status
;
677 INTERFACE_INFO info
[64];
680 // Get an (overlapped) DGRAM socket to test with
681 sock
= socket (AF_INET
, SOCK_DGRAM
, 0);
682 if (sock
== INVALID_SOCKET
)
686 status
= WSAIoctl(sock
,
687 SIO_GET_INTERFACE_LIST
,
696 if (status
== SOCKET_ERROR
)
699 n_interfaces
= bytes
/ sizeof(INTERFACE_INFO
);
701 // SIO_GET_INTERFACE_LIST does not work for IPv6
702 // Instead recent versions of Winsock2 add the new opcode
703 // SIO_ADDRESS_LIST_QUERY.
704 // If this is not available forget about IPv6 local interfaces:-/
705 int n_v6_interfaces
= 0;
707 # if defined (ACE_HAS_IPV6) && defined (SIO_ADDRESS_LIST_QUERY)
709 LPSOCKET_ADDRESS_LIST v6info
;
711 DWORD buflen
= sizeof (SOCKET_ADDRESS_LIST
) + (63 * sizeof (SOCKET_ADDRESS
));
712 ACE_NEW_RETURN (buffer
,
715 v6info
= reinterpret_cast<LPSOCKET_ADDRESS_LIST
> (buffer
);
717 // Get an (overlapped) DGRAM socket to test with.
718 // If it fails only return IPv4 interfaces.
719 sock
= socket (AF_INET6
, SOCK_DGRAM
, IPPROTO_UDP
);
720 if (sock
!= INVALID_SOCKET
)
722 status
= WSAIoctl(sock
,
723 SIO_ADDRESS_LIST_QUERY
,
732 if (status
!= SOCKET_ERROR
)
733 n_v6_interfaces
= v6info
->iAddressCount
;
735 # endif /* ACE_HAS_IPV6 */
737 ACE_NEW_RETURN (addrs
,
738 ACE_INET_Addr
[n_interfaces
+ n_v6_interfaces
],
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 (count
= 0, i
= 0; i
< n_interfaces
; ++i
)
745 LPINTERFACE_INFO lpii
;
746 struct sockaddr_in
*addrp
= 0;
749 if (!(lpii
->iiFlags
& IFF_UP
))
752 // We assume IPv4 addresses here
753 addrp
= reinterpret_cast<struct sockaddr_in
*> (&lpii
->iiAddress
.AddressIn
);
754 if (addrp
->sin_addr
.s_addr
== INADDR_ANY
)
757 // Set the address for the caller.
758 addrs
[count
].set(addrp
, sizeof(sockaddr_in
));
762 # if defined (ACE_HAS_IPV6) && defined (SIO_ADDRESS_LIST_QUERY)
763 // Now go through the list and transfer the good ones to the list of
764 // because they're down or don't have an IP address.
765 for (i
= 0; i
< n_v6_interfaces
; i
++)
767 struct sockaddr_in6
*addr6p
;
769 if (v6info
->Address
[i
].lpSockaddr
->sa_family
!= AF_INET6
)
772 addr6p
= reinterpret_cast<struct sockaddr_in6
*> (v6info
->Address
[i
].lpSockaddr
);
773 if (IN6_IS_ADDR_UNSPECIFIED(&addr6p
->sin6_addr
)) // IN6ADDR_ANY?
776 // Set the address for the caller.
777 addrs
[count
].set(reinterpret_cast<struct sockaddr_in
*> (addr6p
), sizeof(sockaddr_in6
));
781 delete [] buffer
; // Clean up
782 # endif /* ACE_HAS_IPV6 */
792 # endif /* ACE_HAS_WINCE */
794 #elif defined (ACE_HAS_GETIFADDRS)
796 get_ip_interfaces_getifaddrs (size_t &count
,
797 ACE_INET_Addr
*&addrs
)
799 // Take advantage of the BSD getifaddrs function that simplifies
800 // access to connected interfaces.
801 struct ifaddrs
*ifap
= 0;
802 struct ifaddrs
*p_if
= 0;
804 if (::getifaddrs (&ifap
) != 0)
807 // Count number of interfaces.
809 for (p_if
= ifap
; p_if
!= 0; p_if
= p_if
->ifa_next
)
812 // Now create and initialize output array.
813 ACE_NEW_RETURN (addrs
,
814 ACE_INET_Addr
[num_ifs
],
815 -1); // caller must free
817 // Pull the address out of each INET interface. Not every interface
818 // is for IP, so be careful to count properly. When setting the
819 // INET_Addr, note that the 3rd arg (0) says to leave the byte order
820 // (already in net byte order from the interface structure) as is.
825 p_if
= p_if
->ifa_next
)
827 if (p_if
->ifa_addr
&&
828 p_if
->ifa_addr
->sa_family
== AF_INET
)
830 struct sockaddr_in
*addr
=
831 reinterpret_cast<sockaddr_in
*> (p_if
->ifa_addr
);
833 // Sometimes the kernel returns 0.0.0.0 as the interface
834 // address, skip those...
835 if (addr
->sin_addr
.s_addr
!= INADDR_ANY
)
837 addrs
[count
].set ((u_short
) 0,
838 addr
->sin_addr
.s_addr
,
843 # if defined (ACE_HAS_IPV6)
844 else if (p_if
->ifa_addr
&&
845 p_if
->ifa_addr
->sa_family
== AF_INET6
)
847 struct sockaddr_in6
*addr
=
848 reinterpret_cast<sockaddr_in6
*> (p_if
->ifa_addr
);
850 // Skip the ANY address
851 if (!IN6_IS_ADDR_UNSPECIFIED(&addr
->sin6_addr
))
853 addrs
[count
].set(reinterpret_cast<struct sockaddr_in
*> (addr
),
854 sizeof(sockaddr_in6
));
858 # endif /* ACE_HAS_IPV6 */
861 ::freeifaddrs (ifap
);
865 #elif defined (__hpux)
867 get_ip_interfaces_hpux (size_t &count
,
868 ACE_INET_Addr
*&addrs
)
871 size_t num_ifs_found
= 0;
873 // Call specific routine as necessary.
874 ACE_HANDLE handle
= ACE_OS::socket (PF_INET
, SOCK_DGRAM
, 0);
875 ACE_HANDLE handle_ipv6
= ACE_INVALID_HANDLE
;
877 if (handle
== ACE_INVALID_HANDLE
)
878 ACE_ERROR_RETURN ((LM_ERROR
,
880 ACE_TEXT ("ACE::get_ip_interfaces:open")),
884 int tmp_how_many
= 0;
886 result
= ACE_OS::ioctl (handle
,
888 (caddr_t
) &tmp_how_many
);
890 num_ifs
= (size_t)tmp_how_many
;
892 # if defined (ACE_HAS_IPV6)
894 handle_ipv6
= ACE_OS::socket (PF_INET6
, SOCK_DGRAM
, 0);
895 result
= ACE_OS::ioctl (handle_ipv6
,
897 (caddr_t
) &tmp_how_many
);
899 num_ifs
+= (size_t)tmp_how_many
;
904 ACE_OS::close (handle
);
905 ACE_OS::close (handle_ipv6
);
909 // ioctl likes to have an extra IFREQ structure to mark the end of
910 // what it returned, so increase the num_ifs by one.
913 //HPUX requires two passes, First for IPv4, then for IPv6
915 struct ifreq
*ifs
= 0;
917 struct ifreq
[num_ifs
],
919 ACE_OS::memset (ifs
, 0, num_ifs
* sizeof (struct ifreq
));
921 ACE_Auto_Array_Ptr
<struct ifreq
> p_ifs (ifs
);
923 if (p_ifs
.get() == 0)
925 ACE_OS::close (handle
);
926 ACE_OS::close (handle_ipv6
);
932 ACE_OS::memset (&ifcfg
, 0, sizeof (struct ifconf
));
934 ifcfg
.ifc_req
= p_ifs
.get ();
935 ifcfg
.ifc_len
= num_ifs
* sizeof (struct ifreq
);
937 if (ACE_OS::ioctl (handle
,
939 (char *) &ifcfg
) == -1)
941 ACE_OS::close (handle
);
942 ACE_ERROR_RETURN ((LM_ERROR
,
944 ACE_TEXT ("ACE::get_ip_interfaces:")
945 ACE_TEXT ("ioctl - SIOCGIFCONF failed")),
949 ACE_OS::close (handle
);
951 // Now create and initialize output array.
953 ACE_NEW_RETURN (addrs
,
954 ACE_INET_Addr
[num_ifs
],
955 -1); // caller must free
957 struct ifreq
*pcur
= p_ifs
.get ();
958 num_ifs_found
= ifcfg
.ifc_len
/ sizeof (struct ifreq
); // get the number of returned ifs
964 struct sockaddr_in
*addr
=
965 reinterpret_cast<sockaddr_in
*> (&pcur
->ifr_addr
);
966 if (addr
->sin_addr
.s_addr
!= 0)
968 addrs
[count
].set ((u_short
) 0,
969 addr
->sin_addr
.s_addr
,
976 # if defined (ACE_HAS_IPV6)
978 if (handle_ipv6
!= ACE_INVALID_HANDLE
)
980 struct if_laddrreq
*lifs
= 0;
981 ACE_NEW_RETURN (lifs
,
982 struct if_laddrreq
[num_ifs
],
984 ACE_OS::memset (lifs
, 0, num_ifs
* sizeof (struct if_laddrreq
));
986 ACE_Auto_Array_Ptr
<struct if_laddrreq
> p_lifs (lifs
);
988 if (p_lifs
.get() == 0)
990 ACE_OS::close (handle
);
991 ACE_OS::close (handle_ipv6
);
996 struct if_laddrconf lifcfg
;
997 ACE_OS::memset (&lifcfg
, 0, sizeof (struct if_laddrconf
));
999 lifcfg
.iflc_req
= p_lifs
.get ();
1000 lifcfg
.iflc_len
= num_ifs
* sizeof (struct if_laddrreq
);
1002 if (ACE_OS::ioctl (handle_ipv6
,
1004 (char *) &lifcfg
) == -1)
1006 ACE_OS::close (handle
);
1007 ACE_ERROR_RETURN ((LM_ERROR
,
1009 ACE_TEXT ("ACE::get_ip_interfaces:")
1010 ACE_TEXT ("ioctl - SIOCGLIFCONF failed")),
1014 ACE_OS::close (handle_ipv6
);
1016 struct if_laddrreq
*plcur
= p_lifs
.get ();
1017 num_ifs_found
= lifcfg
.iflc_len
/ sizeof (struct if_laddrreq
);
1023 struct sockaddr_in
*addr
=
1024 reinterpret_cast<sockaddr_in
*> (&plcur
->iflr_addr
);
1025 if (!IN6_IS_ADDR_UNSPECIFIED(&reinterpret_cast<sockaddr_in6
*>(addr
)->sin6_addr
))
1027 addrs
[count
].set(addr
, sizeof(struct sockaddr_in6
));
1033 # endif /* ACE_HAS_IPV6 */
1036 #elif defined (_AIX)
1038 get_ip_interfaces_aix (size_t &count
,
1039 ACE_INET_Addr
*&addrs
)
1041 ACE_HANDLE handle
= ACE::get_handle();
1045 if (handle
== ACE_INVALID_HANDLE
)
1046 ACE_ERROR_RETURN ((LM_ERROR
,
1048 ACE_TEXT ("ACE::get_ip_interfaces_aix:")),
1051 if (ACE_OS::ioctl (handle
,
1053 (caddr_t
)&ifc
.ifc_len
) == -1)
1055 ACE_OS::close (handle
);
1056 ACE_ERROR_RETURN((LM_ERROR
,
1058 ACE_TEXT ("get ifconf size")),
1062 ACE_NEW_RETURN (ifc
.ifc_buf
,char [ifc
.ifc_len
], -1);
1064 ACE_Auto_Array_Ptr
<char> safe_buf (ifc
.ifc_buf
);
1065 ACE_OS::memset (safe_buf
.get(), 0, ifc
.ifc_len
);
1067 if (ACE_OS::ioctl(handle
, SIOCGIFCONF
, (caddr_t
)&ifc
) == -1)
1069 ACE_OS::close (handle
);
1070 ACE_ERROR_RETURN((LM_ERROR
,
1072 ACE_TEXT ("get ifconf")),
1076 ACE_OS::close (handle
);
1078 char *buf_start
= safe_buf
.get();
1079 char *buf_end
= buf_start
+ ifc
.ifc_len
;
1082 for (char *ptr
= buf_start
; ptr
< buf_end
; )
1084 struct ifreq
*req
= reinterpret_cast<struct ifreq
*>(ptr
);
1086 ptr
+= req
->ifr_addr
.sa_len
;
1087 if (req
->ifr_addr
.sa_family
== AF_INET
1088 # if defined (ACE_HAS_IPV6)
1089 || req
->ifr_addr
.sa_family
== AF_INET6
1094 ACE_NEW_RETURN (addrs
,ACE_INET_Addr
[num_ifs
], -1);
1096 for (char * ptr
= buf_start
; ptr
< buf_end
; )
1098 struct ifreq
*req
= reinterpret_cast<struct ifreq
*>(ptr
);
1099 // skip the interface name
1101 if (req
->ifr_addr
.sa_family
== AF_INET
1102 # if defined (ACE_HAS_IPV6)
1103 || req
->ifr_addr
.sa_family
== AF_INET6
1107 sockaddr_in
*addr
= (sockaddr_in
*)&req
->ifr_addr
;
1108 addrs
[count
++].set(addr
, addr
->sin_len
);
1110 ptr
+= req
->ifr_addr
.sa_len
;
1116 #elif defined (ACE_VXWORKS) && (ACE_VXWORKS < 0x600) && !defined (ACE_HAS_VXWORKS551_MEDUSA)
1118 get_ip_interfaces_vxworks_lt600 (size_t &count
,
1119 ACE_INET_Addr
*&addrs
)
1122 // Loop through each address structure
1124 # if defined (ACE_HAS_IPV6) && defined (TAILQ_ENTRY)
1125 # define ia_next ia_link.tqe_next
1126 # endif /* TAILQ_ENTRY */
1128 for (struct in_ifaddr
* ia
= in_ifaddr
; ia
!= 0; ia
= ia
->ia_next
)
1133 // Now create and initialize output array.
1134 ACE_NEW_RETURN (addrs
,
1135 ACE_INET_Addr
[count
],
1136 -1); // caller must free
1138 for (struct in_ifaddr
* ia
= in_ifaddr
; ia
!= 0; ia
= ia
->ia_next
)
1140 struct ifnet
* ifp
= ia
->ia_ifa
.ifa_ifp
;
1143 // Get the current interface name
1145 ACE_OS::sprintf(interface
, "%s%d", ifp
->if_name
, ifp
->if_unit
);
1147 // Get the address for the current interface
1148 char address
[INET_ADDR_LEN
];
1149 STATUS status
= ifAddrGet(interface
, address
);
1153 // Concatenate a ':' at the end. This is because in
1154 // ACE_INET_Addr::string_to_addr, the ip_address is
1155 // obtained using ':' as the delimiter. Since, using
1156 // ifAddrGet(), we just get the IP address, I am adding
1157 // a ":" to get with the general case.
1158 ACE_OS::strcat (address
, ":");
1159 addrs
[count
].set (address
);
1163 ACE_ERROR_RETURN ((LM_ERROR
,
1164 ACE_TEXT ("ACE::get_ip_interface failed\n")
1165 ACE_TEXT ("Couldnt get the IP Address\n")),
1173 #endif // ACE_WIN32 || ACE_HAS_GETIFADDRS || __hpux || _AIX || ACE_VXWORKS < 0x600
1176 // return an array of all configured IP interfaces on this host, count
1177 // rc = 0 on success (count == number of interfaces else -1 caller is
1178 // responsible for calling delete [] on parray
1181 ACE::get_ip_interfaces (size_t &count
,
1182 ACE_INET_Addr
*&addrs
)
1184 ACE_TRACE ("ACE::get_ip_interfaces");
1189 #if defined (ACE_WIN32)
1190 return get_ip_interfaces_win32 (count
, addrs
);
1191 #elif defined (ACE_HAS_GETIFADDRS)
1192 return get_ip_interfaces_getifaddrs (count
, addrs
);
1193 #elif defined (__hpux)
1194 return get_ip_interfaces_hpux (count
, addrs
);
1195 #elif defined (_AIX)
1196 return get_ip_interfaces_aix (count
, addrs
);
1197 #elif defined (ACE_VXWORKS) && (ACE_VXWORKS < 0x600) && !defined (ACE_HAS_VXWORKS551_MEDUSA)
1198 return get_ip_interfaces_vxworks_lt600 (count
, addrs
);
1199 #elif (defined (__unix) || defined (__unix__) || defined (__Lynx__) || defined (ACE_OPENVMS) || (defined (ACE_VXWORKS) && (ACE_VXWORKS == 0x650)) || defined (ACE_HAS_RTEMS)) && !defined (ACE_LACKS_NETWORKING)
1200 // COMMON (SVR4 and BSD) UNIX CODE
1202 // Call specific routine as necessary.
1203 ACE_HANDLE handle
= ACE::get_handle();
1205 if (handle
== ACE_INVALID_HANDLE
)
1206 ACE_ERROR_RETURN ((LM_ERROR
,
1208 ACE_TEXT ("ACE::get_ip_interfaces:open")),
1211 size_t num_ifs
, num_ifs_found
;
1213 if (ACE::count_interfaces (handle
, num_ifs
))
1215 ACE_OS::close (handle
);
1219 // ioctl likes to have an extra ifreq structure to mark the end of
1220 // what it returned, so increase the num_ifs by one.
1223 struct IFREQ
*ifs
= 0;
1224 ACE_NEW_RETURN (ifs
,
1225 struct IFREQ
[num_ifs
],
1227 ACE_OS::memset (ifs
, 0, num_ifs
* sizeof (struct IFREQ
));
1229 ACE_Auto_Array_Ptr
<struct IFREQ
> p_ifs (ifs
);
1231 if (p_ifs
.get() == 0)
1233 ACE_OS::close (handle
);
1238 struct IFCONF ifcfg
;
1239 ACE_OS::memset (&ifcfg
, 0, sizeof (struct IFCONF
));
1242 ifcfg
.IFC_FAMILY
= AF_UNSPEC
; // request all families be returned
1243 ifcfg
.IFC_FLAGS
= 0;
1246 ifcfg
.IFC_REQ
= p_ifs
.get ();
1247 ifcfg
.IFC_LEN
= num_ifs
* sizeof (struct IFREQ
);
1249 if (ACE_OS::ioctl (handle
,
1251 (caddr_t
) &ifcfg
) == -1)
1253 ACE_OS::close (handle
);
1254 ACE_ERROR_RETURN ((LM_ERROR
,
1256 ACE_TEXT ("ACE::get_ip_interfaces:")
1257 ACE_TEXT ("ioctl - SIOCGIFCONF failed")),
1261 ACE_OS::close (handle
);
1263 // Now create and initialize output array.
1265 ACE_NEW_RETURN (addrs
,
1266 ACE_INET_Addr
[num_ifs
],
1267 -1); // caller must free
1269 struct IFREQ
*pcur
= p_ifs
.get ();
1270 num_ifs_found
= ifcfg
.IFC_LEN
/ sizeof (struct IFREQ
); // get the number of returned ifs
1272 // Pull the address out of each INET interface. Not every interface
1273 // is for IP, so be careful to count properly. When setting the
1274 // INET_Addr, note that the 3rd arg (0) says to leave the byte order
1275 // (already in net byte order from the interface structure) as is.
1282 if (pcur
->IFR_ADDR
.SA_FAMILY
== AF_INET
1283 # if defined (ACE_HAS_IPV6)
1284 || pcur
->IFR_ADDR
.SA_FAMILY
== AF_INET6
1289 # if !defined(_UNICOS)
1290 struct sockaddr_in
*addr
=
1291 reinterpret_cast<sockaddr_in
*> (&pcur
->IFR_ADDR
);
1293 // Sometimes the kernel returns 0.0.0.0 as an IPv4 interface
1294 // address; skip those...
1295 if (addr
->sin_addr
.s_addr
!= 0
1296 # if defined (ACE_HAS_IPV6)
1297 || (addr
->sin_family
== AF_INET6
&&
1298 !IN6_IS_ADDR_UNSPECIFIED(&reinterpret_cast<sockaddr_in6
*>(addr
)->sin6_addr
))
1302 int addrlen
= static_cast<int> (sizeof (struct sockaddr_in
));
1303 # if defined (ACE_HAS_IPV6)
1304 if (addr
->sin_family
== AF_INET6
)
1305 addrlen
= static_cast<int> (sizeof (struct sockaddr_in6
));
1307 addrs
[count
].set (addr
, addrlen
);
1310 # else /* ! _UNICOS */
1311 // need to explicitly copy on the Cray, since the bitfields kinda
1312 // screw things up here
1313 struct sockaddr_in inAddr
;
1315 inAddr
.sin_len
= pcur
->IFR_ADDR
.sa_len
;
1316 inAddr
.sin_family
= pcur
->IFR_ADDR
.sa_family
;
1317 memcpy((void *)&(inAddr
.sin_addr
),
1318 (const void *)&(pcur
->IFR_ADDR
.sa_data
[8]),
1319 sizeof(struct in_addr
));
1321 if (inAddr
.sin_addr
.s_addr
!= 0)
1323 addrs
[count
].set(&inAddr
, sizeof(struct sockaddr_in
));
1326 # endif /* ! _UNICOS */
1329 #if !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) && !defined (ACE_HAS_RTEMS)
1332 if (pcur
->ifr_addr
.sa_len
<= sizeof (struct sockaddr
))
1338 pcur
= (struct ifreq
*)
1339 (pcur
->ifr_addr
.sa_len
+ (caddr_t
) &pcur
->ifr_addr
);
1341 #endif /* !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) */
1344 # if defined (ACE_HAS_IPV6)
1345 // Retrieve IPv6 local interfaces by scanning /proc/net/if_inet6 if
1346 // it exists. If we cannot open it then ignore possible IPv6
1347 // interfaces, we did our best;-)
1352 struct addrinfo hints
, *res0
;
1355 ACE_OS::memset (&hints
, 0, sizeof (hints
));
1356 hints
.ai_flags
= AI_NUMERICHOST
;
1357 hints
.ai_family
= AF_INET6
;
1359 if ((fp
= ACE_OS::fopen (ACE_TEXT ("/proc/net/if_inet6"), ACE_TEXT ("r"))) != 0)
1362 "%4s%4s%4s%4s%4s%4s%4s%4s %02x %*02x %*02x %*02x %*8s\n",
1363 addr_p
[0], addr_p
[1], addr_p
[2], addr_p
[3],
1364 addr_p
[4], addr_p
[5], addr_p
[6], addr_p
[7], &scopeid
) != EOF
)
1366 // Format the address intoa proper IPv6 decimal address specification and
1367 // resolve the resulting text using getaddrinfo().
1369 const char* ip_fmt
= "%s:%s:%s:%s:%s:%s:%s:%s%%%d";
1370 ACE_OS::sprintf (s_ipaddr
,
1372 addr_p
[0], addr_p
[1], addr_p
[2], addr_p
[3],
1373 addr_p
[4], addr_p
[5], addr_p
[6], addr_p
[7], scopeid
);
1375 error
= getaddrinfo (s_ipaddr
, 0, &hints
, &res0
);
1379 if (res0
->ai_family
== AF_INET6
&&
1380 !IN6_IS_ADDR_UNSPECIFIED (&reinterpret_cast<sockaddr_in6
*> (res0
->ai_addr
)->sin6_addr
))
1382 addrs
[count
].set(reinterpret_cast<sockaddr_in
*> (res0
->ai_addr
), res0
->ai_addrlen
);
1385 freeaddrinfo (res0
);
1388 ACE_OS::fclose (fp
);
1390 # endif /* ACE_HAS_IPV6 */
1394 ACE_UNUSED_ARG (count
);
1395 ACE_UNUSED_ARG (addrs
);
1396 ACE_NOTSUP_RETURN (-1); // no implementation
1397 #endif /* ACE_WIN32 */
1400 // Helper routine for get_ip_interfaces, differs by UNIX platform so
1401 // put into own subroutine. perform some ioctls to retrieve ifconf
1402 // list of ifreq structs.
1405 ACE::count_interfaces (ACE_HANDLE handle
,
1408 #if defined (ACE_WIN32) || defined (ACE_HAS_GETIFADDRS) || defined (__hpux) || defined (_AIX) || (defined (ACE_VXWORKS) && (ACE_VXWORKS < 0x600))
1409 // none of these platforms make use of count_interfaces
1410 ACE_UNUSED_ARG (handle
);
1411 ACE_UNUSED_ARG (how_many
);
1412 ACE_NOTSUP_RETURN (-1); // no implementation
1414 #elif defined (SIOCGIFNUM)
1415 # if defined (SIOCGLIFNUM)
1416 int cmd
= SIOCGLIFNUM
;
1417 struct lifnum if_num
= {AF_UNSPEC
,0,0};
1419 int cmd
= SIOCGIFNUM
;
1421 # endif /* SIOCGLIFNUM */
1422 if (ACE_OS::ioctl (handle
, cmd
, (caddr_t
)&if_num
) == -1)
1423 ACE_ERROR_RETURN ((LM_ERROR
,
1425 ACE_TEXT ("ACE::count_interfaces:")
1426 ACE_TEXT ("ioctl - SIOCGLIFNUM failed")),
1428 # if defined (SIOCGLIFNUM)
1429 how_many
= if_num
.lifn_count
;
1432 # endif /* SIOCGLIFNUM */
1435 #elif (defined (__unix) || defined (__unix__) || defined (__Lynx__) || defined (ACE_OPENVMS) || defined (ACE_HAS_RTEMS)) && !defined (ACE_LACKS_NETWORKING)
1436 // Note: DEC CXX doesn't define "unix". BSD compatible OS: HP UX,
1437 // AIX, SunOS 4.x perform some ioctls to retrieve ifconf list of
1438 // ifreq structs no SIOCGIFNUM on SunOS 4.x, so use guess and scan
1441 // Probably hard to put this many ifs in a unix box..
1442 const int MAX_IF
= 50;
1444 // HACK - set to an unreasonable number
1445 int num_ifs
= MAX_IF
;
1447 struct ifconf ifcfg
;
1448 size_t ifreq_size
= num_ifs
* sizeof (struct ifreq
);
1449 struct ifreq
*p_ifs
=
1450 (struct ifreq
*) ACE_OS::malloc (ifreq_size
);
1458 ACE_OS::memset (p_ifs
, 0, ifreq_size
);
1459 ACE_OS::memset (&ifcfg
, 0, sizeof (struct ifconf
));
1461 ifcfg
.ifc_req
= p_ifs
;
1462 ifcfg
.ifc_len
= ifreq_size
;
1464 if (ACE_OS::ioctl (handle
,
1466 (caddr_t
) &ifcfg
) == -1)
1468 ACE_OS::free (ifcfg
.ifc_req
);
1469 ACE_ERROR_RETURN ((LM_ERROR
,
1471 ACE_TEXT ("ACE::count_interfaces:")
1472 ACE_TEXT ("ioctl - SIOCGIFCONF failed")),
1476 int if_count
= 0, i
;
1478 // get if address out of ifreq buffers. ioctl puts a blank-named
1479 // interface to mark the end of the returned interfaces.
1484 /* In OpenBSD, the length of the list is returned. */
1485 ifcfg
.ifc_len
-= sizeof (struct ifreq
);
1486 if (ifcfg
.ifc_len
< 0)
1490 #if !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) && !defined (ACE_HAS_RTEMS)
1493 if (p_ifs
->ifr_addr
.sa_len
<= sizeof (struct sockaddr
))
1499 p_ifs
= (struct ifreq
*)
1500 (p_ifs
->ifr_addr
.sa_len
+ (caddr_t
) &p_ifs
->ifr_addr
);
1502 #endif /* !defined (__QNX__) && !defined (__FreeBSD__) && !defined(__NetBSD__) */
1505 ACE_OS::free (ifcfg
.ifc_req
);
1507 # if defined (ACE_HAS_IPV6)
1510 if ((fp
= ACE_OS::fopen (ACE_TEXT ("/proc/net/if_inet6"), ACE_TEXT ("r"))) != 0)
1512 // Scan the lines according to the expected format but don't really read any input
1513 while (fscanf (fp
, "%*32s %*02x %*02x %*02x %*02x %*8s\n") != EOF
)
1517 ACE_OS::fclose (fp
);
1519 # endif /* ACE_HAS_IPV6 */
1521 how_many
= if_count
;
1524 ACE_UNUSED_ARG (handle
);
1525 ACE_UNUSED_ARG (how_many
);
1526 ACE_NOTSUP_RETURN (-1); // no implementation
1527 #endif /* sparc && SIOCGIFNUM */
1530 // Routine to return a handle from which ioctl() requests can be made.
1533 ACE::get_handle (void)
1536 ACE_HANDLE handle
= ACE_INVALID_HANDLE
;
1538 handle
= ACE_OS::open ("/dev/udp", O_RDONLY
);
1539 #elif defined (__unix) || defined (__unix__) || defined (__Lynx__) || defined (_AIX) || defined (__hpux) || (defined (ACE_VXWORKS) && (ACE_VXWORKS >= 0x600)) || defined (ACE_OPENVMS) || defined (ACE_HAS_RTEMS)
1540 // Note: DEC CXX doesn't define "unix" BSD compatible OS: HP UX,
1543 handle
= ACE_OS::socket (PF_INET
, SOCK_DGRAM
, 0);
1549 #if defined (ACE_HAS_IPV6)
1551 ip_check (int &ipvn_enabled
, int pf
)
1553 // We only get to this point if ipvn_enabled was -1 in the caller.
1554 // Perform Double-Checked Locking Optimization.
1555 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex
, ace_mon
,
1556 *ACE_Static_Object_Lock::instance (), 0));
1558 if (ipvn_enabled
== -1)
1560 // Determine if the kernel has IPv6 support by attempting to
1561 // create a PF_INET socket and see if it fails.
1562 ACE_HANDLE
const s
= ACE_OS::socket (pf
, SOCK_DGRAM
, 0);
1563 if (s
== ACE_INVALID_HANDLE
)
1570 ACE_OS::closesocket (s
);
1573 return ipvn_enabled
;
1575 #endif /* ACE_HAS_IPV6 */
1578 ACE::ipv4_enabled (void)
1580 #if defined (ACE_HAS_IPV6)
1581 return static_cast<bool> (ace_ipv4_enabled
== -1 ?
1582 ::ip_check (ace_ipv4_enabled
, PF_INET
) :
1585 // Assume it's always enabled since ACE requires some version of
1588 #endif /* ACE_HAS_IPV6*/
1592 ACE::ipv6_enabled (void)
1594 #if defined (ACE_HAS_IPV6)
1595 return ace_ipv6_enabled
== -1 ?
1596 ::ip_check (ace_ipv6_enabled
, PF_INET6
) :
1598 #else /* ACE_HAS_IPV6 */
1600 #endif /* !ACE_HAS_IPV6 */
1603 ACE_END_VERSIONED_NAMESPACE_DECL