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