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