Line data Source code
1 : // Copyright (c) 2011-2021 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // Project: https://snapwebsites.org/project/libaddr
4 : //
5 : // Permission is hereby granted, free of charge, to any
6 : // person obtaining a copy of this software and
7 : // associated documentation files (the "Software"), to
8 : // deal in the Software without restriction, including
9 : // without limitation the rights to use, copy, modify,
10 : // merge, publish, distribute, sublicense, and/or sell
11 : // copies of the Software, and to permit persons to whom
12 : // the Software is furnished to do so, subject to the
13 : // following conditions:
14 : //
15 : // The above copyright notice and this permission notice
16 : // shall be included in all copies or substantial
17 : // portions of the Software.
18 : //
19 : // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
20 : // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
21 : // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
22 : // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
23 : // EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 : // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25 : // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26 : // ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 : // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 : // SOFTWARE.
29 :
30 :
31 : /** \file
32 : * \brief Test the IPv4 interface.
33 : *
34 : * These test verify that the IPv4 side of things function as expected.
35 : *
36 : * Note that some of the tests between the IPv4 and IPv6 overlap. Here
37 : * you mainly find the IPv4 side of things.
38 : */
39 :
40 : // self
41 : //
42 : #include "catch_main.h"
43 :
44 :
45 : // addr lib
46 : //
47 : #include <libaddr/iface.h>
48 :
49 :
50 : // last include
51 : //
52 : #include <snapdev/poison.h>
53 :
54 :
55 :
56 :
57 : /** \brief Details used by the addr class implementation.
58 : *
59 : * We have a function to check whether an address is part of
60 : * the interfaces of your computer. This check requires the
61 : * use of a `struct ifaddrs` and as such it requires to
62 : * delete that structure. We define a deleter for that
63 : * strucure here.
64 : */
65 : namespace
66 : {
67 :
68 : /** \brief Close a socket.
69 : *
70 : * This deleter is used to make sure all the socket we test get closed
71 : * on exit.
72 : *
73 : * \param[in] s The socket to close.
74 : */
75 4 : void socket_deleter(int * s)
76 : {
77 4 : close(*s);
78 4 : }
79 :
80 :
81 : }
82 : // no name namespace
83 :
84 :
85 :
86 17 : CATCH_TEST_CASE( "ipv4::invalid_input", "[ipv4]" )
87 : {
88 30 : CATCH_GIVEN("addr()")
89 : {
90 1 : addr::addr a;
91 :
92 2 : CATCH_SECTION("set IPv4 with an invalid family")
93 : {
94 26 : for(int idx(0); idx < 25; ++idx)
95 : {
96 25 : struct sockaddr_in in = sockaddr_in();
97 0 : do
98 : {
99 25 : in.sin_family = rand();
100 : }
101 25 : while(in.sin_family == AF_INET);
102 25 : in.sin_port = htons(rand());
103 25 : in.sin_addr.s_addr = htonl(rand() ^ (rand() << 16));
104 25 : CATCH_REQUIRE_THROWS_AS(a.set_ipv4(in), addr::addr_invalid_argument);
105 25 : CATCH_REQUIRE_THROWS_AS(addr::addr(in), addr::addr_invalid_argument);
106 : }
107 : }
108 : }
109 :
110 30 : CATCH_GIVEN("addr_parser() with IPv4 settings")
111 : {
112 4 : addr::addr_parser a;
113 :
114 4 : CATCH_SECTION("invalid allow flags (too small)")
115 : {
116 11 : for(int idx(0); idx < 10; ++idx)
117 : {
118 : // test with a negative number
119 : //
120 : int n;
121 0 : do
122 : {
123 10 : n = rand();
124 : }
125 10 : while(n == 0);
126 10 : if(n > 0)
127 : {
128 : // all positive numbers have a corresponding negative
129 : // number so this always flips the sign as expected
130 : //
131 10 : n = -n;
132 : }
133 10 : addr::addr_parser::flag_t const flag(static_cast<addr::addr_parser::flag_t>(n));
134 :
135 10 : CATCH_REQUIRE_THROWS_AS(a.set_allow(flag, true), addr::addr_invalid_argument);
136 10 : CATCH_REQUIRE_THROWS_AS(a.set_allow(flag, false), addr::addr_invalid_argument);
137 10 : CATCH_REQUIRE_THROWS_AS(a.get_allow(flag), addr::addr_invalid_argument);
138 : }
139 : }
140 :
141 4 : CATCH_SECTION("invalid allow flags (too large)")
142 : {
143 11 : for(int idx(0); idx < 10; ++idx)
144 : {
145 : // test with a negative number
146 : //
147 : int n;
148 0 : do
149 : {
150 10 : n = rand();
151 10 : if(n < 0)
152 : {
153 0 : n = -n;
154 : }
155 : }
156 10 : while(n < static_cast<int>(addr::addr_parser::flag_t::FLAG_max));
157 10 : addr::addr_parser::flag_t const flag(static_cast<addr::addr_parser::flag_t>(n));
158 :
159 10 : CATCH_REQUIRE_THROWS_AS(a.set_allow(flag, true), addr::addr_invalid_argument);
160 10 : CATCH_REQUIRE_THROWS_AS(a.set_allow(flag, false), addr::addr_invalid_argument);
161 10 : CATCH_REQUIRE_THROWS_AS(a.get_allow(flag), addr::addr_invalid_argument);
162 : }
163 : }
164 : }
165 :
166 30 : CATCH_GIVEN("addr_parser() with IPv4 addresses")
167 : {
168 4 : CATCH_SECTION("bad address")
169 : {
170 2 : addr::addr_parser p;
171 2 : addr::addr_range::vector_t ips(p.parse("{bad-ip}"));
172 1 : CATCH_REQUIRE(p.has_errors());
173 1 : CATCH_REQUIRE(p.error_count() == 1);
174 1 : CATCH_REQUIRE(p.error_messages() == "Invalid address in \"{bad-ip}\" error -2 -- Name or service not known (errno: 2 -- No such file or directory).\n");
175 1 : CATCH_REQUIRE(p.has_errors());
176 1 : p.clear_errors();
177 1 : CATCH_REQUIRE_FALSE(p.has_errors());
178 1 : CATCH_REQUIRE(ips.size() == 0);
179 : }
180 :
181 4 : CATCH_SECTION("required address")
182 : {
183 2 : addr::addr_parser p;
184 1 : p.set_protocol(IPPROTO_TCP);
185 1 : p.set_allow(addr::addr_parser::flag_t::REQUIRED_ADDRESS, true);
186 2 : addr::addr_range::vector_t ips(p.parse(""));
187 1 : CATCH_REQUIRE(p.has_errors());
188 1 : CATCH_REQUIRE(p.error_count() == 1);
189 1 : CATCH_REQUIRE(p.error_messages() == "Required address is missing.\n");
190 1 : CATCH_REQUIRE(p.has_errors());
191 1 : p.clear_errors();
192 1 : CATCH_REQUIRE_FALSE(p.has_errors());
193 1 : CATCH_REQUIRE(ips.size() == 0);
194 : }
195 : }
196 :
197 30 : CATCH_GIVEN("addr_parser() with IPv4 ports")
198 : {
199 6 : CATCH_SECTION("required port")
200 : {
201 : // optional + required -> required
202 : {
203 2 : addr::addr_parser p;
204 1 : p.set_protocol(IPPROTO_TCP);
205 1 : p.set_allow(addr::addr_parser::flag_t::REQUIRED_PORT, true);
206 2 : addr::addr_range::vector_t ips(p.parse("1.2.3.4"));
207 1 : CATCH_REQUIRE(p.has_errors());
208 1 : CATCH_REQUIRE(p.error_count() == 1);
209 1 : CATCH_REQUIRE(p.error_messages() == "Required port is missing.\n");
210 1 : CATCH_REQUIRE(p.has_errors());
211 1 : p.clear_errors();
212 1 : CATCH_REQUIRE_FALSE(p.has_errors());
213 1 : CATCH_REQUIRE(ips.size() == 0);
214 : }
215 :
216 : // only required -> required just the same
217 : {
218 2 : addr::addr_parser p;
219 1 : p.set_protocol(IPPROTO_TCP);
220 1 : p.set_allow(addr::addr_parser::flag_t::PORT, false);
221 1 : p.set_allow(addr::addr_parser::flag_t::REQUIRED_PORT, true);
222 2 : addr::addr_range::vector_t ips(p.parse("1.2.3.4"));
223 1 : CATCH_REQUIRE(p.has_errors());
224 1 : CATCH_REQUIRE(p.error_count() == 1);
225 1 : CATCH_REQUIRE(p.error_messages() == "Required port is missing.\n");
226 1 : CATCH_REQUIRE(p.has_errors());
227 1 : p.clear_errors();
228 1 : CATCH_REQUIRE_FALSE(p.has_errors());
229 1 : CATCH_REQUIRE(ips.size() == 0);
230 : }
231 : }
232 :
233 6 : CATCH_SECTION("port not allowed")
234 : {
235 2 : addr::addr_parser p;
236 1 : p.set_protocol(IPPROTO_TCP);
237 1 : p.set_allow(addr::addr_parser::flag_t::PORT, false);
238 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::REQUIRED_PORT));
239 2 : addr::addr_range::vector_t ips(p.parse("1.2.3.4:123"));
240 1 : CATCH_REQUIRE(p.has_errors());
241 1 : CATCH_REQUIRE(p.error_count() == 1);
242 1 : CATCH_REQUIRE(p.error_messages() == "Port not allowed (1.2.3.4:123).\n");
243 1 : CATCH_REQUIRE(p.has_errors());
244 1 : p.clear_errors();
245 1 : CATCH_REQUIRE_FALSE(p.has_errors());
246 1 : CATCH_REQUIRE(ips.size() == 0);
247 : }
248 :
249 6 : CATCH_SECTION("invalid port")
250 : {
251 2 : addr::addr_parser p;
252 :
253 : // so to a different default value
254 : //
255 1 : int const default_port(rand() & 0xFFFF);
256 1 : p.set_default_port(default_port);
257 :
258 26 : for(int idx(0); idx < 25; ++idx)
259 : {
260 : int port;
261 0 : do
262 : {
263 25 : port = rand() ^ (rand() << 16);
264 : }
265 25 : while(port >= -1 && port <= 65535); // -1 is valid here, it represents "no default port defined"
266 25 : CATCH_REQUIRE_THROWS_AS(p.set_default_port(port), addr::addr_invalid_argument);
267 :
268 : // verify port unchanged
269 : //
270 25 : CATCH_REQUIRE(p.get_default_port() == default_port);
271 : }
272 : }
273 : }
274 :
275 30 : CATCH_GIVEN("addr_parser() with invalid masks")
276 : {
277 10 : CATCH_SECTION("really large numbers (over 1000)")
278 : {
279 6 : for(int idx(0); idx < 5; ++idx)
280 : {
281 5 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
282 5 : int const port(rand() & 0xFFFF);
283 5 : int const mask((rand() & 0xFF) + 1001);
284 10 : addr::addr_parser p;
285 5 : p.set_protocol(proto);
286 5 : p.set_allow(p.flag_t::MASK, true);
287 10 : addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port) + "/" + std::to_string(mask)));
288 5 : CATCH_REQUIRE(p.has_errors());
289 5 : CATCH_REQUIRE(p.error_count() == 1);
290 5 : CATCH_REQUIRE(p.error_messages() == "Mask number too large (" + std::to_string(mask) + ", expected a maximum of 128).\n");
291 5 : CATCH_REQUIRE(ips.size() == 0);
292 : }
293 : }
294 :
295 10 : CATCH_SECTION("ipv4 mask is limited between 0 and 32")
296 : {
297 6 : for(int idx(0); idx < 5; ++idx)
298 : {
299 5 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
300 5 : int const port(rand() & 0xFFFF);
301 5 : int const mask((rand() & 0xFF) + 33);
302 10 : addr::addr_parser p;
303 5 : p.set_protocol(proto);
304 5 : p.set_allow(p.flag_t::MASK, true);
305 10 : addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port) + "/" + std::to_string(mask)));
306 5 : CATCH_REQUIRE(p.has_errors());
307 5 : CATCH_REQUIRE(p.error_count() == 1);
308 5 : CATCH_REQUIRE(p.error_messages() == "Unsupported mask size (" + std::to_string(mask) + ", expected 32 at the most for an IPv4).\n");
309 5 : CATCH_REQUIRE(ips.size() == 0);
310 : }
311 : }
312 :
313 10 : CATCH_SECTION("ipv4 mask cannot use name")
314 : {
315 6 : for(int idx(0); idx < 5; ++idx)
316 : {
317 5 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
318 5 : int const port(rand() & 0xFFFF);
319 10 : addr::addr_parser p;
320 5 : p.set_protocol(proto);
321 5 : p.set_allow(addr::addr_parser::flag_t::MASK, true);
322 10 : addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port) + "/localhost"));
323 5 : CATCH_REQUIRE(p.has_errors());
324 5 : CATCH_REQUIRE(p.error_count() == 1);
325 5 : CATCH_REQUIRE(p.error_messages() == "Invalid mask in \"/localhost\", error -2 -- Name or service not known (errno: 0 -- Success).\n");
326 5 : CATCH_REQUIRE(ips.size() == 0);
327 : }
328 : }
329 :
330 10 : CATCH_SECTION("ipv4 mask mismatch (mask uses ipv6)")
331 : {
332 1 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
333 1 : int const port(rand() & 0xFFFF);
334 2 : addr::addr_parser p;
335 1 : p.set_protocol(proto);
336 1 : p.set_allow(addr::addr_parser::flag_t::MASK, true);
337 2 : addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port) + "/[1:2:3:4:5:6:7:8]"));
338 1 : CATCH_REQUIRE(p.has_errors());
339 1 : CATCH_REQUIRE(p.error_count() == 1);
340 1 : CATCH_REQUIRE(p.error_messages() == "The address uses the IPv4 syntax, the mask cannot use IPv6.\n");
341 1 : CATCH_REQUIRE(ips.size() == 0);
342 : }
343 :
344 10 : CATCH_SECTION("ipv4 mask mismatch (mask uses ipv6 without [...])")
345 : {
346 1 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
347 1 : int const port(rand() & 0xFFFF);
348 2 : addr::addr_parser p;
349 1 : p.set_protocol(proto);
350 1 : p.set_allow(addr::addr_parser::flag_t::MASK, true);
351 2 : addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port) + "/1:2:3:4:5:6:7:8"));
352 1 : CATCH_REQUIRE(p.has_errors());
353 1 : CATCH_REQUIRE(p.error_count() == 1);
354 1 : CATCH_REQUIRE(p.error_messages() == "Incompatible address between the address and mask address (first was an IPv4 second an IPv6).\n");
355 1 : CATCH_REQUIRE(ips.size() == 0);
356 : }
357 : }
358 :
359 30 : CATCH_GIVEN("addr_parser() with invalid protocols")
360 : {
361 4 : CATCH_SECTION("invalid names")
362 : {
363 2 : addr::addr_parser p;
364 :
365 : // not changing default protocol
366 : //
367 1 : CATCH_REQUIRE(p.get_protocol() == -1);
368 1 : CATCH_REQUIRE_THROWS_AS(p.set_protocol("igmp"), addr::addr_invalid_argument);
369 1 : CATCH_REQUIRE(p.get_protocol() == -1);
370 :
371 : // change protocol to another valid value first
372 : //
373 1 : p.set_protocol("tcp");
374 1 : CATCH_REQUIRE_THROWS_AS(p.set_protocol("icmp"), addr::addr_invalid_argument);
375 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_TCP);
376 : }
377 :
378 4 : CATCH_SECTION("invalid numbers")
379 : {
380 101 : for(int idx(0); idx < 100; ++idx)
381 : {
382 : int protocol;
383 0 : do
384 : {
385 100 : protocol = rand();
386 : }
387 : while(protocol == IPPROTO_IP
388 100 : || protocol == IPPROTO_TCP
389 200 : || protocol == IPPROTO_UDP);
390 :
391 200 : addr::addr_parser p;
392 :
393 100 : CATCH_REQUIRE_THROWS_AS(p.set_protocol(protocol), addr::addr_invalid_argument);
394 100 : CATCH_REQUIRE(p.get_protocol() == -1);
395 :
396 : // change protocol to another valid value first
397 : //
398 100 : p.set_protocol("tcp");
399 100 : CATCH_REQUIRE_THROWS_AS(p.set_protocol(protocol), addr::addr_invalid_argument);
400 100 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_TCP);
401 : }
402 : }
403 : }
404 15 : }
405 :
406 :
407 11 : CATCH_TEST_CASE( "ipv4::addr", "[ipv4]" )
408 : {
409 18 : CATCH_GIVEN("addr()")
410 : {
411 9 : addr::addr a;
412 :
413 18 : CATCH_SECTION("not an IPv4")
414 : {
415 1 : CATCH_REQUIRE_FALSE(a.is_ipv4());
416 :
417 1 : struct sockaddr_in in;
418 1 : CATCH_REQUIRE_THROWS_AS(a.get_ipv4(in), addr::addr_invalid_state);
419 1 : CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY), addr::addr_invalid_state);
420 1 : CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_BRACKETS), addr::addr_invalid_state);
421 1 : CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_PORT), addr::addr_invalid_state);
422 1 : CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_MASK), addr::addr_invalid_state);
423 1 : CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_BRACKETS_MASK), addr::addr_invalid_state);
424 1 : CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ALL), addr::addr_invalid_state);
425 : }
426 :
427 18 : CATCH_SECTION("default network type (0.0.0.0)")
428 : {
429 1 : CATCH_REQUIRE(a.is_default());
430 1 : CATCH_REQUIRE(a.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_ANY);
431 1 : CATCH_REQUIRE(a.get_network_type_string() == "Any");
432 : }
433 :
434 18 : CATCH_SECTION("IPv6 ANY")
435 : {
436 1 : struct sockaddr_in6 in6;
437 1 : a.get_ipv6(in6);
438 1 : CATCH_REQUIRE(in6.sin6_addr.s6_addr32[0] == 0);
439 1 : CATCH_REQUIRE(in6.sin6_addr.s6_addr32[1] == 0);
440 1 : CATCH_REQUIRE(in6.sin6_addr.s6_addr32[2] == 0);
441 1 : CATCH_REQUIRE(in6.sin6_addr.s6_addr32[3] == 0);
442 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "::");
443 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::addr::string_ip_t::STRING_IP_BRACKETS) == "[::]");
444 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::addr::string_ip_t::STRING_IP_PORT) == "[::]:0");
445 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::addr::string_ip_t::STRING_IP_MASK) == "::/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
446 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::addr::string_ip_t::STRING_IP_BRACKETS_MASK) == "[::]/[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]");
447 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::addr::string_ip_t::STRING_IP_ALL) == "[::]:0/[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]");
448 : }
449 :
450 18 : CATCH_SECTION("IPv4 or IPv6 string")
451 : {
452 1 : CATCH_REQUIRE(a.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "::");
453 1 : CATCH_REQUIRE(a.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_BRACKETS) == "[::]");
454 1 : CATCH_REQUIRE(a.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_PORT) == "[::]:0");
455 1 : CATCH_REQUIRE(a.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_MASK) == "::/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
456 1 : CATCH_REQUIRE(a.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_BRACKETS_MASK) == "[::]/[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]");
457 1 : CATCH_REQUIRE(a.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ALL) == "[::]:0/[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]");
458 : }
459 :
460 18 : CATCH_SECTION("interface determination")
461 : {
462 1 : CATCH_REQUIRE(addr::find_addr_interface(a, false) == nullptr);
463 1 : CATCH_REQUIRE(addr::find_addr_interface(a, true) != nullptr);
464 : }
465 :
466 18 : CATCH_SECTION("default name/service/port/protocol")
467 : {
468 1 : CATCH_REQUIRE(a.get_name() == std::string());
469 1 : CATCH_REQUIRE(a.get_service() == std::string());
470 1 : CATCH_REQUIRE(a.get_port() == 0);
471 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_TCP);
472 : }
473 :
474 18 : CATCH_SECTION("compare with self")
475 : {
476 1 : CATCH_REQUIRE(a == a);
477 1 : CATCH_REQUIRE_FALSE(a != a);
478 1 : CATCH_REQUIRE_FALSE(a < a);
479 1 : CATCH_REQUIRE(a <= a);
480 1 : CATCH_REQUIRE_FALSE(a > a);
481 1 : CATCH_REQUIRE(a >= a);
482 : }
483 :
484 18 : CATCH_SECTION("compare with another 0.0.0.0")
485 : {
486 : {
487 1 : addr::addr b;
488 :
489 1 : CATCH_REQUIRE(a == b);
490 1 : CATCH_REQUIRE_FALSE(a != b);
491 1 : CATCH_REQUIRE_FALSE(a < b);
492 1 : CATCH_REQUIRE(a <= b);
493 1 : CATCH_REQUIRE_FALSE(a > b);
494 1 : CATCH_REQUIRE(a >= b);
495 : }
496 :
497 : {
498 1 : struct sockaddr_in6 in6 = sockaddr_in6();
499 1 : in6.sin6_family = AF_INET6;
500 1 : in6.sin6_port = htons(0);
501 1 : in6.sin6_addr.s6_addr32[0] = htonl(0);
502 1 : in6.sin6_addr.s6_addr32[1] = htonl(0);
503 1 : in6.sin6_addr.s6_addr32[2] = htonl(0);
504 1 : in6.sin6_addr.s6_addr32[3] = htonl(0);
505 1 : addr::addr b(in6);
506 :
507 1 : CATCH_REQUIRE(a == b);
508 1 : CATCH_REQUIRE_FALSE(a != b);
509 1 : CATCH_REQUIRE_FALSE(a < b);
510 1 : CATCH_REQUIRE(a <= b);
511 1 : CATCH_REQUIRE_FALSE(a > b);
512 1 : CATCH_REQUIRE(a >= b);
513 : }
514 :
515 : // ANY in IPv4 != ANY in IPv6...
516 : // (i.e. IPv4 sets addr.sin6_addr.s6_addr16[5] == 0xFFFF)
517 : {
518 1 : struct sockaddr_in in = sockaddr_in();
519 1 : in.sin_family = AF_INET;
520 1 : in.sin_port = htons(0);
521 1 : in.sin_addr.s_addr = htonl(0);
522 1 : addr::addr b(in);
523 :
524 1 : CATCH_REQUIRE_FALSE(a == b);
525 1 : CATCH_REQUIRE(a != b);
526 1 : CATCH_REQUIRE(a < b);
527 1 : CATCH_REQUIRE(a <= b);
528 1 : CATCH_REQUIRE_FALSE(a > b);
529 1 : CATCH_REQUIRE_FALSE(a >= b);
530 : }
531 : }
532 :
533 18 : CATCH_SECTION("compare with IPv4 127.0.0.1")
534 : {
535 1 : struct sockaddr_in in = sockaddr_in();
536 1 : in.sin_family = AF_INET;
537 1 : in.sin_port = htons(80);
538 1 : in.sin_addr.s_addr = htonl((127 << 24) | 1);
539 1 : addr::addr b(in);
540 :
541 1 : CATCH_REQUIRE_FALSE(a == b);
542 1 : CATCH_REQUIRE(a != b);
543 1 : CATCH_REQUIRE(a < b);
544 1 : CATCH_REQUIRE(a <= b);
545 1 : CATCH_REQUIRE_FALSE(a > b);
546 1 : CATCH_REQUIRE_FALSE(a >= b);
547 : }
548 : }
549 9 : }
550 :
551 :
552 18 : CATCH_TEST_CASE( "ipv4::address", "[ipv4]" )
553 : {
554 32 : CATCH_GIVEN("addr() with an IPv4")
555 : {
556 3 : addr::addr a;
557 :
558 6 : CATCH_SECTION("set_ipv4() / get_ipv4()")
559 : {
560 11 : for(int idx(0); idx < 10; ++idx)
561 : {
562 10 : struct sockaddr_in in = sockaddr_in();
563 10 : in.sin_family = AF_INET;
564 10 : in.sin_port = htons(rand());
565 10 : in.sin_addr.s_addr = htonl(rand() ^ (rand() << 16));
566 :
567 : // test constructor
568 : //
569 10 : addr::addr b(in);
570 10 : struct sockaddr_in out;
571 10 : b.get_ipv4(out);
572 10 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
573 :
574 : // test set
575 : //
576 10 : a.set_ipv4(in);
577 10 : a.get_ipv4(out);
578 10 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
579 : }
580 : }
581 :
582 6 : CATCH_SECTION("set_ipv4() / to_ipv4_string()")
583 : {
584 11 : for(int idx(0); idx < 10; ++idx)
585 : {
586 10 : struct sockaddr_in in = sockaddr_in();
587 10 : in.sin_family = AF_INET;
588 10 : uint16_t const port(rand());
589 10 : in.sin_port = htons(port);
590 10 : uint32_t const address(rand() ^ (rand() << 16));
591 10 : in.sin_addr.s_addr = htonl(address);
592 :
593 10 : std::string ip(
594 20 : std::to_string((address >> 24) & 255)
595 30 : + "."
596 40 : + std::to_string((address >> 16) & 255)
597 30 : + "."
598 40 : + std::to_string((address >> 8) & 255)
599 30 : + "."
600 20 : + std::to_string((address >> 0) & 255)
601 40 : );
602 20 : std::string port_str(std::to_string(static_cast<int>(port)));
603 :
604 : // check IPv4 as a string
605 : //
606 10 : a.set_ipv4(in);
607 10 : CATCH_REQUIRE(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == ip);
608 10 : CATCH_REQUIRE(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_BRACKETS) == ip);
609 10 : CATCH_REQUIRE(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_PORT) == ip + ":" + port_str);
610 10 : CATCH_REQUIRE(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_MASK) == ip + "/255.255.255.255"); // will change to 32 at some point
611 10 : CATCH_REQUIRE(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_BRACKETS_MASK) == ip + "/255.255.255.255");
612 10 : CATCH_REQUIRE(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ALL) == ip + ":" + port_str + "/255.255.255.255");
613 : }
614 : }
615 :
616 6 : CATCH_SECTION("name of various IPs")
617 : {
618 1 : struct sockaddr_in in = sockaddr_in();
619 1 : in.sin_family = AF_INET;
620 1 : in.sin_port = htons(rand());
621 1 : in.sin_addr.s_addr = 0;
622 :
623 : // verify network type
624 : //
625 1 : a.set_ipv4(in);
626 1 : CATCH_REQUIRE(a.get_name() == std::string()); // no name for "any" (TCP)
627 :
628 1 : a.set_protocol(IPPROTO_UDP);
629 1 : CATCH_REQUIRE(a.get_name() == std::string()); // no name for "any" (UDP)
630 :
631 1 : in.sin_addr.s_addr = htonl(0x7f000001);
632 1 : a.set_ipv4(in);
633 1 : char hostname[HOST_NAME_MAX + 1];
634 1 : hostname[HOST_NAME_MAX] = '\0';
635 1 : CATCH_REQUIRE(gethostname(hostname, sizeof(hostname)) == 0);
636 1 : CATCH_REQUIRE(hostname[0] != '\0');
637 2 : std::string localhost(a.get_name());
638 1 : bool const localhost_flag(localhost == hostname || localhost == "localhost");
639 1 : CATCH_REQUIRE(localhost_flag);
640 :
641 1 : CATCH_REQUIRE(addr::find_addr_interface(a, false) != nullptr);
642 : }
643 : }
644 :
645 32 : CATCH_GIVEN("addr_parser() with IPv4 addresses")
646 : {
647 14 : CATCH_SECTION("verify basics")
648 : {
649 2 : addr::addr_parser p;
650 1 : p.set_protocol(IPPROTO_TCP);
651 1 : CATCH_REQUIRE(p.get_default_address4() == "");
652 1 : CATCH_REQUIRE(p.get_default_address6() == "");
653 1 : CATCH_REQUIRE(p.get_default_port() == -1);
654 1 : CATCH_REQUIRE(p.get_default_mask4() == "");
655 1 : CATCH_REQUIRE(p.get_default_mask6() == "");
656 2 : addr::addr_range::vector_t ips(p.parse("1.2.3.4"));
657 1 : CATCH_REQUIRE_FALSE(p.has_errors());
658 1 : CATCH_REQUIRE(ips.size() == 1);
659 1 : addr::addr_range const & r(ips[0]);
660 1 : CATCH_REQUIRE(r.has_from());
661 1 : CATCH_REQUIRE_FALSE(r.has_to());
662 1 : CATCH_REQUIRE_FALSE(r.is_range());
663 1 : CATCH_REQUIRE_FALSE(r.is_empty());
664 1 : addr::addr f(r.get_from());
665 1 : CATCH_REQUIRE(f.is_ipv4());
666 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
667 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
668 1 : CATCH_REQUIRE(f.get_port() == 0);
669 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
670 1 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
671 1 : uint8_t mask[16] = {};
672 1 : f.get_mask(mask);
673 17 : for(int idx(0); idx < 16; ++idx)
674 : {
675 16 : CATCH_REQUIRE(mask[idx] == 255);
676 : }
677 : }
678 :
679 14 : CATCH_SECTION("verify default address")
680 : {
681 2 : addr::addr_parser p;
682 :
683 1 : p.set_default_address("1.5.19.200");
684 1 : CATCH_REQUIRE(p.get_default_address4() == "1.5.19.200");
685 1 : CATCH_REQUIRE(p.get_default_address6() == "");
686 1 : p.set_default_address("");
687 1 : CATCH_REQUIRE(p.get_default_address4() == "");
688 1 : CATCH_REQUIRE(p.get_default_address6() == "");
689 :
690 1 : p.set_default_address("1.5.19.200");
691 1 : CATCH_REQUIRE(p.get_default_address4() == "1.5.19.200");
692 1 : CATCH_REQUIRE(p.get_default_address6() == "");
693 1 : p.set_default_address("[4:5:4:5:7:8:7:8]");
694 1 : CATCH_REQUIRE(p.get_default_address4() == "1.5.19.200");
695 1 : CATCH_REQUIRE(p.get_default_address6() == "4:5:4:5:7:8:7:8");
696 1 : p.set_default_address("");
697 1 : CATCH_REQUIRE(p.get_default_address4() == "");
698 1 : CATCH_REQUIRE(p.get_default_address6() == "");
699 : }
700 :
701 14 : CATCH_SECTION("verify default mask")
702 : {
703 2 : addr::addr_parser p;
704 :
705 1 : p.set_default_mask("1.5.19.200");
706 1 : CATCH_REQUIRE(p.get_default_mask4() == "1.5.19.200");
707 1 : CATCH_REQUIRE(p.get_default_mask6() == "");
708 1 : p.set_default_mask("");
709 1 : CATCH_REQUIRE(p.get_default_mask4() == "");
710 1 : CATCH_REQUIRE(p.get_default_mask6() == "");
711 :
712 1 : p.set_default_mask("1.5.19.200");
713 1 : CATCH_REQUIRE(p.get_default_mask4() == "1.5.19.200");
714 1 : CATCH_REQUIRE(p.get_default_mask6() == "");
715 1 : p.set_default_mask("[4:5:4:5:7:8:7:8]");
716 1 : CATCH_REQUIRE(p.get_default_mask4() == "1.5.19.200");
717 1 : CATCH_REQUIRE(p.get_default_mask6() == "4:5:4:5:7:8:7:8");
718 1 : p.set_default_mask("");
719 1 : CATCH_REQUIRE(p.get_default_mask4() == "");
720 1 : CATCH_REQUIRE(p.get_default_mask6() == "");
721 : }
722 :
723 14 : CATCH_SECTION("verify default allow flags")
724 : {
725 2 : addr::addr_parser p;
726 :
727 13 : for(int idx(0); idx < static_cast<int>(addr::addr_parser::flag_t::FLAG_max); ++idx)
728 : {
729 12 : switch(static_cast<addr::addr_parser::flag_t>(idx))
730 : {
731 3 : case addr::addr_parser::flag_t::ADDRESS:
732 : case addr::addr_parser::flag_t::ADDRESS_LOOKUP:
733 : case addr::addr_parser::flag_t::PORT:
734 : // only these are true by default
735 : //
736 3 : CATCH_REQUIRE(p.get_allow(static_cast<addr::addr_parser::flag_t>(idx)));
737 3 : break;
738 :
739 9 : default:
740 9 : CATCH_REQUIRE_FALSE(p.get_allow(static_cast<addr::addr_parser::flag_t>(idx)));
741 9 : break;
742 :
743 : }
744 : }
745 : }
746 :
747 14 : CATCH_SECTION("verify contradictory flags")
748 : {
749 2 : addr::addr_parser p;
750 :
751 : // by default these are set to false
752 : //
753 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS));
754 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_SPACES));
755 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_PORTS_COMMAS));
756 :
757 : // check setting MULTI_ADDRESSES_COMMAS to true
758 : //
759 1 : p.set_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS, true);
760 1 : CATCH_REQUIRE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS));
761 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_SPACES));
762 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_PORTS_COMMAS));
763 :
764 : // add MULTI_ADDRESSES_SPACES
765 : //
766 1 : p.set_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_SPACES, true);
767 1 : CATCH_REQUIRE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS));
768 1 : CATCH_REQUIRE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_SPACES));
769 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_PORTS_COMMAS));
770 :
771 : // add MULTI_PORTS_COMMAS
772 : //
773 1 : p.set_allow(addr::addr_parser::flag_t::MULTI_PORTS_COMMAS, true);
774 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS));
775 1 : CATCH_REQUIRE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_SPACES));
776 1 : CATCH_REQUIRE(p.get_allow(addr::addr_parser::flag_t::MULTI_PORTS_COMMAS));
777 :
778 : // add MULTI_ADDRESSES_COMMAS again
779 : //
780 1 : p.set_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS, true);
781 1 : CATCH_REQUIRE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS));
782 1 : CATCH_REQUIRE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_SPACES));
783 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_PORTS_COMMAS));
784 :
785 : // remove MULTI_ADDRESSES_SPACES
786 : //
787 1 : p.set_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_SPACES, false);
788 1 : CATCH_REQUIRE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS));
789 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_SPACES));
790 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_PORTS_COMMAS));
791 :
792 : // back to MULTI_PORTS_COMMAS
793 : //
794 1 : p.set_allow(addr::addr_parser::flag_t::MULTI_PORTS_COMMAS, true);
795 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS));
796 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_SPACES));
797 1 : CATCH_REQUIRE(p.get_allow(addr::addr_parser::flag_t::MULTI_PORTS_COMMAS));
798 :
799 : // add MULTI_ADDRESSES_COMMAS first now
800 : //
801 1 : p.set_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS, true);
802 1 : CATCH_REQUIRE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS));
803 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_SPACES));
804 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_PORTS_COMMAS));
805 : }
806 :
807 14 : CATCH_SECTION("default address")
808 : {
809 2 : addr::addr_parser p;
810 1 : p.set_protocol(IPPROTO_TCP);
811 1 : p.set_default_address("5.5.5.5");
812 1 : CATCH_REQUIRE(p.get_default_address4() == "5.5.5.5");
813 1 : CATCH_REQUIRE(p.get_default_address6() == "");
814 2 : addr::addr_range::vector_t ips(p.parse(""));
815 1 : CATCH_REQUIRE_FALSE(p.has_errors());
816 1 : CATCH_REQUIRE(ips.size() == 1);
817 1 : addr::addr_range const & r(ips[0]);
818 1 : CATCH_REQUIRE(r.has_from());
819 1 : CATCH_REQUIRE_FALSE(r.has_to());
820 1 : CATCH_REQUIRE_FALSE(r.is_range());
821 1 : CATCH_REQUIRE_FALSE(r.is_empty());
822 1 : addr::addr f(r.get_from());
823 1 : CATCH_REQUIRE(f.is_ipv4());
824 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "5.5.5.5");
825 1 : CATCH_REQUIRE(f.get_port() == 0);
826 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
827 1 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
828 : }
829 :
830 14 : CATCH_SECTION("address, no port allowed")
831 : {
832 : // specific address with a default
833 : {
834 2 : addr::addr_parser p;
835 1 : p.set_allow(addr::addr_parser::flag_t::PORT, false);
836 1 : p.set_protocol(IPPROTO_TCP);
837 1 : p.set_default_address("5.5.5.5");
838 1 : CATCH_REQUIRE(p.get_default_address4() == "5.5.5.5");
839 1 : CATCH_REQUIRE(p.get_default_address6() == "");
840 2 : addr::addr_range::vector_t ips(p.parse("9.9.9.9"));
841 1 : CATCH_REQUIRE_FALSE(p.has_errors());
842 1 : CATCH_REQUIRE(ips.size() == 1);
843 1 : addr::addr_range const & r(ips[0]);
844 1 : CATCH_REQUIRE(r.has_from());
845 1 : CATCH_REQUIRE_FALSE(r.has_to());
846 1 : CATCH_REQUIRE_FALSE(r.is_range());
847 1 : CATCH_REQUIRE_FALSE(r.is_empty());
848 1 : addr::addr f(r.get_from());
849 1 : CATCH_REQUIRE(f.is_ipv4());
850 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "9.9.9.9");
851 1 : CATCH_REQUIRE(f.get_port() == 0);
852 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
853 1 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
854 : }
855 :
856 : // only a default address
857 : {
858 2 : addr::addr_parser p;
859 1 : p.set_allow(addr::addr_parser::flag_t::PORT, false);
860 1 : p.set_protocol(IPPROTO_TCP);
861 1 : p.set_default_address("5.5.5.5");
862 1 : CATCH_REQUIRE(p.get_default_address4() == "5.5.5.5");
863 1 : CATCH_REQUIRE(p.get_default_address6() == "");
864 2 : addr::addr_range::vector_t ips(p.parse(""));
865 1 : CATCH_REQUIRE_FALSE(p.has_errors());
866 1 : CATCH_REQUIRE(ips.size() == 1);
867 1 : addr::addr_range const & r(ips[0]);
868 1 : CATCH_REQUIRE(r.has_from());
869 1 : CATCH_REQUIRE_FALSE(r.has_to());
870 1 : CATCH_REQUIRE_FALSE(r.is_range());
871 1 : CATCH_REQUIRE_FALSE(r.is_empty());
872 1 : addr::addr f(r.get_from());
873 1 : CATCH_REQUIRE(f.is_ipv4());
874 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "5.5.5.5");
875 1 : CATCH_REQUIRE(f.get_port() == 0);
876 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
877 1 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
878 : }
879 : }
880 : }
881 :
882 32 : CATCH_GIVEN("addr_parser() with multiple IPv4 addresses in one string")
883 : {
884 6 : CATCH_SECTION("3 IPs separated by commas")
885 : {
886 2 : addr::addr_parser p;
887 1 : p.set_protocol(IPPROTO_TCP);
888 1 : p.set_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS, true);
889 2 : addr::addr_range::vector_t ips(p.parse("1.2.3.4:55,5.6.7.8,,,,10.11.12.99:77"));
890 1 : CATCH_REQUIRE_FALSE(p.has_errors());
891 1 : CATCH_REQUIRE(ips.size() == 3);
892 :
893 1 : uint8_t mask[16] = {};
894 :
895 : // 1.2.3.4:55
896 : {
897 1 : addr::addr_range const & r(ips[0]);
898 1 : CATCH_REQUIRE(r.has_from());
899 1 : CATCH_REQUIRE_FALSE(r.has_to());
900 1 : CATCH_REQUIRE_FALSE(r.is_range());
901 1 : CATCH_REQUIRE_FALSE(r.is_empty());
902 1 : addr::addr f(r.get_from());
903 1 : CATCH_REQUIRE(f.is_ipv4());
904 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
905 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
906 1 : CATCH_REQUIRE(f.get_port() == 55);
907 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
908 1 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
909 1 : f.get_mask(mask);
910 17 : for(int idx(0); idx < 16; ++idx)
911 : {
912 16 : CATCH_REQUIRE(mask[idx] == 255);
913 : }
914 : }
915 :
916 : // 5.6.7.8
917 : {
918 1 : addr::addr_range const & r(ips[1]);
919 1 : CATCH_REQUIRE(r.has_from());
920 1 : CATCH_REQUIRE_FALSE(r.has_to());
921 1 : CATCH_REQUIRE_FALSE(r.is_range());
922 1 : CATCH_REQUIRE_FALSE(r.is_empty());
923 1 : addr::addr f(r.get_from());
924 1 : CATCH_REQUIRE(f.is_ipv4());
925 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "5.6.7.8");
926 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "5.6.7.8");
927 1 : CATCH_REQUIRE(f.get_port() == 0);
928 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
929 1 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
930 1 : f.get_mask(mask);
931 17 : for(int idx(0); idx < 16; ++idx)
932 : {
933 16 : CATCH_REQUIRE(mask[idx] == 255);
934 : }
935 : }
936 :
937 : // 10.11.12.99:77
938 : {
939 1 : addr::addr_range const & r(ips[2]);
940 1 : CATCH_REQUIRE(r.has_from());
941 1 : CATCH_REQUIRE_FALSE(r.has_to());
942 1 : CATCH_REQUIRE_FALSE(r.is_range());
943 1 : CATCH_REQUIRE_FALSE(r.is_empty());
944 1 : addr::addr f(r.get_from());
945 1 : CATCH_REQUIRE(f.is_ipv4());
946 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "10.11.12.99");
947 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "10.11.12.99");
948 1 : CATCH_REQUIRE(f.get_port() == 77);
949 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
950 1 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
951 1 : f.get_mask(mask);
952 17 : for(int idx(0); idx < 16; ++idx)
953 : {
954 16 : CATCH_REQUIRE(mask[idx] == 255);
955 : }
956 : }
957 : }
958 :
959 6 : CATCH_SECTION("3 IPs separated by spaces")
960 : {
961 2 : addr::addr_parser p;
962 1 : p.set_protocol(IPPROTO_TCP);
963 1 : p.set_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_SPACES, true);
964 2 : addr::addr_range::vector_t ips(p.parse("1.2.3.4:55 5.6.7.8 10.11.12.99:77"));
965 1 : CATCH_REQUIRE_FALSE(p.has_errors());
966 1 : CATCH_REQUIRE(ips.size() == 3);
967 :
968 1 : uint8_t mask[16] = {};
969 :
970 : // 1.2.3.4:55
971 : {
972 1 : addr::addr_range const & r(ips[0]);
973 1 : CATCH_REQUIRE(r.has_from());
974 1 : CATCH_REQUIRE_FALSE(r.has_to());
975 1 : CATCH_REQUIRE_FALSE(r.is_range());
976 1 : CATCH_REQUIRE_FALSE(r.is_empty());
977 1 : addr::addr f(r.get_from());
978 1 : CATCH_REQUIRE(f.is_ipv4());
979 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
980 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
981 1 : CATCH_REQUIRE(f.get_port() == 55);
982 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
983 1 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
984 1 : f.get_mask(mask);
985 17 : for(int idx(0); idx < 16; ++idx)
986 : {
987 16 : CATCH_REQUIRE(mask[idx] == 255);
988 : }
989 : }
990 :
991 : // 5.6.7.8
992 : {
993 1 : addr::addr_range const & r(ips[1]);
994 1 : CATCH_REQUIRE(r.has_from());
995 1 : CATCH_REQUIRE_FALSE(r.has_to());
996 1 : CATCH_REQUIRE_FALSE(r.is_range());
997 1 : CATCH_REQUIRE_FALSE(r.is_empty());
998 1 : addr::addr f(r.get_from());
999 1 : CATCH_REQUIRE(f.is_ipv4());
1000 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "5.6.7.8");
1001 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "5.6.7.8");
1002 1 : CATCH_REQUIRE(f.get_port() == 0);
1003 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1004 1 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
1005 1 : f.get_mask(mask);
1006 17 : for(int idx(0); idx < 16; ++idx)
1007 : {
1008 16 : CATCH_REQUIRE(mask[idx] == 255);
1009 : }
1010 : }
1011 :
1012 : // 10.11.12.99:77
1013 : {
1014 1 : addr::addr_range const & r(ips[2]);
1015 1 : CATCH_REQUIRE(r.has_from());
1016 1 : CATCH_REQUIRE_FALSE(r.has_to());
1017 1 : CATCH_REQUIRE_FALSE(r.is_range());
1018 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1019 1 : addr::addr f(r.get_from());
1020 1 : CATCH_REQUIRE(f.is_ipv4());
1021 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "10.11.12.99");
1022 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "10.11.12.99");
1023 1 : CATCH_REQUIRE(f.get_port() == 77);
1024 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1025 1 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1026 1 : f.get_mask(mask);
1027 17 : for(int idx(0); idx < 16; ++idx)
1028 : {
1029 16 : CATCH_REQUIRE(mask[idx] == 255);
1030 : }
1031 : }
1032 : }
1033 :
1034 6 : CATCH_SECTION("3 IPs separated by commas and/or spaces")
1035 : {
1036 2 : addr::addr_parser p;
1037 1 : p.set_protocol(IPPROTO_TCP);
1038 1 : p.set_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS, true);
1039 1 : p.set_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_SPACES, true);
1040 2 : addr::addr_range::vector_t ips(p.parse(" 1.2.3.4:55,, 5.6.7.8 , 10.11.12.99:77 "));
1041 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1042 1 : CATCH_REQUIRE(ips.size() == 3);
1043 :
1044 1 : uint8_t mask[16] = {};
1045 :
1046 : // 1.2.3.4:55
1047 : {
1048 1 : addr::addr_range const & r(ips[0]);
1049 1 : CATCH_REQUIRE(r.has_from());
1050 1 : CATCH_REQUIRE_FALSE(r.has_to());
1051 1 : CATCH_REQUIRE_FALSE(r.is_range());
1052 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1053 1 : addr::addr f(r.get_from());
1054 1 : CATCH_REQUIRE(f.is_ipv4());
1055 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
1056 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
1057 1 : CATCH_REQUIRE(f.get_port() == 55);
1058 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1059 1 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
1060 1 : f.get_mask(mask);
1061 17 : for(int idx(0); idx < 16; ++idx)
1062 : {
1063 16 : CATCH_REQUIRE(mask[idx] == 255);
1064 : }
1065 : }
1066 :
1067 : // 5.6.7.8
1068 : {
1069 1 : addr::addr_range const & r(ips[1]);
1070 1 : CATCH_REQUIRE(r.has_from());
1071 1 : CATCH_REQUIRE_FALSE(r.has_to());
1072 1 : CATCH_REQUIRE_FALSE(r.is_range());
1073 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1074 1 : addr::addr f(r.get_from());
1075 1 : CATCH_REQUIRE(f.is_ipv4());
1076 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "5.6.7.8");
1077 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "5.6.7.8");
1078 1 : CATCH_REQUIRE(f.get_port() == 0);
1079 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1080 1 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
1081 1 : f.get_mask(mask);
1082 17 : for(int idx(0); idx < 16; ++idx)
1083 : {
1084 16 : CATCH_REQUIRE(mask[idx] == 255);
1085 : }
1086 : }
1087 :
1088 : // 10.11.12.99:77
1089 : {
1090 1 : addr::addr_range const & r(ips[2]);
1091 1 : CATCH_REQUIRE(r.has_from());
1092 1 : CATCH_REQUIRE_FALSE(r.has_to());
1093 1 : CATCH_REQUIRE_FALSE(r.is_range());
1094 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1095 1 : addr::addr f(r.get_from());
1096 1 : CATCH_REQUIRE(f.is_ipv4());
1097 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "10.11.12.99");
1098 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "10.11.12.99");
1099 1 : CATCH_REQUIRE(f.get_port() == 77);
1100 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1101 1 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1102 1 : f.get_mask(mask);
1103 17 : for(int idx(0); idx < 16; ++idx)
1104 : {
1105 16 : CATCH_REQUIRE(mask[idx] == 255);
1106 : }
1107 : }
1108 : }
1109 : }
1110 :
1111 32 : CATCH_GIVEN("addr_parser() with numeric only IPv4 addresses")
1112 : {
1113 6 : CATCH_SECTION("Simple numeric IPv4")
1114 : {
1115 2 : addr::addr_parser p;
1116 1 : p.set_protocol(IPPROTO_TCP);
1117 1 : p.set_allow(addr::addr_parser::flag_t::ADDRESS_LOOKUP, false);
1118 2 : addr::addr_range::vector_t ips(p.parse("4.3.1.2:3003"));
1119 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1120 1 : CATCH_REQUIRE(ips.size() == 1);
1121 :
1122 1 : addr::addr_range const & r(ips[0]);
1123 1 : CATCH_REQUIRE(r.has_from());
1124 1 : CATCH_REQUIRE_FALSE(r.has_to());
1125 1 : CATCH_REQUIRE_FALSE(r.is_range());
1126 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1127 1 : addr::addr f(r.get_from());
1128 1 : CATCH_REQUIRE(f.is_ipv4());
1129 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "4.3.1.2");
1130 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "4.3.1.2");
1131 1 : CATCH_REQUIRE(f.get_port() == 3003);
1132 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1133 1 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
1134 1 : uint8_t mask[16] = {};
1135 1 : f.get_mask(mask);
1136 17 : for(int idx(0); idx < 16; ++idx)
1137 : {
1138 16 : CATCH_REQUIRE(mask[idx] == 255);
1139 : }
1140 : }
1141 :
1142 6 : CATCH_SECTION("Invalid domain name address when we only accept numeric IPs")
1143 : {
1144 2 : addr::addr_parser p;
1145 1 : p.set_protocol(IPPROTO_TCP);
1146 1 : p.set_allow(addr::addr_parser::flag_t::ADDRESS_LOOKUP, false);
1147 2 : addr::addr_range::vector_t ips(p.parse("www.example.com:4471"));
1148 1 : CATCH_REQUIRE(p.has_errors());
1149 1 : CATCH_REQUIRE(p.error_count() == 1);
1150 1 : CATCH_REQUIRE(p.error_messages() == "Unknown address in \"www.example.com\" (no DNS lookup was allowed).\n");
1151 1 : CATCH_REQUIRE(ips.size() == 0);
1152 : }
1153 :
1154 6 : CATCH_SECTION("Invalid port: service name not allowed")
1155 : {
1156 2 : addr::addr_parser p;
1157 1 : p.set_protocol(IPPROTO_TCP);
1158 1 : p.set_allow(addr::addr_parser::flag_t::ADDRESS_LOOKUP, false);
1159 2 : addr::addr_range::vector_t ips(p.parse("192.168.255.32:https"));
1160 1 : CATCH_REQUIRE(p.has_errors());
1161 1 : CATCH_REQUIRE(p.error_count() == 1);
1162 1 : CATCH_REQUIRE(p.error_messages() == "Invalid port in \"https\" (no service name lookup allowed).\n");
1163 1 : CATCH_REQUIRE(ips.size() == 0);
1164 : }
1165 : }
1166 16 : }
1167 :
1168 :
1169 5 : CATCH_TEST_CASE( "ipv4::ports", "[ipv4]" )
1170 : {
1171 6 : CATCH_GIVEN("addr_parser() with IPv4 addresses and port")
1172 : {
1173 6 : CATCH_SECTION("verify port")
1174 : {
1175 65537 : for(int port(0); port < 65536; ++port)
1176 : {
1177 65536 : int proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1178 131072 : addr::addr_parser p;
1179 65536 : p.set_protocol(proto);
1180 131072 : addr::addr_range::vector_t ips(p.parse("192.168.12.199:" + std::to_string(port)));
1181 65536 : CATCH_REQUIRE_FALSE(p.has_errors());
1182 65536 : CATCH_REQUIRE(ips.size() == 1);
1183 65536 : addr::addr_range const & r(ips[0]);
1184 65536 : addr::addr f(r.get_from());
1185 65536 : CATCH_REQUIRE(f.is_ipv4());
1186 65536 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "192.168.12.199");
1187 65536 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "192.168.12.199");
1188 65536 : CATCH_REQUIRE(f.get_port() == port);
1189 65536 : CATCH_REQUIRE(f.get_protocol() == proto);
1190 65536 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1191 : }
1192 : }
1193 :
1194 6 : CATCH_SECTION("default address with various port")
1195 : {
1196 101 : for(int idx(0); idx < 100; ++idx)
1197 : {
1198 100 : uint16_t const port(rand());
1199 200 : addr::addr_parser p;
1200 100 : p.set_protocol(IPPROTO_TCP);
1201 100 : p.set_default_address("5.5.5.5");
1202 100 : CATCH_REQUIRE(p.get_default_address4() == "5.5.5.5");
1203 100 : CATCH_REQUIRE(p.get_default_address6() == "");
1204 200 : addr::addr_range::vector_t ips(p.parse(":" + std::to_string(static_cast<int>(port))));
1205 100 : CATCH_REQUIRE_FALSE(p.has_errors());
1206 100 : CATCH_REQUIRE(ips.size() == 1);
1207 100 : addr::addr_range const & r(ips[0]);
1208 100 : CATCH_REQUIRE(r.has_from());
1209 100 : CATCH_REQUIRE_FALSE(r.has_to());
1210 100 : CATCH_REQUIRE_FALSE(r.is_range());
1211 100 : CATCH_REQUIRE_FALSE(r.is_empty());
1212 100 : addr::addr f(r.get_from());
1213 100 : CATCH_REQUIRE(f.is_ipv4());
1214 100 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
1215 100 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
1216 100 : CATCH_REQUIRE(f.get_port() == port);
1217 100 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1218 100 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
1219 : }
1220 : }
1221 :
1222 6 : CATCH_SECTION("address with default port")
1223 : {
1224 26 : for(int idx(0); idx < 25; ++idx)
1225 : {
1226 25 : uint16_t const port(rand());
1227 50 : addr::addr_parser p;
1228 25 : p.set_protocol(IPPROTO_TCP);
1229 25 : p.set_default_port(port);
1230 25 : CATCH_REQUIRE(p.get_default_port() == port);
1231 50 : addr::addr_range::vector_t ips(p.parse("5.5.5.5"));
1232 25 : CATCH_REQUIRE_FALSE(p.has_errors());
1233 25 : CATCH_REQUIRE(ips.size() == 1);
1234 25 : addr::addr_range const & r(ips[0]);
1235 25 : CATCH_REQUIRE(r.has_from());
1236 25 : CATCH_REQUIRE_FALSE(r.has_to());
1237 25 : CATCH_REQUIRE_FALSE(r.is_range());
1238 25 : CATCH_REQUIRE_FALSE(r.is_empty());
1239 25 : addr::addr f(r.get_from());
1240 25 : CATCH_REQUIRE(f.is_ipv4());
1241 25 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
1242 25 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
1243 25 : CATCH_REQUIRE(f.get_port() == port);
1244 25 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1245 25 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
1246 : }
1247 :
1248 26 : for(int idx(0); idx < 25; ++idx)
1249 : {
1250 25 : uint16_t const port(rand());
1251 50 : addr::addr_parser p;
1252 25 : p.set_protocol(IPPROTO_TCP);
1253 25 : p.set_default_port(port);
1254 25 : CATCH_REQUIRE(p.get_default_port() == port);
1255 50 : addr::addr_range::vector_t ips(p.parse("5.5.5.5:"));
1256 25 : CATCH_REQUIRE_FALSE(p.has_errors());
1257 25 : CATCH_REQUIRE(ips.size() == 1);
1258 25 : addr::addr_range const & r(ips[0]);
1259 25 : CATCH_REQUIRE(r.has_from());
1260 25 : CATCH_REQUIRE_FALSE(r.has_to());
1261 25 : CATCH_REQUIRE_FALSE(r.is_range());
1262 25 : CATCH_REQUIRE_FALSE(r.is_empty());
1263 25 : addr::addr f(r.get_from());
1264 25 : CATCH_REQUIRE(f.is_ipv4());
1265 25 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
1266 25 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
1267 25 : CATCH_REQUIRE(f.get_port() == port);
1268 25 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1269 25 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
1270 : }
1271 : }
1272 : }
1273 3 : }
1274 :
1275 :
1276 9 : CATCH_TEST_CASE( "ipv4::masks", "[ipv4]" )
1277 : {
1278 14 : CATCH_GIVEN("addr_parser() of address:port/mask")
1279 : {
1280 14 : CATCH_SECTION("mask allowed, but no mask")
1281 : {
1282 1 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1283 1 : int const port(rand() & 0xFFFF);
1284 2 : addr::addr_parser p;
1285 1 : p.set_protocol(proto);
1286 1 : p.set_allow(addr::addr_parser::flag_t::MASK, true);
1287 2 : addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port)));
1288 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1289 1 : CATCH_REQUIRE(ips.size() == 1);
1290 1 : addr::addr_range const & r(ips[0]);
1291 1 : addr::addr f(r.get_from());
1292 1 : CATCH_REQUIRE(f.is_ipv4());
1293 2 : std::string result("172.19.6.91:" + std::to_string(port) + "/255.255.255.255");
1294 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1295 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1296 1 : CATCH_REQUIRE(f.get_port() == port);
1297 1 : CATCH_REQUIRE(f.get_protocol() == proto);
1298 1 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1299 : }
1300 :
1301 14 : CATCH_SECTION("empty mask")
1302 : {
1303 1 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1304 1 : int const port(rand() & 0xFFFF);
1305 2 : addr::addr_parser p;
1306 1 : p.set_protocol(proto);
1307 1 : p.set_allow(addr::addr_parser::flag_t::MASK, true);
1308 2 : addr::addr_range::vector_t ips(p.parse("172.18.5.91:" + std::to_string(port) + "/"));
1309 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1310 1 : CATCH_REQUIRE(ips.size() == 1);
1311 1 : addr::addr_range const & r(ips[0]);
1312 1 : addr::addr f(r.get_from());
1313 1 : CATCH_REQUIRE(f.is_ipv4());
1314 2 : std::string result("172.18.5.91:" + std::to_string(port) + "/255.255.255.255");
1315 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1316 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1317 1 : CATCH_REQUIRE(f.get_port() == port);
1318 1 : CATCH_REQUIRE(f.get_protocol() == proto);
1319 1 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1320 : }
1321 :
1322 14 : CATCH_SECTION("one number masks")
1323 : {
1324 34 : for(int idx(0); idx <= 32; ++idx)
1325 : {
1326 33 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1327 33 : int const port(rand() & 0xFFFF);
1328 66 : addr::addr_parser p;
1329 33 : p.set_protocol(proto);
1330 33 : p.set_allow(addr::addr_parser::flag_t::MASK, true);
1331 66 : addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port) + "/" + std::to_string(idx)));
1332 33 : CATCH_REQUIRE_FALSE(p.has_errors());
1333 33 : CATCH_REQUIRE(ips.size() == 1);
1334 33 : addr::addr_range const & r(ips[0]);
1335 33 : addr::addr f(r.get_from());
1336 33 : CATCH_REQUIRE(f.is_ipv4());
1337 33 : uint64_t const mask(std::numeric_limits<uint64_t>::max() << (32 - idx));
1338 33 : std::string mask_str(
1339 66 : std::to_string((mask >> 24) & 255)
1340 99 : + "."
1341 132 : + std::to_string((mask >> 16) & 255)
1342 99 : + "."
1343 132 : + std::to_string((mask >> 8) & 255)
1344 99 : + "."
1345 132 : + std::to_string((mask >> 0) & 255));
1346 66 : std::string result("172.17.3.91:" + std::to_string(port) + "/" + mask_str);
1347 33 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1348 33 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1349 33 : CATCH_REQUIRE(f.get_port() == port);
1350 33 : CATCH_REQUIRE(f.get_protocol() == proto);
1351 33 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1352 : }
1353 : }
1354 :
1355 14 : CATCH_SECTION("address like mask")
1356 : {
1357 26 : for(int idx(0); idx < 25; ++idx)
1358 : {
1359 25 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1360 25 : int const port(rand() & 0xFFFF);
1361 50 : addr::addr_parser p;
1362 25 : p.set_protocol(proto);
1363 25 : p.set_allow(addr::addr_parser::flag_t::MASK, true);
1364 : // when specified as an IP, the mask can be absolutely anything
1365 25 : uint8_t mask[4];
1366 125 : for(int j(0); j < 4; ++j)
1367 : {
1368 100 : mask[j] = rand();
1369 : }
1370 25 : std::string const mask_str(
1371 50 : std::to_string(static_cast<int>(mask[0]))
1372 75 : + "."
1373 100 : + std::to_string(static_cast<int>(mask[1]))
1374 75 : + "."
1375 100 : + std::to_string(static_cast<int>(mask[2]))
1376 75 : + "."
1377 100 : + std::to_string(static_cast<int>(mask[3])));
1378 50 : addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port) + "/" + mask_str));
1379 25 : CATCH_REQUIRE_FALSE(p.has_errors());
1380 25 : CATCH_REQUIRE(ips.size() == 1);
1381 25 : addr::addr_range const & r(ips[0]);
1382 25 : addr::addr f(r.get_from());
1383 25 : CATCH_REQUIRE(f.is_ipv4());
1384 50 : std::string result("172.17.3.91:" + std::to_string(port) + "/" + mask_str);
1385 25 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1386 25 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1387 25 : CATCH_REQUIRE(f.get_port() == port);
1388 25 : CATCH_REQUIRE(f.get_protocol() == proto);
1389 25 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1390 : }
1391 : }
1392 :
1393 14 : CATCH_SECTION("address like default mask")
1394 : {
1395 26 : for(int idx(0); idx < 25; ++idx)
1396 : {
1397 25 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1398 25 : int const port(rand() & 0xFFFF);
1399 50 : addr::addr_parser p;
1400 25 : p.set_protocol(proto);
1401 25 : p.set_allow(addr::addr_parser::flag_t::MASK, true);
1402 : // when specified as an IP, the mask can be absolutely anything
1403 : // (here the mask is a string an it will be parsed by the
1404 : // parser if required)
1405 : //
1406 25 : uint8_t mask[4];
1407 125 : for(int j(0); j < 4; ++j)
1408 : {
1409 100 : mask[j] = rand();
1410 : }
1411 25 : std::string const mask_str(
1412 50 : std::to_string(static_cast<int>(mask[0]))
1413 75 : + "."
1414 100 : + std::to_string(static_cast<int>(mask[1]))
1415 75 : + "."
1416 100 : + std::to_string(static_cast<int>(mask[2]))
1417 75 : + "."
1418 100 : + std::to_string(static_cast<int>(mask[3])));
1419 25 : p.set_default_mask(mask_str);
1420 50 : addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port)));
1421 25 : CATCH_REQUIRE_FALSE(p.has_errors());
1422 25 : CATCH_REQUIRE(ips.size() == 1);
1423 25 : addr::addr_range const & r(ips[0]);
1424 25 : addr::addr f(r.get_from());
1425 25 : CATCH_REQUIRE(f.is_ipv4());
1426 50 : std::string result("172.17.3.91:" + std::to_string(port) + "/" + mask_str);
1427 25 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1428 25 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1429 25 : CATCH_REQUIRE(f.get_port() == port);
1430 25 : CATCH_REQUIRE(f.get_protocol() == proto);
1431 25 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1432 25 : uint8_t verify_mask[16];
1433 25 : f.get_mask(verify_mask);
1434 325 : for(int j(0); j < 16 - 4; ++j)
1435 : {
1436 300 : CATCH_REQUIRE(verify_mask[j] == 255);
1437 : }
1438 125 : for(int j(12); j < 16; ++j)
1439 : {
1440 100 : CATCH_REQUIRE(verify_mask[j] == mask[j - 12]);
1441 : }
1442 : }
1443 : }
1444 :
1445 14 : CATCH_SECTION("address like mask with a default")
1446 : {
1447 26 : for(int idx(0); idx < 25; ++idx)
1448 : {
1449 25 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1450 25 : int const port(rand() & 0xFFFF);
1451 50 : addr::addr_parser p;
1452 25 : p.set_protocol(proto);
1453 25 : p.set_allow(addr::addr_parser::flag_t::MASK, true);
1454 :
1455 : // here we want a default and an IP with a specific mask
1456 : // to make sure that the specific mask has priority
1457 : //
1458 25 : uint8_t mask[4];
1459 125 : for(int j(0); j < 4; ++j)
1460 : {
1461 100 : mask[j] = rand();
1462 : }
1463 25 : std::string const mask_str(
1464 50 : std::to_string(static_cast<int>(mask[0]))
1465 75 : + "."
1466 100 : + std::to_string(static_cast<int>(mask[1]))
1467 75 : + "."
1468 100 : + std::to_string(static_cast<int>(mask[2]))
1469 75 : + "."
1470 100 : + std::to_string(static_cast<int>(mask[3])));
1471 :
1472 25 : uint8_t default_mask[4];
1473 125 : for(int j(0); j < 4; ++j)
1474 : {
1475 100 : default_mask[j] = rand();
1476 : }
1477 25 : std::string const default_mask_str(
1478 50 : std::to_string(static_cast<int>(default_mask[0]))
1479 75 : + "."
1480 100 : + std::to_string(static_cast<int>(default_mask[1]))
1481 75 : + "."
1482 100 : + std::to_string(static_cast<int>(default_mask[2]))
1483 75 : + "."
1484 100 : + std::to_string(static_cast<int>(default_mask[3])));
1485 25 : p.set_default_mask(default_mask_str);
1486 :
1487 50 : addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port) + "/" + mask_str));
1488 25 : CATCH_REQUIRE_FALSE(p.has_errors());
1489 25 : CATCH_REQUIRE(ips.size() == 1);
1490 25 : addr::addr_range const & r(ips[0]);
1491 25 : addr::addr f(r.get_from());
1492 25 : CATCH_REQUIRE(f.is_ipv4());
1493 50 : std::string result("172.17.3.91:" + std::to_string(port) + "/" + mask_str);
1494 25 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1495 25 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1496 25 : CATCH_REQUIRE(f.get_port() == port);
1497 25 : CATCH_REQUIRE(f.get_protocol() == proto);
1498 25 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1499 25 : uint8_t verify_mask[16];
1500 25 : f.get_mask(verify_mask);
1501 325 : for(int j(0); j < 16 - 4; ++j)
1502 : {
1503 300 : CATCH_REQUIRE(verify_mask[j] == 255);
1504 : }
1505 125 : for(int j(12); j < 16; ++j)
1506 : {
1507 100 : CATCH_REQUIRE(verify_mask[j] == mask[j - 12]);
1508 : }
1509 : }
1510 : }
1511 :
1512 14 : CATCH_SECTION("two addresses and a mask for a match / no match")
1513 : {
1514 1 : int const port1(rand() & 0xFFFF);
1515 2 : addr::addr_parser p;
1516 1 : p.set_allow(addr::addr_parser::flag_t::MASK, true);
1517 :
1518 : // parse the IP with a mask
1519 : //
1520 1 : int proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1521 1 : p.set_protocol(proto);
1522 2 : addr::addr_range::vector_t ips1(p.parse("192.168.0.0:" + std::to_string(port1) + "/16"));
1523 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1524 1 : CATCH_REQUIRE(ips1.size() == 1);
1525 1 : addr::addr_range const & r1(ips1[0]);
1526 1 : addr::addr f1(r1.get_from());
1527 1 : CATCH_REQUIRE(f1.is_ipv4());
1528 1 : CATCH_REQUIRE(f1.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ALL) == "192.168.0.0:" + std::to_string(port1) + "/255.255.0.0");
1529 1 : CATCH_REQUIRE(f1.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ALL) == "192.168.0.0:" + std::to_string(port1) + "/255.255.0.0");
1530 1 : CATCH_REQUIRE(f1.get_port() == port1);
1531 1 : CATCH_REQUIRE(f1.get_protocol() == proto);
1532 1 : CATCH_REQUIRE(f1.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1533 :
1534 : // reuse parser
1535 : //
1536 1 : proto = rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP;
1537 1 : p.set_protocol(proto);
1538 1 : int const port2(rand() & 0xFFFF);
1539 2 : addr::addr_range::vector_t ips2(p.parse("192.168.5.36:" + std::to_string(port2)));
1540 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1541 1 : CATCH_REQUIRE(ips2.size() == 1);
1542 1 : addr::addr_range const & r2(ips2[0]);
1543 1 : addr::addr f2(r2.get_from());
1544 1 : CATCH_REQUIRE(f2.is_ipv4());
1545 1 : CATCH_REQUIRE(f2.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ALL) == "192.168.5.36:" + std::to_string(port2) + "/255.255.255.255");
1546 1 : CATCH_REQUIRE(f2.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ALL) == "192.168.5.36:" + std::to_string(port2) + "/255.255.255.255");
1547 1 : CATCH_REQUIRE(f2.get_port() == port2);
1548 1 : CATCH_REQUIRE(f2.get_protocol() == proto);
1549 1 : CATCH_REQUIRE(f2.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1550 :
1551 : // 3rd with a mask along the full IP
1552 : //
1553 1 : proto = rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP;
1554 1 : p.set_protocol(proto);
1555 1 : int const port3(rand() & 0xFFFF);
1556 2 : addr::addr_range::vector_t ips3(p.parse("192.168.5.36:" + std::to_string(port3) + "/16"));
1557 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1558 1 : CATCH_REQUIRE(ips3.size() == 1);
1559 1 : addr::addr_range const & r3(ips3[0]);
1560 1 : addr::addr f3(r3.get_from());
1561 1 : CATCH_REQUIRE(f3.is_ipv4());
1562 1 : CATCH_REQUIRE(f3.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ALL) == "192.168.5.36:" + std::to_string(port3) + "/255.255.0.0");
1563 1 : CATCH_REQUIRE(f3.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ALL) == "192.168.5.36:" + std::to_string(port3) + "/255.255.0.0");
1564 1 : CATCH_REQUIRE(f3.get_port() == port3);
1565 1 : CATCH_REQUIRE(f3.get_protocol() == proto);
1566 1 : CATCH_REQUIRE(f3.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1567 :
1568 : // just a side test
1569 : //
1570 1 : CATCH_REQUIRE(f1 != f2);
1571 1 : CATCH_REQUIRE(f1 != f3);
1572 1 : CATCH_REQUIRE(f2 == f3);
1573 :
1574 : // check whether p1 matches p2 and vice versa
1575 : //
1576 1 : CATCH_REQUIRE(f1.match(f2)); // f2 & mask1 == f1
1577 1 : CATCH_REQUIRE(f1.match(f3)); // f3 & mask1 == f1
1578 :
1579 1 : CATCH_REQUIRE_FALSE(f2.match(f1)); // f1 & mask2 != f2
1580 1 : CATCH_REQUIRE(f2.match(f3)); // f3 & mask2 == f2 (because f2 == f3 anyway)
1581 :
1582 1 : CATCH_REQUIRE(f3.match(f1)); // f1 & mask3 == f3
1583 1 : CATCH_REQUIRE(f3.match(f2)); // f2 & mask3 == f3
1584 :
1585 1 : f3.apply_mask();
1586 :
1587 1 : CATCH_REQUIRE(f1 != f2);
1588 1 : CATCH_REQUIRE(f1 == f3);
1589 1 : CATCH_REQUIRE(f2 != f3);
1590 :
1591 : // re-run the match() calls with f3 since it changed...
1592 : //
1593 1 : CATCH_REQUIRE(f1.match(f3)); // f3 & mask1 == f1
1594 :
1595 1 : CATCH_REQUIRE_FALSE(f2.match(f3)); // f3 & mask2 == f2 (because f2 != f3 anymore)
1596 :
1597 1 : CATCH_REQUIRE(f3.match(f1)); // f1 & mask3 == f3
1598 1 : CATCH_REQUIRE(f3.match(f2)); // f2 & mask3 == f3
1599 : }
1600 : }
1601 7 : }
1602 :
1603 :
1604 8 : CATCH_TEST_CASE( "ipv4::protocol", "[ipv4]" )
1605 : {
1606 12 : CATCH_GIVEN("addr()")
1607 : {
1608 2 : addr::addr a;
1609 :
1610 4 : CATCH_SECTION("default protocol")
1611 : {
1612 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_TCP);
1613 : }
1614 :
1615 4 : CATCH_SECTION("set_protocol()")
1616 : {
1617 : // setup a random protocol
1618 : //
1619 1 : int const start_protocol([]()
1620 : {
1621 1 : switch(rand() % 3)
1622 : {
1623 1 : case 0:
1624 1 : return IPPROTO_IP;
1625 :
1626 0 : case 1:
1627 0 : return IPPROTO_TCP;
1628 :
1629 : //case 2:
1630 0 : default:
1631 0 : return IPPROTO_UDP;
1632 :
1633 : }
1634 1 : }());
1635 1 : a.set_protocol(start_protocol);
1636 :
1637 : // test 100 invalid protocols
1638 : //
1639 101 : for(int idx(0); idx < 100; ++idx)
1640 : {
1641 : int invalid_protocol;
1642 0 : do
1643 : {
1644 100 : invalid_protocol = rand();
1645 : }
1646 : while(invalid_protocol == IPPROTO_IP
1647 100 : || invalid_protocol == IPPROTO_TCP
1648 200 : || invalid_protocol == IPPROTO_UDP);
1649 100 : CATCH_REQUIRE_THROWS_AS(a.set_protocol(invalid_protocol), addr::addr_invalid_argument);
1650 :
1651 : // make sure the protocol does not change on errors
1652 100 : CATCH_REQUIRE(a.get_protocol() == start_protocol);
1653 : }
1654 :
1655 : // null string is not allowed
1656 : //
1657 1 : CATCH_REQUIRE_THROWS_AS(a.set_protocol(nullptr), addr::addr_invalid_argument);
1658 :
1659 : // other "invalid" (unsupported, really) string protocols
1660 : //
1661 1 : CATCH_REQUIRE_THROWS_AS(a.set_protocol("icmp"), addr::addr_invalid_argument);
1662 1 : CATCH_REQUIRE_THROWS_AS(a.set_protocol("raw"), addr::addr_invalid_argument);
1663 1 : CATCH_REQUIRE_THROWS_AS(a.set_protocol("hmp"), addr::addr_invalid_argument);
1664 :
1665 : // test all valid protocols (numeric)
1666 : //
1667 1 : a.set_protocol(IPPROTO_IP);
1668 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_IP);
1669 1 : a.set_protocol(IPPROTO_TCP);
1670 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_TCP);
1671 1 : a.set_protocol(IPPROTO_UDP);
1672 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_UDP);
1673 :
1674 : // test all valid protocols (ascii)
1675 : //
1676 1 : a.set_protocol("ip");
1677 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_IP);
1678 1 : a.set_protocol("tcp");
1679 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_TCP);
1680 1 : a.set_protocol("udp");
1681 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_UDP);
1682 : }
1683 : }
1684 :
1685 12 : CATCH_GIVEN("addr_parser()")
1686 : {
1687 6 : addr::addr_parser p;
1688 :
1689 6 : CATCH_SECTION("verify default")
1690 : {
1691 1 : CATCH_REQUIRE(p.get_protocol() == -1);
1692 : }
1693 :
1694 6 : CATCH_SECTION("test 3 allowed protocols")
1695 : {
1696 : // by string
1697 : //
1698 1 : p.set_protocol("ip");
1699 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_IP);
1700 1 : p.set_protocol("tcp");
1701 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_TCP);
1702 1 : p.set_protocol("udp");
1703 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_UDP);
1704 :
1705 : // numerically
1706 : //
1707 1 : p.set_protocol(IPPROTO_IP);
1708 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_IP);
1709 1 : p.set_protocol(IPPROTO_TCP);
1710 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_TCP);
1711 1 : p.set_protocol(IPPROTO_UDP);
1712 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_UDP);
1713 : }
1714 :
1715 6 : CATCH_SECTION("verify clearing works")
1716 : {
1717 1 : p.set_protocol("ip");
1718 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_IP);
1719 1 : p.clear_protocol();
1720 1 : CATCH_REQUIRE(p.get_protocol() == -1);
1721 :
1722 1 : p.set_protocol("tcp");
1723 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_TCP);
1724 1 : p.clear_protocol();
1725 1 : CATCH_REQUIRE(p.get_protocol() == -1);
1726 :
1727 1 : p.set_protocol("udp");
1728 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_UDP);
1729 1 : p.clear_protocol();
1730 1 : CATCH_REQUIRE(p.get_protocol() == -1);
1731 : }
1732 : }
1733 :
1734 12 : CATCH_GIVEN("addr_parser with any protocol")
1735 : {
1736 1 : addr::addr a;
1737 :
1738 2 : CATCH_SECTION("get address with all protocols")
1739 : {
1740 2 : addr::addr_parser p;
1741 : //p.set_protocol(...); -- by default we'll get all the protocols supported
1742 2 : addr::addr_range::vector_t ips(p.parse("127.0.0.1"));
1743 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1744 1 : CATCH_REQUIRE(!ips.empty());
1745 4 : for(size_t idx(0); idx < ips.size(); ++idx)
1746 : {
1747 3 : addr::addr_range const & r(ips[idx]);
1748 3 : CATCH_REQUIRE(r.has_from());
1749 3 : CATCH_REQUIRE_FALSE(r.has_to());
1750 3 : CATCH_REQUIRE_FALSE(r.is_range());
1751 3 : CATCH_REQUIRE_FALSE(r.is_empty());
1752 3 : addr::addr f(r.get_from());
1753 3 : if(f.is_ipv4())
1754 : {
1755 3 : CATCH_REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "127.0.0.1");
1756 3 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "127.0.0.1");
1757 3 : CATCH_REQUIRE(f.get_port() == 0);
1758 : //CATCH_REQUIRE(f.get_protocol() == ...); -- may be TCP, UDP, IP
1759 3 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_LOOPBACK);
1760 : }
1761 : else
1762 : {
1763 0 : CATCH_REQUIRE(f.to_ipv6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "::1");
1764 0 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "::1");
1765 0 : CATCH_REQUIRE(f.get_port() == 0);
1766 : //CATCH_REQUIRE(f.get_protocol() == ...); -- may be TCP, UDP, IP
1767 0 : CATCH_REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_LOOPBACK);
1768 : }
1769 : }
1770 : }
1771 : }
1772 6 : }
1773 :
1774 :
1775 10 : CATCH_TEST_CASE( "ipv4::network_type", "[ipv4]" )
1776 : {
1777 16 : CATCH_GIVEN("addr()")
1778 : {
1779 8 : addr::addr a;
1780 :
1781 16 : CATCH_SECTION("any (0.0.0.0)")
1782 : {
1783 1 : struct sockaddr_in in = sockaddr_in();
1784 1 : in.sin_family = AF_INET;
1785 1 : in.sin_port = htons(rand());
1786 1 : in.sin_addr.s_addr = 0;
1787 :
1788 : // verify network type
1789 : //
1790 1 : a.set_ipv4(in);
1791 :
1792 1 : CATCH_REQUIRE(a.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_ANY);
1793 1 : CATCH_REQUIRE(a.get_network_type_string() == "Any");
1794 : }
1795 :
1796 16 : CATCH_SECTION("private address 10.x.x.x/8")
1797 : {
1798 11 : for(int idx(0); idx < 10; ++idx)
1799 : {
1800 10 : struct sockaddr_in in = sockaddr_in();
1801 10 : in.sin_family = AF_INET;
1802 10 : in.sin_port = htons(rand());
1803 : uint32_t address((10 << 24)
1804 10 : | ((rand() & 255) << 16)
1805 10 : | ((rand() & 255) << 8)
1806 10 : | ((rand() & 255) << 0));
1807 10 : in.sin_addr.s_addr = htonl(address);
1808 :
1809 : // verify network type
1810 : //
1811 10 : a.set_ipv4(in);
1812 10 : CATCH_REQUIRE(a.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1813 10 : CATCH_REQUIRE(a.get_network_type_string() == "Private");
1814 : }
1815 : }
1816 :
1817 16 : CATCH_SECTION("private address 172.16.x.x/12")
1818 : {
1819 11 : for(int idx(0); idx < 10; ++idx)
1820 : {
1821 10 : struct sockaddr_in in = sockaddr_in();
1822 10 : in.sin_family = AF_INET;
1823 10 : in.sin_port = htons(rand());
1824 : uint32_t address((172 << 24)
1825 10 : | (((rand() & 15) | 16) << 16)
1826 10 : | ((rand() & 255) << 8)
1827 10 : | ((rand() & 255) << 0));
1828 10 : in.sin_addr.s_addr = htonl(address);
1829 :
1830 : // verify network type
1831 : //
1832 10 : a.set_ipv4(in);
1833 10 : CATCH_REQUIRE(a.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1834 10 : CATCH_REQUIRE(a.get_network_type_string() == "Private");
1835 : }
1836 : }
1837 :
1838 16 : CATCH_SECTION("private address 192.168.x.x/16")
1839 : {
1840 11 : for(int idx(0); idx < 10; ++idx)
1841 : {
1842 10 : struct sockaddr_in in = sockaddr_in();
1843 10 : in.sin_family = AF_INET;
1844 10 : in.sin_port = htons(rand());
1845 : uint32_t address((192 << 24)
1846 : | (168 << 16)
1847 10 : | ((rand() & 255) << 8)
1848 10 : | ((rand() & 255) << 0));
1849 10 : in.sin_addr.s_addr = htonl(address);
1850 :
1851 : // verify network type
1852 : //
1853 10 : a.set_ipv4(in);
1854 10 : CATCH_REQUIRE(a.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1855 10 : CATCH_REQUIRE(a.get_network_type_string() == "Private");
1856 : }
1857 : }
1858 :
1859 16 : CATCH_SECTION("private address 100.66.x.x/10")
1860 : {
1861 11 : for(int idx(0); idx < 10; ++idx)
1862 : {
1863 10 : struct sockaddr_in in = sockaddr_in();
1864 10 : in.sin_family = AF_INET;
1865 10 : in.sin_port = htons(rand());
1866 : uint32_t address((100 << 24)
1867 10 : | (((rand() & 63) | 64) << 16)
1868 10 : | ((rand() & 255) << 8)
1869 10 : | ((rand() & 255) << 0));
1870 10 : in.sin_addr.s_addr = htonl(address);
1871 :
1872 : // verify network type
1873 : //
1874 10 : a.set_ipv4(in);
1875 10 : CATCH_REQUIRE(a.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_CARRIER);
1876 10 : CATCH_REQUIRE(a.get_network_type_string() == "Carrier");
1877 : }
1878 : }
1879 :
1880 16 : CATCH_SECTION("private address 169.254.x.x/16")
1881 : {
1882 11 : for(int idx(0); idx < 10; ++idx)
1883 : {
1884 10 : struct sockaddr_in in = sockaddr_in();
1885 10 : in.sin_family = AF_INET;
1886 10 : in.sin_port = htons(rand());
1887 : uint32_t address((169 << 24)
1888 : | (254 << 16)
1889 10 : | ((rand() & 255) << 8)
1890 10 : | ((rand() & 255) << 0));
1891 10 : in.sin_addr.s_addr = htonl(address);
1892 :
1893 : // verify network type
1894 : //
1895 10 : a.set_ipv4(in);
1896 10 : CATCH_REQUIRE(a.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_LINK_LOCAL);
1897 10 : CATCH_REQUIRE(a.get_network_type_string() == "Local Link");
1898 : }
1899 : }
1900 :
1901 16 : CATCH_SECTION("private address 224.x.x.x/4")
1902 : {
1903 11 : for(int idx(0); idx < 10; ++idx)
1904 : {
1905 10 : struct sockaddr_in in = sockaddr_in();
1906 10 : in.sin_family = AF_INET;
1907 10 : in.sin_port = htons(rand());
1908 10 : uint32_t address((((rand() & 15) | 224) << 24)
1909 10 : | ((rand() & 255) << 16)
1910 10 : | ((rand() & 255) << 8)
1911 10 : | ((rand() & 255) << 0));
1912 10 : in.sin_addr.s_addr = htonl(address);
1913 :
1914 : // verify network type
1915 : //
1916 10 : a.set_ipv4(in);
1917 10 : CATCH_REQUIRE(a.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_MULTICAST);
1918 10 : CATCH_REQUIRE(a.get_network_type_string() == "Multicast");
1919 :
1920 : // make sure no interface uses that IP
1921 : //
1922 10 : CATCH_REQUIRE(addr::find_addr_interface(a, false) == nullptr);
1923 : }
1924 : }
1925 :
1926 16 : CATCH_SECTION("private address 127.x.x.x/8")
1927 : {
1928 11 : for(int idx(0); idx < 10; ++idx)
1929 : {
1930 10 : struct sockaddr_in in = sockaddr_in();
1931 10 : in.sin_family = AF_INET;
1932 10 : in.sin_port = htons(rand());
1933 : uint32_t address((127 << 24)
1934 10 : | ((rand() & 255) << 16)
1935 10 : | ((rand() & 255) << 8)
1936 10 : | ((rand() & 255) << 0));
1937 10 : in.sin_addr.s_addr = htonl(address);
1938 :
1939 : // verify network type
1940 : //
1941 10 : a.set_ipv4(in);
1942 10 : CATCH_REQUIRE(a.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_LOOPBACK);
1943 10 : CATCH_REQUIRE(a.get_network_type_string() == "Loopback");
1944 : }
1945 : }
1946 : }
1947 8 : }
1948 :
1949 :
1950 8 : CATCH_TEST_CASE( "ipv4::network", "[ipv4]" )
1951 : {
1952 12 : CATCH_GIVEN("set_from_socket()")
1953 : {
1954 12 : CATCH_SECTION("invalid socket")
1955 : {
1956 1 : addr::addr a;
1957 1 : CATCH_REQUIRE_THROWS_AS(a.set_from_socket(-1, true), addr::addr_invalid_argument);
1958 1 : CATCH_REQUIRE_THROWS_AS(a.set_from_socket(-1, false), addr::addr_invalid_argument);
1959 : }
1960 :
1961 12 : CATCH_SECTION("non-opened file descriptor")
1962 : {
1963 1 : addr::addr a;
1964 :
1965 : // unless we have a bug, there should not be any file descriptor
1966 : // currently open with an ID of 1,000
1967 : //
1968 1 : CATCH_REQUIRE_THROWS_AS(a.set_from_socket(1000, true), addr::addr_io_error);
1969 1 : CATCH_REQUIRE_THROWS_AS(a.set_from_socket(1000, false), addr::addr_io_error);
1970 : }
1971 :
1972 12 : CATCH_SECTION("unknown socket type")
1973 : {
1974 1 : addr::addr a;
1975 :
1976 1 : int s(socket(AF_UNIX, SOCK_STREAM, 0));
1977 1 : CATCH_REQUIRE(s >= 0);
1978 2 : std::shared_ptr<int> auto_free(&s, socket_deleter);
1979 :
1980 : // unless we have a bug, there should not be any file descriptor
1981 : // currently open with an ID of 1,000
1982 : //
1983 1 : CATCH_REQUIRE_THROWS_AS(a.set_from_socket(s, true), addr::addr_io_error);
1984 1 : CATCH_REQUIRE_THROWS_AS(a.set_from_socket(s, false), addr::addr_invalid_state);
1985 : }
1986 :
1987 12 : CATCH_SECTION("create a server, but do not test it (yet)...")
1988 : {
1989 2 : addr::addr_parser p;
1990 2 : addr::addr_range::vector_t ips(p.parse("127.0.0.1:49999"));
1991 1 : CATCH_REQUIRE(ips.size() >= 1);
1992 :
1993 1 : addr::addr & a(ips[0].get_from());
1994 1 : int s(a.create_socket(addr::addr::SOCKET_FLAG_NONBLOCK | addr::addr::SOCKET_FLAG_CLOEXEC | addr::addr::SOCKET_FLAG_REUSE));
1995 1 : CATCH_REQUIRE(s >= 0);
1996 2 : std::shared_ptr<int> auto_free(&s, socket_deleter);
1997 :
1998 1 : CATCH_REQUIRE(a.bind(s) == 0);
1999 : }
2000 :
2001 12 : CATCH_SECTION("connect with TCP to 127.0.0.1")
2002 : {
2003 1 : if(SNAP_CATCH2_NAMESPACE::g_tcp_port != -1)
2004 : {
2005 2 : addr::addr_parser p;
2006 2 : addr::addr_range::vector_t ips(p.parse("127.0.0.1:" + std::to_string(SNAP_CATCH2_NAMESPACE::g_tcp_port)));
2007 1 : CATCH_REQUIRE(ips.size() >= 1);
2008 :
2009 1 : addr::addr & a(ips[0].get_from());
2010 1 : int s(a.create_socket(addr::addr::SOCKET_FLAG_CLOEXEC));// | addr::addr::SOCKET_FLAG_REUSE));
2011 1 : CATCH_REQUIRE(s >= 0);
2012 2 : std::shared_ptr<int> auto_free(&s, socket_deleter);
2013 :
2014 1 : CATCH_REQUIRE(a.connect(s) == 0);
2015 :
2016 : // get socket info from the other side (peer == true)
2017 : //
2018 1 : addr::addr b;
2019 1 : b.set_from_socket(s, true);
2020 1 : CATCH_REQUIRE(b.is_ipv4());
2021 1 : CATCH_REQUIRE(b.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "127.0.0.1");
2022 1 : CATCH_REQUIRE(b.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "127.0.0.1");
2023 :
2024 : // in this case we know what the port is since we specified
2025 : // that when connecting
2026 : //
2027 1 : CATCH_REQUIRE(b.get_port() == SNAP_CATCH2_NAMESPACE::g_tcp_port);
2028 :
2029 : // now try this side (peer == false)
2030 : //
2031 1 : addr::addr c;
2032 1 : c.set_from_socket(s, false);
2033 1 : CATCH_REQUIRE(c.is_ipv4());
2034 1 : CATCH_REQUIRE(c.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "127.0.0.1");
2035 1 : CATCH_REQUIRE(c.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "127.0.0.1");
2036 :
2037 : // we cannot be sure of the port, there is a range we could
2038 : // test better (more constraining) but for this test is
2039 : // certainly does not matter much; it has to be more than
2040 : // 1023, though
2041 : //
2042 1 : CATCH_REQUIRE(c.get_port() > 1023);
2043 : }
2044 : else
2045 : {
2046 : // avoid issue of no assertions
2047 : //
2048 0 : CATCH_REQUIRE(SNAP_CATCH2_NAMESPACE::g_tcp_port == -1);
2049 0 : std::cout << "connect to 127.0.0.1 test skipped as no TCP port was specified on the command line." << std::endl;
2050 : }
2051 : }
2052 :
2053 12 : CATCH_SECTION("connect with UDP to 127.0.0.1")
2054 : {
2055 2 : addr::addr_parser p;
2056 1 : p.set_protocol("udp");
2057 2 : addr::addr_range::vector_t ips(p.parse("127.0.0.1:53"));
2058 1 : CATCH_REQUIRE(ips.size() >= 1);
2059 :
2060 1 : addr::addr & a(ips[0].get_from());
2061 1 : int s(a.create_socket(addr::addr::SOCKET_FLAG_CLOEXEC));// | addr::addr::SOCKET_FLAG_REUSE));
2062 1 : CATCH_REQUIRE(s >= 0);
2063 2 : std::shared_ptr<int> auto_free(&s, socket_deleter);
2064 :
2065 1 : CATCH_REQUIRE(a.connect(s) == -1);
2066 :
2067 : // get socket info from the other side (peer == true)
2068 : //
2069 1 : addr::addr b;
2070 1 : CATCH_REQUIRE_THROWS_AS(b.set_from_socket(s, true), addr::addr_io_error);
2071 1 : CATCH_REQUIRE_FALSE(b.is_ipv4());
2072 1 : CATCH_REQUIRE(b.to_ipv6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "::");
2073 1 : CATCH_REQUIRE(b.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "::");
2074 :
2075 : // in this case we know what the port is since we specified
2076 : // that when connecting
2077 : //
2078 1 : CATCH_REQUIRE(b.get_port() == 0);
2079 :
2080 : // now try this side (peer == false)
2081 : //
2082 1 : addr::addr c;
2083 1 : c.set_from_socket(s, false);
2084 1 : CATCH_REQUIRE(c.is_ipv4());
2085 1 : CATCH_REQUIRE(c.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "0.0.0.0");
2086 1 : CATCH_REQUIRE(c.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "0.0.0.0");
2087 :
2088 : // we cannot be sure of the port, there is a range we could
2089 : // test better (more constraining) but for this test is
2090 : // certainly does not matter much; it has to be more than
2091 : // 1023, though
2092 : //
2093 1 : CATCH_REQUIRE(c.get_port() == 0);
2094 : }
2095 : }
2096 6 : }
2097 :
2098 :
2099 15 : CATCH_TEST_CASE( "ipv4::string_to_addr", "[ipv4]" )
2100 : {
2101 26 : CATCH_GIVEN("string_to_addr() ipv4")
2102 : {
2103 26 : CATCH_SECTION("empty address without defaults")
2104 : {
2105 1 : addr::addr a(addr::string_to_addr(std::string()));
2106 :
2107 1 : CATCH_REQUIRE(a.is_ipv4());
2108 :
2109 1 : struct sockaddr_in in = sockaddr_in();
2110 1 : in.sin_family = AF_INET;
2111 1 : in.sin_port = 0;
2112 1 : in.sin_addr.s_addr = htonl((0 << 24) | (0 << 16) | (0 << 8) | (0 << 0));
2113 :
2114 : // test string_to_addr accuracy
2115 : //
2116 1 : struct sockaddr_in out;
2117 1 : a.get_ipv4(out);
2118 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
2119 :
2120 1 : uint8_t mask[16];
2121 1 : a.get_mask(mask);
2122 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
2123 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
2124 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
2125 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
2126 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
2127 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
2128 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
2129 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
2130 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
2131 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
2132 1 : CATCH_REQUIRE(mask[10] == 0xFF);
2133 1 : CATCH_REQUIRE(mask[11] == 0xFF);
2134 1 : CATCH_REQUIRE(mask[12] == 0xFF);
2135 1 : CATCH_REQUIRE(mask[13] == 0xFF);
2136 1 : CATCH_REQUIRE(mask[14] == 0xFF);
2137 1 : CATCH_REQUIRE(mask[15] == 0xFF);
2138 : }
2139 26 : CATCH_SECTION("explicit defaults")
2140 : {
2141 1 : addr::addr a(addr::string_to_addr("5.14.34.111", std::string(), -1, std::string(), false));
2142 :
2143 1 : CATCH_REQUIRE(a.is_ipv4());
2144 :
2145 1 : struct sockaddr_in in = sockaddr_in();
2146 1 : in.sin_family = AF_INET;
2147 1 : in.sin_port = 0;
2148 1 : in.sin_addr.s_addr = htonl((5 << 24) | (14 << 16) | (34 << 8) | (111 << 0));
2149 :
2150 : // test string_to_addr accuracy
2151 : //
2152 1 : struct sockaddr_in out;
2153 1 : a.get_ipv4(out);
2154 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
2155 :
2156 1 : uint8_t mask[16];
2157 1 : a.get_mask(mask);
2158 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
2159 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
2160 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
2161 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
2162 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
2163 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
2164 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
2165 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
2166 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
2167 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
2168 1 : CATCH_REQUIRE(mask[10] == 0xFF);
2169 1 : CATCH_REQUIRE(mask[11] == 0xFF);
2170 1 : CATCH_REQUIRE(mask[12] == 0xFF);
2171 1 : CATCH_REQUIRE(mask[13] == 0xFF);
2172 1 : CATCH_REQUIRE(mask[14] == 0xFF);
2173 1 : CATCH_REQUIRE(mask[15] == 0xFF);
2174 : }
2175 26 : CATCH_SECTION("defaults")
2176 : {
2177 1 : addr::addr a(addr::string_to_addr("7.149.104.211"));
2178 :
2179 1 : CATCH_REQUIRE(a.is_ipv4());
2180 :
2181 1 : struct sockaddr_in in = sockaddr_in();
2182 1 : in.sin_family = AF_INET;
2183 1 : in.sin_port = 0;
2184 1 : in.sin_addr.s_addr = htonl((7 << 24) | (149 << 16) | (104 << 8) | (211 << 0));
2185 :
2186 : // test string_to_addr accuracy
2187 : //
2188 1 : struct sockaddr_in out;
2189 1 : a.get_ipv4(out);
2190 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
2191 :
2192 1 : uint8_t mask[16];
2193 1 : a.get_mask(mask);
2194 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
2195 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
2196 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
2197 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
2198 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
2199 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
2200 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
2201 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
2202 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
2203 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
2204 1 : CATCH_REQUIRE(mask[10] == 0xFF);
2205 1 : CATCH_REQUIRE(mask[11] == 0xFF);
2206 1 : CATCH_REQUIRE(mask[12] == 0xFF);
2207 1 : CATCH_REQUIRE(mask[13] == 0xFF);
2208 1 : CATCH_REQUIRE(mask[14] == 0xFF);
2209 1 : CATCH_REQUIRE(mask[15] == 0xFF);
2210 : }
2211 26 : CATCH_SECTION("addr & default addr")
2212 : {
2213 1 : addr::addr a(addr::string_to_addr("37.149.174.11", "1.205.32.11"));
2214 :
2215 1 : CATCH_REQUIRE(a.is_ipv4());
2216 :
2217 1 : struct sockaddr_in in = sockaddr_in();
2218 1 : in.sin_family = AF_INET;
2219 1 : in.sin_port = 0;
2220 1 : in.sin_addr.s_addr = htonl((37 << 24) | (149 << 16) | (174 << 8) | (11 << 0));
2221 :
2222 : // test string_to_addr accuracy
2223 : //
2224 1 : struct sockaddr_in out;
2225 1 : a.get_ipv4(out);
2226 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
2227 :
2228 1 : uint8_t mask[16];
2229 1 : a.get_mask(mask);
2230 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
2231 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
2232 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
2233 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
2234 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
2235 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
2236 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
2237 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
2238 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
2239 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
2240 1 : CATCH_REQUIRE(mask[10] == 0xFF);
2241 1 : CATCH_REQUIRE(mask[11] == 0xFF);
2242 1 : CATCH_REQUIRE(mask[12] == 0xFF);
2243 1 : CATCH_REQUIRE(mask[13] == 0xFF);
2244 1 : CATCH_REQUIRE(mask[14] == 0xFF);
2245 1 : CATCH_REQUIRE(mask[15] == 0xFF);
2246 : }
2247 26 : CATCH_SECTION("no addr, expect default addr")
2248 : {
2249 1 : addr::addr a(addr::string_to_addr("", "1.205.32.11"));
2250 :
2251 1 : CATCH_REQUIRE(a.is_ipv4());
2252 :
2253 1 : struct sockaddr_in in = sockaddr_in();
2254 1 : in.sin_family = AF_INET;
2255 1 : in.sin_port = 0;
2256 1 : in.sin_addr.s_addr = htonl((1 << 24) | (205 << 16) | (32 << 8) | (11 << 0));
2257 :
2258 : // test string_to_addr accuracy
2259 : //
2260 1 : struct sockaddr_in out;
2261 1 : a.get_ipv4(out);
2262 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
2263 :
2264 1 : uint8_t mask[16];
2265 1 : a.get_mask(mask);
2266 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
2267 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
2268 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
2269 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
2270 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
2271 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
2272 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
2273 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
2274 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
2275 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
2276 1 : CATCH_REQUIRE(mask[10] == 0xFF);
2277 1 : CATCH_REQUIRE(mask[11] == 0xFF);
2278 1 : CATCH_REQUIRE(mask[12] == 0xFF);
2279 1 : CATCH_REQUIRE(mask[13] == 0xFF);
2280 1 : CATCH_REQUIRE(mask[14] == 0xFF);
2281 1 : CATCH_REQUIRE(mask[15] == 0xFF);
2282 : }
2283 26 : CATCH_SECTION("addr and port, with a default port")
2284 : {
2285 1 : addr::addr a(addr::string_to_addr("69.109.223.17:697", "1.205.32.11", 123));
2286 :
2287 1 : CATCH_REQUIRE(a.is_ipv4());
2288 :
2289 1 : struct sockaddr_in in = sockaddr_in();
2290 1 : in.sin_family = AF_INET;
2291 1 : in.sin_port = htons(697);
2292 1 : in.sin_addr.s_addr = htonl((69 << 24) | (109 << 16) | (223 << 8) | (17 << 0));
2293 :
2294 : // test string_to_addr accuracy
2295 : //
2296 1 : struct sockaddr_in out;
2297 1 : a.get_ipv4(out);
2298 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
2299 :
2300 1 : uint8_t mask[16];
2301 1 : a.get_mask(mask);
2302 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
2303 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
2304 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
2305 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
2306 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
2307 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
2308 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
2309 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
2310 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
2311 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
2312 1 : CATCH_REQUIRE(mask[10] == 0xFF);
2313 1 : CATCH_REQUIRE(mask[11] == 0xFF);
2314 1 : CATCH_REQUIRE(mask[12] == 0xFF);
2315 1 : CATCH_REQUIRE(mask[13] == 0xFF);
2316 1 : CATCH_REQUIRE(mask[14] == 0xFF);
2317 1 : CATCH_REQUIRE(mask[15] == 0xFF);
2318 : }
2319 26 : CATCH_SECTION("addr without port, with a default port")
2320 : {
2321 1 : addr::addr a(addr::string_to_addr("169.209.23.217", "1.205.32.11", 123));
2322 :
2323 1 : CATCH_REQUIRE(a.is_ipv4());
2324 :
2325 1 : struct sockaddr_in in = sockaddr_in();
2326 1 : in.sin_family = AF_INET;
2327 1 : in.sin_port = htons(123);
2328 1 : in.sin_addr.s_addr = htonl((169 << 24) | (209 << 16) | (23 << 8) | (217 << 0));
2329 :
2330 : // test string_to_addr accuracy
2331 : //
2332 1 : struct sockaddr_in out;
2333 1 : a.get_ipv4(out);
2334 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
2335 :
2336 1 : uint8_t mask[16];
2337 1 : a.get_mask(mask);
2338 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
2339 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
2340 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
2341 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
2342 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
2343 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
2344 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
2345 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
2346 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
2347 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
2348 1 : CATCH_REQUIRE(mask[10] == 0xFF);
2349 1 : CATCH_REQUIRE(mask[11] == 0xFF);
2350 1 : CATCH_REQUIRE(mask[12] == 0xFF);
2351 1 : CATCH_REQUIRE(mask[13] == 0xFF);
2352 1 : CATCH_REQUIRE(mask[14] == 0xFF);
2353 1 : CATCH_REQUIRE(mask[15] == 0xFF);
2354 : }
2355 26 : CATCH_SECTION("addr without port but protocol")
2356 : {
2357 1 : addr::addr a(addr::string_to_addr("4.5.123.7", "1.205.32.11", 60000, "tcp"));
2358 :
2359 1 : CATCH_REQUIRE(a.is_ipv4());
2360 :
2361 1 : struct sockaddr_in in = sockaddr_in();
2362 1 : in.sin_family = AF_INET;
2363 1 : in.sin_port = htons(60000);
2364 1 : in.sin_addr.s_addr = htonl((4 << 24) | (5 << 16) | (123 << 8) | (7 << 0));
2365 :
2366 : // test string_to_addr accuracy
2367 : //
2368 1 : struct sockaddr_in out;
2369 1 : a.get_ipv4(out);
2370 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
2371 :
2372 1 : uint8_t mask[16];
2373 1 : a.get_mask(mask);
2374 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
2375 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
2376 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
2377 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
2378 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
2379 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
2380 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
2381 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
2382 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
2383 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
2384 1 : CATCH_REQUIRE(mask[10] == 0xFF);
2385 1 : CATCH_REQUIRE(mask[11] == 0xFF);
2386 1 : CATCH_REQUIRE(mask[12] == 0xFF);
2387 1 : CATCH_REQUIRE(mask[13] == 0xFF);
2388 1 : CATCH_REQUIRE(mask[14] == 0xFF);
2389 1 : CATCH_REQUIRE(mask[15] == 0xFF);
2390 : }
2391 26 : CATCH_SECTION("addr with port and protocol")
2392 : {
2393 1 : addr::addr a(addr::string_to_addr("204.105.13.9:65", "1.205.32.11", 60000, "tcp"));
2394 :
2395 1 : CATCH_REQUIRE(a.is_ipv4());
2396 :
2397 1 : struct sockaddr_in in = sockaddr_in();
2398 1 : in.sin_family = AF_INET;
2399 1 : in.sin_port = htons(65);
2400 1 : in.sin_addr.s_addr = htonl((204 << 24) | (105 << 16) | (13 << 8) | (9 << 0));
2401 :
2402 : // test string_to_addr accuracy
2403 : //
2404 1 : struct sockaddr_in out;
2405 1 : a.get_ipv4(out);
2406 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
2407 :
2408 1 : uint8_t mask[16];
2409 1 : a.get_mask(mask);
2410 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
2411 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
2412 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
2413 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
2414 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
2415 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
2416 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
2417 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
2418 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
2419 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
2420 1 : CATCH_REQUIRE(mask[10] == 0xFF);
2421 1 : CATCH_REQUIRE(mask[11] == 0xFF);
2422 1 : CATCH_REQUIRE(mask[12] == 0xFF);
2423 1 : CATCH_REQUIRE(mask[13] == 0xFF);
2424 1 : CATCH_REQUIRE(mask[14] == 0xFF);
2425 1 : CATCH_REQUIRE(mask[15] == 0xFF);
2426 : }
2427 26 : CATCH_SECTION("addr with port and protocol but no mask, albeit allowed")
2428 : {
2429 1 : addr::addr a(addr::string_to_addr("94.95.131.18:765", "11.205.32.21", 54003, "tcp", true));
2430 :
2431 1 : CATCH_REQUIRE(a.is_ipv4());
2432 :
2433 1 : struct sockaddr_in in = sockaddr_in();
2434 1 : in.sin_family = AF_INET;
2435 1 : in.sin_port = htons(765);
2436 1 : in.sin_addr.s_addr = htonl((94 << 24) | (95 << 16) | (131 << 8) | (18 << 0));
2437 :
2438 : // test string_to_addr accuracy
2439 : //
2440 1 : struct sockaddr_in out;
2441 1 : a.get_ipv4(out);
2442 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
2443 :
2444 1 : uint8_t mask[16];
2445 1 : a.get_mask(mask);
2446 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
2447 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
2448 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
2449 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
2450 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
2451 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
2452 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
2453 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
2454 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
2455 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
2456 1 : CATCH_REQUIRE(mask[10] == 0xFF);
2457 1 : CATCH_REQUIRE(mask[11] == 0xFF);
2458 1 : CATCH_REQUIRE(mask[12] == 0xFF);
2459 1 : CATCH_REQUIRE(mask[13] == 0xFF);
2460 1 : CATCH_REQUIRE(mask[14] == 0xFF);
2461 1 : CATCH_REQUIRE(mask[15] == 0xFF);
2462 : }
2463 26 : CATCH_SECTION("addr with port and protocol and mask, albeit allowed")
2464 : {
2465 1 : addr::addr a(addr::string_to_addr("44.45.141.48:765/30", "11.205.32.21", 54003, "tcp", true));
2466 :
2467 1 : CATCH_REQUIRE(a.is_ipv4());
2468 :
2469 1 : struct sockaddr_in in = sockaddr_in();
2470 1 : in.sin_family = AF_INET;
2471 1 : in.sin_port = htons(765);
2472 1 : in.sin_addr.s_addr = htonl((44 << 24) | (45 << 16) | (141 << 8) | (48 << 0));
2473 :
2474 : // test string_to_addr accuracy
2475 : //
2476 1 : struct sockaddr_in out;
2477 1 : a.get_ipv4(out);
2478 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
2479 :
2480 1 : uint8_t mask[16];
2481 1 : a.get_mask(mask);
2482 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
2483 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
2484 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
2485 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
2486 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
2487 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
2488 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
2489 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
2490 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
2491 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
2492 1 : CATCH_REQUIRE(mask[10] == 0xFF);
2493 1 : CATCH_REQUIRE(mask[11] == 0xFF);
2494 1 : CATCH_REQUIRE(mask[12] == 0xFF);
2495 1 : CATCH_REQUIRE(mask[13] == 0xFF);
2496 1 : CATCH_REQUIRE(mask[14] == 0xFF);
2497 1 : CATCH_REQUIRE(mask[15] == 0xFC);
2498 : }
2499 26 : CATCH_SECTION("addr with port and protocol and mask, albeit allowed")
2500 : {
2501 1 : addr::addr a(addr::string_to_addr("160.0.0.0:1675/4", "11.205.32.21", 14003, "udp", true));
2502 :
2503 1 : CATCH_REQUIRE(a.is_ipv4());
2504 :
2505 1 : struct sockaddr_in in = sockaddr_in();
2506 1 : in.sin_family = AF_INET;
2507 1 : in.sin_port = htons(1675);
2508 1 : in.sin_addr.s_addr = htonl((160 << 24) | (0 << 16) | (0 << 8) | (0 << 0));
2509 :
2510 : // test string_to_addr accuracy
2511 : //
2512 1 : struct sockaddr_in out;
2513 1 : a.get_ipv4(out);
2514 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
2515 :
2516 1 : uint8_t mask[16];
2517 1 : a.get_mask(mask);
2518 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
2519 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
2520 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
2521 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
2522 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
2523 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
2524 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
2525 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
2526 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
2527 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
2528 1 : CATCH_REQUIRE(mask[10] == 0xFF);
2529 1 : CATCH_REQUIRE(mask[11] == 0xFF);
2530 1 : CATCH_REQUIRE(mask[12] == 0xF0);
2531 1 : CATCH_REQUIRE(mask[13] == 0x00);
2532 1 : CATCH_REQUIRE(mask[14] == 0x00);
2533 1 : CATCH_REQUIRE(mask[15] == 0x00);
2534 : }
2535 26 : CATCH_SECTION("addr with port and invalid protocol so we get an exception")
2536 : {
2537 1 : CATCH_REQUIRE_THROWS_AS(addr::string_to_addr("169.60.33.0:9322/24", std::string(), -1, "icmp", true),
2538 : addr::addr_invalid_argument);
2539 : }
2540 : }
2541 : // TODO: add ipv6 tests, although at this point it's not too
2542 : // important here, it may change in the future
2543 : //
2544 :
2545 : //addr string_to_addr(
2546 : // std::string const & a
2547 : // , std::string const & default_address = std::string()
2548 : // , int default_port = -1
2549 : // , std::string const & protocol = std::string()
2550 : // , bool mask = false);
2551 19 : }
2552 :
2553 :
2554 : // vim: ts=4 sw=4 et
|