diff options
author | Timothy Simpson <simpsont@objectcomputing.com> | 2020-08-05 13:43:10 -0500 |
---|---|---|
committer | Timothy Simpson <simpsont@objectcomputing.com> | 2020-08-05 13:43:10 -0500 |
commit | 4ea6844994d56f78341365b3f71fba6993fecd8f (patch) | |
tree | 01b111546143fd4f3f67d10d638443931c00bf20 /ACE/tests | |
parent | 92238c4101bcf7ab4d0e335dec66684479b98960 (diff) | |
download | ATCD-4ea6844994d56f78341365b3f71fba6993fecd8f.tar.gz |
Adding Test for Multicast Join By Interface
Diffstat (limited to 'ACE/tests')
-rw-r--r-- | ACE/tests/Multicast_Interfaces_Test.cpp | 182 | ||||
-rw-r--r-- | ACE/tests/run_test.lst | 1 | ||||
-rw-r--r-- | ACE/tests/tests.mpc | 7 |
3 files changed, 190 insertions, 0 deletions
diff --git a/ACE/tests/Multicast_Interfaces_Test.cpp b/ACE/tests/Multicast_Interfaces_Test.cpp new file mode 100644 index 00000000000..3fae41f7dd0 --- /dev/null +++ b/ACE/tests/Multicast_Interfaces_Test.cpp @@ -0,0 +1,182 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file Enum_Interfaces_Test.cpp + * + * This is a simple test of <ACE::get_ip_interfaces>. This call + * retrieves the IP addresses assigned to the host by + * interrogating the kernel. Network applications typically + * assume gethostbyname(uname()) will work, but this is just a + * convention. It is also problematic if the resolver code + * (DNS/NIS+...) is misconfigured. This happens more than + * programmers realize. It is better to find out by asking the + * kernel for local address assignments. This API is similar to + * what netstat -ni or ifconfig -a produces on UNIX or ipconfig on + * Windows NT. In fact, it was by reverse engineering these tools + * that this api was created. + * + * @author Michael R. MacFaden <mrm@cisco.com> + */ +//============================================================================= + +#include "test_config.h" + +#include "ace/OS_Memory.h" +#include "ace/OS_NS_sys_utsname.h" +#include "ace/SOCK_Dgram_Mcast.h" +#include "ace/SString.h" + +#include <set> +#include <string> + +typedef std::set<ACE_TString> nameset; + +#ifdef ACE_WIN32 +void get_valid_ipv4_interface_names_win32(nameset& names) { + names.clear(); + + // Initial call to determine actual memory size needed + IP_ADAPTER_ADDRESSES tmp_addrs; + ULONG bufLen = 0; + if (GetAdaptersAddresses (AF_INET, 0, 0, &tmp_addrs, &bufLen) != ERROR_BUFFER_OVERFLOW) + { + return; + } + + // Get required output buffer and retrieve info for real. + char *buf = 0; + ACE_NEW (buf, char[bufLen]); + PIP_ADAPTER_ADDRESSES pAddrs = reinterpret_cast<PIP_ADAPTER_ADDRESSES> (buf); + if (::GetAdaptersAddresses (AF_INET, 0, 0, pAddrs, &bufLen) != NO_ERROR) + { + delete[] buf; + return; + } + + while (pAddrs) + { + if (!pAddrs->NoMulticast) + { + PIP_ADAPTER_UNICAST_ADDRESS_LH pUnicast = pAddrs->FirstUnicastAddress; + LPSOCKADDR sa = pUnicast->Address.lpSockaddr; + if (sa->sa_family == AF_INET) + { + names.insert(ACE_TEXT_WCHAR_TO_TCHAR(pAddrs->FriendlyName)); + } + } + pAddrs = pAddrs->Next; + } + + delete[] buf; +} +#elif defined ACE_HAS_GETIFADDRS +void get_valid_ipv4_interface_names_getifaddrs(nameset& names) { +} +#endif + +void get_valid_ipv4_interface_names(nameset& names) { +#ifdef ACE_WIN32 +get_valid_ipv4_interface_names_win32(names); +#elif defined ACE_HAS_GETIFADDRS +get_valid_ipv4_interface_names_getifaddrs(names); +#endif +} + +#ifdef ACE_HAS_IPV6 +#ifdef ACE_WIN32 +void get_valid_ipv6_interface_names_win32(nameset& names) { + names.clear(); + + // Initial call to determine actual memory size needed + IP_ADAPTER_ADDRESSES tmp_addrs; + ULONG bufLen = 0; + if (GetAdaptersAddresses (AF_INET, 0, 0, &tmp_addrs, &bufLen) != ERROR_BUFFER_OVERFLOW) + { + return; + } + + // Get required output buffer and retrieve info for real. + char *buf = 0; + ACE_NEW (buf, char[bufLen]); + PIP_ADAPTER_ADDRESSES pAddrs = reinterpret_cast<PIP_ADAPTER_ADDRESSES> (buf); + if (::GetAdaptersAddresses (AF_INET6, 0, 0, pAddrs, &bufLen) != NO_ERROR) + { + delete[] buf; + return; + } + + while (pAddrs) + { + if (!pAddrs->NoMulticast) + { + PIP_ADAPTER_UNICAST_ADDRESS_LH pUnicast = pAddrs->FirstUnicastAddress; + LPSOCKADDR sa = pUnicast->Address.lpSockaddr; + if (sa->sa_family == AF_INET6) + { + names.insert(ACE_TEXT_WCHAR_TO_TCHAR(pAddrs->FriendlyName)); + } + } + pAddrs = pAddrs->Next; + } + + delete[] buf; +} +#elif defined ACE_HAS_GETIFADDRS +void get_valid_ipv6_interface_names_getifaddrs(nameset& names) { +} +#endif + +void get_valid_ipv6_interface_names(nameset& names) { +#ifdef ACE_WIN32 +get_valid_ipv6_interface_names_win32(names); +#elif defined ACE_HAS_GETIFADDRS +get_valid_ipv6_interface_names_getifaddrs(names); +#endif +} +#endif /* ACE_HAS_IPV6 */ + +int create_socket_and_join_multicast(const ACE_INET_Addr& mc_addr, const ACE_TString& if_name) { + int result = 0; + ACE_SOCK_Dgram_Mcast sock; + sock.opts(ACE_SOCK_Dgram_Mcast::OPT_BINDADDR_NO | ACE_SOCK_Dgram_Mcast::DEFOPT_NULLIFACE); + result = sock.join(mc_addr, 1, if_name.empty() ? 0 : if_name.c_str()); + result |= sock.close(); + return result; +} + +int +run_main (int, ACE_TCHAR *[]) +{ + ACE_START_TEST (ACE_TEXT ("Multicast_Interfaces_Test")); + + int result = 0; + + ACE_utsname uname; + ACE_OS::uname (&uname); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Machine: %C running on %C\n"), + uname.nodename, uname.machine )); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Platform: %C, %C, %C\n"), + uname.sysname, uname.release, uname.version )); + + nameset names; + + get_valid_ipv4_interface_names(names); + ACE_INET_Addr ipv4_mc_addr("239.255.0.7:1234", AF_INET); + result |= create_socket_and_join_multicast(ipv4_mc_addr, ACE_TString()); + for (nameset::const_iterator it = names.begin(); result == 0 && it != names.end(); ++it) { + result |= create_socket_and_join_multicast(ipv4_mc_addr, *it); + } + +#ifdef ACE_HAS_IPV6 + get_valid_ipv6_interface_names(names); + ACE_INET_Addr ipv6_mc_addr("ff03::7:4321", AF_INET6); + result |= create_socket_and_join_multicast(ipv6_mc_addr, ACE_TString()); + for (nameset::const_iterator it = names.begin(); result == 0 && it != names.end(); ++it) { + result |= create_socket_and_join_multicast(ipv6_mc_addr, *it); + } +#endif /* ACE_HAS_IPV6 */ + + ACE_END_TEST; + return result; +} diff --git a/ACE/tests/run_test.lst b/ACE/tests/run_test.lst index 1e09306ecd8..b9d9321d510 100644 --- a/ACE/tests/run_test.lst +++ b/ACE/tests/run_test.lst @@ -167,6 +167,7 @@ Monotonic_Manual_Event_Test Monotonic_Message_Queue_Test: !ACE_FOR_TAO Monotonic_Task_Test: !ACE_FOR_TAO Multicast_Test: !ST !NO_MCAST !nsk !LynxOS !LabVIEW_RT +Multicast_Interfaces_Test: !ST !NO_MCAST !nsk !LynxOS !LabVIEW_RT Multihomed_INET_Addr_Test: !ACE_FOR_TAO Naming_Test: !NO_OTHER !LynxOS !VxWorks !nsk !ACE_FOR_TAO !PHARLAP Network_Adapters_Test: !ACE_FOR_TAO diff --git a/ACE/tests/tests.mpc b/ACE/tests/tests.mpc index f604aa67a8b..3789283e13d 100644 --- a/ACE/tests/tests.mpc +++ b/ACE/tests/tests.mpc @@ -1208,6 +1208,13 @@ project(Multicast Test) : acetest { } } +project(Multicast Interfaces Test) : acetest { + exename = Multicast_Interfaces_Test + Source_Files { + Multicast_Interfaces_Test.cpp + } +} + project(Multihomed INET Addr Test) : acetest { avoids += ace_for_tao exename = Multihomed_INET_Addr_Test |