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