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