• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // network_v6.cpp
3 // ~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2021 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 
12 // Disable autolinking for unit tests.
13 #if !defined(BOOST_ALL_NO_LIB)
14 #define BOOST_ALL_NO_LIB 1
15 #endif // !defined(BOOST_ALL_NO_LIB)
16 
17 // Test that header file is self-contained.
18 #include <boost/asio/ip/network_v6.hpp>
19 
20 #include "../unit_test.hpp"
21 #include <sstream>
22 
23 //------------------------------------------------------------------------------
24 
25 // ip_network_v6_compile test
26 // ~~~~~~~~~~~~~~~~~~~~~~~~~~
27 // The following test checks that all public member functions on the class
28 // ip::network_v6 compile and link correctly. Runtime failures are ignored.
29 
30 namespace ip_network_v6_compile {
31 
test()32 void test()
33 {
34   using namespace boost::asio;
35   namespace ip = boost::asio::ip;
36 
37   try
38   {
39     boost::system::error_code ec;
40 
41     // network_v6 constructors.
42 
43     ip::network_v6 net1(ip::make_address_v6("2001:370::10:7344"), 64);
44     ip::network_v6 net2(ip::make_address_v6("2001:370::10:7345"), 96);
45 
46     // network_v6 functions.
47 
48     ip::address_v6 addr1 = net1.address();
49     (void)addr1;
50 
51     unsigned short prefix_len = net1.prefix_length();
52     (void)prefix_len;
53 
54     ip::address_v6 addr3 = net1.network();
55     (void)addr3;
56 
57     ip::address_v6_range hosts = net1.hosts();
58     (void)hosts;
59 
60     ip::network_v6 net3 = net1.canonical();
61     (void)net3;
62 
63     bool b1 = net1.is_host();
64     (void)b1;
65 
66     bool b2 = net1.is_subnet_of(net2);
67     (void)b2;
68 
69     std::string s1 = net1.to_string();
70     (void)s1;
71 
72     std::string s2 = net1.to_string(ec);
73     (void)s2;
74 
75     // network_v6 comparisons.
76 
77     bool b3 = (net1 == net2);
78     (void)b3;
79 
80     bool b4 = (net1 != net2);
81     (void)b4;
82 
83     // network_v6 creation functions.
84 
85     net1 = ip::make_network_v6(ip::address_v6(), 24);
86     net1 = ip::make_network_v6("10.0.0.0/8");
87     net1 = ip::make_network_v6("10.0.0.0/8", ec);
88     net1 = ip::make_network_v6(s1);
89     net1 = ip::make_network_v6(s1, ec);
90 #if defined(BOOST_ASIO_HAS_STRING_VIEW)
91 # if defined(BOOST_ASIO_HAS_STD_STRING_VIEW)
92     std::string_view string_view_value("0::0/8");
93 # elif defined(BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
94     std::experimental::string_view string_view_value("0::0/8");
95 # endif // defined(BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
96     net1 = ip::make_network_v6(string_view_value);
97     net1 = ip::make_network_v6(string_view_value, ec);
98 #endif // defined(BOOST_ASIO_STD_STRING_VIEW)
99 
100     // network_v6 I/O.
101 
102     std::ostringstream os;
103     os << net1;
104 
105 #if !defined(BOOST_NO_STD_WSTREAMBUF)
106     std::wostringstream wos;
107     wos << net1;
108 #endif // !defined(BOOST_NO_STD_WSTREAMBUF)
109   }
110   catch (std::exception&)
111   {
112   }
113 }
114 
115 } // namespace ip_network_v6_compile
116 
117 //------------------------------------------------------------------------------
118 
119 // ip_network_v6_runtime test
120 // ~~~~~~~~~~~~~~~~~~~~~~~~~~
121 // The following test checks that the various public member functions meet the
122 // necessary postconditions.
123 
124 namespace ip_network_v6_runtime {
125 
test()126 void test()
127 {
128   using boost::asio::ip::address_v6;
129   using boost::asio::ip::make_address_v6;
130   using boost::asio::ip::network_v6;
131   using boost::asio::ip::make_network_v6;
132 
133   address_v6 addr = make_address_v6("2001:370::10:7344");
134 
135   std::string msg;
136   try
137   {
138     make_network_v6(addr, 129);
139   }
140   catch(std::out_of_range& ex)
141   {
142     msg = ex.what();
143   }
144   BOOST_ASIO_CHECK(msg == std::string("prefix length too large"));
145 
146   // construct address range from address and prefix length
147   BOOST_ASIO_CHECK(network_v6(make_address_v6("2001:370::10:7344"), 128).network() == make_address_v6("2001:370::10:7344"));
148   BOOST_ASIO_CHECK(network_v6(make_address_v6("2001:370::10:7344"), 64).network() == make_address_v6("2001:370::"));
149   BOOST_ASIO_CHECK(network_v6(make_address_v6("2001:370::10:7344"), 27).network() == make_address_v6("2001:360::"));
150 
151   // construct address range from string in CIDR notation
152   BOOST_ASIO_CHECK(make_network_v6("2001:370::10:7344/128").network() == make_address_v6("2001:370::10:7344"));
153   BOOST_ASIO_CHECK(make_network_v6("2001:370::10:7344/64").network() == make_address_v6("2001:370::"));
154   BOOST_ASIO_CHECK(make_network_v6("2001:370::10:7344/27").network() == make_address_v6("2001:360::"));
155 
156   // construct network from invalid string
157   boost::system::error_code ec;
158   make_network_v6("a:b/24", ec);
159   BOOST_ASIO_CHECK(!!ec);
160   make_network_v6("2001:370::10:7344/129", ec);
161   BOOST_ASIO_CHECK(!!ec);
162   make_network_v6("2001:370::10:7344/-1", ec);
163   BOOST_ASIO_CHECK(!!ec);
164   make_network_v6("2001:370::10:7344/", ec);
165   BOOST_ASIO_CHECK(!!ec);
166   make_network_v6("2001:370::10:7344", ec);
167   BOOST_ASIO_CHECK(!!ec);
168 
169   // prefix length
170   BOOST_ASIO_CHECK(make_network_v6("2001:370::10:7344/128").prefix_length() == 128);
171   BOOST_ASIO_CHECK(network_v6(make_address_v6("2001:370::10:7344"), 27).prefix_length() == 27);
172 
173   // to string
174   std::string a("2001:370::10:7344/64");
175   BOOST_ASIO_CHECK(make_network_v6(a.c_str()).to_string() == a);
176   BOOST_ASIO_CHECK(network_v6(make_address_v6("2001:370::10:7344"), 27).to_string() == std::string("2001:370::10:7344/27"));
177 
178   // return host part
179   BOOST_ASIO_CHECK(make_network_v6("2001:370::10:7344/64").address() == make_address_v6("2001:370::10:7344"));
180   BOOST_ASIO_CHECK(make_network_v6("2001:370::10:7344/27").address().to_string() == "2001:370::10:7344");
181 
182   // return network in CIDR notation
183   BOOST_ASIO_CHECK(make_network_v6("2001:370::10:7344/27").canonical().to_string() == "2001:360::/27");
184 
185   // is host
186   BOOST_ASIO_CHECK(make_network_v6("2001:370::10:7344/128").is_host());
187   BOOST_ASIO_CHECK(!make_network_v6("2001:370::10:7344/127").is_host());
188 
189   // is real subnet of
190   BOOST_ASIO_CHECK(make_network_v6("2001:370::10:3744/64").is_subnet_of(make_network_v6("2001:370::/16")));
191   BOOST_ASIO_CHECK(make_network_v6("2001:370::/64").is_subnet_of(make_network_v6("2001:370::/16")));
192   BOOST_ASIO_CHECK(make_network_v6("2001:0db8:85a3::/64").is_subnet_of(make_network_v6("2001:0d00::/24")));
193 
194   BOOST_ASIO_CHECK(!make_network_v6("2001:370::10:3744/128").is_subnet_of(make_network_v6("2001:370::10:3744/128")));
195   BOOST_ASIO_CHECK(make_network_v6("2001:0db8:85a3::/64").is_subnet_of(make_network_v6("2001:0dc0::/24")));
196 
197   network_v6 r(make_network_v6("2001:370::/64"));
198   BOOST_ASIO_CHECK(!r.is_subnet_of(r));
199 
200   network_v6 net12(make_network_v6("2001:370::10:7344/64"));
201   network_v6 net13(make_network_v6("2001:0db8::/127"));
202   network_v6 net14(make_network_v6("2001:0db8::/125"));
203   network_v6 net15(make_network_v6("2001:0db8::/119"));
204 
205   // network
206   BOOST_ASIO_CHECK(net12.network() == make_address_v6("2001:370::"));
207   BOOST_ASIO_CHECK(net13.network() == make_address_v6("2001:0db8::"));
208   BOOST_ASIO_CHECK(net14.network() == make_address_v6("2001:0db8::"));
209   BOOST_ASIO_CHECK(net15.network() == make_address_v6("2001:0db8::"));
210 
211   // iterator
212   //BOOST_ASIO_CHECK(std::distance(net12.hosts().begin(),net12.hosts().end()) == 18446744073709552000);
213   BOOST_ASIO_CHECK(std::distance(net13.hosts().begin(),net13.hosts().end()) == 2);
214   BOOST_ASIO_CHECK(std::distance(net14.hosts().begin(),net14.hosts().end()) == 8);
215   BOOST_ASIO_CHECK(std::distance(net15.hosts().begin(),net15.hosts().end()) == 512);
216   BOOST_ASIO_CHECK(*net12.hosts().begin() == make_address_v6("2001:0370::"));
217   BOOST_ASIO_CHECK(net12.hosts().end() != net12.hosts().find(make_address_v6("2001:0370::ffff:ffff:ffff:ffff")));
218   BOOST_ASIO_CHECK(*net13.hosts().begin() == make_address_v6("2001:0db8::"));
219   BOOST_ASIO_CHECK(net13.hosts().end() != net13.hosts().find(make_address_v6("2001:0db8::1")));
220   BOOST_ASIO_CHECK(net13.hosts().end() == net13.hosts().find(make_address_v6("2001:0db8::2")));
221   BOOST_ASIO_CHECK(*net14.hosts().begin() == make_address_v6("2001:0db8::"));
222   BOOST_ASIO_CHECK(net14.hosts().end() != net14.hosts().find(make_address_v6("2001:0db8::7")));
223   BOOST_ASIO_CHECK(net14.hosts().end() == net14.hosts().find(make_address_v6("2001:0db8::8")));
224   BOOST_ASIO_CHECK(*net15.hosts().begin() == make_address_v6("2001:0db8::"));
225   BOOST_ASIO_CHECK(net15.hosts().end() != net15.hosts().find(make_address_v6("2001:0db8::01ff")));
226   BOOST_ASIO_CHECK(net15.hosts().end() == net15.hosts().find(make_address_v6("2001:0db8::0200")));
227 }
228 
229 } // namespace ip_network_v6_runtime
230 
231 //------------------------------------------------------------------------------
232 
233 BOOST_ASIO_TEST_SUITE
234 (
235   "ip/network_v6",
236   BOOST_ASIO_TEST_CASE(ip_network_v6_compile::test)
237   BOOST_ASIO_TEST_CASE(ip_network_v6_runtime::test)
238 )
239