Revert "Minor modernization of DynamicAny code"
[ACE_TAO.git] / TAO / tests / IOR_Endpoint_Hostnames / list_interfaces.cpp
blobd8678f70aca5c928f876d7aae53bbb1b39d99e7c
1 //
2 // Extract the address for each network interface using EXACTLY
3 // the same algorithm as TAO_IIOP_Acceptor, and then print
4 // it. This is used by the run_test.pl to know how to set up
5 // "expected results" for hostnames in IORs.
6 //
8 #include "tao/corba.h"
9 #include "ace/ACE.h"
10 #include <memory>
11 #include "ace/INET_Addr.h"
12 #include "ace/Log_Msg.h"
13 #include "ace/OS_NS_stdio.h"
15 #if defined (ACE_HAS_IPV6) && !defined (ACE_USES_IPV4_IPV6_MIGRATION)
16 ACE_INET_Addr default_address (static_cast<unsigned short> (0), ACE_IPV6_ANY, AF_INET6);
17 #else
18 ACE_INET_Addr default_address (static_cast<unsigned short> (0), static_cast<ACE_UINT32> (INADDR_ANY));
19 #endif /* ACE_HAS_IPV6 && !ACE_USES_IPV4_IPV6_MIGRATION */
21 int
22 ACE_TMAIN(int argc, ACE_TCHAR *argv[])
24 ACE_UNUSED_ARG (argc);
25 ACE_UNUSED_ARG (argv);
27 #if defined (ACE_HAS_IPV6)
28 int def_type = AF_UNSPEC;
29 #endif /* ACE_HAS_IPV6 */
31 // network interfaces.
32 ACE_INET_Addr *if_addrs = 0;
33 size_t if_cnt = 0;
35 if (ACE::get_ip_interfaces (if_cnt,
36 if_addrs) != 0
37 && errno != ENOTSUP)
39 // In the case where errno == ENOTSUP, if_cnt and if_addrs will
40 // not be modified, and will each remain equal to zero. This
41 // causes the default interface to be used.
42 return -1;
45 if (if_cnt == 0 || if_addrs == 0)
47 ACE_DEBUG ((LM_WARNING,
48 ACE_TEXT ("TAO (%P|%t) Unable to probe network ")
49 ACE_TEXT ("interfaces. Using default.\n")));
51 if_cnt = 1; // Force the network interface count to be one.
52 delete [] if_addrs;
53 ACE_NEW_RETURN (if_addrs,
54 ACE_INET_Addr[if_cnt],
55 -1);
58 // Scan for the loopback interface since it shouldn't be included in
59 // the list of cached hostnames unless it is the only interface.
60 size_t lo_cnt = 0; // Loopback interface count
61 for (size_t j = 0; j < if_cnt; ++j)
62 if (if_addrs[j].is_loopback ())
63 ++lo_cnt;
65 #if defined (ACE_HAS_IPV6)
66 size_t ipv4_cnt = 0;
67 size_t ipv4_lo_cnt = 0;
68 size_t ipv6_ll = 0;
69 bool ipv6_non_ll = false;
70 // Scan for IPv4 interfaces since these should not be included
71 // when IPv6-only is selected.
72 for (size_t j = 0; j < if_cnt; ++j)
73 if (if_addrs[j].get_type () != AF_INET6 ||
74 if_addrs[j].is_ipv4_mapped_ipv6 ())
76 ++ipv4_cnt;
77 if (if_addrs[j].is_loopback ())
78 ++ipv4_lo_cnt; // keep track of IPv4 loopback ifs
80 else if (!if_addrs[j].is_linklocal () &&
81 !if_addrs[j].is_loopback())
83 ipv6_non_ll = true; // we have at least 1 non-local IPv6 if
85 else if (// !orb_core->orb_params ()->use_ipv6_link_local () &&
86 if_addrs[j].is_linklocal ())
88 ++ipv6_ll; // count link local addrs to exclude them afterwards
90 #endif /* ACE_HAS_IPV6 */
92 std::unique_ptr<ACE_INET_Addr[]> safe_if_addrs (if_addrs);
94 #if defined (ACE_HAS_IPV6)
95 bool ipv4_only = def_type == AF_INET;
96 bool ipv6_only = (def_type == AF_INET6); // ||
97 // orb_core->orb_params ()->connect_ipv6_only ();
98 #if defined (ACE_WIN32)
99 if (default_address.get_type () == AF_INET)
100 ipv4_only = true;
101 else
102 ipv6_only = true;
103 #endif /* ACE_WIN32 */
104 // If the loopback interface is the only interface then include it
105 // in the list of interfaces to query for a hostname, otherwise
106 // exclude it from the list.
107 bool ignore_lo;
108 if (ipv6_only)
109 // only exclude loopback if non-local if exists
110 ignore_lo = ipv6_non_ll;
111 else if (ipv4_only)
112 ignore_lo = ipv4_cnt != ipv4_lo_cnt;
113 else
114 ignore_lo = if_cnt != lo_cnt;
116 // Adjust counts for IPv6 only if required
117 size_t if_ok_cnt = if_cnt;
118 if (ipv6_only)
120 if_ok_cnt -= ipv4_cnt;
121 lo_cnt -= ipv4_lo_cnt;
122 ipv4_lo_cnt = 0;
124 else if (ipv4_only)
126 if_ok_cnt = ipv4_cnt;
127 lo_cnt = ipv4_lo_cnt;
128 ipv6_ll = 0;
131 // In case there are no non-local IPv6 ifs in the list only exclude
132 // IPv4 loopback.
133 // IPv6 loopback will be needed to successfully connect IPv6 clients
134 // in a localhost environment.
135 if (!ipv4_only && !ipv6_non_ll)
136 lo_cnt = ipv4_lo_cnt;
137 #else /* ACE_HAS_IPV6 */
138 // If the loopback interface is the only interface then include it
139 // in the list of interfaces to query for a hostname, otherwise
140 // exclude it from the list.
141 bool ignore_lo;
142 ignore_lo = if_cnt != lo_cnt;
143 #endif /* !ACE_HAS_IPV6 */
145 // The number of hosts/interfaces we want to cache may not be the
146 // same as the number of detected interfaces so keep a separate
147 // count.
148 size_t host_cnt = 0;
150 for (size_t i = 0; i < if_cnt; ++i)
152 #if defined (ACE_HAS_IPV6)
153 // Ignore any loopback interface if there are other
154 // non-loopback interfaces.
155 if (ignore_lo &&
156 if_addrs[i].is_loopback () &&
157 (ipv4_only ||
158 ipv6_non_ll ||
159 if_addrs[i].get_type () != AF_INET6))
160 continue;
162 // Ignore any non-IPv4 interfaces when so required.
163 if (ipv4_only &&
164 (if_addrs[i].get_type () != AF_INET))
165 continue;
167 // Ignore any non-IPv6 interfaces when so required.
168 if (ipv6_only &&
169 (if_addrs[i].get_type () != AF_INET6 ||
170 if_addrs[i].is_ipv4_mapped_ipv6 ()))
171 continue;
173 // Ignore all IPv6 link local interfaces when so required.
174 if (// !orb_core->orb_params ()->use_ipv6_link_local () &&
175 if_addrs[i].is_linklocal ())
176 continue;
177 #else /* ACE_HAS_IPV6 */
178 // Ignore any loopback interface if there are other
179 // non-loopback interfaces.
180 if (ignore_lo &&
181 if_addrs[i].is_loopback ())
182 continue;
183 #endif /* !ACE_HAS_IPV6 */
185 // Print the address as a string.
186 ACE_OS::printf ("%s\n", if_addrs[i].get_host_addr());
188 ++host_cnt;
191 return 0;