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