Line data Source code
1 : /* test_addr_ipv4.cpp
2 : * Copyright (C) 2011-2017 Made to Order Software Corporation
3 : *
4 : * Project: http://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 : #include "test_addr_main.h"
33 : #include "libaddr/addr.h"
34 :
35 : #include <sstream>
36 : #include <fstream>
37 :
38 : #include <string.h>
39 : //#include <math.h>
40 : //#include <time.h>
41 : #include <unistd.h>
42 : #include <limits.h>
43 :
44 :
45 :
46 17 : TEST_CASE( "ipv4::invalid_input", "ipv4" )
47 : {
48 30 : GIVEN("addr()")
49 : {
50 2 : addr::addr a;
51 :
52 2 : SECTION("set IPv4 with an invalid family")
53 : {
54 26 : for(int idx(0); idx < 25; ++idx)
55 : {
56 25 : struct sockaddr_in in = sockaddr_in();
57 0 : do
58 : {
59 25 : in.sin_family = rand();
60 : }
61 25 : while(in.sin_family == AF_INET);
62 25 : in.sin_port = htons(rand());
63 25 : in.sin_addr.s_addr = htonl(rand() ^ (rand() << 16));
64 25 : REQUIRE_THROWS_AS(a.set_ipv4(in), addr::addr_invalid_argument_exception);
65 25 : REQUIRE_THROWS_AS(addr::addr b(in), addr::addr_invalid_argument_exception);
66 : }
67 : }
68 : }
69 :
70 30 : GIVEN("addr_parser() with IPv4 settings")
71 : {
72 4 : addr::addr_parser a;
73 :
74 4 : SECTION("invalid allow flags (too small)")
75 : {
76 11 : for(int idx(0); idx < 10; ++idx)
77 : {
78 : // test with a negative number
79 : //
80 : int n;
81 0 : do
82 : {
83 10 : n = rand();
84 : }
85 10 : while(n == 0);
86 10 : if(n > 0)
87 : {
88 : // all positive numbers have a corresponding negative
89 : // number so this always flips the sign as expected
90 : //
91 10 : n = -n;
92 : }
93 10 : addr::addr_parser::flag_t const flag(static_cast<addr::addr_parser::flag_t>(n));
94 :
95 10 : REQUIRE_THROWS_AS(a.set_allow(flag, true), addr::addr_invalid_argument_exception);
96 10 : REQUIRE_THROWS_AS(a.set_allow(flag, false), addr::addr_invalid_argument_exception);
97 10 : REQUIRE_THROWS_AS(a.get_allow(flag), addr::addr_invalid_argument_exception);
98 : }
99 : }
100 :
101 4 : SECTION("invalid allow flags (too large)")
102 : {
103 11 : for(int idx(0); idx < 10; ++idx)
104 : {
105 : // test with a negative number
106 : //
107 : int n;
108 0 : do
109 : {
110 10 : n = rand();
111 10 : if(n < 0)
112 : {
113 0 : n = -n;
114 : }
115 : }
116 10 : while(n < static_cast<int>(addr::addr_parser::flag_t::FLAG_max));
117 10 : addr::addr_parser::flag_t const flag(static_cast<addr::addr_parser::flag_t>(n));
118 :
119 10 : REQUIRE_THROWS_AS(a.set_allow(flag, true), addr::addr_invalid_argument_exception);
120 10 : REQUIRE_THROWS_AS(a.set_allow(flag, false), addr::addr_invalid_argument_exception);
121 10 : REQUIRE_THROWS_AS(a.get_allow(flag), addr::addr_invalid_argument_exception);
122 : }
123 : }
124 : }
125 :
126 30 : GIVEN("addr_parser() with IPv4 addresses")
127 : {
128 4 : SECTION("bad address")
129 : {
130 2 : addr::addr_parser p;
131 2 : addr::addr_range::vector_t ips(p.parse("{bad-ip}"));
132 1 : REQUIRE(p.has_errors());
133 1 : REQUIRE(p.error_count() == 1);
134 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");
135 1 : REQUIRE(p.has_errors());
136 1 : p.clear_errors();
137 1 : REQUIRE_FALSE(p.has_errors());
138 1 : REQUIRE(ips.size() == 0);
139 : }
140 :
141 4 : SECTION("required address")
142 : {
143 2 : addr::addr_parser p;
144 1 : p.set_protocol(IPPROTO_TCP);
145 1 : p.set_allow(addr::addr_parser::flag_t::REQUIRED_ADDRESS, true);
146 2 : addr::addr_range::vector_t ips(p.parse(""));
147 1 : REQUIRE(p.has_errors());
148 1 : REQUIRE(p.error_count() == 1);
149 1 : REQUIRE(p.error_messages() == "Required address is missing.\n");
150 1 : REQUIRE(p.has_errors());
151 1 : p.clear_errors();
152 1 : REQUIRE_FALSE(p.has_errors());
153 1 : REQUIRE(ips.size() == 0);
154 : }
155 : }
156 :
157 30 : GIVEN("addr_parser() with IPv4 ports")
158 : {
159 6 : SECTION("required port")
160 : {
161 : // optional + required -> required
162 : {
163 2 : addr::addr_parser p;
164 1 : p.set_protocol(IPPROTO_TCP);
165 1 : p.set_allow(addr::addr_parser::flag_t::REQUIRED_PORT, true);
166 2 : addr::addr_range::vector_t ips(p.parse("1.2.3.4"));
167 1 : REQUIRE(p.has_errors());
168 1 : REQUIRE(p.error_count() == 1);
169 1 : REQUIRE(p.error_messages() == "Required port is missing.\n");
170 1 : REQUIRE(p.has_errors());
171 1 : p.clear_errors();
172 1 : REQUIRE_FALSE(p.has_errors());
173 1 : REQUIRE(ips.size() == 0);
174 : }
175 :
176 : // only required -> required just the same
177 : {
178 2 : addr::addr_parser p;
179 1 : p.set_protocol(IPPROTO_TCP);
180 1 : p.set_allow(addr::addr_parser::flag_t::PORT, false);
181 1 : p.set_allow(addr::addr_parser::flag_t::REQUIRED_PORT, true);
182 2 : addr::addr_range::vector_t ips(p.parse("1.2.3.4"));
183 1 : REQUIRE(p.has_errors());
184 1 : REQUIRE(p.error_count() == 1);
185 1 : REQUIRE(p.error_messages() == "Required port is missing.\n");
186 1 : REQUIRE(p.has_errors());
187 1 : p.clear_errors();
188 1 : REQUIRE_FALSE(p.has_errors());
189 1 : REQUIRE(ips.size() == 0);
190 : }
191 : }
192 :
193 6 : SECTION("port not allowed")
194 : {
195 2 : addr::addr_parser p;
196 1 : p.set_protocol(IPPROTO_TCP);
197 1 : p.set_allow(addr::addr_parser::flag_t::PORT, false);
198 1 : REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::REQUIRED_PORT));
199 2 : addr::addr_range::vector_t ips(p.parse("1.2.3.4:123"));
200 1 : REQUIRE(p.has_errors());
201 1 : REQUIRE(p.error_count() == 1);
202 1 : REQUIRE(p.error_messages() == "Port not allowed (1.2.3.4:123).\n");
203 1 : REQUIRE(p.has_errors());
204 1 : p.clear_errors();
205 1 : REQUIRE_FALSE(p.has_errors());
206 1 : REQUIRE(ips.size() == 0);
207 : }
208 :
209 6 : SECTION("invalid port")
210 : {
211 2 : addr::addr_parser p;
212 :
213 : // so to a different default value
214 : //
215 1 : int const default_port(rand() & 0xFFFF);
216 1 : p.set_default_port(default_port);
217 :
218 26 : for(int idx(0); idx < 25; ++idx)
219 : {
220 : int port;
221 0 : do
222 : {
223 25 : port = rand() ^ (rand() << 16);
224 : }
225 25 : while(port >= -1 && port <= 65535); // -1 is valid here, it represents "no default port defined"
226 25 : REQUIRE_THROWS_AS(p.set_default_port(port), addr::addr_invalid_argument_exception);
227 :
228 : // verify port unchanged
229 : //
230 25 : REQUIRE(p.get_default_port() == default_port);
231 : }
232 : }
233 : }
234 :
235 30 : GIVEN("addr_parser() with invalid masks")
236 : {
237 10 : SECTION("really large numbers (over 1000)")
238 : {
239 6 : for(int idx(0); idx < 5; ++idx)
240 : {
241 5 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
242 5 : int const port(rand() & 0xFFFF);
243 5 : int const mask((rand() & 0xFF) + 1001);
244 10 : addr::addr_parser p;
245 5 : p.set_protocol(proto);
246 5 : p.set_allow(p.flag_t::MASK, true);
247 10 : addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port) + "/" + std::to_string(mask)));
248 5 : REQUIRE(p.has_errors());
249 5 : REQUIRE(p.error_count() == 1);
250 5 : REQUIRE(p.error_messages() == "Mask number too large (" + std::to_string(mask) + ", expected a maximum of 128).\n");
251 5 : REQUIRE(ips.size() == 0);
252 : }
253 : }
254 :
255 10 : SECTION("ipv4 mask is limited between 0 and 32")
256 : {
257 6 : for(int idx(0); idx < 5; ++idx)
258 : {
259 5 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
260 5 : int const port(rand() & 0xFFFF);
261 5 : int const mask((rand() & 0xFF) + 33);
262 10 : addr::addr_parser p;
263 5 : p.set_protocol(proto);
264 5 : p.set_allow(p.flag_t::MASK, true);
265 10 : addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port) + "/" + std::to_string(mask)));
266 5 : REQUIRE(p.has_errors());
267 5 : REQUIRE(p.error_count() == 1);
268 5 : REQUIRE(p.error_messages() == "Unsupported mask size (" + std::to_string(mask) + ", expected 32 at the most for an IPv4).\n");
269 5 : REQUIRE(ips.size() == 0);
270 : }
271 : }
272 :
273 10 : SECTION("ipv4 mask cannot use name")
274 : {
275 6 : for(int idx(0); idx < 5; ++idx)
276 : {
277 5 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
278 5 : int const port(rand() & 0xFFFF);
279 10 : addr::addr_parser p;
280 5 : p.set_protocol(proto);
281 5 : p.set_allow(addr::addr_parser::flag_t::MASK, true);
282 10 : addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port) + "/localhost"));
283 5 : REQUIRE(p.has_errors());
284 5 : REQUIRE(p.error_count() == 1);
285 5 : REQUIRE(p.error_messages() == "Invalid mask in \"/localhost\", error -2 -- Name or service not known (errno: 0 -- Success).\n");
286 5 : REQUIRE(ips.size() == 0);
287 : }
288 : }
289 :
290 10 : SECTION("ipv4 mask mismatch (mask uses ipv6)")
291 : {
292 1 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
293 1 : int const port(rand() & 0xFFFF);
294 2 : addr::addr_parser p;
295 1 : p.set_protocol(proto);
296 1 : p.set_allow(addr::addr_parser::flag_t::MASK, true);
297 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]"));
298 1 : REQUIRE(p.has_errors());
299 1 : REQUIRE(p.error_count() == 1);
300 1 : REQUIRE(p.error_messages() == "The address uses the IPv4 syntax, the mask cannot use IPv6.\n");
301 1 : REQUIRE(ips.size() == 0);
302 : }
303 :
304 10 : SECTION("ipv4 mask mismatch (mask uses ipv6 without [...])")
305 : {
306 1 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
307 1 : int const port(rand() & 0xFFFF);
308 2 : addr::addr_parser p;
309 1 : p.set_protocol(proto);
310 1 : p.set_allow(addr::addr_parser::flag_t::MASK, true);
311 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"));
312 1 : REQUIRE(p.has_errors());
313 1 : REQUIRE(p.error_count() == 1);
314 1 : REQUIRE(p.error_messages() == "Incompatible address between the address and mask address (first was an IPv4 second an IPv6).\n");
315 1 : REQUIRE(ips.size() == 0);
316 : }
317 : }
318 :
319 30 : GIVEN("addr_parser() with invalid protocols")
320 : {
321 4 : SECTION("invalid names")
322 : {
323 2 : addr::addr_parser p;
324 :
325 : // not changing default protocol
326 : //
327 1 : REQUIRE(p.get_protocol() == -1);
328 1 : REQUIRE_THROWS_AS(p.set_protocol("igmp"), addr::addr_invalid_argument_exception);
329 1 : REQUIRE(p.get_protocol() == -1);
330 :
331 : // change protocol to another valid value first
332 : //
333 1 : p.set_protocol("tcp");
334 1 : REQUIRE_THROWS_AS(p.set_protocol("icmp"), addr::addr_invalid_argument_exception);
335 1 : REQUIRE(p.get_protocol() == IPPROTO_TCP);
336 : }
337 :
338 4 : SECTION("invalid numbers")
339 : {
340 101 : for(int idx(0); idx < 100; ++idx)
341 : {
342 : int protocol;
343 0 : do
344 : {
345 100 : protocol = rand();
346 : }
347 : while(protocol == IPPROTO_IP
348 100 : || protocol == IPPROTO_TCP
349 200 : || protocol == IPPROTO_UDP);
350 :
351 200 : addr::addr_parser p;
352 :
353 100 : REQUIRE_THROWS_AS(p.set_protocol(protocol), addr::addr_invalid_argument_exception);
354 100 : REQUIRE(p.get_protocol() == -1);
355 :
356 : // change protocol to another valid value first
357 : //
358 100 : p.set_protocol("tcp");
359 100 : REQUIRE_THROWS_AS(p.set_protocol(protocol), addr::addr_invalid_argument_exception);
360 100 : REQUIRE(p.get_protocol() == IPPROTO_TCP);
361 : }
362 : }
363 : }
364 15 : }
365 :
366 :
367 11 : TEST_CASE( "ipv4::addr", "ipv4" )
368 : {
369 18 : GIVEN("addr()")
370 : {
371 18 : addr::addr a;
372 :
373 18 : SECTION("not an IPv4")
374 : {
375 1 : REQUIRE_FALSE(a.is_ipv4());
376 :
377 : struct sockaddr_in in;
378 1 : REQUIRE_THROWS_AS(a.get_ipv4(in), addr::addr_invalid_state_exception);
379 1 : REQUIRE_THROWS_AS(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY), addr::addr_invalid_state_exception);
380 1 : REQUIRE_THROWS_AS(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_BRACKETS), addr::addr_invalid_state_exception);
381 1 : REQUIRE_THROWS_AS(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_PORT), addr::addr_invalid_state_exception);
382 1 : REQUIRE_THROWS_AS(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_MASK), addr::addr_invalid_state_exception);
383 1 : REQUIRE_THROWS_AS(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_BRACKETS_MASK), addr::addr_invalid_state_exception);
384 1 : REQUIRE_THROWS_AS(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ALL), addr::addr_invalid_state_exception);
385 : }
386 :
387 18 : SECTION("default network type (0.0.0.0)")
388 : {
389 1 : REQUIRE(a.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_ANY);
390 1 : REQUIRE(a.get_network_type_string() == "Any");
391 : }
392 :
393 18 : SECTION("IPv6 ANY")
394 : {
395 : struct sockaddr_in6 in6;
396 1 : a.get_ipv6(in6);
397 1 : REQUIRE(in6.sin6_addr.s6_addr32[0] == 0);
398 1 : REQUIRE(in6.sin6_addr.s6_addr32[1] == 0);
399 1 : REQUIRE(in6.sin6_addr.s6_addr32[2] == 0);
400 1 : REQUIRE(in6.sin6_addr.s6_addr32[3] == 0);
401 1 : REQUIRE(a.to_ipv6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "::");
402 1 : REQUIRE(a.to_ipv6_string(addr::addr::string_ip_t::STRING_IP_BRACKETS) == "[::]");
403 1 : REQUIRE(a.to_ipv6_string(addr::addr::string_ip_t::STRING_IP_PORT) == "[::]:0");
404 1 : REQUIRE(a.to_ipv6_string(addr::addr::string_ip_t::STRING_IP_MASK) == "::/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
405 1 : REQUIRE(a.to_ipv6_string(addr::addr::string_ip_t::STRING_IP_BRACKETS_MASK) == "[::]/[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]");
406 1 : REQUIRE(a.to_ipv6_string(addr::addr::string_ip_t::STRING_IP_ALL) == "[::]:0/[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]");
407 : }
408 :
409 18 : SECTION("IPv4 or IPv6 string")
410 : {
411 1 : REQUIRE(a.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "::");
412 1 : REQUIRE(a.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_BRACKETS) == "[::]");
413 1 : REQUIRE(a.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_PORT) == "[::]:0");
414 1 : REQUIRE(a.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_MASK) == "::/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
415 1 : REQUIRE(a.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_BRACKETS_MASK) == "[::]/[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]");
416 1 : REQUIRE(a.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ALL) == "[::]:0/[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]");
417 : }
418 :
419 18 : SECTION("interface determination")
420 : {
421 1 : REQUIRE(a.is_computer_interface_address() == addr::addr::computer_interface_address_t::COMPUTER_INTERFACE_ADDRESS_FALSE);
422 1 : REQUIRE(a.get_iface_name() == std::string());
423 : }
424 :
425 18 : SECTION("default name/service/port/protocol")
426 : {
427 1 : REQUIRE(a.get_name() == std::string());
428 1 : REQUIRE(a.get_service() == std::string());
429 1 : REQUIRE(a.get_port() == 0);
430 1 : REQUIRE(a.get_protocol() == IPPROTO_TCP);
431 : }
432 :
433 18 : SECTION("compare with self")
434 : {
435 1 : REQUIRE(a == a);
436 1 : REQUIRE_FALSE(a != a);
437 1 : REQUIRE_FALSE(a < a);
438 1 : REQUIRE(a <= a);
439 1 : REQUIRE_FALSE(a > a);
440 1 : REQUIRE(a >= a);
441 : }
442 :
443 18 : SECTION("compare with another 0.0.0.0")
444 : {
445 : {
446 2 : addr::addr b;
447 :
448 1 : REQUIRE(a == b);
449 1 : REQUIRE_FALSE(a != b);
450 1 : REQUIRE_FALSE(a < b);
451 1 : REQUIRE(a <= b);
452 1 : REQUIRE_FALSE(a > b);
453 1 : REQUIRE(a >= b);
454 : }
455 :
456 : {
457 1 : struct sockaddr_in6 in6 = sockaddr_in6();
458 1 : in6.sin6_family = AF_INET6;
459 1 : in6.sin6_port = htons(0);
460 1 : in6.sin6_addr.s6_addr32[0] = htonl(0);
461 1 : in6.sin6_addr.s6_addr32[1] = htonl(0);
462 1 : in6.sin6_addr.s6_addr32[2] = htonl(0);
463 1 : in6.sin6_addr.s6_addr32[3] = htonl(0);
464 2 : addr::addr b(in6);
465 :
466 1 : REQUIRE(a == b);
467 1 : REQUIRE_FALSE(a != b);
468 1 : REQUIRE_FALSE(a < b);
469 1 : REQUIRE(a <= b);
470 1 : REQUIRE_FALSE(a > b);
471 1 : REQUIRE(a >= b);
472 : }
473 :
474 : // ANY in IPv4 != ANY in IPv6...
475 : // (i.e. IPv4 sets addr.sin6_addr.s6_addr16[5] == 0xFFFF)
476 : {
477 1 : struct sockaddr_in in = sockaddr_in();
478 1 : in.sin_family = AF_INET;
479 1 : in.sin_port = htons(0);
480 1 : in.sin_addr.s_addr = htonl(0);
481 2 : addr::addr b(in);
482 :
483 1 : REQUIRE_FALSE(a == b);
484 1 : REQUIRE(a != b);
485 1 : REQUIRE(a < b);
486 1 : REQUIRE(a <= b);
487 1 : REQUIRE_FALSE(a > b);
488 1 : REQUIRE_FALSE(a >= b);
489 : }
490 : }
491 :
492 18 : SECTION("compare with IPv4 127.0.0.1")
493 : {
494 1 : struct sockaddr_in in = sockaddr_in();
495 1 : in.sin_family = AF_INET;
496 1 : in.sin_port = htons(80);
497 1 : in.sin_addr.s_addr = htonl((127 << 24) | 1);
498 2 : addr::addr b(in);
499 :
500 1 : REQUIRE_FALSE(a == b);
501 1 : REQUIRE(a != b);
502 1 : REQUIRE(a < b);
503 1 : REQUIRE(a <= b);
504 1 : REQUIRE_FALSE(a > b);
505 1 : REQUIRE_FALSE(a >= b);
506 : }
507 : }
508 9 : }
509 :
510 :
511 15 : TEST_CASE( "ipv4::address", "ipv4" )
512 : {
513 26 : GIVEN("addr() with an IPv4")
514 : {
515 6 : addr::addr a;
516 :
517 6 : SECTION("set_ipv4() / get_ipv4()")
518 : {
519 11 : for(int idx(0); idx < 10; ++idx)
520 : {
521 10 : struct sockaddr_in in = sockaddr_in();
522 10 : in.sin_family = AF_INET;
523 10 : in.sin_port = htons(rand());
524 10 : in.sin_addr.s_addr = htonl(rand() ^ (rand() << 16));
525 :
526 : // test constructor
527 : //
528 20 : addr::addr b(in);
529 : struct sockaddr_in out;
530 10 : b.get_ipv4(out);
531 10 : REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
532 :
533 : // test set
534 : //
535 10 : a.set_ipv4(in);
536 10 : a.get_ipv4(out);
537 10 : REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
538 : }
539 : }
540 :
541 6 : SECTION("set_ipv4() / to_ipv4_string()")
542 : {
543 11 : for(int idx(0); idx < 10; ++idx)
544 : {
545 10 : struct sockaddr_in in = sockaddr_in();
546 10 : in.sin_family = AF_INET;
547 10 : uint16_t const port(rand());
548 10 : in.sin_port = htons(port);
549 10 : uint32_t const address(rand() ^ (rand() << 16));
550 10 : in.sin_addr.s_addr = htonl(address);
551 :
552 : std::string ip(
553 20 : std::to_string((address >> 24) & 255)
554 20 : + "."
555 40 : + std::to_string((address >> 16) & 255)
556 20 : + "."
557 40 : + std::to_string((address >> 8) & 255)
558 20 : + "."
559 20 : + std::to_string((address >> 0) & 255)
560 30 : );
561 20 : std::string port_str(std::to_string(static_cast<int>(port)));
562 :
563 : // check IPv4 as a string
564 : //
565 10 : a.set_ipv4(in);
566 10 : REQUIRE(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == ip);
567 10 : REQUIRE(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_BRACKETS) == ip);
568 10 : REQUIRE(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_PORT) == ip + ":" + port_str);
569 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
570 10 : REQUIRE(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_BRACKETS_MASK) == ip + "/255.255.255.255");
571 10 : REQUIRE(a.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ALL) == ip + ":" + port_str + "/255.255.255.255");
572 : }
573 : }
574 :
575 6 : SECTION("name of various IPs")
576 : {
577 1 : struct sockaddr_in in = sockaddr_in();
578 1 : in.sin_family = AF_INET;
579 1 : in.sin_port = htons(rand());
580 1 : in.sin_addr.s_addr = 0;
581 :
582 : // verify network type
583 : //
584 1 : a.set_ipv4(in);
585 1 : REQUIRE(a.get_name() == std::string()); // no name for "any" (TCP)
586 :
587 1 : a.set_protocol(IPPROTO_UDP);
588 1 : REQUIRE(a.get_name() == std::string()); // no name for "any" (UDP)
589 :
590 1 : in.sin_addr.s_addr = htonl(0x7f000001);
591 1 : a.set_ipv4(in);
592 : char hostname[HOST_NAME_MAX + 1];
593 1 : hostname[HOST_NAME_MAX] = '\0';
594 1 : REQUIRE(gethostname(hostname, sizeof(hostname)) == 0);
595 1 : REQUIRE(hostname[0] != '\0');
596 1 : REQUIRE(a.get_name() == hostname);
597 1 : REQUIRE(a.is_computer_interface_address() == addr::addr::computer_interface_address_t::COMPUTER_INTERFACE_ADDRESS_TRUE);
598 : }
599 : }
600 :
601 26 : GIVEN("addr_parser() with IPv4 addresses")
602 : {
603 14 : SECTION("verify basics")
604 : {
605 2 : addr::addr_parser p;
606 1 : p.set_protocol(IPPROTO_TCP);
607 1 : REQUIRE(p.get_default_address4() == "");
608 1 : REQUIRE(p.get_default_address6() == "");
609 1 : REQUIRE(p.get_default_port() == -1);
610 1 : REQUIRE(p.get_default_mask4() == "");
611 1 : REQUIRE(p.get_default_mask6() == "");
612 2 : addr::addr_range::vector_t ips(p.parse("1.2.3.4"));
613 1 : REQUIRE_FALSE(p.has_errors());
614 1 : REQUIRE(ips.size() == 1);
615 1 : addr::addr_range const & r(ips[0]);
616 1 : REQUIRE(r.has_from());
617 1 : REQUIRE_FALSE(r.has_to());
618 1 : REQUIRE_FALSE(r.is_range());
619 1 : REQUIRE_FALSE(r.is_empty());
620 2 : addr::addr f(r.get_from());
621 1 : REQUIRE(f.is_ipv4());
622 1 : REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
623 1 : REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
624 1 : REQUIRE(f.get_port() == 0);
625 1 : REQUIRE(f.get_protocol() == IPPROTO_TCP);
626 1 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
627 1 : uint8_t mask[16] = {};
628 1 : f.get_mask(mask);
629 17 : for(int idx(0); idx < 16; ++idx)
630 : {
631 16 : REQUIRE(mask[idx] == 255);
632 : }
633 : }
634 :
635 14 : SECTION("verify default address")
636 : {
637 2 : addr::addr_parser p;
638 :
639 1 : p.set_default_address("1.5.19.200");
640 1 : REQUIRE(p.get_default_address4() == "1.5.19.200");
641 1 : REQUIRE(p.get_default_address6() == "");
642 1 : p.set_default_address("");
643 1 : REQUIRE(p.get_default_address4() == "");
644 1 : REQUIRE(p.get_default_address6() == "");
645 :
646 1 : p.set_default_address("1.5.19.200");
647 1 : REQUIRE(p.get_default_address4() == "1.5.19.200");
648 1 : REQUIRE(p.get_default_address6() == "");
649 1 : p.set_default_address("[4:5:4:5:7:8:7:8]");
650 1 : REQUIRE(p.get_default_address4() == "1.5.19.200");
651 1 : REQUIRE(p.get_default_address6() == "4:5:4:5:7:8:7:8");
652 1 : p.set_default_address("");
653 1 : REQUIRE(p.get_default_address4() == "");
654 1 : REQUIRE(p.get_default_address6() == "");
655 : }
656 :
657 14 : SECTION("verify default mask")
658 : {
659 2 : addr::addr_parser p;
660 :
661 1 : p.set_default_mask("1.5.19.200");
662 1 : REQUIRE(p.get_default_mask4() == "1.5.19.200");
663 1 : REQUIRE(p.get_default_mask6() == "");
664 1 : p.set_default_mask("");
665 1 : REQUIRE(p.get_default_mask4() == "");
666 1 : REQUIRE(p.get_default_mask6() == "");
667 :
668 1 : p.set_default_mask("1.5.19.200");
669 1 : REQUIRE(p.get_default_mask4() == "1.5.19.200");
670 1 : REQUIRE(p.get_default_mask6() == "");
671 1 : p.set_default_mask("[4:5:4:5:7:8:7:8]");
672 1 : REQUIRE(p.get_default_mask4() == "1.5.19.200");
673 1 : REQUIRE(p.get_default_mask6() == "4:5:4:5:7:8:7:8");
674 1 : p.set_default_mask("");
675 1 : REQUIRE(p.get_default_mask4() == "");
676 1 : REQUIRE(p.get_default_mask6() == "");
677 : }
678 :
679 14 : SECTION("verify default allow flags")
680 : {
681 2 : addr::addr_parser p;
682 :
683 13 : for(int idx(0); idx < static_cast<int>(addr::addr_parser::flag_t::FLAG_max); ++idx)
684 : {
685 12 : switch(static_cast<addr::addr_parser::flag_t>(idx))
686 : {
687 : case addr::addr_parser::flag_t::ADDRESS:
688 : case addr::addr_parser::flag_t::PORT:
689 : // only the ADDRESS and PORT are true by default
690 : //
691 2 : REQUIRE(p.get_allow(static_cast<addr::addr_parser::flag_t>(idx)));
692 2 : break;
693 :
694 : default:
695 10 : REQUIRE_FALSE(p.get_allow(static_cast<addr::addr_parser::flag_t>(idx)));
696 10 : break;
697 :
698 : }
699 : }
700 : }
701 :
702 14 : SECTION("verify contradictory flags")
703 : {
704 2 : addr::addr_parser p;
705 :
706 : // by default we start with false
707 : //
708 1 : REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS));
709 1 : REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS_AND_SPACES));
710 1 : REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_PORTS_COMMAS));
711 :
712 : // check setting MULTI_ADDRESSES_COMMAS to true
713 : //
714 1 : p.set_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS, true);
715 1 : REQUIRE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS));
716 1 : REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS_AND_SPACES));
717 1 : REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_PORTS_COMMAS));
718 :
719 : // add MULTI_ADDRESSES_COMMAS_AND_SPACES
720 : //
721 1 : p.set_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS_AND_SPACES, true);
722 1 : REQUIRE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS));
723 1 : REQUIRE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS_AND_SPACES));
724 1 : REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_PORTS_COMMAS));
725 :
726 : // add MULTI_PORTS_COMMAS
727 : //
728 1 : p.set_allow(addr::addr_parser::flag_t::MULTI_PORTS_COMMAS, true);
729 1 : REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS));
730 1 : REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS_AND_SPACES));
731 1 : REQUIRE(p.get_allow(addr::addr_parser::flag_t::MULTI_PORTS_COMMAS));
732 :
733 : // add MULTI_ADDRESSES_COMMAS_AND_SPACES only
734 : //
735 1 : p.set_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS_AND_SPACES, true);
736 1 : REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS));
737 1 : REQUIRE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS_AND_SPACES));
738 1 : REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_PORTS_COMMAS));
739 :
740 : // add MULTI_ADDRESSES_COMMAS second, order should not affect anything
741 : //
742 1 : p.set_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS, true);
743 1 : REQUIRE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS));
744 1 : REQUIRE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS_AND_SPACES));
745 1 : REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_PORTS_COMMAS));
746 :
747 : // back to MULTI_PORTS_COMMAS
748 : //
749 1 : p.set_allow(addr::addr_parser::flag_t::MULTI_PORTS_COMMAS, true);
750 1 : REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS));
751 1 : REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS_AND_SPACES));
752 1 : REQUIRE(p.get_allow(addr::addr_parser::flag_t::MULTI_PORTS_COMMAS));
753 :
754 : // add MULTI_ADDRESSES_COMMAS first now
755 : //
756 1 : p.set_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS, true);
757 1 : REQUIRE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS));
758 1 : REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS_AND_SPACES));
759 1 : REQUIRE_FALSE(p.get_allow(addr::addr_parser::flag_t::MULTI_PORTS_COMMAS));
760 : }
761 :
762 14 : SECTION("default address")
763 : {
764 2 : addr::addr_parser p;
765 1 : p.set_protocol(IPPROTO_TCP);
766 1 : p.set_default_address("5.5.5.5");
767 1 : REQUIRE(p.get_default_address4() == "5.5.5.5");
768 1 : REQUIRE(p.get_default_address6() == "");
769 2 : addr::addr_range::vector_t ips(p.parse(""));
770 1 : REQUIRE_FALSE(p.has_errors());
771 1 : REQUIRE(ips.size() == 1);
772 1 : addr::addr_range const & r(ips[0]);
773 1 : REQUIRE(r.has_from());
774 1 : REQUIRE_FALSE(r.has_to());
775 1 : REQUIRE_FALSE(r.is_range());
776 1 : REQUIRE_FALSE(r.is_empty());
777 2 : addr::addr f(r.get_from());
778 1 : REQUIRE(f.is_ipv4());
779 1 : REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "5.5.5.5");
780 1 : REQUIRE(f.get_port() == 0);
781 1 : REQUIRE(f.get_protocol() == IPPROTO_TCP);
782 1 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
783 : }
784 :
785 14 : SECTION("address, not port allowed")
786 : {
787 : // specific address with a default
788 : {
789 2 : addr::addr_parser p;
790 1 : p.set_allow(addr::addr_parser::flag_t::PORT, false);
791 1 : p.set_protocol(IPPROTO_TCP);
792 1 : p.set_default_address("5.5.5.5");
793 1 : REQUIRE(p.get_default_address4() == "5.5.5.5");
794 1 : REQUIRE(p.get_default_address6() == "");
795 2 : addr::addr_range::vector_t ips(p.parse("9.9.9.9"));
796 1 : REQUIRE_FALSE(p.has_errors());
797 1 : REQUIRE(ips.size() == 1);
798 1 : addr::addr_range const & r(ips[0]);
799 1 : REQUIRE(r.has_from());
800 1 : REQUIRE_FALSE(r.has_to());
801 1 : REQUIRE_FALSE(r.is_range());
802 1 : REQUIRE_FALSE(r.is_empty());
803 2 : addr::addr f(r.get_from());
804 1 : REQUIRE(f.is_ipv4());
805 1 : REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "9.9.9.9");
806 1 : REQUIRE(f.get_port() == 0);
807 1 : REQUIRE(f.get_protocol() == IPPROTO_TCP);
808 1 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
809 : }
810 :
811 : // only a default address
812 : {
813 2 : addr::addr_parser p;
814 1 : p.set_allow(addr::addr_parser::flag_t::PORT, false);
815 1 : p.set_protocol(IPPROTO_TCP);
816 1 : p.set_default_address("5.5.5.5");
817 1 : REQUIRE(p.get_default_address4() == "5.5.5.5");
818 1 : REQUIRE(p.get_default_address6() == "");
819 2 : addr::addr_range::vector_t ips(p.parse(""));
820 1 : REQUIRE_FALSE(p.has_errors());
821 1 : REQUIRE(ips.size() == 1);
822 1 : addr::addr_range const & r(ips[0]);
823 1 : REQUIRE(r.has_from());
824 1 : REQUIRE_FALSE(r.has_to());
825 1 : REQUIRE_FALSE(r.is_range());
826 1 : REQUIRE_FALSE(r.is_empty());
827 2 : addr::addr f(r.get_from());
828 1 : REQUIRE(f.is_ipv4());
829 1 : REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "5.5.5.5");
830 1 : REQUIRE(f.get_port() == 0);
831 1 : REQUIRE(f.get_protocol() == IPPROTO_TCP);
832 1 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
833 : }
834 : }
835 : }
836 :
837 26 : GIVEN("addr_parser() with multiple IPv4 addresses in one string")
838 : {
839 6 : SECTION("3 IPs separated by commas")
840 : {
841 2 : addr::addr_parser p;
842 1 : p.set_protocol(IPPROTO_TCP);
843 1 : p.set_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS, true);
844 2 : addr::addr_range::vector_t ips(p.parse("1.2.3.4:55,5.6.7.8,,,,10.11.12.99:77"));
845 1 : REQUIRE_FALSE(p.has_errors());
846 1 : REQUIRE(ips.size() == 3);
847 :
848 1 : uint8_t mask[16] = {};
849 :
850 : // 1.2.3.4:55
851 : {
852 1 : addr::addr_range const & r(ips[0]);
853 1 : REQUIRE(r.has_from());
854 1 : REQUIRE_FALSE(r.has_to());
855 1 : REQUIRE_FALSE(r.is_range());
856 1 : REQUIRE_FALSE(r.is_empty());
857 2 : addr::addr f(r.get_from());
858 1 : REQUIRE(f.is_ipv4());
859 1 : REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
860 1 : REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
861 1 : REQUIRE(f.get_port() == 55);
862 1 : REQUIRE(f.get_protocol() == IPPROTO_TCP);
863 1 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
864 1 : f.get_mask(mask);
865 17 : for(int idx(0); idx < 16; ++idx)
866 : {
867 16 : REQUIRE(mask[idx] == 255);
868 : }
869 : }
870 :
871 : // 5.6.7.8
872 : {
873 1 : addr::addr_range const & r(ips[1]);
874 1 : REQUIRE(r.has_from());
875 1 : REQUIRE_FALSE(r.has_to());
876 1 : REQUIRE_FALSE(r.is_range());
877 1 : REQUIRE_FALSE(r.is_empty());
878 2 : addr::addr f(r.get_from());
879 1 : REQUIRE(f.is_ipv4());
880 1 : REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "5.6.7.8");
881 1 : REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "5.6.7.8");
882 1 : REQUIRE(f.get_port() == 0);
883 1 : REQUIRE(f.get_protocol() == IPPROTO_TCP);
884 1 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
885 1 : f.get_mask(mask);
886 17 : for(int idx(0); idx < 16; ++idx)
887 : {
888 16 : REQUIRE(mask[idx] == 255);
889 : }
890 : }
891 :
892 : // 10.11.12.99:77
893 : {
894 1 : addr::addr_range const & r(ips[2]);
895 1 : REQUIRE(r.has_from());
896 1 : REQUIRE_FALSE(r.has_to());
897 1 : REQUIRE_FALSE(r.is_range());
898 1 : REQUIRE_FALSE(r.is_empty());
899 2 : addr::addr f(r.get_from());
900 1 : REQUIRE(f.is_ipv4());
901 1 : REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "10.11.12.99");
902 1 : REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "10.11.12.99");
903 1 : REQUIRE(f.get_port() == 77);
904 1 : REQUIRE(f.get_protocol() == IPPROTO_TCP);
905 1 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
906 1 : f.get_mask(mask);
907 17 : for(int idx(0); idx < 16; ++idx)
908 : {
909 16 : REQUIRE(mask[idx] == 255);
910 : }
911 : }
912 : }
913 :
914 6 : SECTION("3 IPs separated by spaces")
915 : {
916 2 : addr::addr_parser p;
917 1 : p.set_protocol(IPPROTO_TCP);
918 1 : p.set_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_SPACES, true);
919 2 : addr::addr_range::vector_t ips(p.parse("1.2.3.4:55 5.6.7.8 10.11.12.99:77"));
920 1 : REQUIRE_FALSE(p.has_errors());
921 1 : REQUIRE(ips.size() == 3);
922 :
923 1 : uint8_t mask[16] = {};
924 :
925 : // 1.2.3.4:55
926 : {
927 1 : addr::addr_range const & r(ips[0]);
928 1 : REQUIRE(r.has_from());
929 1 : REQUIRE_FALSE(r.has_to());
930 1 : REQUIRE_FALSE(r.is_range());
931 1 : REQUIRE_FALSE(r.is_empty());
932 2 : addr::addr f(r.get_from());
933 1 : REQUIRE(f.is_ipv4());
934 1 : REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
935 1 : REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
936 1 : REQUIRE(f.get_port() == 55);
937 1 : REQUIRE(f.get_protocol() == IPPROTO_TCP);
938 1 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
939 1 : f.get_mask(mask);
940 17 : for(int idx(0); idx < 16; ++idx)
941 : {
942 16 : REQUIRE(mask[idx] == 255);
943 : }
944 : }
945 :
946 : // 5.6.7.8
947 : {
948 1 : addr::addr_range const & r(ips[1]);
949 1 : REQUIRE(r.has_from());
950 1 : REQUIRE_FALSE(r.has_to());
951 1 : REQUIRE_FALSE(r.is_range());
952 1 : REQUIRE_FALSE(r.is_empty());
953 2 : addr::addr f(r.get_from());
954 1 : REQUIRE(f.is_ipv4());
955 1 : REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "5.6.7.8");
956 1 : REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "5.6.7.8");
957 1 : REQUIRE(f.get_port() == 0);
958 1 : REQUIRE(f.get_protocol() == IPPROTO_TCP);
959 1 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
960 1 : f.get_mask(mask);
961 17 : for(int idx(0); idx < 16; ++idx)
962 : {
963 16 : REQUIRE(mask[idx] == 255);
964 : }
965 : }
966 :
967 : // 10.11.12.99:77
968 : {
969 1 : addr::addr_range const & r(ips[2]);
970 1 : REQUIRE(r.has_from());
971 1 : REQUIRE_FALSE(r.has_to());
972 1 : REQUIRE_FALSE(r.is_range());
973 1 : REQUIRE_FALSE(r.is_empty());
974 2 : addr::addr f(r.get_from());
975 1 : REQUIRE(f.is_ipv4());
976 1 : REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "10.11.12.99");
977 1 : REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "10.11.12.99");
978 1 : REQUIRE(f.get_port() == 77);
979 1 : REQUIRE(f.get_protocol() == IPPROTO_TCP);
980 1 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
981 1 : f.get_mask(mask);
982 17 : for(int idx(0); idx < 16; ++idx)
983 : {
984 16 : REQUIRE(mask[idx] == 255);
985 : }
986 : }
987 : }
988 :
989 6 : SECTION("3 IPs separated by commas and/or spaces")
990 : {
991 2 : addr::addr_parser p;
992 1 : p.set_protocol(IPPROTO_TCP);
993 1 : p.set_allow(addr::addr_parser::flag_t::MULTI_ADDRESSES_COMMAS_AND_SPACES, true);
994 2 : addr::addr_range::vector_t ips(p.parse(" 1.2.3.4:55,, 5.6.7.8 , 10.11.12.99:77 "));
995 1 : REQUIRE_FALSE(p.has_errors());
996 1 : REQUIRE(ips.size() == 3);
997 :
998 1 : uint8_t mask[16] = {};
999 :
1000 : // 1.2.3.4:55
1001 : {
1002 1 : addr::addr_range const & r(ips[0]);
1003 1 : REQUIRE(r.has_from());
1004 1 : REQUIRE_FALSE(r.has_to());
1005 1 : REQUIRE_FALSE(r.is_range());
1006 1 : REQUIRE_FALSE(r.is_empty());
1007 2 : addr::addr f(r.get_from());
1008 1 : REQUIRE(f.is_ipv4());
1009 1 : REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
1010 1 : REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
1011 1 : REQUIRE(f.get_port() == 55);
1012 1 : REQUIRE(f.get_protocol() == IPPROTO_TCP);
1013 1 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
1014 1 : f.get_mask(mask);
1015 17 : for(int idx(0); idx < 16; ++idx)
1016 : {
1017 16 : REQUIRE(mask[idx] == 255);
1018 : }
1019 : }
1020 :
1021 : // 5.6.7.8
1022 : {
1023 1 : addr::addr_range const & r(ips[1]);
1024 1 : REQUIRE(r.has_from());
1025 1 : REQUIRE_FALSE(r.has_to());
1026 1 : REQUIRE_FALSE(r.is_range());
1027 1 : REQUIRE_FALSE(r.is_empty());
1028 2 : addr::addr f(r.get_from());
1029 1 : REQUIRE(f.is_ipv4());
1030 1 : REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "5.6.7.8");
1031 1 : REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "5.6.7.8");
1032 1 : REQUIRE(f.get_port() == 0);
1033 1 : REQUIRE(f.get_protocol() == IPPROTO_TCP);
1034 1 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
1035 1 : f.get_mask(mask);
1036 17 : for(int idx(0); idx < 16; ++idx)
1037 : {
1038 16 : REQUIRE(mask[idx] == 255);
1039 : }
1040 : }
1041 :
1042 : // 10.11.12.99:77
1043 : {
1044 1 : addr::addr_range const & r(ips[2]);
1045 1 : REQUIRE(r.has_from());
1046 1 : REQUIRE_FALSE(r.has_to());
1047 1 : REQUIRE_FALSE(r.is_range());
1048 1 : REQUIRE_FALSE(r.is_empty());
1049 2 : addr::addr f(r.get_from());
1050 1 : REQUIRE(f.is_ipv4());
1051 1 : REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "10.11.12.99");
1052 1 : REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "10.11.12.99");
1053 1 : REQUIRE(f.get_port() == 77);
1054 1 : REQUIRE(f.get_protocol() == IPPROTO_TCP);
1055 1 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1056 1 : f.get_mask(mask);
1057 17 : for(int idx(0); idx < 16; ++idx)
1058 : {
1059 16 : REQUIRE(mask[idx] == 255);
1060 : }
1061 : }
1062 : }
1063 : }
1064 13 : }
1065 :
1066 :
1067 5 : TEST_CASE( "ipv4::ports", "ipv4" )
1068 : {
1069 6 : GIVEN("addr_parser() with IPv4 addresses and port")
1070 : {
1071 6 : SECTION("verify port")
1072 : {
1073 65537 : for(int port(0); port < 65536; ++port)
1074 : {
1075 65536 : int proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1076 131072 : addr::addr_parser p;
1077 65536 : p.set_protocol(proto);
1078 131072 : addr::addr_range::vector_t ips(p.parse("192.168.12.199:" + std::to_string(port)));
1079 65536 : REQUIRE_FALSE(p.has_errors());
1080 65536 : REQUIRE(ips.size() == 1);
1081 65536 : addr::addr_range const & r(ips[0]);
1082 131072 : addr::addr f(r.get_from());
1083 65536 : REQUIRE(f.is_ipv4());
1084 65536 : REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "192.168.12.199");
1085 65536 : REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "192.168.12.199");
1086 65536 : REQUIRE(f.get_port() == port);
1087 65536 : REQUIRE(f.get_protocol() == proto);
1088 65536 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1089 : }
1090 : }
1091 :
1092 6 : SECTION("default address with various port")
1093 : {
1094 101 : for(int idx(0); idx < 100; ++idx)
1095 : {
1096 100 : uint16_t const port(rand());
1097 200 : addr::addr_parser p;
1098 100 : p.set_protocol(IPPROTO_TCP);
1099 100 : p.set_default_address("5.5.5.5");
1100 100 : REQUIRE(p.get_default_address4() == "5.5.5.5");
1101 100 : REQUIRE(p.get_default_address6() == "");
1102 200 : addr::addr_range::vector_t ips(p.parse(":" + std::to_string(static_cast<int>(port))));
1103 100 : REQUIRE_FALSE(p.has_errors());
1104 100 : REQUIRE(ips.size() == 1);
1105 100 : addr::addr_range const & r(ips[0]);
1106 100 : REQUIRE(r.has_from());
1107 100 : REQUIRE_FALSE(r.has_to());
1108 100 : REQUIRE_FALSE(r.is_range());
1109 100 : REQUIRE_FALSE(r.is_empty());
1110 200 : addr::addr f(r.get_from());
1111 100 : REQUIRE(f.is_ipv4());
1112 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)));
1113 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)));
1114 100 : REQUIRE(f.get_port() == port);
1115 100 : REQUIRE(f.get_protocol() == IPPROTO_TCP);
1116 100 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
1117 : }
1118 : }
1119 :
1120 6 : SECTION("address with default port")
1121 : {
1122 26 : for(int idx(0); idx < 25; ++idx)
1123 : {
1124 25 : uint16_t const port(rand());
1125 50 : addr::addr_parser p;
1126 25 : p.set_protocol(IPPROTO_TCP);
1127 25 : p.set_default_port(port);
1128 25 : REQUIRE(p.get_default_port() == port);
1129 50 : addr::addr_range::vector_t ips(p.parse("5.5.5.5"));
1130 25 : REQUIRE_FALSE(p.has_errors());
1131 25 : REQUIRE(ips.size() == 1);
1132 25 : addr::addr_range const & r(ips[0]);
1133 25 : REQUIRE(r.has_from());
1134 25 : REQUIRE_FALSE(r.has_to());
1135 25 : REQUIRE_FALSE(r.is_range());
1136 25 : REQUIRE_FALSE(r.is_empty());
1137 50 : addr::addr f(r.get_from());
1138 25 : REQUIRE(f.is_ipv4());
1139 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)));
1140 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)));
1141 25 : REQUIRE(f.get_port() == port);
1142 25 : REQUIRE(f.get_protocol() == IPPROTO_TCP);
1143 25 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
1144 : }
1145 :
1146 26 : for(int idx(0); idx < 25; ++idx)
1147 : {
1148 25 : uint16_t const port(rand());
1149 50 : addr::addr_parser p;
1150 25 : p.set_protocol(IPPROTO_TCP);
1151 25 : p.set_default_port(port);
1152 25 : REQUIRE(p.get_default_port() == port);
1153 50 : addr::addr_range::vector_t ips(p.parse("5.5.5.5:"));
1154 25 : REQUIRE_FALSE(p.has_errors());
1155 25 : REQUIRE(ips.size() == 1);
1156 25 : addr::addr_range const & r(ips[0]);
1157 25 : REQUIRE(r.has_from());
1158 25 : REQUIRE_FALSE(r.has_to());
1159 25 : REQUIRE_FALSE(r.is_range());
1160 25 : REQUIRE_FALSE(r.is_empty());
1161 50 : addr::addr f(r.get_from());
1162 25 : REQUIRE(f.is_ipv4());
1163 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)));
1164 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)));
1165 25 : REQUIRE(f.get_port() == port);
1166 25 : REQUIRE(f.get_protocol() == IPPROTO_TCP);
1167 25 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PUBLIC);
1168 : }
1169 : }
1170 : }
1171 3 : }
1172 :
1173 :
1174 9 : TEST_CASE( "ipv4::masks", "ipv4" )
1175 : {
1176 14 : GIVEN("addr_parser() of address:port/mask")
1177 : {
1178 14 : SECTION("mask allowed, but no mask")
1179 : {
1180 1 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1181 1 : int const port(rand() & 0xFFFF);
1182 2 : addr::addr_parser p;
1183 1 : p.set_protocol(proto);
1184 1 : p.set_allow(addr::addr_parser::flag_t::MASK, true);
1185 2 : addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port)));
1186 1 : REQUIRE_FALSE(p.has_errors());
1187 1 : REQUIRE(ips.size() == 1);
1188 1 : addr::addr_range const & r(ips[0]);
1189 2 : addr::addr f(r.get_from());
1190 1 : REQUIRE(f.is_ipv4());
1191 2 : std::string result("172.19.6.91:" + std::to_string(port) + "/255.255.255.255");
1192 1 : REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1193 1 : REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1194 1 : REQUIRE(f.get_port() == port);
1195 1 : REQUIRE(f.get_protocol() == proto);
1196 1 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1197 : }
1198 :
1199 14 : SECTION("empty mask")
1200 : {
1201 1 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1202 1 : int const port(rand() & 0xFFFF);
1203 2 : addr::addr_parser p;
1204 1 : p.set_protocol(proto);
1205 1 : p.set_allow(addr::addr_parser::flag_t::MASK, true);
1206 2 : addr::addr_range::vector_t ips(p.parse("172.18.5.91:" + std::to_string(port) + "/"));
1207 1 : REQUIRE_FALSE(p.has_errors());
1208 1 : REQUIRE(ips.size() == 1);
1209 1 : addr::addr_range const & r(ips[0]);
1210 2 : addr::addr f(r.get_from());
1211 1 : REQUIRE(f.is_ipv4());
1212 2 : std::string result("172.18.5.91:" + std::to_string(port) + "/255.255.255.255");
1213 1 : REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1214 1 : REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1215 1 : REQUIRE(f.get_port() == port);
1216 1 : REQUIRE(f.get_protocol() == proto);
1217 1 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1218 : }
1219 :
1220 14 : SECTION("one number masks")
1221 : {
1222 34 : for(int idx(0); idx <= 32; ++idx)
1223 : {
1224 33 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1225 33 : int const port(rand() & 0xFFFF);
1226 66 : addr::addr_parser p;
1227 33 : p.set_protocol(proto);
1228 33 : p.set_allow(addr::addr_parser::flag_t::MASK, true);
1229 66 : addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port) + "/" + std::to_string(idx)));
1230 33 : REQUIRE_FALSE(p.has_errors());
1231 33 : REQUIRE(ips.size() == 1);
1232 33 : addr::addr_range const & r(ips[0]);
1233 66 : addr::addr f(r.get_from());
1234 33 : REQUIRE(f.is_ipv4());
1235 33 : uint64_t const mask(-1LL << (32 - idx));
1236 : std::string mask_str(
1237 66 : std::to_string((mask >> 24) & 255)
1238 66 : + "."
1239 132 : + std::to_string((mask >> 16) & 255)
1240 66 : + "."
1241 132 : + std::to_string((mask >> 8) & 255)
1242 66 : + "."
1243 132 : + std::to_string((mask >> 0) & 255));
1244 66 : std::string result("172.17.3.91:" + std::to_string(port) + "/" + mask_str);
1245 33 : REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1246 33 : REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1247 33 : REQUIRE(f.get_port() == port);
1248 33 : REQUIRE(f.get_protocol() == proto);
1249 33 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1250 : }
1251 : }
1252 :
1253 14 : SECTION("address like mask")
1254 : {
1255 26 : for(int idx(0); idx < 25; ++idx)
1256 : {
1257 25 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1258 25 : int const port(rand() & 0xFFFF);
1259 50 : addr::addr_parser p;
1260 25 : p.set_protocol(proto);
1261 25 : p.set_allow(addr::addr_parser::flag_t::MASK, true);
1262 : // when specified as an IP, the mask can be absolutely anything
1263 : uint8_t mask[4];
1264 125 : for(int j(0); j < 4; ++j)
1265 : {
1266 100 : mask[j] = rand();
1267 : }
1268 : std::string const mask_str(
1269 50 : std::to_string(static_cast<int>(mask[0]))
1270 50 : + "."
1271 100 : + std::to_string(static_cast<int>(mask[1]))
1272 50 : + "."
1273 100 : + std::to_string(static_cast<int>(mask[2]))
1274 50 : + "."
1275 100 : + std::to_string(static_cast<int>(mask[3])));
1276 50 : addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port) + "/" + mask_str));
1277 25 : REQUIRE_FALSE(p.has_errors());
1278 25 : REQUIRE(ips.size() == 1);
1279 25 : addr::addr_range const & r(ips[0]);
1280 50 : addr::addr f(r.get_from());
1281 25 : REQUIRE(f.is_ipv4());
1282 50 : std::string result("172.17.3.91:" + std::to_string(port) + "/" + mask_str);
1283 25 : REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1284 25 : REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1285 25 : REQUIRE(f.get_port() == port);
1286 25 : REQUIRE(f.get_protocol() == proto);
1287 25 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1288 : }
1289 : }
1290 :
1291 14 : SECTION("address like default mask")
1292 : {
1293 26 : for(int idx(0); idx < 25; ++idx)
1294 : {
1295 25 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1296 25 : int const port(rand() & 0xFFFF);
1297 50 : addr::addr_parser p;
1298 25 : p.set_protocol(proto);
1299 25 : p.set_allow(addr::addr_parser::flag_t::MASK, true);
1300 : // when specified as an IP, the mask can be absolutely anything
1301 : // (here the mask is a string an it will be parsed by the
1302 : // parser if required)
1303 : //
1304 : uint8_t mask[4];
1305 125 : for(int j(0); j < 4; ++j)
1306 : {
1307 100 : mask[j] = rand();
1308 : }
1309 : std::string const mask_str(
1310 50 : std::to_string(static_cast<int>(mask[0]))
1311 50 : + "."
1312 100 : + std::to_string(static_cast<int>(mask[1]))
1313 50 : + "."
1314 100 : + std::to_string(static_cast<int>(mask[2]))
1315 50 : + "."
1316 100 : + std::to_string(static_cast<int>(mask[3])));
1317 25 : p.set_default_mask(mask_str);
1318 50 : addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port)));
1319 25 : REQUIRE_FALSE(p.has_errors());
1320 25 : REQUIRE(ips.size() == 1);
1321 25 : addr::addr_range const & r(ips[0]);
1322 50 : addr::addr f(r.get_from());
1323 25 : REQUIRE(f.is_ipv4());
1324 50 : std::string result("172.17.3.91:" + std::to_string(port) + "/" + mask_str);
1325 25 : REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1326 25 : REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1327 25 : REQUIRE(f.get_port() == port);
1328 25 : REQUIRE(f.get_protocol() == proto);
1329 25 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1330 : uint8_t verify_mask[16];
1331 25 : f.get_mask(verify_mask);
1332 325 : for(int j(0); j < 16 - 4; ++j)
1333 : {
1334 300 : REQUIRE(verify_mask[j] == 255);
1335 : }
1336 125 : for(int j(12); j < 16; ++j)
1337 : {
1338 100 : REQUIRE(verify_mask[j] == mask[j - 12]);
1339 : }
1340 : }
1341 : }
1342 :
1343 14 : SECTION("address like mask with a default")
1344 : {
1345 26 : for(int idx(0); idx < 25; ++idx)
1346 : {
1347 25 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1348 25 : int const port(rand() & 0xFFFF);
1349 50 : addr::addr_parser p;
1350 25 : p.set_protocol(proto);
1351 25 : p.set_allow(addr::addr_parser::flag_t::MASK, true);
1352 :
1353 : // here we want a default and an IP with a specific mask
1354 : // to make sure that the specific mask has priority
1355 : //
1356 : uint8_t mask[4];
1357 125 : for(int j(0); j < 4; ++j)
1358 : {
1359 100 : mask[j] = rand();
1360 : }
1361 : std::string const mask_str(
1362 50 : std::to_string(static_cast<int>(mask[0]))
1363 50 : + "."
1364 100 : + std::to_string(static_cast<int>(mask[1]))
1365 50 : + "."
1366 100 : + std::to_string(static_cast<int>(mask[2]))
1367 50 : + "."
1368 100 : + std::to_string(static_cast<int>(mask[3])));
1369 :
1370 : uint8_t default_mask[4];
1371 125 : for(int j(0); j < 4; ++j)
1372 : {
1373 100 : default_mask[j] = rand();
1374 : }
1375 : std::string const default_mask_str(
1376 50 : std::to_string(static_cast<int>(default_mask[0]))
1377 50 : + "."
1378 100 : + std::to_string(static_cast<int>(default_mask[1]))
1379 50 : + "."
1380 100 : + std::to_string(static_cast<int>(default_mask[2]))
1381 50 : + "."
1382 100 : + std::to_string(static_cast<int>(default_mask[3])));
1383 25 : p.set_default_mask(default_mask_str);
1384 :
1385 50 : addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port) + "/" + mask_str));
1386 25 : REQUIRE_FALSE(p.has_errors());
1387 25 : REQUIRE(ips.size() == 1);
1388 25 : addr::addr_range const & r(ips[0]);
1389 50 : addr::addr f(r.get_from());
1390 25 : REQUIRE(f.is_ipv4());
1391 50 : std::string result("172.17.3.91:" + std::to_string(port) + "/" + mask_str);
1392 25 : REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1393 25 : REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ALL) == result);
1394 25 : REQUIRE(f.get_port() == port);
1395 25 : REQUIRE(f.get_protocol() == proto);
1396 25 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1397 : uint8_t verify_mask[16];
1398 25 : f.get_mask(verify_mask);
1399 325 : for(int j(0); j < 16 - 4; ++j)
1400 : {
1401 300 : REQUIRE(verify_mask[j] == 255);
1402 : }
1403 125 : for(int j(12); j < 16; ++j)
1404 : {
1405 100 : REQUIRE(verify_mask[j] == mask[j - 12]);
1406 : }
1407 : }
1408 : }
1409 :
1410 14 : SECTION("two addresses and a mask for a match / no match")
1411 : {
1412 1 : int const port1(rand() & 0xFFFF);
1413 2 : addr::addr_parser p;
1414 1 : p.set_allow(addr::addr_parser::flag_t::MASK, true);
1415 :
1416 : // parse the IP with a mask
1417 : //
1418 1 : int proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1419 1 : p.set_protocol(proto);
1420 2 : addr::addr_range::vector_t ips1(p.parse("192.168.0.0:" + std::to_string(port1) + "/16"));
1421 1 : REQUIRE_FALSE(p.has_errors());
1422 1 : REQUIRE(ips1.size() == 1);
1423 1 : addr::addr_range const & r1(ips1[0]);
1424 2 : addr::addr f1(r1.get_from());
1425 1 : REQUIRE(f1.is_ipv4());
1426 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");
1427 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");
1428 1 : REQUIRE(f1.get_port() == port1);
1429 1 : REQUIRE(f1.get_protocol() == proto);
1430 1 : REQUIRE(f1.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1431 :
1432 : // reuse parser
1433 : //
1434 1 : proto = rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP;
1435 1 : p.set_protocol(proto);
1436 1 : int const port2(rand() & 0xFFFF);
1437 2 : addr::addr_range::vector_t ips2(p.parse("192.168.5.36:" + std::to_string(port2)));
1438 1 : REQUIRE_FALSE(p.has_errors());
1439 1 : REQUIRE(ips2.size() == 1);
1440 1 : addr::addr_range const & r2(ips2[0]);
1441 2 : addr::addr f2(r2.get_from());
1442 1 : REQUIRE(f2.is_ipv4());
1443 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");
1444 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");
1445 1 : REQUIRE(f2.get_port() == port2);
1446 1 : REQUIRE(f2.get_protocol() == proto);
1447 1 : REQUIRE(f2.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1448 :
1449 : // 3rd with a mask along the full IP
1450 : //
1451 1 : proto = rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP;
1452 1 : p.set_protocol(proto);
1453 1 : int const port3(rand() & 0xFFFF);
1454 2 : addr::addr_range::vector_t ips3(p.parse("192.168.5.36:" + std::to_string(port3) + "/16"));
1455 1 : REQUIRE_FALSE(p.has_errors());
1456 1 : REQUIRE(ips3.size() == 1);
1457 1 : addr::addr_range const & r3(ips3[0]);
1458 2 : addr::addr f3(r3.get_from());
1459 1 : REQUIRE(f3.is_ipv4());
1460 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");
1461 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");
1462 1 : REQUIRE(f3.get_port() == port3);
1463 1 : REQUIRE(f3.get_protocol() == proto);
1464 1 : REQUIRE(f3.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1465 :
1466 : // just a side test
1467 : //
1468 1 : REQUIRE(f1 != f2);
1469 1 : REQUIRE(f1 != f3);
1470 1 : REQUIRE(f2 == f3);
1471 :
1472 : // check whether p1 matches p2 and vice versa
1473 : //
1474 1 : REQUIRE(f1.match(f2)); // f2 & mask1 == f1
1475 1 : REQUIRE(f1.match(f3)); // f3 & mask1 == f1
1476 :
1477 1 : REQUIRE_FALSE(f2.match(f1)); // f1 & mask2 != f2
1478 1 : REQUIRE(f2.match(f3)); // f3 & mask2 == f2 (because f2 == f3 anyway)
1479 :
1480 1 : REQUIRE(f3.match(f1)); // f1 & mask3 == f3
1481 1 : REQUIRE(f3.match(f2)); // f2 & mask3 == f3
1482 :
1483 1 : f3.apply_mask();
1484 :
1485 1 : REQUIRE(f1 != f2);
1486 1 : REQUIRE(f1 == f3);
1487 1 : REQUIRE(f2 != f3);
1488 :
1489 : // re-run the match() calls with f3 since it changed...
1490 : //
1491 1 : REQUIRE(f1.match(f3)); // f3 & mask1 == f1
1492 :
1493 1 : REQUIRE_FALSE(f2.match(f3)); // f3 & mask2 == f2 (because f2 != f3 anymore)
1494 :
1495 1 : REQUIRE(f3.match(f1)); // f1 & mask3 == f3
1496 1 : REQUIRE(f3.match(f2)); // f2 & mask3 == f3
1497 : }
1498 : }
1499 7 : }
1500 :
1501 :
1502 8 : TEST_CASE( "ipv4::protocol", "ipv4" )
1503 : {
1504 12 : GIVEN("addr()")
1505 : {
1506 4 : addr::addr a;
1507 :
1508 4 : SECTION("default protocol")
1509 : {
1510 1 : REQUIRE(a.get_protocol() == IPPROTO_TCP);
1511 : }
1512 :
1513 4 : SECTION("set_protocol()")
1514 : {
1515 : // setup a random protocol
1516 : //
1517 1 : int const start_protocol([]()
1518 : {
1519 1 : switch(rand() % 3)
1520 : {
1521 : case 0:
1522 0 : return IPPROTO_IP;
1523 :
1524 : case 1:
1525 0 : return IPPROTO_TCP;
1526 :
1527 : //case 2:
1528 : default:
1529 1 : return IPPROTO_UDP;
1530 :
1531 : }
1532 1 : }());
1533 1 : a.set_protocol(start_protocol);
1534 :
1535 : // test 100 invalid protocols
1536 : //
1537 101 : for(int idx(0); idx < 100; ++idx)
1538 : {
1539 : int invalid_protocol;
1540 0 : do
1541 : {
1542 100 : invalid_protocol = rand();
1543 : }
1544 : while(invalid_protocol == IPPROTO_IP
1545 100 : || invalid_protocol == IPPROTO_TCP
1546 200 : || invalid_protocol == IPPROTO_UDP);
1547 100 : REQUIRE_THROWS_AS(a.set_protocol(invalid_protocol), addr::addr_invalid_argument_exception);
1548 :
1549 : // make sure the protocol does not change on errors
1550 100 : REQUIRE(a.get_protocol() == start_protocol);
1551 : }
1552 :
1553 : // null string is not allowed
1554 : //
1555 1 : REQUIRE_THROWS_AS(a.set_protocol(nullptr), addr::addr_invalid_argument_exception);
1556 :
1557 : // other "invalid" (unsupported, really) string protocols
1558 : //
1559 1 : REQUIRE_THROWS_AS(a.set_protocol("icmp"), addr::addr_invalid_argument_exception);
1560 1 : REQUIRE_THROWS_AS(a.set_protocol("raw"), addr::addr_invalid_argument_exception);
1561 1 : REQUIRE_THROWS_AS(a.set_protocol("hmp"), addr::addr_invalid_argument_exception);
1562 :
1563 : // test all valid protocols (numeric)
1564 : //
1565 1 : a.set_protocol(IPPROTO_IP);
1566 1 : REQUIRE(a.get_protocol() == IPPROTO_IP);
1567 1 : a.set_protocol(IPPROTO_TCP);
1568 1 : REQUIRE(a.get_protocol() == IPPROTO_TCP);
1569 1 : a.set_protocol(IPPROTO_UDP);
1570 1 : REQUIRE(a.get_protocol() == IPPROTO_UDP);
1571 :
1572 : // test all valid protocols (ascii)
1573 : //
1574 1 : a.set_protocol("ip");
1575 1 : REQUIRE(a.get_protocol() == IPPROTO_IP);
1576 1 : a.set_protocol("tcp");
1577 1 : REQUIRE(a.get_protocol() == IPPROTO_TCP);
1578 1 : a.set_protocol("udp");
1579 1 : REQUIRE(a.get_protocol() == IPPROTO_UDP);
1580 : }
1581 : }
1582 :
1583 12 : GIVEN("addr_parser()")
1584 : {
1585 6 : addr::addr_parser p;
1586 :
1587 6 : SECTION("verify default")
1588 : {
1589 1 : REQUIRE(p.get_protocol() == -1);
1590 : }
1591 :
1592 6 : SECTION("test 3 allowed protocols")
1593 : {
1594 : // by string
1595 : //
1596 1 : p.set_protocol("ip");
1597 1 : REQUIRE(p.get_protocol() == IPPROTO_IP);
1598 1 : p.set_protocol("tcp");
1599 1 : REQUIRE(p.get_protocol() == IPPROTO_TCP);
1600 1 : p.set_protocol("udp");
1601 1 : REQUIRE(p.get_protocol() == IPPROTO_UDP);
1602 :
1603 : // numerically
1604 : //
1605 1 : p.set_protocol(IPPROTO_IP);
1606 1 : REQUIRE(p.get_protocol() == IPPROTO_IP);
1607 1 : p.set_protocol(IPPROTO_TCP);
1608 1 : REQUIRE(p.get_protocol() == IPPROTO_TCP);
1609 1 : p.set_protocol(IPPROTO_UDP);
1610 1 : REQUIRE(p.get_protocol() == IPPROTO_UDP);
1611 : }
1612 :
1613 6 : SECTION("verify clearing works")
1614 : {
1615 1 : p.set_protocol("ip");
1616 1 : REQUIRE(p.get_protocol() == IPPROTO_IP);
1617 1 : p.clear_protocol();
1618 1 : REQUIRE(p.get_protocol() == -1);
1619 :
1620 1 : p.set_protocol("tcp");
1621 1 : REQUIRE(p.get_protocol() == IPPROTO_TCP);
1622 1 : p.clear_protocol();
1623 1 : REQUIRE(p.get_protocol() == -1);
1624 :
1625 1 : p.set_protocol("udp");
1626 1 : REQUIRE(p.get_protocol() == IPPROTO_UDP);
1627 1 : p.clear_protocol();
1628 1 : REQUIRE(p.get_protocol() == -1);
1629 : }
1630 : }
1631 :
1632 12 : GIVEN("addr_parser with any protocol")
1633 : {
1634 2 : addr::addr a;
1635 :
1636 2 : SECTION("get address with all protocols")
1637 : {
1638 2 : addr::addr_parser p;
1639 : //p.set_protocol(...); -- by default we'll get all the protocols supported
1640 2 : addr::addr_range::vector_t ips(p.parse("127.0.0.1"));
1641 1 : REQUIRE_FALSE(p.has_errors());
1642 1 : REQUIRE(!ips.empty());
1643 4 : for(size_t idx(0); idx < ips.size(); ++idx)
1644 : {
1645 3 : addr::addr_range const & r(ips[idx]);
1646 3 : REQUIRE(r.has_from());
1647 3 : REQUIRE_FALSE(r.has_to());
1648 3 : REQUIRE_FALSE(r.is_range());
1649 3 : REQUIRE_FALSE(r.is_empty());
1650 6 : addr::addr f(r.get_from());
1651 3 : if(f.is_ipv4())
1652 : {
1653 3 : REQUIRE(f.to_ipv4_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "127.0.0.1");
1654 3 : REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "127.0.0.1");
1655 3 : REQUIRE(f.get_port() == 0);
1656 : //REQUIRE(f.get_protocol() == ...); -- may be TCP, UDP, IP
1657 3 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_LOOPBACK);
1658 : }
1659 : else
1660 : {
1661 0 : REQUIRE(f.to_ipv6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "::1");
1662 0 : REQUIRE(f.to_ipv4or6_string(addr::addr::string_ip_t::STRING_IP_ONLY) == "::1");
1663 0 : REQUIRE(f.get_port() == 0);
1664 : //REQUIRE(f.get_protocol() == ...); -- may be TCP, UDP, IP
1665 0 : REQUIRE(f.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_LOOPBACK);
1666 : }
1667 : }
1668 : }
1669 : }
1670 6 : }
1671 :
1672 :
1673 10 : TEST_CASE( "ipv4::network_type", "ipv4" )
1674 : {
1675 16 : GIVEN("addr()")
1676 : {
1677 16 : addr::addr a;
1678 :
1679 16 : SECTION("any (0.0.0.0)")
1680 : {
1681 1 : struct sockaddr_in in = sockaddr_in();
1682 1 : in.sin_family = AF_INET;
1683 1 : in.sin_port = htons(rand());
1684 1 : in.sin_addr.s_addr = 0;
1685 :
1686 : // verify network type
1687 : //
1688 1 : a.set_ipv4(in);
1689 :
1690 1 : REQUIRE(a.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_ANY);
1691 1 : REQUIRE(a.get_network_type_string() == "Any");
1692 : }
1693 :
1694 16 : SECTION("private address 10.x.x.x/8")
1695 : {
1696 11 : for(int idx(0); idx < 10; ++idx)
1697 : {
1698 10 : struct sockaddr_in in = sockaddr_in();
1699 10 : in.sin_family = AF_INET;
1700 10 : in.sin_port = htons(rand());
1701 : uint32_t address((10 << 24)
1702 10 : | ((rand() & 255) << 16)
1703 10 : | ((rand() & 255) << 8)
1704 10 : | ((rand() & 255) << 0));
1705 10 : in.sin_addr.s_addr = htonl(address);
1706 :
1707 : // verify network type
1708 : //
1709 10 : a.set_ipv4(in);
1710 10 : REQUIRE(a.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1711 10 : REQUIRE(a.get_network_type_string() == "Private");
1712 : }
1713 : }
1714 :
1715 16 : SECTION("private address 172.16.x.x/12")
1716 : {
1717 11 : for(int idx(0); idx < 10; ++idx)
1718 : {
1719 10 : struct sockaddr_in in = sockaddr_in();
1720 10 : in.sin_family = AF_INET;
1721 10 : in.sin_port = htons(rand());
1722 : uint32_t address((172 << 24)
1723 10 : | (((rand() & 15) | 16) << 16)
1724 10 : | ((rand() & 255) << 8)
1725 10 : | ((rand() & 255) << 0));
1726 10 : in.sin_addr.s_addr = htonl(address);
1727 :
1728 : // verify network type
1729 : //
1730 10 : a.set_ipv4(in);
1731 10 : REQUIRE(a.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1732 10 : REQUIRE(a.get_network_type_string() == "Private");
1733 : }
1734 : }
1735 :
1736 16 : SECTION("private address 192.168.x.x/16")
1737 : {
1738 11 : for(int idx(0); idx < 10; ++idx)
1739 : {
1740 10 : struct sockaddr_in in = sockaddr_in();
1741 10 : in.sin_family = AF_INET;
1742 10 : in.sin_port = htons(rand());
1743 : uint32_t address((192 << 24)
1744 : | (168 << 16)
1745 10 : | ((rand() & 255) << 8)
1746 10 : | ((rand() & 255) << 0));
1747 10 : in.sin_addr.s_addr = htonl(address);
1748 :
1749 : // verify network type
1750 : //
1751 10 : a.set_ipv4(in);
1752 10 : REQUIRE(a.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_PRIVATE);
1753 10 : REQUIRE(a.get_network_type_string() == "Private");
1754 : }
1755 : }
1756 :
1757 16 : SECTION("private address 100.66.x.x/10")
1758 : {
1759 11 : for(int idx(0); idx < 10; ++idx)
1760 : {
1761 10 : struct sockaddr_in in = sockaddr_in();
1762 10 : in.sin_family = AF_INET;
1763 10 : in.sin_port = htons(rand());
1764 : uint32_t address((100 << 24)
1765 10 : | (((rand() & 63) | 64) << 16)
1766 10 : | ((rand() & 255) << 8)
1767 10 : | ((rand() & 255) << 0));
1768 10 : in.sin_addr.s_addr = htonl(address);
1769 :
1770 : // verify network type
1771 : //
1772 10 : a.set_ipv4(in);
1773 10 : REQUIRE(a.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_CARRIER);
1774 10 : REQUIRE(a.get_network_type_string() == "Carrier");
1775 : }
1776 : }
1777 :
1778 16 : SECTION("private address 169.254.x.x/16")
1779 : {
1780 11 : for(int idx(0); idx < 10; ++idx)
1781 : {
1782 10 : struct sockaddr_in in = sockaddr_in();
1783 10 : in.sin_family = AF_INET;
1784 10 : in.sin_port = htons(rand());
1785 : uint32_t address((169 << 24)
1786 : | (254 << 16)
1787 10 : | ((rand() & 255) << 8)
1788 10 : | ((rand() & 255) << 0));
1789 10 : in.sin_addr.s_addr = htonl(address);
1790 :
1791 : // verify network type
1792 : //
1793 10 : a.set_ipv4(in);
1794 10 : REQUIRE(a.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_LINK_LOCAL);
1795 10 : REQUIRE(a.get_network_type_string() == "Local Link");
1796 : }
1797 : }
1798 :
1799 16 : SECTION("private address 224.x.x.x/4")
1800 : {
1801 11 : for(int idx(0); idx < 10; ++idx)
1802 : {
1803 10 : struct sockaddr_in in = sockaddr_in();
1804 10 : in.sin_family = AF_INET;
1805 10 : in.sin_port = htons(rand());
1806 10 : uint32_t address((((rand() & 15) | 224) << 24)
1807 10 : | ((rand() & 255) << 16)
1808 10 : | ((rand() & 255) << 8)
1809 10 : | ((rand() & 255) << 0));
1810 10 : in.sin_addr.s_addr = htonl(address);
1811 :
1812 : // verify network type
1813 : //
1814 10 : a.set_ipv4(in);
1815 10 : REQUIRE(a.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_MULTICAST);
1816 10 : REQUIRE(a.get_network_type_string() == "Multicast");
1817 :
1818 : // make sure no interface uses that IP
1819 : //
1820 10 : REQUIRE(a.is_computer_interface_address() == addr::addr::computer_interface_address_t::COMPUTER_INTERFACE_ADDRESS_FALSE);
1821 : }
1822 : }
1823 :
1824 16 : SECTION("private address 127.x.x.x/8")
1825 : {
1826 11 : for(int idx(0); idx < 10; ++idx)
1827 : {
1828 10 : struct sockaddr_in in = sockaddr_in();
1829 10 : in.sin_family = AF_INET;
1830 10 : in.sin_port = htons(rand());
1831 : uint32_t address((127 << 24)
1832 10 : | ((rand() & 255) << 16)
1833 10 : | ((rand() & 255) << 8)
1834 10 : | ((rand() & 255) << 0));
1835 10 : in.sin_addr.s_addr = htonl(address);
1836 :
1837 : // verify network type
1838 : //
1839 10 : a.set_ipv4(in);
1840 10 : REQUIRE(a.get_network_type() == addr::addr::network_type_t::NETWORK_TYPE_LOOPBACK);
1841 10 : REQUIRE(a.get_network_type_string() == "Loopback");
1842 : }
1843 : }
1844 : }
1845 14 : }
1846 :
1847 :
1848 :
1849 :
1850 : // vim: ts=4 sw=4 et
|