network_v4.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. //
  2. // network_v4.cpp
  3. // ~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. // Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com)
  7. //
  8. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  9. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // Disable autolinking for unit tests.
  12. #if !defined(BOOST_ALL_NO_LIB)
  13. #define BOOST_ALL_NO_LIB 1
  14. #endif // !defined(BOOST_ALL_NO_LIB)
  15. // Test that header file is self-contained.
  16. #include <boost/asio/ip/network_v4.hpp>
  17. #include "../unit_test.hpp"
  18. #include <sstream>
  19. //------------------------------------------------------------------------------
  20. // ip_network_v4_compile test
  21. // ~~~~~~~~~~~~~~~~~~~~~~~~~~
  22. // The following test checks that all public member functions on the class
  23. // ip::network_v4 compile and link correctly. Runtime failures are ignored.
  24. namespace ip_network_v4_compile {
  25. void test()
  26. {
  27. using namespace boost::asio;
  28. namespace ip = boost::asio::ip;
  29. try
  30. {
  31. boost::system::error_code ec;
  32. // network_v4 constructors.
  33. ip::network_v4 net1(ip::make_address_v4("192.168.1.0"), 32);
  34. ip::network_v4 net2(ip::make_address_v4("192.168.1.0"),
  35. ip::make_address_v4("255.255.255.0"));
  36. // network_v4 functions.
  37. ip::address_v4 addr1 = net1.address();
  38. (void)addr1;
  39. unsigned short prefix_len = net1.prefix_length();
  40. (void)prefix_len;
  41. ip::address_v4 addr2 = net1.netmask();
  42. (void)addr2;
  43. ip::address_v4 addr3 = net1.network();
  44. (void)addr3;
  45. ip::address_v4 addr4 = net1.broadcast();
  46. (void)addr4;
  47. ip::address_v4_range hosts = net1.hosts();
  48. (void)hosts;
  49. ip::network_v4 net3 = net1.canonical();
  50. (void)net3;
  51. bool b1 = net1.is_host();
  52. (void)b1;
  53. bool b2 = net1.is_subnet_of(net2);
  54. (void)b2;
  55. std::string s1 = net1.to_string();
  56. (void)s1;
  57. std::string s2 = net1.to_string(ec);
  58. (void)s2;
  59. // network_v4 comparisons.
  60. bool b3 = (net1 == net2);
  61. (void)b3;
  62. bool b4 = (net1 != net2);
  63. (void)b4;
  64. // network_v4 creation functions.
  65. net1 = ip::make_network_v4(ip::address_v4(), 24);
  66. net1 = ip::make_network_v4(ip::address_v4(), ip::address_v4());
  67. net1 = ip::make_network_v4("10.0.0.0/8");
  68. net1 = ip::make_network_v4("10.0.0.0/8", ec);
  69. net1 = ip::make_network_v4(s1);
  70. net1 = ip::make_network_v4(s1, ec);
  71. #if defined(BOOST_ASIO_HAS_STRING_VIEW)
  72. # if defined(BOOST_ASIO_HAS_STD_STRING_VIEW)
  73. std::string_view string_view_value("10.0.0.0/8");
  74. # elif defined(BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
  75. std::experimental::string_view string_view_value("10.0.0.0/8");
  76. # endif // defined(BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
  77. net1 = ip::make_network_v4(string_view_value);
  78. net1 = ip::make_network_v4(string_view_value, ec);
  79. #endif // defined(BOOST_ASIO_HAS_STRING_VIEW)
  80. // network_v4 I/O.
  81. std::ostringstream os;
  82. os << net1;
  83. #if !defined(BOOST_NO_STD_WSTREAMBUF)
  84. std::wostringstream wos;
  85. wos << net1;
  86. #endif // !defined(BOOST_NO_STD_WSTREAMBUF)
  87. }
  88. catch (std::exception&)
  89. {
  90. }
  91. }
  92. } // namespace ip_network_v4_compile
  93. //------------------------------------------------------------------------------
  94. // ip_network_v4_runtime test
  95. // ~~~~~~~~~~~~~~~~~~~~~~~~~~
  96. // The following test checks that the various public member functions meet the
  97. // necessary postconditions.
  98. namespace ip_network_v4_runtime {
  99. void test()
  100. {
  101. using boost::asio::ip::address_v4;
  102. using boost::asio::ip::make_address_v4;
  103. using boost::asio::ip::network_v4;
  104. using boost::asio::ip::make_network_v4;
  105. address_v4 addr = make_address_v4("1.2.3.4");
  106. // calculate prefix length
  107. network_v4 net1(addr, make_address_v4("255.255.255.0"));
  108. BOOST_ASIO_CHECK(net1.prefix_length() == 24);
  109. network_v4 net2(addr, make_address_v4("255.255.255.192"));
  110. BOOST_ASIO_CHECK(net2.prefix_length() == 26);
  111. network_v4 net3(addr, make_address_v4("128.0.0.0"));
  112. BOOST_ASIO_CHECK(net3.prefix_length() == 1);
  113. std::string msg;
  114. try
  115. {
  116. make_network_v4(addr, make_address_v4("255.255.255.1"));
  117. }
  118. catch(std::exception& ex)
  119. {
  120. msg = ex.what();
  121. }
  122. BOOST_ASIO_CHECK(msg == std::string("non-contiguous netmask"));
  123. msg.clear();
  124. try
  125. {
  126. make_network_v4(addr, make_address_v4("0.255.255.0"));
  127. }
  128. catch(std::exception& ex)
  129. {
  130. msg = ex.what();
  131. }
  132. BOOST_ASIO_CHECK(msg == std::string("non-contiguous netmask"));
  133. // calculate netmask
  134. network_v4 net4(addr, 23);
  135. BOOST_ASIO_CHECK(net4.netmask() == make_address_v4("255.255.254.0"));
  136. network_v4 net5(addr, 12);
  137. BOOST_ASIO_CHECK(net5.netmask() == make_address_v4("255.240.0.0"));
  138. network_v4 net6(addr, 24);
  139. BOOST_ASIO_CHECK(net6.netmask() == make_address_v4("255.255.255.0"));
  140. network_v4 net7(addr, 16);
  141. BOOST_ASIO_CHECK(net7.netmask() == make_address_v4("255.255.0.0"));
  142. network_v4 net8(addr, 8);
  143. BOOST_ASIO_CHECK(net8.netmask() == make_address_v4("255.0.0.0"));
  144. network_v4 net9(addr, 32);
  145. BOOST_ASIO_CHECK(net9.netmask() == make_address_v4("255.255.255.255"));
  146. network_v4 net10(addr, 1);
  147. BOOST_ASIO_CHECK(net10.netmask() == make_address_v4("128.0.0.0"));
  148. network_v4 net11(addr, 0);
  149. BOOST_ASIO_CHECK(net11.netmask() == make_address_v4("0.0.0.0"));
  150. msg.clear();
  151. try
  152. {
  153. make_network_v4(addr, 33);
  154. }
  155. catch(std::out_of_range& ex)
  156. {
  157. msg = ex.what();
  158. }
  159. BOOST_ASIO_CHECK(msg == std::string("prefix length too large"));
  160. // construct address range from address and prefix length
  161. BOOST_ASIO_CHECK(network_v4(make_address_v4("192.168.77.100"), 32).network() == make_address_v4("192.168.77.100"));
  162. BOOST_ASIO_CHECK(network_v4(make_address_v4("192.168.77.100"), 24).network() == make_address_v4("192.168.77.0"));
  163. BOOST_ASIO_CHECK(network_v4(make_address_v4("192.168.77.128"), 25).network() == make_address_v4("192.168.77.128"));
  164. // construct address range from string in CIDR notation
  165. BOOST_ASIO_CHECK(make_network_v4("192.168.77.100/32").network() == make_address_v4("192.168.77.100"));
  166. BOOST_ASIO_CHECK(make_network_v4("192.168.77.100/24").network() == make_address_v4("192.168.77.0"));
  167. BOOST_ASIO_CHECK(make_network_v4("192.168.77.128/25").network() == make_address_v4("192.168.77.128"));
  168. // construct network from invalid string
  169. boost::system::error_code ec;
  170. make_network_v4("10.0.0.256/24", ec);
  171. BOOST_ASIO_CHECK(!!ec);
  172. make_network_v4("10.0.0.0/33", ec);
  173. BOOST_ASIO_CHECK(!!ec);
  174. make_network_v4("10.0.0.0/-1", ec);
  175. BOOST_ASIO_CHECK(!!ec);
  176. make_network_v4("10.0.0.0/", ec);
  177. BOOST_ASIO_CHECK(!!ec);
  178. make_network_v4("10.0.0.0", ec);
  179. BOOST_ASIO_CHECK(!!ec);
  180. // prefix length
  181. BOOST_ASIO_CHECK(make_network_v4("193.99.144.80/24").prefix_length() == 24);
  182. BOOST_ASIO_CHECK(network_v4(make_address_v4("193.99.144.80"), 24).prefix_length() == 24);
  183. BOOST_ASIO_CHECK(network_v4(make_address_v4("192.168.77.0"), make_address_v4("255.255.255.0")).prefix_length() == 24);
  184. // to string
  185. std::string a("192.168.77.0/32");
  186. BOOST_ASIO_CHECK(make_network_v4(a.c_str()).to_string() == a);
  187. BOOST_ASIO_CHECK(network_v4(make_address_v4("192.168.77.10"), 24).to_string() == std::string("192.168.77.10/24"));
  188. // return host part
  189. BOOST_ASIO_CHECK(make_network_v4("192.168.77.11/24").address() == make_address_v4("192.168.77.11"));
  190. // return host in CIDR notation
  191. BOOST_ASIO_CHECK(make_network_v4("192.168.78.30/20").address().to_string() == "192.168.78.30");
  192. // return network in CIDR notation
  193. BOOST_ASIO_CHECK(make_network_v4("192.168.78.30/20").canonical().to_string() == "192.168.64.0/20");
  194. // is host
  195. BOOST_ASIO_CHECK(make_network_v4("192.168.77.0/32").is_host());
  196. BOOST_ASIO_CHECK(!make_network_v4("192.168.77.0/31").is_host());
  197. // is real subnet of
  198. BOOST_ASIO_CHECK(make_network_v4("192.168.0.192/24").is_subnet_of(make_network_v4("192.168.0.0/16")));
  199. BOOST_ASIO_CHECK(make_network_v4("192.168.0.0/24").is_subnet_of(make_network_v4("192.168.192.168/16")));
  200. BOOST_ASIO_CHECK(make_network_v4("192.168.0.192/24").is_subnet_of(make_network_v4("192.168.192.168/16")));
  201. BOOST_ASIO_CHECK(make_network_v4("192.168.0.0/24").is_subnet_of(make_network_v4("192.168.0.0/16")));
  202. BOOST_ASIO_CHECK(make_network_v4("192.168.0.0/24").is_subnet_of(make_network_v4("192.168.0.0/23")));
  203. BOOST_ASIO_CHECK(make_network_v4("192.168.0.0/24").is_subnet_of(make_network_v4("192.168.0.0/0")));
  204. BOOST_ASIO_CHECK(make_network_v4("192.168.0.0/32").is_subnet_of(make_network_v4("192.168.0.0/24")));
  205. BOOST_ASIO_CHECK(!make_network_v4("192.168.0.0/32").is_subnet_of(make_network_v4("192.168.0.0/32")));
  206. BOOST_ASIO_CHECK(!make_network_v4("192.168.0.0/24").is_subnet_of(make_network_v4("192.168.1.0/24")));
  207. BOOST_ASIO_CHECK(!make_network_v4("192.168.0.0/16").is_subnet_of(make_network_v4("192.168.1.0/24")));
  208. network_v4 r(make_network_v4("192.168.0.0/24"));
  209. BOOST_ASIO_CHECK(!r.is_subnet_of(r));
  210. network_v4 net12(make_network_v4("192.168.0.2/24"));
  211. network_v4 net13(make_network_v4("192.168.1.1/28"));
  212. network_v4 net14(make_network_v4("192.168.1.21/28"));
  213. // network
  214. BOOST_ASIO_CHECK(net12.network() == make_address_v4("192.168.0.0"));
  215. BOOST_ASIO_CHECK(net13.network() == make_address_v4("192.168.1.0"));
  216. BOOST_ASIO_CHECK(net14.network() == make_address_v4("192.168.1.16"));
  217. // netmask
  218. BOOST_ASIO_CHECK(net12.netmask() == make_address_v4("255.255.255.0"));
  219. BOOST_ASIO_CHECK(net13.netmask() == make_address_v4("255.255.255.240"));
  220. BOOST_ASIO_CHECK(net14.netmask() == make_address_v4("255.255.255.240"));
  221. // broadcast
  222. BOOST_ASIO_CHECK(net12.broadcast() == make_address_v4("192.168.0.255"));
  223. BOOST_ASIO_CHECK(net13.broadcast() == make_address_v4("192.168.1.15"));
  224. BOOST_ASIO_CHECK(net14.broadcast() == make_address_v4("192.168.1.31"));
  225. // iterator
  226. BOOST_ASIO_CHECK(std::distance(net12.hosts().begin(),net12.hosts().end()) == 254);
  227. BOOST_ASIO_CHECK(*net12.hosts().begin() == make_address_v4("192.168.0.1"));
  228. BOOST_ASIO_CHECK(net12.hosts().end() != net12.hosts().find(make_address_v4("192.168.0.10")));
  229. BOOST_ASIO_CHECK(net12.hosts().end() == net12.hosts().find(make_address_v4("192.168.1.10")));
  230. BOOST_ASIO_CHECK(std::distance(net13.hosts().begin(),net13.hosts().end()) == 14);
  231. BOOST_ASIO_CHECK(*net13.hosts().begin() == make_address_v4("192.168.1.1"));
  232. BOOST_ASIO_CHECK(net13.hosts().end() != net13.hosts().find(make_address_v4("192.168.1.14")));
  233. BOOST_ASIO_CHECK(net13.hosts().end() == net13.hosts().find(make_address_v4("192.168.1.15")));
  234. BOOST_ASIO_CHECK(std::distance(net14.hosts().begin(),net14.hosts().end()) == 14);
  235. BOOST_ASIO_CHECK(*net14.hosts().begin() == make_address_v4("192.168.1.17"));
  236. BOOST_ASIO_CHECK(net14.hosts().end() != net14.hosts().find(make_address_v4("192.168.1.30")));
  237. BOOST_ASIO_CHECK(net14.hosts().end() == net14.hosts().find(make_address_v4("192.168.1.31")));
  238. }
  239. } // namespace ip_network_v4_runtime
  240. //------------------------------------------------------------------------------
  241. BOOST_ASIO_TEST_SUITE
  242. (
  243. "ip/network_v4",
  244. BOOST_ASIO_TEST_CASE(ip_network_v4_compile::test)
  245. BOOST_ASIO_TEST_CASE(ip_network_v4_runtime::test)
  246. )