]>
Commit | Line | Data |
---|---|---|
b32b8144 FG |
1 | // |
2 | // network_v4.cpp | |
3 | // ~~~~~~~~~~~~~~ | |
4 | // | |
11fdf7f2 | 5 | // Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
b32b8144 FG |
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_v4.hpp> | |
19 | ||
20 | #include "../unit_test.hpp" | |
21 | #include <sstream> | |
22 | ||
23 | //------------------------------------------------------------------------------ | |
24 | ||
25 | // ip_network_v4_compile test | |
26 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
27 | // The following test checks that all public member functions on the class | |
28 | // ip::network_v4 compile and link correctly. Runtime failures are ignored. | |
29 | ||
30 | namespace ip_network_v4_compile { | |
31 | ||
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_v4 constructors. | |
42 | ||
43 | ip::network_v4 net1(ip::make_address_v4("192.168.1.0"), 32); | |
44 | ip::network_v4 net2(ip::make_address_v4("192.168.1.0"), | |
45 | ip::make_address_v4("255.255.255.0")); | |
46 | ||
47 | // network_v4 functions. | |
48 | ||
49 | ip::address_v4 addr1 = net1.address(); | |
50 | (void)addr1; | |
51 | ||
52 | unsigned short prefix_len = net1.prefix_length(); | |
53 | (void)prefix_len; | |
54 | ||
55 | ip::address_v4 addr2 = net1.netmask(); | |
56 | (void)addr2; | |
57 | ||
58 | ip::address_v4 addr3 = net1.network(); | |
59 | (void)addr3; | |
60 | ||
61 | ip::address_v4 addr4 = net1.broadcast(); | |
62 | (void)addr4; | |
63 | ||
64 | ip::address_v4_range hosts = net1.hosts(); | |
65 | (void)hosts; | |
66 | ||
67 | ip::network_v4 net3 = net1.canonical(); | |
68 | (void)net3; | |
69 | ||
70 | bool b1 = net1.is_host(); | |
71 | (void)b1; | |
72 | ||
73 | bool b2 = net1.is_subnet_of(net2); | |
74 | (void)b2; | |
75 | ||
76 | std::string s1 = net1.to_string(); | |
77 | (void)s1; | |
78 | ||
79 | std::string s2 = net1.to_string(ec); | |
80 | (void)s2; | |
81 | ||
82 | // network_v4 comparisons. | |
83 | ||
84 | bool b3 = (net1 == net2); | |
85 | (void)b3; | |
86 | ||
87 | bool b4 = (net1 != net2); | |
88 | (void)b4; | |
89 | ||
90 | // network_v4 creation functions. | |
91 | ||
92 | net1 = ip::make_network_v4(ip::address_v4(), 24); | |
93 | net1 = ip::make_network_v4(ip::address_v4(), ip::address_v4()); | |
94 | net1 = ip::make_network_v4("10.0.0.0/8"); | |
95 | net1 = ip::make_network_v4("10.0.0.0/8", ec); | |
96 | net1 = ip::make_network_v4(s1); | |
97 | net1 = ip::make_network_v4(s1, ec); | |
11fdf7f2 TL |
98 | #if defined(BOOST_ASIO_HAS_STRING_VIEW) |
99 | # if defined(BOOST_ASIO_HAS_STD_STRING_VIEW) | |
b32b8144 | 100 | std::string_view string_view_value("10.0.0.0/8"); |
11fdf7f2 TL |
101 | # elif defined(BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) |
102 | std::experimental::string_view string_view_value("10.0.0.0/8"); | |
b32b8144 FG |
103 | # endif // defined(BOOST_ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW) |
104 | net1 = ip::make_network_v4(string_view_value); | |
105 | net1 = ip::make_network_v4(string_view_value, ec); | |
11fdf7f2 | 106 | #endif // defined(BOOST_ASIO_HAS_STRING_VIEW) |
b32b8144 FG |
107 | |
108 | // network_v4 I/O. | |
109 | ||
110 | std::ostringstream os; | |
111 | os << net1; | |
112 | ||
113 | #if !defined(BOOST_NO_STD_WSTREAMBUF) | |
114 | std::wostringstream wos; | |
115 | wos << net1; | |
116 | #endif // !defined(BOOST_NO_STD_WSTREAMBUF) | |
117 | } | |
118 | catch (std::exception&) | |
119 | { | |
120 | } | |
121 | } | |
122 | ||
123 | } // namespace ip_network_v4_compile | |
124 | ||
125 | //------------------------------------------------------------------------------ | |
126 | ||
127 | // ip_network_v4_runtime test | |
128 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
129 | // The following test checks that the various public member functions meet the | |
130 | // necessary postconditions. | |
131 | ||
132 | namespace ip_network_v4_runtime { | |
133 | ||
134 | void test() | |
135 | { | |
136 | using boost::asio::ip::address_v4; | |
137 | using boost::asio::ip::make_address_v4; | |
138 | using boost::asio::ip::network_v4; | |
139 | using boost::asio::ip::make_network_v4; | |
140 | ||
141 | address_v4 addr = make_address_v4("1.2.3.4"); | |
142 | ||
143 | // calculate prefix length | |
144 | ||
145 | network_v4 net1(addr, make_address_v4("255.255.255.0")); | |
146 | BOOST_ASIO_CHECK(net1.prefix_length() == 24); | |
147 | ||
148 | network_v4 net2(addr, make_address_v4("255.255.255.192")); | |
149 | BOOST_ASIO_CHECK(net2.prefix_length() == 26); | |
150 | ||
151 | network_v4 net3(addr, make_address_v4("128.0.0.0")); | |
152 | BOOST_ASIO_CHECK(net3.prefix_length() == 1); | |
153 | ||
154 | std::string msg; | |
155 | try | |
156 | { | |
157 | make_network_v4(addr, make_address_v4("255.255.255.1")); | |
158 | } | |
159 | catch(std::exception& ex) | |
160 | { | |
161 | msg = ex.what(); | |
162 | } | |
163 | BOOST_ASIO_CHECK(msg == std::string("non-contiguous netmask")); | |
164 | ||
165 | msg.clear(); | |
166 | try | |
167 | { | |
168 | make_network_v4(addr, make_address_v4("0.255.255.0")); | |
169 | } | |
170 | catch(std::exception& ex) | |
171 | { | |
172 | msg = ex.what(); | |
173 | } | |
174 | BOOST_ASIO_CHECK(msg == std::string("non-contiguous netmask")); | |
175 | ||
176 | // calculate netmask | |
177 | ||
178 | network_v4 net4(addr, 23); | |
179 | BOOST_ASIO_CHECK(net4.netmask() == make_address_v4("255.255.254.0")); | |
180 | ||
181 | network_v4 net5(addr, 12); | |
182 | BOOST_ASIO_CHECK(net5.netmask() == make_address_v4("255.240.0.0")); | |
183 | ||
184 | network_v4 net6(addr, 24); | |
185 | BOOST_ASIO_CHECK(net6.netmask() == make_address_v4("255.255.255.0")); | |
186 | ||
187 | network_v4 net7(addr, 16); | |
188 | BOOST_ASIO_CHECK(net7.netmask() == make_address_v4("255.255.0.0")); | |
189 | ||
190 | network_v4 net8(addr, 8); | |
191 | BOOST_ASIO_CHECK(net8.netmask() == make_address_v4("255.0.0.0")); | |
192 | ||
193 | network_v4 net9(addr, 32); | |
194 | BOOST_ASIO_CHECK(net9.netmask() == make_address_v4("255.255.255.255")); | |
195 | ||
196 | network_v4 net10(addr, 1); | |
197 | BOOST_ASIO_CHECK(net10.netmask() == make_address_v4("128.0.0.0")); | |
198 | ||
199 | network_v4 net11(addr, 0); | |
200 | BOOST_ASIO_CHECK(net11.netmask() == make_address_v4("0.0.0.0")); | |
201 | ||
202 | msg.clear(); | |
203 | try | |
204 | { | |
205 | make_network_v4(addr, 33); | |
206 | } | |
207 | catch(std::out_of_range& ex) | |
208 | { | |
209 | msg = ex.what(); | |
210 | } | |
211 | BOOST_ASIO_CHECK(msg == std::string("prefix length too large")); | |
212 | ||
213 | // construct address range from address and prefix length | |
214 | BOOST_ASIO_CHECK(network_v4(make_address_v4("192.168.77.100"), 32).network() == make_address_v4("192.168.77.100")); | |
215 | BOOST_ASIO_CHECK(network_v4(make_address_v4("192.168.77.100"), 24).network() == make_address_v4("192.168.77.0")); | |
216 | BOOST_ASIO_CHECK(network_v4(make_address_v4("192.168.77.128"), 25).network() == make_address_v4("192.168.77.128")); | |
217 | ||
218 | // construct address range from string in CIDR notation | |
219 | BOOST_ASIO_CHECK(make_network_v4("192.168.77.100/32").network() == make_address_v4("192.168.77.100")); | |
220 | BOOST_ASIO_CHECK(make_network_v4("192.168.77.100/24").network() == make_address_v4("192.168.77.0")); | |
221 | BOOST_ASIO_CHECK(make_network_v4("192.168.77.128/25").network() == make_address_v4("192.168.77.128")); | |
222 | ||
223 | // construct network from invalid string | |
224 | boost::system::error_code ec; | |
225 | make_network_v4("10.0.0.256/24", ec); | |
226 | BOOST_ASIO_CHECK(!!ec); | |
227 | make_network_v4("10.0.0.0/33", ec); | |
228 | BOOST_ASIO_CHECK(!!ec); | |
229 | make_network_v4("10.0.0.0/-1", ec); | |
230 | BOOST_ASIO_CHECK(!!ec); | |
231 | make_network_v4("10.0.0.0/", ec); | |
232 | BOOST_ASIO_CHECK(!!ec); | |
233 | make_network_v4("10.0.0.0", ec); | |
234 | BOOST_ASIO_CHECK(!!ec); | |
235 | ||
236 | // prefix length | |
237 | BOOST_ASIO_CHECK(make_network_v4("193.99.144.80/24").prefix_length() == 24); | |
238 | BOOST_ASIO_CHECK(network_v4(make_address_v4("193.99.144.80"), 24).prefix_length() == 24); | |
239 | BOOST_ASIO_CHECK(network_v4(make_address_v4("192.168.77.0"), make_address_v4("255.255.255.0")).prefix_length() == 24); | |
240 | ||
241 | // to string | |
242 | std::string a("192.168.77.0/32"); | |
243 | BOOST_ASIO_CHECK(make_network_v4(a.c_str()).to_string() == a); | |
244 | BOOST_ASIO_CHECK(network_v4(make_address_v4("192.168.77.10"), 24).to_string() == std::string("192.168.77.10/24")); | |
245 | ||
246 | // return host part | |
247 | BOOST_ASIO_CHECK(make_network_v4("192.168.77.11/24").address() == make_address_v4("192.168.77.11")); | |
248 | ||
249 | // return host in CIDR notation | |
250 | BOOST_ASIO_CHECK(make_network_v4("192.168.78.30/20").address().to_string() == "192.168.78.30"); | |
251 | ||
252 | // return network in CIDR notation | |
253 | BOOST_ASIO_CHECK(make_network_v4("192.168.78.30/20").canonical().to_string() == "192.168.64.0/20"); | |
254 | ||
255 | // is host | |
256 | BOOST_ASIO_CHECK(make_network_v4("192.168.77.0/32").is_host()); | |
257 | BOOST_ASIO_CHECK(!make_network_v4("192.168.77.0/31").is_host()); | |
258 | ||
259 | // is real subnet of | |
260 | BOOST_ASIO_CHECK(make_network_v4("192.168.0.192/24").is_subnet_of(make_network_v4("192.168.0.0/16"))); | |
261 | BOOST_ASIO_CHECK(make_network_v4("192.168.0.0/24").is_subnet_of(make_network_v4("192.168.192.168/16"))); | |
262 | BOOST_ASIO_CHECK(make_network_v4("192.168.0.192/24").is_subnet_of(make_network_v4("192.168.192.168/16"))); | |
263 | BOOST_ASIO_CHECK(make_network_v4("192.168.0.0/24").is_subnet_of(make_network_v4("192.168.0.0/16"))); | |
264 | BOOST_ASIO_CHECK(make_network_v4("192.168.0.0/24").is_subnet_of(make_network_v4("192.168.0.0/23"))); | |
265 | BOOST_ASIO_CHECK(make_network_v4("192.168.0.0/24").is_subnet_of(make_network_v4("192.168.0.0/0"))); | |
266 | BOOST_ASIO_CHECK(make_network_v4("192.168.0.0/32").is_subnet_of(make_network_v4("192.168.0.0/24"))); | |
267 | ||
268 | BOOST_ASIO_CHECK(!make_network_v4("192.168.0.0/32").is_subnet_of(make_network_v4("192.168.0.0/32"))); | |
269 | BOOST_ASIO_CHECK(!make_network_v4("192.168.0.0/24").is_subnet_of(make_network_v4("192.168.1.0/24"))); | |
270 | BOOST_ASIO_CHECK(!make_network_v4("192.168.0.0/16").is_subnet_of(make_network_v4("192.168.1.0/24"))); | |
271 | ||
272 | network_v4 r(make_network_v4("192.168.0.0/24")); | |
273 | BOOST_ASIO_CHECK(!r.is_subnet_of(r)); | |
274 | ||
275 | network_v4 net12(make_network_v4("192.168.0.2/24")); | |
276 | network_v4 net13(make_network_v4("192.168.1.1/28")); | |
277 | network_v4 net14(make_network_v4("192.168.1.21/28")); | |
278 | // network | |
279 | BOOST_ASIO_CHECK(net12.network() == make_address_v4("192.168.0.0")); | |
280 | BOOST_ASIO_CHECK(net13.network() == make_address_v4("192.168.1.0")); | |
281 | BOOST_ASIO_CHECK(net14.network() == make_address_v4("192.168.1.16")); | |
282 | // netmask | |
283 | BOOST_ASIO_CHECK(net12.netmask() == make_address_v4("255.255.255.0")); | |
284 | BOOST_ASIO_CHECK(net13.netmask() == make_address_v4("255.255.255.240")); | |
285 | BOOST_ASIO_CHECK(net14.netmask() == make_address_v4("255.255.255.240")); | |
286 | // broadcast | |
287 | BOOST_ASIO_CHECK(net12.broadcast() == make_address_v4("192.168.0.255")); | |
288 | BOOST_ASIO_CHECK(net13.broadcast() == make_address_v4("192.168.1.15")); | |
289 | BOOST_ASIO_CHECK(net14.broadcast() == make_address_v4("192.168.1.31")); | |
290 | // iterator | |
291 | BOOST_ASIO_CHECK(std::distance(net12.hosts().begin(),net12.hosts().end()) == 254); | |
292 | BOOST_ASIO_CHECK(*net12.hosts().begin() == make_address_v4("192.168.0.1")); | |
293 | BOOST_ASIO_CHECK(net12.hosts().end() != net12.hosts().find(make_address_v4("192.168.0.10"))); | |
294 | BOOST_ASIO_CHECK(net12.hosts().end() == net12.hosts().find(make_address_v4("192.168.1.10"))); | |
295 | BOOST_ASIO_CHECK(std::distance(net13.hosts().begin(),net13.hosts().end()) == 14); | |
296 | BOOST_ASIO_CHECK(*net13.hosts().begin() == make_address_v4("192.168.1.1")); | |
297 | BOOST_ASIO_CHECK(net13.hosts().end() != net13.hosts().find(make_address_v4("192.168.1.14"))); | |
298 | BOOST_ASIO_CHECK(net13.hosts().end() == net13.hosts().find(make_address_v4("192.168.1.15"))); | |
299 | BOOST_ASIO_CHECK(std::distance(net14.hosts().begin(),net14.hosts().end()) == 14); | |
300 | BOOST_ASIO_CHECK(*net14.hosts().begin() == make_address_v4("192.168.1.17")); | |
301 | BOOST_ASIO_CHECK(net14.hosts().end() != net14.hosts().find(make_address_v4("192.168.1.30"))); | |
302 | BOOST_ASIO_CHECK(net14.hosts().end() == net14.hosts().find(make_address_v4("192.168.1.31"))); | |
303 | } | |
304 | ||
305 | } // namespace ip_network_v4_runtime | |
306 | ||
307 | //------------------------------------------------------------------------------ | |
308 | ||
309 | BOOST_ASIO_TEST_SUITE | |
310 | ( | |
311 | "ip/network_v4", | |
312 | BOOST_ASIO_TEST_CASE(ip_network_v4_compile::test) | |
313 | BOOST_ASIO_TEST_CASE(ip_network_v4_runtime::test) | |
314 | ) |