Line data Source code
1 : // Copyright (c) 2011-2025 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/libaddr
4 : // contact@m2osw.com
5 : //
6 : // Permission is hereby granted, free of charge, to any
7 : // person obtaining a copy of this software and
8 : // associated documentation files (the "Software"), to
9 : // deal in the Software without restriction, including
10 : // without limitation the rights to use, copy, modify,
11 : // merge, publish, distribute, sublicense, and/or sell
12 : // copies of the Software, and to permit persons to whom
13 : // the Software is furnished to do so, subject to the
14 : // following conditions:
15 : //
16 : // The above copyright notice and this permission notice
17 : // shall be included in all copies or substantial
18 : // portions of the Software.
19 : //
20 : // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
21 : // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
22 : // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 : // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
24 : // EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 : // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 : // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27 : // ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 : // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 : // SOFTWARE.
30 :
31 :
32 : /** \file
33 : * \brief Test the IPv4 interface.
34 : *
35 : * These test verify that the IPv4 side of things function as expected.
36 : *
37 : * Note that some of the tests between the IPv4 and IPv6 overlap. Here
38 : * you mainly find the IPv4 side of things.
39 : */
40 :
41 : // addr
42 : //
43 : #include <libaddr/iface.h>
44 :
45 :
46 : // self
47 : //
48 : #include "catch_main.h"
49 :
50 :
51 : // last include
52 : //
53 : #include <snapdev/poison.h>
54 :
55 :
56 :
57 :
58 : /** \brief Details used by the addr class implementation.
59 : *
60 : * We have a function to check whether an address is part of
61 : * the interfaces of your computer. This check requires the
62 : * use of a `struct ifaddrs` and as such it requires to
63 : * delete that structure. We define a deleter for that
64 : * structure here.
65 : */
66 : namespace
67 : {
68 :
69 : /** \brief Close a socket.
70 : *
71 : * This deleter is used to make sure all the socket we test get closed
72 : * on exit.
73 : *
74 : * \param[in] s The socket to close.
75 : */
76 5 : void socket_deleter(int * s)
77 : {
78 5 : close(*s);
79 5 : }
80 :
81 :
82 : }
83 : // no name namespace
84 :
85 :
86 :
87 15 : CATCH_TEST_CASE("ipv4::invalid_input", "[ipv4]")
88 : {
89 15 : CATCH_GIVEN("addr()")
90 : {
91 1 : addr::addr a;
92 :
93 1 : CATCH_START_SECTION("ipv4::invalid_input: set IPv4 with an invalid family")
94 : {
95 26 : for(int idx(0); idx < 25; ++idx)
96 : {
97 25 : struct sockaddr_in in = sockaddr_in();
98 : do
99 : {
100 25 : in.sin_family = rand();
101 : }
102 25 : while(in.sin_family == AF_INET);
103 25 : in.sin_port = htons(rand());
104 25 : in.sin_addr.s_addr = htonl(rand() ^ (rand() << 16));
105 25 : CATCH_REQUIRE_THROWS_AS(a.set_ipv4(in), addr::addr_invalid_argument);
106 50 : CATCH_REQUIRE_THROWS_AS(addr::addr(in), addr::addr_invalid_argument);
107 : }
108 : }
109 1 : CATCH_END_SECTION()
110 16 : }
111 :
112 15 : CATCH_GIVEN("addr_parser() with IPv4 settings")
113 : {
114 2 : addr::addr_parser a;
115 :
116 2 : CATCH_START_SECTION("ipv4::addr_parser(): invalid allow flags (too small)")
117 : {
118 11 : for(int idx(0); idx < 10; ++idx)
119 : {
120 : // test with a negative number
121 : //
122 : int n;
123 : do
124 : {
125 10 : n = rand();
126 : }
127 10 : while(n == 0);
128 10 : if(n > 0)
129 : {
130 : // all positive numbers have a corresponding negative
131 : // number so this always flips the sign as expected
132 : //
133 10 : n = -n;
134 : }
135 10 : addr::allow_t const flag(static_cast<addr::allow_t>(n));
136 :
137 10 : CATCH_REQUIRE_THROWS_AS(a.set_allow(flag, true), addr::addr_invalid_argument);
138 10 : CATCH_REQUIRE_THROWS_AS(a.set_allow(flag, false), addr::addr_invalid_argument);
139 10 : CATCH_REQUIRE_THROWS_AS(a.get_allow(flag), addr::addr_invalid_argument);
140 : }
141 : }
142 2 : CATCH_END_SECTION()
143 :
144 2 : CATCH_START_SECTION("ipv4::addr_parser(): invalid allow flags (too large)")
145 : {
146 11 : for(int idx(0); idx < 10; ++idx)
147 : {
148 : // test with a negative number
149 : //
150 : int n;
151 : do
152 : {
153 10 : n = rand();
154 10 : if(n < 0)
155 : {
156 0 : n = -n;
157 : }
158 : }
159 10 : while(n < static_cast<int>(addr::allow_t::ALLOW_max));
160 10 : addr::allow_t const flag(static_cast<addr::allow_t>(n));
161 :
162 10 : CATCH_REQUIRE_THROWS_AS(a.set_allow(flag, true), addr::addr_invalid_argument);
163 10 : CATCH_REQUIRE_THROWS_AS(a.set_allow(flag, false), addr::addr_invalid_argument);
164 10 : CATCH_REQUIRE_THROWS_AS(a.get_allow(flag), addr::addr_invalid_argument);
165 : }
166 : }
167 2 : CATCH_END_SECTION()
168 17 : }
169 :
170 15 : CATCH_GIVEN("addr_parser() with IPv4 addresses")
171 : {
172 2 : CATCH_START_SECTION("ipv4::addr_parser(): bad address")
173 : {
174 1 : addr::addr_parser p;
175 3 : addr::addr_range::vector_t ips(p.parse("{bad-ip}"));
176 1 : CATCH_REQUIRE(p.has_errors());
177 1 : CATCH_REQUIRE(p.error_count() == 1);
178 1 : CATCH_REQUIRE(p.error_messages() == "Invalid address in \"{bad-ip}\" error -2 -- Name or service not known (errno: 22 -- Invalid argument).\n");
179 1 : CATCH_REQUIRE(p.has_errors());
180 1 : p.clear_errors();
181 1 : CATCH_REQUIRE_FALSE(p.has_errors());
182 1 : CATCH_REQUIRE(ips.size() == 0);
183 1 : }
184 2 : CATCH_END_SECTION()
185 :
186 2 : CATCH_START_SECTION("ipv4::addr_parser(): required address")
187 : {
188 1 : addr::addr_parser p;
189 1 : p.set_protocol(IPPROTO_TCP);
190 1 : p.set_allow(addr::allow_t::ALLOW_REQUIRED_ADDRESS, true);
191 3 : addr::addr_range::vector_t ips(p.parse(""));
192 1 : CATCH_REQUIRE(p.has_errors());
193 1 : CATCH_REQUIRE(p.error_count() == 1);
194 1 : CATCH_REQUIRE(p.error_messages() == "Required address is missing.\n");
195 1 : CATCH_REQUIRE(p.has_errors());
196 1 : p.clear_errors();
197 1 : CATCH_REQUIRE_FALSE(p.has_errors());
198 1 : CATCH_REQUIRE(ips.size() == 0);
199 1 : }
200 2 : CATCH_END_SECTION()
201 15 : }
202 :
203 15 : CATCH_GIVEN("addr_parser() with IPv4 ports")
204 : {
205 3 : CATCH_START_SECTION("ipv4::addr_parser(): required port")
206 : {
207 : // optional + required -> required
208 : {
209 1 : addr::addr_parser p;
210 1 : p.set_protocol(IPPROTO_TCP);
211 1 : p.set_allow(addr::allow_t::ALLOW_REQUIRED_PORT, true);
212 3 : addr::addr_range::vector_t ips(p.parse("1.2.3.4"));
213 1 : CATCH_REQUIRE(p.has_errors());
214 1 : CATCH_REQUIRE(p.error_count() == 1);
215 1 : CATCH_REQUIRE(p.error_messages() == "Required port is missing.\n");
216 1 : CATCH_REQUIRE(p.has_errors());
217 1 : p.clear_errors();
218 1 : CATCH_REQUIRE_FALSE(p.has_errors());
219 1 : CATCH_REQUIRE(ips.size() == 0);
220 1 : }
221 :
222 : // only required -> required just the same
223 : {
224 1 : addr::addr_parser p;
225 1 : p.set_protocol(IPPROTO_TCP);
226 1 : p.set_allow(addr::allow_t::ALLOW_PORT, false);
227 1 : p.set_allow(addr::allow_t::ALLOW_REQUIRED_PORT, true);
228 3 : addr::addr_range::vector_t ips(p.parse("1.2.3.4"));
229 1 : CATCH_REQUIRE(p.has_errors());
230 1 : CATCH_REQUIRE(p.error_count() == 1);
231 1 : CATCH_REQUIRE(p.error_messages() == "Required port is missing.\n");
232 1 : CATCH_REQUIRE(p.has_errors());
233 1 : p.clear_errors();
234 1 : CATCH_REQUIRE_FALSE(p.has_errors());
235 1 : CATCH_REQUIRE(ips.size() == 0);
236 1 : }
237 : }
238 3 : CATCH_END_SECTION()
239 :
240 3 : CATCH_START_SECTION("ipv4::addr_parser(): port not allowed")
241 : {
242 1 : addr::addr_parser p;
243 1 : p.set_protocol(IPPROTO_TCP);
244 1 : p.set_allow(addr::allow_t::ALLOW_PORT, false);
245 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_REQUIRED_PORT));
246 3 : addr::addr_range::vector_t ips(p.parse("1.2.3.4:123"));
247 1 : CATCH_REQUIRE(p.has_errors());
248 1 : CATCH_REQUIRE(p.error_count() == 1);
249 1 : CATCH_REQUIRE(p.error_messages() == "Port not allowed (1.2.3.4:123).\n");
250 1 : CATCH_REQUIRE(p.has_errors());
251 1 : p.clear_errors();
252 1 : CATCH_REQUIRE_FALSE(p.has_errors());
253 1 : CATCH_REQUIRE(ips.size() == 0);
254 1 : }
255 3 : CATCH_END_SECTION()
256 :
257 3 : CATCH_START_SECTION("ipv4::addr_parser(): invalid port")
258 : {
259 1 : addr::addr_parser p;
260 :
261 : // so to a different default value
262 : //
263 1 : int const default_port(rand() & 0xFFFF);
264 1 : p.set_default_port(default_port);
265 :
266 26 : for(int idx(0); idx < 25; ++idx)
267 : {
268 25 : int port(0);
269 : do
270 : {
271 25 : port = rand() ^ (rand() << 16);
272 : }
273 25 : while(port >= -1 && port <= 65535); // -1 is valid here, it represents "no default port defined"
274 25 : CATCH_REQUIRE_THROWS_AS(p.set_default_port(port), addr::addr_invalid_argument);
275 :
276 25 : std::string const port_str(std::to_string(port));
277 25 : CATCH_REQUIRE_THROWS_AS(p.set_default_port(port_str), addr::addr_invalid_argument);
278 :
279 : // verify port unchanged
280 : //
281 25 : CATCH_REQUIRE(p.get_default_port() == default_port);
282 25 : }
283 :
284 5 : CATCH_REQUIRE_THROWS_AS(p.set_default_port("not-a-number"), addr::addr_invalid_argument);
285 1 : }
286 3 : CATCH_END_SECTION()
287 15 : }
288 :
289 15 : CATCH_GIVEN("addr_parser() with invalid masks")
290 : {
291 5 : CATCH_START_SECTION("ipv4::addr_parser(): really large numbers (over 1000)")
292 : {
293 6 : for(int idx(0); idx < 5; ++idx)
294 : {
295 5 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
296 5 : int const port(rand() & 0xFFFF);
297 5 : int const mask((rand() & 0xFF) + 10001);
298 5 : addr::addr_parser p;
299 5 : p.set_protocol(proto);
300 5 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
301 5 : addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port) + "/" + std::to_string(mask)));
302 5 : CATCH_REQUIRE(p.has_errors());
303 5 : CATCH_REQUIRE(p.error_count() == 1);
304 5 : CATCH_REQUIRE(p.error_messages() == "Mask size too large (" + std::to_string(mask) + ", expected a maximum of 128).\n");
305 5 : CATCH_REQUIRE(ips.size() == 0);
306 5 : }
307 : }
308 5 : CATCH_END_SECTION()
309 :
310 5 : CATCH_START_SECTION("ipv4::addr_parser(): ipv4 mask is limited between 0 and 32")
311 : {
312 6 : for(int idx(0); idx < 5; ++idx)
313 : {
314 5 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
315 5 : int const port(rand() & 0xFFFF);
316 5 : int const mask((rand() & 0xFF) + 33);
317 5 : addr::addr_parser p;
318 5 : p.set_protocol(proto);
319 5 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
320 5 : addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port) + "/" + std::to_string(mask)));
321 5 : CATCH_REQUIRE(p.has_errors());
322 5 : CATCH_REQUIRE(p.error_count() == 1);
323 5 : CATCH_REQUIRE(p.error_messages() == "Unsupported mask size (" + std::to_string(mask) + ", expected 32 at the most for an IPv4).\n");
324 5 : CATCH_REQUIRE(ips.size() == 0);
325 5 : }
326 : }
327 5 : CATCH_END_SECTION()
328 :
329 5 : CATCH_START_SECTION("ipv4::addr_parser(): ipv4 mask cannot use name")
330 : {
331 6 : for(int idx(0); idx < 5; ++idx)
332 : {
333 5 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
334 5 : int const port(rand() & 0xFFFF);
335 5 : addr::addr_parser p;
336 5 : p.set_protocol(proto);
337 5 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
338 5 : p.set_allow(addr::allow_t::ALLOW_ADDRESS_MASK, true);
339 5 : addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port) + "/localhost"));
340 5 : CATCH_REQUIRE(p.has_errors());
341 5 : CATCH_REQUIRE(p.error_count() == 1);
342 5 : CATCH_REQUIRE(p.error_messages() == "Invalid mask in \"/localhost\", error -2 -- Name or service not known (errno: 0 -- Success).\n");
343 5 : CATCH_REQUIRE(ips.size() == 0);
344 5 : }
345 : }
346 5 : CATCH_END_SECTION()
347 :
348 5 : CATCH_START_SECTION("ipv4::addr_parser(): ipv4 mask mismatch (mask uses ipv6)")
349 : {
350 1 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
351 1 : int const port(rand() & 0xFFFF);
352 1 : addr::addr_parser p;
353 1 : p.set_protocol(proto);
354 1 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
355 1 : p.set_allow(addr::allow_t::ALLOW_ADDRESS_MASK, true);
356 1 : addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port) + "/[1:2:3:4:5:6:7:8]"));
357 1 : CATCH_REQUIRE(p.has_errors());
358 1 : CATCH_REQUIRE(p.error_count() == 1);
359 1 : CATCH_REQUIRE(p.error_messages() == "The address uses the IPv4 syntax, the mask cannot use IPv6.\n");
360 1 : CATCH_REQUIRE(ips.size() == 0);
361 1 : }
362 5 : CATCH_END_SECTION()
363 :
364 5 : CATCH_START_SECTION("ipv4::addr_parser(): ipv4 mask mismatch (mask uses ipv6 without [...])")
365 : {
366 1 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
367 1 : int const port(rand() & 0xFFFF);
368 1 : addr::addr_parser p;
369 1 : p.set_protocol(proto);
370 1 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
371 1 : p.set_allow(addr::allow_t::ALLOW_ADDRESS_MASK, true);
372 1 : addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port) + "/1:2:3:4:5:6:7:8"));
373 1 : CATCH_REQUIRE(p.has_errors());
374 1 : CATCH_REQUIRE(p.error_count() == 1);
375 1 : CATCH_REQUIRE(p.error_messages() == "Incompatible address between the address and mask address (first was an IPv4 second an IPv6).\n");
376 1 : CATCH_REQUIRE(ips.size() == 0);
377 1 : }
378 5 : CATCH_END_SECTION()
379 15 : }
380 :
381 15 : CATCH_GIVEN("addr_parser() with invalid protocols")
382 : {
383 2 : CATCH_START_SECTION("ipv4::addr_parser(): invalid names")
384 : {
385 1 : addr::addr_parser p;
386 :
387 : // not changing default protocol
388 : //
389 1 : CATCH_REQUIRE(p.get_protocol() == -1);
390 5 : CATCH_REQUIRE_THROWS_AS(p.set_protocol("unknown"), addr::addr_invalid_argument);
391 1 : CATCH_REQUIRE(p.get_protocol() == -1);
392 :
393 : // change protocol to another valid value first
394 : //
395 3 : p.set_protocol("tcp");
396 5 : CATCH_REQUIRE_THROWS_AS(p.set_protocol("another"), addr::addr_invalid_argument);
397 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_TCP);
398 1 : }
399 2 : CATCH_END_SECTION()
400 :
401 2 : CATCH_START_SECTION("ipv4::addr_parser(): invalid numbers")
402 : {
403 101 : for(int idx(0); idx < 100; ++idx)
404 : {
405 : int protocol;
406 : do
407 : {
408 100 : protocol = rand();
409 : }
410 : while(protocol == IPPROTO_IP
411 100 : || protocol == IPPROTO_TCP
412 200 : || protocol == IPPROTO_UDP);
413 :
414 100 : addr::addr_parser p;
415 :
416 100 : CATCH_REQUIRE_THROWS_AS(p.set_protocol(protocol), addr::addr_invalid_argument);
417 100 : CATCH_REQUIRE(p.get_protocol() == -1);
418 :
419 : // change protocol to another valid value first
420 : //
421 300 : p.set_protocol("tcp");
422 100 : CATCH_REQUIRE_THROWS_AS(p.set_protocol(protocol), addr::addr_invalid_argument);
423 100 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_TCP);
424 100 : }
425 : }
426 2 : CATCH_END_SECTION()
427 15 : }
428 15 : }
429 :
430 :
431 9 : CATCH_TEST_CASE("ipv4::address_defaults", "[ipv4][ipv6]")
432 : {
433 9 : CATCH_GIVEN("addr()")
434 : {
435 9 : addr::addr a;
436 :
437 9 : CATCH_START_SECTION("ipv4::addr: by default (all zeroes) IP is not an IPv4")
438 : {
439 1 : CATCH_REQUIRE_FALSE(a.is_ipv4());
440 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET);
441 1 : CATCH_REQUIRE(a.get_family() == AF_INET6);
442 1 : CATCH_REQUIRE(a.get_hostname() == std::string());
443 1 : CATCH_REQUIRE(a.is_hostname_an_ip());
444 1 : CATCH_REQUIRE(a.get_interface() == std::string());
445 :
446 1 : struct sockaddr_in in;
447 1 : CATCH_REQUIRE_THROWS_AS(a.get_ipv4(in), addr::addr_invalid_state);
448 2 : CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::STRING_IP_ADDRESS), addr::addr_invalid_state);
449 2 : CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS), addr::addr_invalid_state);
450 2 : CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT), addr::addr_invalid_state);
451 2 : CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::STRING_IP_ADDRESS | addr::STRING_IP_PORT | addr::STRING_IP_MASK), addr::addr_invalid_state);
452 2 : CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT | addr::STRING_IP_BRACKET_MASK), addr::addr_invalid_state);
453 2 : CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::STRING_IP_ALL), addr::addr_invalid_state);
454 : }
455 9 : CATCH_END_SECTION()
456 :
457 9 : CATCH_START_SECTION("ipv4::addr: default network type (:: and 0.0.0.0)")
458 : {
459 1 : a.set_port(80);
460 :
461 : // at first this is still an IPv6
462 : //
463 1 : CATCH_REQUIRE(a.is_default());
464 1 : CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_ANY);
465 3 : CATCH_REQUIRE(std::string(a.get_network_type_string()) == "Any");
466 1 : CATCH_REQUIRE_FALSE(a.is_lan());
467 1 : CATCH_REQUIRE_FALSE(a.is_lan(true));
468 1 : CATCH_REQUIRE_FALSE(a.is_lan(false));
469 1 : CATCH_REQUIRE(a.get_port() == 80);
470 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_TCP);
471 1 : CATCH_REQUIRE(a.is_wan());
472 1 : CATCH_REQUIRE(a.is_wan(true));
473 1 : CATCH_REQUIRE_FALSE(a.is_wan(false));
474 1 : CATCH_REQUIRE(a.is_valid());
475 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::STRING_IP_ADDRESS | addr::STRING_IP_DEFAULT_AS_ASTERISK) == "*");
476 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::STRING_IP_ADDRESS | addr::STRING_IP_DEFAULT_AS_ASTERISK | addr::STRING_IP_PORT) == "[*]:80");
477 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::STRING_IP_ADDRESS | addr::STRING_IP_DEFAULT_AS_ASTERISK | addr::STRING_IP_PORT_NAME) == "[*]:http");
478 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_DEFAULT_AS_ASTERISK) == "[*]");
479 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::STRING_IP_ADDRESS) == "::");
480 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::STRING_IP_BRACKET_ADDRESS) == "[::]");
481 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_DEFAULT_AS_IPV4) == "0.0.0.0");
482 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_DEFAULT_AS_IPV4 | addr::STRING_IP_PORT) == "0.0.0.0:80");
483 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_DEFAULT_AS_IPV4 | addr::STRING_IP_PORT_NAME) == "0.0.0.0:http");
484 :
485 : // make it an IPv4 and try again
486 : //
487 1 : struct sockaddr_in in = sockaddr_in();
488 1 : in.sin_family = AF_INET;
489 1 : in.sin_port = htons(80);
490 1 : a.set_ipv4(in);
491 :
492 1 : CATCH_REQUIRE(a.is_default());
493 1 : CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_ANY);
494 3 : CATCH_REQUIRE(std::string(a.get_network_type_string()) == "Any");
495 1 : CATCH_REQUIRE_FALSE(a.is_lan());
496 1 : CATCH_REQUIRE_FALSE(a.is_lan(true));
497 1 : CATCH_REQUIRE_FALSE(a.is_lan(false));
498 1 : CATCH_REQUIRE(a.is_wan());
499 1 : CATCH_REQUIRE(a.is_wan(true));
500 1 : CATCH_REQUIRE_FALSE(a.is_wan(false));
501 1 : CATCH_REQUIRE(a.is_valid());
502 1 : CATCH_REQUIRE(a.to_ipv4_string(addr::STRING_IP_ADDRESS | addr::STRING_IP_DEFAULT_AS_ASTERISK) == "*");
503 1 : CATCH_REQUIRE(a.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_DEFAULT_AS_ASTERISK) == "*");
504 1 : CATCH_REQUIRE(a.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_DEFAULT_AS_ASTERISK | addr::STRING_IP_PORT) == "*:80");
505 1 : CATCH_REQUIRE(a.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_DEFAULT_AS_ASTERISK | addr::STRING_IP_PORT_NAME) == "*:http");
506 1 : CATCH_REQUIRE(a.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS) == "0.0.0.0");
507 1 : CATCH_REQUIRE(a.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT) == "0.0.0.0:80");
508 1 : CATCH_REQUIRE(a.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT_NAME) == "0.0.0.0:http");
509 : }
510 9 : CATCH_END_SECTION()
511 :
512 9 : CATCH_START_SECTION("ipv4::addr: IPv6 ANY")
513 : {
514 1 : struct sockaddr_in6 in6;
515 1 : a.get_ipv6(in6);
516 1 : CATCH_REQUIRE(in6.sin6_addr.s6_addr32[0] == 0);
517 1 : CATCH_REQUIRE(in6.sin6_addr.s6_addr32[1] == 0);
518 1 : CATCH_REQUIRE(in6.sin6_addr.s6_addr32[2] == 0);
519 1 : CATCH_REQUIRE(in6.sin6_addr.s6_addr32[3] == 0);
520 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::STRING_IP_ADDRESS) == "::");
521 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::STRING_IP_BRACKET_ADDRESS) == "[::]");
522 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT) == "[::]:0");
523 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::STRING_IP_ADDRESS | addr::STRING_IP_MASK) == "::/128");
524 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_BRACKET_MASK) == "[::]/128");
525 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::STRING_IP_ALL) == "[::]:0/128");
526 : }
527 9 : CATCH_END_SECTION()
528 :
529 9 : CATCH_START_SECTION("ipv4::addr: IPv4 or IPv6 string")
530 : {
531 1 : CATCH_REQUIRE(a.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "::");
532 1 : CATCH_REQUIRE(a.to_ipv4or6_string(addr::STRING_IP_BRACKET_ADDRESS) == "[::]");
533 1 : CATCH_REQUIRE(a.to_ipv4or6_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT) == "[::]:0");
534 1 : CATCH_REQUIRE(a.to_ipv4or6_string(addr::STRING_IP_ADDRESS | addr::STRING_IP_MASK) == "::/128");
535 1 : CATCH_REQUIRE(a.to_ipv4or6_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_BRACKET_MASK) == "[::]/128");
536 1 : CATCH_REQUIRE(a.to_ipv4or6_string(addr::STRING_IP_ALL) == "[::]:0/128");
537 : }
538 9 : CATCH_END_SECTION()
539 :
540 9 : CATCH_START_SECTION("ipv4::addr: interface determination")
541 : {
542 1 : CATCH_REQUIRE(addr::find_addr_interface(a, false) == nullptr);
543 1 : CATCH_REQUIRE(addr::find_addr_interface(a, true) != nullptr);
544 : }
545 9 : CATCH_END_SECTION()
546 :
547 9 : CATCH_START_SECTION("ipv4::addr: default name/service/port/protocol")
548 : {
549 1 : CATCH_REQUIRE(a.get_name() == std::string());
550 1 : CATCH_REQUIRE(a.get_service() == std::string());
551 1 : CATCH_REQUIRE(a.get_port() == 0);
552 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_TCP);
553 : }
554 9 : CATCH_END_SECTION()
555 :
556 9 : CATCH_START_SECTION("ipv4::addr: compare with self")
557 : {
558 1 : CATCH_REQUIRE(a == a);
559 1 : CATCH_REQUIRE_FALSE(a != a);
560 1 : CATCH_REQUIRE_FALSE(a < a);
561 1 : CATCH_REQUIRE(a <= a);
562 1 : CATCH_REQUIRE_FALSE(a > a);
563 1 : CATCH_REQUIRE(a >= a);
564 : }
565 9 : CATCH_END_SECTION()
566 :
567 9 : CATCH_START_SECTION("ipv4::addr: compare with another 0.0.0.0")
568 : {
569 : {
570 1 : addr::addr b;
571 :
572 1 : CATCH_REQUIRE(a == b);
573 1 : CATCH_REQUIRE_FALSE(a != b);
574 1 : CATCH_REQUIRE_FALSE(a < b);
575 1 : CATCH_REQUIRE(a <= b);
576 1 : CATCH_REQUIRE_FALSE(a > b);
577 1 : CATCH_REQUIRE(a >= b);
578 1 : }
579 :
580 : {
581 1 : struct sockaddr_in6 in6 = sockaddr_in6();
582 1 : in6.sin6_family = AF_INET6;
583 1 : in6.sin6_port = htons(0);
584 1 : in6.sin6_addr.s6_addr32[0] = htonl(0);
585 1 : in6.sin6_addr.s6_addr32[1] = htonl(0);
586 1 : in6.sin6_addr.s6_addr32[2] = htonl(0);
587 1 : in6.sin6_addr.s6_addr32[3] = htonl(0);
588 1 : addr::addr b(in6);
589 :
590 1 : CATCH_REQUIRE(a == b);
591 1 : CATCH_REQUIRE_FALSE(a != b);
592 1 : CATCH_REQUIRE_FALSE(a < b);
593 1 : CATCH_REQUIRE(a <= b);
594 1 : CATCH_REQUIRE_FALSE(a > b);
595 1 : CATCH_REQUIRE(a >= b);
596 1 : }
597 :
598 : // ANY in IPv4 != ANY in IPv6...
599 : // (i.e. IPv4 sets addr.sin6_addr.s6_addr16[5] == 0xFFFF)
600 : {
601 1 : struct sockaddr_in in = sockaddr_in();
602 1 : in.sin_family = AF_INET;
603 1 : in.sin_port = htons(0);
604 1 : in.sin_addr.s_addr = htonl(0);
605 1 : addr::addr b(in);
606 :
607 1 : CATCH_REQUIRE_FALSE(a == b);
608 1 : CATCH_REQUIRE(a != b);
609 1 : CATCH_REQUIRE(a < b);
610 1 : CATCH_REQUIRE(a <= b);
611 1 : CATCH_REQUIRE_FALSE(a > b);
612 1 : CATCH_REQUIRE_FALSE(a >= b);
613 1 : }
614 : }
615 9 : CATCH_END_SECTION()
616 :
617 9 : CATCH_START_SECTION("ipv4::addr: compare with IPv4 127.0.0.1")
618 : {
619 1 : struct sockaddr_in in = sockaddr_in();
620 1 : in.sin_family = AF_INET;
621 1 : in.sin_port = htons(80);
622 1 : in.sin_addr.s_addr = htonl((127 << 24) | 1);
623 1 : addr::addr b(in);
624 :
625 1 : CATCH_REQUIRE_FALSE(a == b);
626 1 : CATCH_REQUIRE(a != b);
627 1 : CATCH_REQUIRE(a < b);
628 1 : CATCH_REQUIRE(a <= b);
629 1 : CATCH_REQUIRE_FALSE(a > b);
630 1 : CATCH_REQUIRE_FALSE(a >= b);
631 1 : }
632 9 : CATCH_END_SECTION()
633 18 : }
634 9 : }
635 :
636 :
637 21 : CATCH_TEST_CASE("ipv4::address", "[ipv4]")
638 : {
639 21 : CATCH_GIVEN("addr() with an IPv4")
640 : {
641 3 : addr::addr a;
642 :
643 3 : CATCH_START_SECTION("ipv4::addr: set_ipv4() / get_ipv4()")
644 : {
645 11 : for(int idx(0); idx < 10; ++idx)
646 : {
647 10 : struct sockaddr_in in = sockaddr_in();
648 10 : in.sin_family = AF_INET;
649 10 : in.sin_port = htons(rand());
650 10 : in.sin_addr.s_addr = htonl(rand() ^ (rand() << 16));
651 :
652 : // test constructor
653 : //
654 10 : addr::addr b(in);
655 10 : struct sockaddr_in out;
656 10 : b.get_ipv4(out);
657 10 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
658 :
659 : // test set
660 : //
661 10 : a.set_ipv4(in);
662 10 : a.get_ipv4(out);
663 10 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
664 10 : }
665 : }
666 3 : CATCH_END_SECTION()
667 :
668 3 : CATCH_START_SECTION("ipv4::addr: set_ipv4() / to_ipv4_string()")
669 : {
670 11 : for(int idx(0); idx < 10; ++idx)
671 : {
672 10 : struct sockaddr_in in = sockaddr_in();
673 10 : in.sin_family = AF_INET;
674 10 : uint16_t const port(rand());
675 10 : in.sin_port = htons(port);
676 10 : uint32_t const address(rand() ^ (rand() << 16));
677 10 : in.sin_addr.s_addr = htonl(address);
678 :
679 10 : std::string ip(
680 20 : std::to_string((address >> 24) & 255)
681 40 : + "."
682 40 : + std::to_string((address >> 16) & 255)
683 40 : + "."
684 40 : + std::to_string((address >> 8) & 255)
685 40 : + "."
686 20 : + std::to_string((address >> 0) & 255)
687 30 : );
688 10 : std::string port_str(std::to_string(static_cast<int>(port)));
689 :
690 : // check IPv4 as a string
691 : //
692 10 : a.set_ipv4(in);
693 10 : CATCH_REQUIRE(a.to_ipv4_string(addr::STRING_IP_ADDRESS) == ip);
694 10 : CATCH_REQUIRE(a.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS) == ip);
695 10 : CATCH_REQUIRE(a.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT) == ip + ":" + port_str);
696 10 : CATCH_REQUIRE(a.to_ipv4_string(addr::STRING_IP_ADDRESS | addr::STRING_IP_MASK) == ip + "/32");
697 10 : CATCH_REQUIRE(a.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_BRACKET_MASK) == ip + "/32");
698 10 : CATCH_REQUIRE(a.to_ipv4_string(addr::STRING_IP_ALL) == ip + ":" + port_str + "/32");
699 :
700 : // if the mask is not a valid IPv4 mask, then we get an exception
701 : //
702 10 : std::uint8_t invalid_mask[16] = { 255, 255 };
703 10 : a.set_mask(invalid_mask);
704 20 : CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::STRING_IP_ALL), addr::addr_unexpected_mask);
705 10 : invalid_mask[3] = 255;
706 10 : a.set_mask(invalid_mask);
707 20 : CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::STRING_IP_ALL), addr::addr_unexpected_mask);
708 10 : std::uint8_t const valid_mask[16] = {
709 : 255, 255, 255, 255,
710 : 255, 255, 255, 255,
711 : 255, 255, 255, 255,
712 10 : static_cast<std::uint8_t>(rand()),
713 10 : static_cast<std::uint8_t>(rand()),
714 10 : static_cast<std::uint8_t>(rand()),
715 10 : static_cast<std::uint8_t>(rand()),
716 10 : };
717 10 : a.set_mask(valid_mask);
718 10 : a.set_mask_count(128);
719 10 : }
720 : }
721 3 : CATCH_END_SECTION()
722 :
723 3 : CATCH_START_SECTION("ipv4::addr: name of various IPs")
724 : {
725 1 : struct sockaddr_in in = sockaddr_in();
726 1 : in.sin_family = AF_INET;
727 1 : in.sin_port = htons(rand());
728 1 : in.sin_addr.s_addr = 0;
729 :
730 : // verify network type
731 : //
732 1 : a.set_ipv4(in);
733 1 : CATCH_REQUIRE(a.get_name() == std::string()); // no name for "any" (TCP)
734 :
735 1 : a.set_protocol(IPPROTO_UDP);
736 1 : CATCH_REQUIRE(a.get_name() == std::string()); // no name for "any" (UDP)
737 :
738 1 : in.sin_addr.s_addr = htonl(0x7f000001);
739 1 : a.set_ipv4(in);
740 1 : char hostname[HOST_NAME_MAX + 1];
741 1 : hostname[HOST_NAME_MAX] = '\0';
742 1 : CATCH_REQUIRE(gethostname(hostname, sizeof(hostname)) == 0);
743 1 : CATCH_REQUIRE(hostname[0] != '\0');
744 1 : std::string localhost(a.get_name());
745 1 : bool const localhost_flag(localhost == hostname || localhost == "localhost");
746 1 : CATCH_REQUIRE(localhost_flag);
747 :
748 1 : CATCH_REQUIRE(addr::find_addr_interface(a, false) != nullptr);
749 1 : }
750 3 : CATCH_END_SECTION()
751 24 : }
752 :
753 21 : CATCH_GIVEN("addr_parser() with IPv4 addresses")
754 : {
755 7 : CATCH_START_SECTION("ipv4::addr: verify basics")
756 : {
757 1 : addr::addr_parser p;
758 1 : p.set_protocol(IPPROTO_TCP);
759 1 : CATCH_REQUIRE(p.get_default_address4() == "");
760 1 : CATCH_REQUIRE(p.get_default_address6() == "");
761 1 : CATCH_REQUIRE(p.get_default_port() == -1);
762 1 : CATCH_REQUIRE(p.get_default_mask4() == "");
763 1 : CATCH_REQUIRE(p.get_default_mask6() == "");
764 3 : addr::addr_range::vector_t ips(p.parse("1.2.3.4"));
765 1 : CATCH_REQUIRE_FALSE(p.has_errors());
766 1 : CATCH_REQUIRE(ips.size() == 1);
767 1 : addr::addr_range const & r(ips[0]);
768 1 : CATCH_REQUIRE(r.has_from());
769 1 : CATCH_REQUIRE_FALSE(r.has_to());
770 1 : CATCH_REQUIRE_FALSE(r.is_range());
771 1 : CATCH_REQUIRE_FALSE(r.is_empty());
772 1 : addr::addr f(r.get_from());
773 1 : CATCH_REQUIRE(f.is_ipv4());
774 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
775 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
776 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "1.2.3.4");
777 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "1.2.3.4");
778 1 : CATCH_REQUIRE(f.get_port() == 0);
779 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
780 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
781 1 : CATCH_REQUIRE_FALSE(f.is_lan());
782 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
783 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
784 1 : CATCH_REQUIRE(f.is_wan());
785 1 : CATCH_REQUIRE(f.is_wan(true));
786 1 : CATCH_REQUIRE(f.is_wan(false));
787 1 : uint8_t mask[16] = {};
788 1 : f.get_mask(mask);
789 17 : for(int idx(0); idx < 16; ++idx)
790 : {
791 16 : CATCH_REQUIRE(mask[idx] == 255);
792 : }
793 1 : }
794 7 : CATCH_END_SECTION()
795 :
796 7 : CATCH_START_SECTION("ipv4::addr: verify default address")
797 : {
798 1 : addr::addr_parser p;
799 :
800 3 : p.set_default_address("1.5.19.200");
801 1 : CATCH_REQUIRE(p.get_default_address4() == "1.5.19.200");
802 1 : CATCH_REQUIRE(p.get_default_address6() == "");
803 3 : p.set_default_address("");
804 1 : CATCH_REQUIRE(p.get_default_address4() == "");
805 1 : CATCH_REQUIRE(p.get_default_address6() == "");
806 :
807 3 : p.set_default_address("1.5.19.200");
808 1 : CATCH_REQUIRE(p.get_default_address4() == "1.5.19.200");
809 1 : CATCH_REQUIRE(p.get_default_address6() == "");
810 3 : p.set_default_address("[4:5:4:5:7:8:7:8]");
811 1 : CATCH_REQUIRE(p.get_default_address4() == "1.5.19.200");
812 1 : CATCH_REQUIRE(p.get_default_address6() == "4:5:4:5:7:8:7:8");
813 3 : p.set_default_address("");
814 1 : CATCH_REQUIRE(p.get_default_address4() == "");
815 1 : CATCH_REQUIRE(p.get_default_address6() == "");
816 1 : }
817 7 : CATCH_END_SECTION()
818 :
819 7 : CATCH_START_SECTION("ipv4::addr: verify default mask")
820 : {
821 1 : addr::addr_parser p;
822 :
823 3 : p.set_default_mask("1.5.19.200");
824 1 : CATCH_REQUIRE(p.get_default_mask4() == "1.5.19.200");
825 1 : CATCH_REQUIRE(p.get_default_mask6() == "");
826 3 : p.set_default_mask("");
827 1 : CATCH_REQUIRE(p.get_default_mask4() == "");
828 1 : CATCH_REQUIRE(p.get_default_mask6() == "");
829 :
830 3 : p.set_default_mask("1.5.19.200");
831 1 : CATCH_REQUIRE(p.get_default_mask4() == "1.5.19.200");
832 1 : CATCH_REQUIRE(p.get_default_mask6() == "");
833 3 : p.set_default_mask("[4:5:4:5:7:8:7:8]");
834 1 : CATCH_REQUIRE(p.get_default_mask4() == "1.5.19.200");
835 1 : CATCH_REQUIRE(p.get_default_mask6() == "4:5:4:5:7:8:7:8");
836 3 : p.set_default_mask("");
837 1 : CATCH_REQUIRE(p.get_default_mask4() == "");
838 1 : CATCH_REQUIRE(p.get_default_mask6() == "");
839 1 : }
840 7 : CATCH_END_SECTION()
841 :
842 7 : CATCH_START_SECTION("ipv4::addr: verify default allow flags")
843 : {
844 1 : addr::addr_parser p;
845 :
846 17 : for(int idx(0); idx < static_cast<int>(addr::allow_t::ALLOW_max); ++idx)
847 : {
848 16 : switch(static_cast<addr::allow_t>(idx))
849 : {
850 3 : case addr::allow_t::ALLOW_ADDRESS:
851 : case addr::allow_t::ALLOW_ADDRESS_LOOKUP:
852 : case addr::allow_t::ALLOW_PORT:
853 : // only these are true by default
854 : //
855 3 : CATCH_REQUIRE(p.get_allow(static_cast<addr::allow_t>(idx)));
856 3 : break;
857 :
858 13 : default:
859 13 : CATCH_REQUIRE_FALSE(p.get_allow(static_cast<addr::allow_t>(idx)));
860 13 : break;
861 :
862 : }
863 : }
864 1 : }
865 7 : CATCH_END_SECTION()
866 :
867 7 : CATCH_START_SECTION("ipv4::addr: verify contradictory flags")
868 : {
869 1 : addr::addr_parser p;
870 :
871 : // by default these are set to false
872 : //
873 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS));
874 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES));
875 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_PORTS_COMMAS));
876 :
877 : // check setting MULTI_ADDRESSES_COMMAS to true
878 : //
879 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS, true);
880 1 : CATCH_REQUIRE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS));
881 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES));
882 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_PORTS_COMMAS));
883 :
884 : // add MULTI_ADDRESSES_SPACES
885 : //
886 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES, true);
887 1 : CATCH_REQUIRE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS));
888 1 : CATCH_REQUIRE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES));
889 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_PORTS_COMMAS));
890 :
891 : // add MULTI_PORTS_COMMAS
892 : //
893 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_PORTS_COMMAS, true);
894 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS));
895 1 : CATCH_REQUIRE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES));
896 1 : CATCH_REQUIRE(p.get_allow(addr::allow_t::ALLOW_MULTI_PORTS_COMMAS));
897 :
898 : // add MULTI_ADDRESSES_COMMAS again
899 : //
900 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS, true);
901 1 : CATCH_REQUIRE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS));
902 1 : CATCH_REQUIRE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES));
903 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_PORTS_COMMAS));
904 :
905 : // remove MULTI_ADDRESSES_SPACES
906 : //
907 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES, false);
908 1 : CATCH_REQUIRE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS));
909 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES));
910 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_PORTS_COMMAS));
911 :
912 : // back to MULTI_PORTS_COMMAS
913 : //
914 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_PORTS_COMMAS, true);
915 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS));
916 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES));
917 1 : CATCH_REQUIRE(p.get_allow(addr::allow_t::ALLOW_MULTI_PORTS_COMMAS));
918 :
919 : // add MULTI_ADDRESSES_COMMAS first now
920 : //
921 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS, true);
922 1 : CATCH_REQUIRE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS));
923 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES));
924 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_PORTS_COMMAS));
925 1 : }
926 7 : CATCH_END_SECTION()
927 :
928 7 : CATCH_START_SECTION("ipv4::addr: default address")
929 : {
930 1 : addr::addr_parser p;
931 1 : p.set_protocol(IPPROTO_TCP);
932 3 : p.set_default_address("5.5.5.5");
933 1 : CATCH_REQUIRE(p.get_default_address4() == "5.5.5.5");
934 1 : CATCH_REQUIRE(p.get_default_address6() == "");
935 3 : addr::addr_range::vector_t ips(p.parse(""));
936 1 : CATCH_REQUIRE_FALSE(p.has_errors());
937 1 : CATCH_REQUIRE(ips.size() == 1);
938 1 : addr::addr_range const & r(ips[0]);
939 1 : CATCH_REQUIRE(r.has_from());
940 1 : CATCH_REQUIRE_FALSE(r.has_to());
941 1 : CATCH_REQUIRE_FALSE(r.is_range());
942 1 : CATCH_REQUIRE_FALSE(r.is_empty());
943 1 : addr::addr f(r.get_from());
944 1 : CATCH_REQUIRE(f.is_ipv4());
945 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
946 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
947 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "5.5.5.5");
948 1 : CATCH_REQUIRE(f.get_port() == 0);
949 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
950 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
951 1 : CATCH_REQUIRE_FALSE(f.is_lan());
952 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
953 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
954 1 : CATCH_REQUIRE(f.is_wan());
955 1 : CATCH_REQUIRE(f.is_wan(true));
956 1 : CATCH_REQUIRE(f.is_wan(false));
957 1 : }
958 7 : CATCH_END_SECTION()
959 :
960 7 : CATCH_START_SECTION("ipv4::addr: address, no port allowed")
961 : {
962 : // specific address with a default
963 : {
964 1 : addr::addr_parser p;
965 1 : p.set_allow(addr::allow_t::ALLOW_PORT, false);
966 1 : p.set_protocol(IPPROTO_TCP);
967 3 : p.set_default_address("5.5.5.5");
968 1 : CATCH_REQUIRE(p.get_default_address4() == "5.5.5.5");
969 1 : CATCH_REQUIRE(p.get_default_address6() == "");
970 3 : addr::addr_range::vector_t ips(p.parse("9.9.9.9"));
971 1 : CATCH_REQUIRE_FALSE(p.has_errors());
972 1 : CATCH_REQUIRE(ips.size() == 1);
973 1 : addr::addr_range const & r(ips[0]);
974 1 : CATCH_REQUIRE(r.has_from());
975 1 : CATCH_REQUIRE_FALSE(r.has_to());
976 1 : CATCH_REQUIRE_FALSE(r.is_range());
977 1 : CATCH_REQUIRE_FALSE(r.is_empty());
978 1 : addr::addr f(r.get_from());
979 1 : CATCH_REQUIRE(f.is_ipv4());
980 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
981 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
982 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "9.9.9.9");
983 1 : CATCH_REQUIRE(f.get_port() == 0);
984 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
985 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
986 1 : CATCH_REQUIRE_FALSE(f.is_lan());
987 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
988 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
989 1 : CATCH_REQUIRE(f.is_wan());
990 1 : CATCH_REQUIRE(f.is_wan(true));
991 1 : CATCH_REQUIRE(f.is_wan(false));
992 1 : }
993 :
994 : // only a default address
995 : {
996 1 : addr::addr_parser p;
997 1 : p.set_allow(addr::allow_t::ALLOW_PORT, false);
998 1 : p.set_protocol(IPPROTO_TCP);
999 3 : p.set_default_address("5.5.5.5");
1000 1 : CATCH_REQUIRE(p.get_default_address4() == "5.5.5.5");
1001 1 : CATCH_REQUIRE(p.get_default_address6() == "");
1002 3 : addr::addr_range::vector_t ips(p.parse(""));
1003 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1004 1 : CATCH_REQUIRE(ips.size() == 1);
1005 1 : addr::addr_range const & r(ips[0]);
1006 1 : CATCH_REQUIRE(r.has_from());
1007 1 : CATCH_REQUIRE_FALSE(r.has_to());
1008 1 : CATCH_REQUIRE_FALSE(r.is_range());
1009 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1010 1 : addr::addr f(r.get_from());
1011 1 : CATCH_REQUIRE(f.is_ipv4());
1012 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1013 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1014 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "5.5.5.5");
1015 1 : CATCH_REQUIRE(f.get_port() == 0);
1016 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1017 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1018 1 : CATCH_REQUIRE_FALSE(f.is_lan());
1019 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1020 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1021 1 : CATCH_REQUIRE(f.is_wan());
1022 1 : CATCH_REQUIRE(f.is_wan(true));
1023 1 : CATCH_REQUIRE(f.is_wan(false));
1024 1 : }
1025 : }
1026 7 : CATCH_END_SECTION()
1027 21 : }
1028 :
1029 21 : CATCH_GIVEN("addr_parser() with multiple IPv4 addresses in one string")
1030 : {
1031 6 : CATCH_START_SECTION("ipv4::addr: 3 IPs separated by commas")
1032 : {
1033 1 : addr::addr_parser p;
1034 1 : p.set_protocol(IPPROTO_TCP);
1035 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS, true);
1036 3 : addr::addr_range::vector_t ips(p.parse("1.2.3.4:55,5.6.7.8,,,,10.11.12.99:77"));
1037 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1038 1 : CATCH_REQUIRE(ips.size() == 3);
1039 :
1040 1 : uint8_t mask[16] = {};
1041 :
1042 : // 1.2.3.4:55
1043 : {
1044 1 : addr::addr_range const & r(ips[0]);
1045 1 : CATCH_REQUIRE(r.has_from());
1046 1 : CATCH_REQUIRE_FALSE(r.has_to());
1047 1 : CATCH_REQUIRE_FALSE(r.is_range());
1048 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1049 1 : addr::addr f(r.get_from());
1050 1 : CATCH_REQUIRE(f.is_ipv4());
1051 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1052 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1053 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "1.2.3.4");
1054 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "1.2.3.4");
1055 1 : CATCH_REQUIRE(f.get_port() == 55);
1056 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1057 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1058 1 : CATCH_REQUIRE_FALSE(f.is_lan());
1059 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1060 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1061 1 : CATCH_REQUIRE(f.is_wan());
1062 1 : CATCH_REQUIRE(f.is_wan(true));
1063 1 : CATCH_REQUIRE(f.is_wan(false));
1064 1 : f.get_mask(mask);
1065 17 : for(int idx(0); idx < 16; ++idx)
1066 : {
1067 16 : CATCH_REQUIRE(mask[idx] == 255);
1068 : }
1069 1 : }
1070 :
1071 : // 5.6.7.8
1072 : {
1073 1 : addr::addr_range const & r(ips[1]);
1074 1 : CATCH_REQUIRE(r.has_from());
1075 1 : CATCH_REQUIRE_FALSE(r.has_to());
1076 1 : CATCH_REQUIRE_FALSE(r.is_range());
1077 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1078 1 : addr::addr f(r.get_from());
1079 1 : CATCH_REQUIRE(f.is_ipv4());
1080 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1081 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1082 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "5.6.7.8");
1083 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "5.6.7.8");
1084 1 : CATCH_REQUIRE(f.get_port() == 0);
1085 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1086 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1087 1 : CATCH_REQUIRE_FALSE(f.is_lan());
1088 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1089 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1090 1 : CATCH_REQUIRE(f.is_wan());
1091 1 : CATCH_REQUIRE(f.is_wan(true));
1092 1 : CATCH_REQUIRE(f.is_wan(false));
1093 1 : f.get_mask(mask);
1094 17 : for(int idx(0); idx < 16; ++idx)
1095 : {
1096 16 : CATCH_REQUIRE(mask[idx] == 255);
1097 : }
1098 1 : }
1099 :
1100 : // 10.11.12.99:77
1101 : {
1102 1 : addr::addr_range const & r(ips[2]);
1103 1 : CATCH_REQUIRE(r.has_from());
1104 1 : CATCH_REQUIRE_FALSE(r.has_to());
1105 1 : CATCH_REQUIRE_FALSE(r.is_range());
1106 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1107 1 : addr::addr f(r.get_from());
1108 1 : CATCH_REQUIRE(f.is_ipv4());
1109 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1110 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1111 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "10.11.12.99");
1112 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "10.11.12.99");
1113 1 : CATCH_REQUIRE(f.get_port() == 77);
1114 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1115 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
1116 1 : CATCH_REQUIRE(f.is_lan());
1117 1 : CATCH_REQUIRE(f.is_lan(true));
1118 1 : CATCH_REQUIRE(f.is_lan(false));
1119 1 : CATCH_REQUIRE_FALSE(f.is_wan());
1120 1 : CATCH_REQUIRE_FALSE(f.is_wan(true));
1121 1 : CATCH_REQUIRE_FALSE(f.is_wan(false));
1122 1 : f.get_mask(mask);
1123 17 : for(int idx(0); idx < 16; ++idx)
1124 : {
1125 16 : CATCH_REQUIRE(mask[idx] == 255);
1126 : }
1127 1 : }
1128 1 : }
1129 6 : CATCH_END_SECTION()
1130 :
1131 6 : CATCH_START_SECTION("ipv4::addr: 3 IPs separated by spaces")
1132 : {
1133 1 : addr::addr_parser p;
1134 1 : p.set_protocol(IPPROTO_TCP);
1135 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES, true);
1136 3 : addr::addr_range::vector_t ips(p.parse("1.2.3.4:55 5.6.7.8 10.11.12.99:77"));
1137 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1138 1 : CATCH_REQUIRE(ips.size() == 3);
1139 :
1140 1 : uint8_t mask[16] = {};
1141 :
1142 : // 1.2.3.4:55
1143 : {
1144 1 : addr::addr_range const & r(ips[0]);
1145 1 : CATCH_REQUIRE(r.has_from());
1146 1 : CATCH_REQUIRE_FALSE(r.has_to());
1147 1 : CATCH_REQUIRE_FALSE(r.is_range());
1148 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1149 1 : addr::addr f(r.get_from());
1150 1 : CATCH_REQUIRE(f.is_ipv4());
1151 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1152 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1153 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "1.2.3.4");
1154 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "1.2.3.4");
1155 1 : CATCH_REQUIRE(f.get_port() == 55);
1156 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1157 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1158 1 : CATCH_REQUIRE_FALSE(f.is_lan());
1159 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1160 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1161 1 : CATCH_REQUIRE(f.is_wan());
1162 1 : CATCH_REQUIRE(f.is_wan(true));
1163 1 : CATCH_REQUIRE(f.is_wan(false));
1164 1 : f.get_mask(mask);
1165 17 : for(int idx(0); idx < 16; ++idx)
1166 : {
1167 16 : CATCH_REQUIRE(mask[idx] == 255);
1168 : }
1169 1 : }
1170 :
1171 : // 5.6.7.8
1172 : {
1173 1 : addr::addr_range const & r(ips[1]);
1174 1 : CATCH_REQUIRE(r.has_from());
1175 1 : CATCH_REQUIRE_FALSE(r.has_to());
1176 1 : CATCH_REQUIRE_FALSE(r.is_range());
1177 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1178 1 : addr::addr f(r.get_from());
1179 1 : CATCH_REQUIRE(f.is_ipv4());
1180 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1181 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1182 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "5.6.7.8");
1183 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "5.6.7.8");
1184 1 : CATCH_REQUIRE(f.get_port() == 0);
1185 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1186 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1187 1 : CATCH_REQUIRE_FALSE(f.is_lan());
1188 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1189 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1190 1 : CATCH_REQUIRE(f.is_wan());
1191 1 : CATCH_REQUIRE(f.is_wan(true));
1192 1 : CATCH_REQUIRE(f.is_wan(false));
1193 1 : f.get_mask(mask);
1194 17 : for(int idx(0); idx < 16; ++idx)
1195 : {
1196 16 : CATCH_REQUIRE(mask[idx] == 255);
1197 : }
1198 1 : }
1199 :
1200 : // 10.11.12.99:77
1201 : {
1202 1 : addr::addr_range const & r(ips[2]);
1203 1 : CATCH_REQUIRE(r.has_from());
1204 1 : CATCH_REQUIRE_FALSE(r.has_to());
1205 1 : CATCH_REQUIRE_FALSE(r.is_range());
1206 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1207 1 : addr::addr f(r.get_from());
1208 1 : CATCH_REQUIRE(f.is_ipv4());
1209 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1210 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1211 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "10.11.12.99");
1212 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "10.11.12.99");
1213 1 : CATCH_REQUIRE(f.get_port() == 77);
1214 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1215 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
1216 1 : CATCH_REQUIRE(f.is_lan());
1217 1 : CATCH_REQUIRE(f.is_lan(true));
1218 1 : CATCH_REQUIRE(f.is_lan(false));
1219 1 : CATCH_REQUIRE_FALSE(f.is_wan());
1220 1 : CATCH_REQUIRE_FALSE(f.is_wan(true));
1221 1 : CATCH_REQUIRE_FALSE(f.is_wan(false));
1222 1 : f.get_mask(mask);
1223 17 : for(int idx(0); idx < 16; ++idx)
1224 : {
1225 16 : CATCH_REQUIRE(mask[idx] == 255);
1226 : }
1227 1 : }
1228 1 : }
1229 6 : CATCH_END_SECTION()
1230 :
1231 6 : CATCH_START_SECTION("ipv4::addr: 3 IPs separated by commas and/or spaces")
1232 : {
1233 1 : addr::addr_parser p;
1234 1 : p.set_protocol(IPPROTO_TCP);
1235 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS, true);
1236 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES, true);
1237 3 : addr::addr_range::vector_t ips(p.parse(" 1.2.3.4:55,, 5.6.7.8 , 10.11.12.99:77 "));
1238 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1239 1 : CATCH_REQUIRE(ips.size() == 3);
1240 :
1241 1 : uint8_t mask[16] = {};
1242 :
1243 : // 1.2.3.4:55
1244 : {
1245 1 : addr::addr_range const & r(ips[0]);
1246 1 : CATCH_REQUIRE(r.has_from());
1247 1 : CATCH_REQUIRE_FALSE(r.has_to());
1248 1 : CATCH_REQUIRE_FALSE(r.is_range());
1249 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1250 1 : addr::addr f(r.get_from());
1251 1 : CATCH_REQUIRE(f.is_ipv4());
1252 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1253 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1254 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "1.2.3.4");
1255 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "1.2.3.4");
1256 1 : CATCH_REQUIRE(f.get_port() == 55);
1257 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1258 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1259 1 : CATCH_REQUIRE_FALSE(f.is_lan());
1260 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1261 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1262 1 : CATCH_REQUIRE(f.is_wan());
1263 1 : CATCH_REQUIRE(f.is_wan(true));
1264 1 : CATCH_REQUIRE(f.is_wan(false));
1265 1 : f.get_mask(mask);
1266 17 : for(int idx(0); idx < 16; ++idx)
1267 : {
1268 16 : CATCH_REQUIRE(mask[idx] == 255);
1269 : }
1270 1 : }
1271 :
1272 : // 5.6.7.8
1273 : {
1274 1 : addr::addr_range const & r(ips[1]);
1275 1 : CATCH_REQUIRE(r.has_from());
1276 1 : CATCH_REQUIRE_FALSE(r.has_to());
1277 1 : CATCH_REQUIRE_FALSE(r.is_range());
1278 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1279 1 : addr::addr f(r.get_from());
1280 1 : CATCH_REQUIRE(f.is_ipv4());
1281 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1282 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1283 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "5.6.7.8");
1284 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "5.6.7.8");
1285 1 : CATCH_REQUIRE(f.get_port() == 0);
1286 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1287 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1288 1 : CATCH_REQUIRE_FALSE(f.is_lan());
1289 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1290 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1291 1 : CATCH_REQUIRE(f.is_wan());
1292 1 : CATCH_REQUIRE(f.is_wan(true));
1293 1 : CATCH_REQUIRE(f.is_wan(false));
1294 1 : f.get_mask(mask);
1295 17 : for(int idx(0); idx < 16; ++idx)
1296 : {
1297 16 : CATCH_REQUIRE(mask[idx] == 255);
1298 : }
1299 1 : }
1300 :
1301 : // 10.11.12.99:77
1302 : {
1303 1 : addr::addr_range const & r(ips[2]);
1304 1 : CATCH_REQUIRE(r.has_from());
1305 1 : CATCH_REQUIRE_FALSE(r.has_to());
1306 1 : CATCH_REQUIRE_FALSE(r.is_range());
1307 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1308 1 : addr::addr f(r.get_from());
1309 1 : CATCH_REQUIRE(f.is_ipv4());
1310 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1311 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1312 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "10.11.12.99");
1313 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "10.11.12.99");
1314 1 : CATCH_REQUIRE(f.get_port() == 77);
1315 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1316 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
1317 1 : CATCH_REQUIRE(f.is_lan());
1318 1 : CATCH_REQUIRE(f.is_lan(true));
1319 1 : CATCH_REQUIRE(f.is_lan(false));
1320 1 : CATCH_REQUIRE_FALSE(f.is_wan());
1321 1 : CATCH_REQUIRE_FALSE(f.is_wan(true));
1322 1 : CATCH_REQUIRE_FALSE(f.is_wan(false));
1323 1 : f.get_mask(mask);
1324 17 : for(int idx(0); idx < 16; ++idx)
1325 : {
1326 16 : CATCH_REQUIRE(mask[idx] == 255);
1327 : }
1328 1 : }
1329 1 : }
1330 6 : CATCH_END_SECTION()
1331 :
1332 6 : CATCH_START_SECTION("ipv4::addr: 3 IPs with hash (#) comments")
1333 : {
1334 1 : addr::addr_parser p;
1335 1 : p.set_protocol(IPPROTO_TCP);
1336 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS, true);
1337 1 : p.set_allow(addr::allow_t::ALLOW_COMMENT_HASH, true);
1338 3 : addr::addr_range::vector_t ips(p.parse("1.2.3.4:55#first,5.6.7.8#second,10.11.12.99:77#third"));
1339 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1340 1 : CATCH_REQUIRE(ips.size() == 3);
1341 :
1342 1 : uint8_t mask[16] = {};
1343 :
1344 : // 1.2.3.4:55
1345 : {
1346 1 : addr::addr_range const & r(ips[0]);
1347 1 : CATCH_REQUIRE(r.has_from());
1348 1 : CATCH_REQUIRE_FALSE(r.has_to());
1349 1 : CATCH_REQUIRE_FALSE(r.is_range());
1350 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1351 1 : addr::addr f(r.get_from());
1352 1 : CATCH_REQUIRE(f.is_ipv4());
1353 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1354 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1355 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "1.2.3.4");
1356 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "1.2.3.4");
1357 1 : CATCH_REQUIRE(f.get_port() == 55);
1358 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1359 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1360 1 : CATCH_REQUIRE_FALSE(f.is_lan());
1361 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1362 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1363 1 : CATCH_REQUIRE(f.is_wan());
1364 1 : CATCH_REQUIRE(f.is_wan(true));
1365 1 : CATCH_REQUIRE(f.is_wan(false));
1366 1 : f.get_mask(mask);
1367 17 : for(int idx(0); idx < 16; ++idx)
1368 : {
1369 16 : CATCH_REQUIRE(mask[idx] == 255);
1370 : }
1371 1 : }
1372 :
1373 : // 5.6.7.8
1374 : {
1375 1 : addr::addr_range const & r(ips[1]);
1376 1 : CATCH_REQUIRE(r.has_from());
1377 1 : CATCH_REQUIRE_FALSE(r.has_to());
1378 1 : CATCH_REQUIRE_FALSE(r.is_range());
1379 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1380 1 : addr::addr f(r.get_from());
1381 1 : CATCH_REQUIRE(f.is_ipv4());
1382 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1383 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1384 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "5.6.7.8");
1385 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "5.6.7.8");
1386 1 : CATCH_REQUIRE(f.get_port() == 0);
1387 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1388 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1389 1 : CATCH_REQUIRE_FALSE(f.is_lan());
1390 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1391 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1392 1 : CATCH_REQUIRE(f.is_wan());
1393 1 : CATCH_REQUIRE(f.is_wan(true));
1394 1 : CATCH_REQUIRE(f.is_wan(false));
1395 1 : f.get_mask(mask);
1396 17 : for(int idx(0); idx < 16; ++idx)
1397 : {
1398 16 : CATCH_REQUIRE(mask[idx] == 255);
1399 : }
1400 1 : }
1401 :
1402 : // 10.11.12.99:77
1403 : {
1404 1 : addr::addr_range const & r(ips[2]);
1405 1 : CATCH_REQUIRE(r.has_from());
1406 1 : CATCH_REQUIRE_FALSE(r.has_to());
1407 1 : CATCH_REQUIRE_FALSE(r.is_range());
1408 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1409 1 : addr::addr f(r.get_from());
1410 1 : CATCH_REQUIRE(f.is_ipv4());
1411 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1412 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1413 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "10.11.12.99");
1414 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "10.11.12.99");
1415 1 : CATCH_REQUIRE(f.get_port() == 77);
1416 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1417 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
1418 1 : CATCH_REQUIRE(f.is_lan());
1419 1 : CATCH_REQUIRE(f.is_lan(true));
1420 1 : CATCH_REQUIRE(f.is_lan(false));
1421 1 : CATCH_REQUIRE_FALSE(f.is_wan());
1422 1 : CATCH_REQUIRE_FALSE(f.is_wan(true));
1423 1 : CATCH_REQUIRE_FALSE(f.is_wan(false));
1424 1 : f.get_mask(mask);
1425 17 : for(int idx(0); idx < 16; ++idx)
1426 : {
1427 16 : CATCH_REQUIRE(mask[idx] == 255);
1428 : }
1429 1 : }
1430 1 : }
1431 6 : CATCH_END_SECTION()
1432 :
1433 6 : CATCH_START_SECTION("ipv4::addr: 3 IPs with semicolon (;) comments")
1434 : {
1435 1 : addr::addr_parser p;
1436 1 : p.set_protocol(IPPROTO_TCP);
1437 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS, true);
1438 1 : p.set_allow(addr::allow_t::ALLOW_COMMENT_SEMICOLON, true);
1439 3 : addr::addr_range::vector_t ips(p.parse("1.2.3.4:55;first,5.6.7.8;second,10.11.12.99:77;third"));
1440 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1441 1 : CATCH_REQUIRE(ips.size() == 3);
1442 :
1443 1 : uint8_t mask[16] = {};
1444 :
1445 : // 1.2.3.4:55
1446 : {
1447 1 : addr::addr_range const & r(ips[0]);
1448 1 : CATCH_REQUIRE(r.has_from());
1449 1 : CATCH_REQUIRE_FALSE(r.has_to());
1450 1 : CATCH_REQUIRE_FALSE(r.is_range());
1451 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1452 1 : addr::addr f(r.get_from());
1453 1 : CATCH_REQUIRE(f.is_ipv4());
1454 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1455 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1456 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "1.2.3.4");
1457 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "1.2.3.4");
1458 1 : CATCH_REQUIRE(f.get_port() == 55);
1459 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1460 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1461 1 : CATCH_REQUIRE_FALSE(f.is_lan());
1462 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1463 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1464 1 : CATCH_REQUIRE(f.is_wan());
1465 1 : CATCH_REQUIRE(f.is_wan(true));
1466 1 : CATCH_REQUIRE(f.is_wan(false));
1467 1 : f.get_mask(mask);
1468 17 : for(int idx(0); idx < 16; ++idx)
1469 : {
1470 16 : CATCH_REQUIRE(mask[idx] == 255);
1471 : }
1472 1 : }
1473 :
1474 : // 5.6.7.8
1475 : {
1476 1 : addr::addr_range const & r(ips[1]);
1477 1 : CATCH_REQUIRE(r.has_from());
1478 1 : CATCH_REQUIRE_FALSE(r.has_to());
1479 1 : CATCH_REQUIRE_FALSE(r.is_range());
1480 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1481 1 : addr::addr f(r.get_from());
1482 1 : CATCH_REQUIRE(f.is_ipv4());
1483 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1484 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1485 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "5.6.7.8");
1486 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "5.6.7.8");
1487 1 : CATCH_REQUIRE(f.get_port() == 0);
1488 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1489 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1490 1 : CATCH_REQUIRE_FALSE(f.is_lan());
1491 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1492 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1493 1 : CATCH_REQUIRE(f.is_wan());
1494 1 : CATCH_REQUIRE(f.is_wan(true));
1495 1 : CATCH_REQUIRE(f.is_wan(false));
1496 1 : f.get_mask(mask);
1497 17 : for(int idx(0); idx < 16; ++idx)
1498 : {
1499 16 : CATCH_REQUIRE(mask[idx] == 255);
1500 : }
1501 1 : }
1502 :
1503 : // 10.11.12.99:77
1504 : {
1505 1 : addr::addr_range const & r(ips[2]);
1506 1 : CATCH_REQUIRE(r.has_from());
1507 1 : CATCH_REQUIRE_FALSE(r.has_to());
1508 1 : CATCH_REQUIRE_FALSE(r.is_range());
1509 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1510 1 : addr::addr f(r.get_from());
1511 1 : CATCH_REQUIRE(f.is_ipv4());
1512 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1513 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1514 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "10.11.12.99");
1515 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "10.11.12.99");
1516 1 : CATCH_REQUIRE(f.get_port() == 77);
1517 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1518 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
1519 1 : CATCH_REQUIRE(f.is_lan());
1520 1 : CATCH_REQUIRE(f.is_lan(true));
1521 1 : CATCH_REQUIRE(f.is_lan(false));
1522 1 : CATCH_REQUIRE_FALSE(f.is_wan());
1523 1 : CATCH_REQUIRE_FALSE(f.is_wan(true));
1524 1 : CATCH_REQUIRE_FALSE(f.is_wan(false));
1525 1 : f.get_mask(mask);
1526 17 : for(int idx(0); idx < 16; ++idx)
1527 : {
1528 16 : CATCH_REQUIRE(mask[idx] == 255);
1529 : }
1530 1 : }
1531 1 : }
1532 6 : CATCH_END_SECTION()
1533 :
1534 6 : CATCH_START_SECTION("ipv4::addr: 3 IPs with hash (#) and semicolon (;) comments")
1535 : {
1536 1 : addr::addr_parser p;
1537 1 : p.set_protocol(IPPROTO_TCP);
1538 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS, true);
1539 1 : p.set_allow(addr::allow_t::ALLOW_COMMENT_HASH, true);
1540 1 : p.set_allow(addr::allow_t::ALLOW_COMMENT_SEMICOLON, true);
1541 3 : addr::addr_range::vector_t ips(p.parse("1.2.3.4:55;first,5.6.7.8#second,10.11.12.99:77;third"));
1542 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1543 1 : CATCH_REQUIRE(ips.size() == 3);
1544 :
1545 1 : uint8_t mask[16] = {};
1546 :
1547 : // 1.2.3.4:55
1548 : {
1549 1 : addr::addr_range const & r(ips[0]);
1550 1 : CATCH_REQUIRE(r.has_from());
1551 1 : CATCH_REQUIRE_FALSE(r.has_to());
1552 1 : CATCH_REQUIRE_FALSE(r.is_range());
1553 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1554 1 : addr::addr f(r.get_from());
1555 1 : CATCH_REQUIRE(f.is_ipv4());
1556 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1557 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1558 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "1.2.3.4");
1559 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "1.2.3.4");
1560 1 : CATCH_REQUIRE(f.get_port() == 55);
1561 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1562 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1563 1 : CATCH_REQUIRE_FALSE(f.is_lan());
1564 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1565 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1566 1 : CATCH_REQUIRE(f.is_wan());
1567 1 : CATCH_REQUIRE(f.is_wan(true));
1568 1 : CATCH_REQUIRE(f.is_wan(false));
1569 1 : f.get_mask(mask);
1570 17 : for(int idx(0); idx < 16; ++idx)
1571 : {
1572 16 : CATCH_REQUIRE(mask[idx] == 255);
1573 : }
1574 1 : }
1575 :
1576 : // 5.6.7.8
1577 : {
1578 1 : addr::addr_range const & r(ips[1]);
1579 1 : CATCH_REQUIRE(r.has_from());
1580 1 : CATCH_REQUIRE_FALSE(r.has_to());
1581 1 : CATCH_REQUIRE_FALSE(r.is_range());
1582 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1583 1 : addr::addr f(r.get_from());
1584 1 : CATCH_REQUIRE(f.is_ipv4());
1585 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1586 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1587 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "5.6.7.8");
1588 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "5.6.7.8");
1589 1 : CATCH_REQUIRE(f.get_port() == 0);
1590 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1591 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1592 1 : CATCH_REQUIRE_FALSE(f.is_lan());
1593 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1594 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1595 1 : CATCH_REQUIRE(f.is_wan());
1596 1 : CATCH_REQUIRE(f.is_wan(true));
1597 1 : CATCH_REQUIRE(f.is_wan(false));
1598 1 : f.get_mask(mask);
1599 17 : for(int idx(0); idx < 16; ++idx)
1600 : {
1601 16 : CATCH_REQUIRE(mask[idx] == 255);
1602 : }
1603 1 : }
1604 :
1605 : // 10.11.12.99:77
1606 : {
1607 1 : addr::addr_range const & r(ips[2]);
1608 1 : CATCH_REQUIRE(r.has_from());
1609 1 : CATCH_REQUIRE_FALSE(r.has_to());
1610 1 : CATCH_REQUIRE_FALSE(r.is_range());
1611 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1612 1 : addr::addr f(r.get_from());
1613 1 : CATCH_REQUIRE(f.is_ipv4());
1614 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1615 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1616 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "10.11.12.99");
1617 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "10.11.12.99");
1618 1 : CATCH_REQUIRE(f.get_port() == 77);
1619 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1620 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
1621 1 : CATCH_REQUIRE(f.is_lan());
1622 1 : CATCH_REQUIRE(f.is_lan(true));
1623 1 : CATCH_REQUIRE(f.is_lan(false));
1624 1 : CATCH_REQUIRE_FALSE(f.is_wan());
1625 1 : CATCH_REQUIRE_FALSE(f.is_wan(true));
1626 1 : CATCH_REQUIRE_FALSE(f.is_wan(false));
1627 1 : f.get_mask(mask);
1628 17 : for(int idx(0); idx < 16; ++idx)
1629 : {
1630 16 : CATCH_REQUIRE(mask[idx] == 255);
1631 : }
1632 1 : }
1633 1 : }
1634 6 : CATCH_END_SECTION()
1635 21 : }
1636 :
1637 21 : CATCH_GIVEN("addr_parser() with numeric only IPv4 addresses")
1638 : {
1639 3 : CATCH_START_SECTION("ipv4::addr: simple numeric IPv4")
1640 : {
1641 1 : addr::addr_parser p;
1642 1 : p.set_protocol(IPPROTO_TCP);
1643 1 : p.set_allow(addr::allow_t::ALLOW_ADDRESS_LOOKUP, false);
1644 3 : addr::addr_range::vector_t ips(p.parse("4.3.1.2:3003"));
1645 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1646 1 : CATCH_REQUIRE(ips.size() == 1);
1647 :
1648 1 : addr::addr_range const & r(ips[0]);
1649 1 : CATCH_REQUIRE(r.has_from());
1650 1 : CATCH_REQUIRE_FALSE(r.has_to());
1651 1 : CATCH_REQUIRE_FALSE(r.is_range());
1652 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1653 1 : addr::addr f(r.get_from());
1654 1 : CATCH_REQUIRE(f.is_ipv4());
1655 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1656 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1657 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "4.3.1.2");
1658 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "4.3.1.2");
1659 1 : CATCH_REQUIRE(f.get_port() == 3003);
1660 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1661 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1662 1 : CATCH_REQUIRE_FALSE(f.is_lan());
1663 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1664 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1665 1 : CATCH_REQUIRE(f.is_wan());
1666 1 : CATCH_REQUIRE(f.is_wan(true));
1667 1 : CATCH_REQUIRE(f.is_wan(false));
1668 1 : uint8_t mask[16] = {};
1669 1 : f.get_mask(mask);
1670 17 : for(int idx(0); idx < 16; ++idx)
1671 : {
1672 16 : CATCH_REQUIRE(mask[idx] == 255);
1673 : }
1674 1 : }
1675 3 : CATCH_END_SECTION()
1676 :
1677 3 : CATCH_START_SECTION("ipv4::addr: invalid domain name address when we only accept numeric IPs")
1678 : {
1679 1 : addr::addr_parser p;
1680 1 : p.set_protocol(IPPROTO_TCP);
1681 1 : p.set_allow(addr::allow_t::ALLOW_ADDRESS_LOOKUP, false);
1682 3 : addr::addr_range::vector_t ips(p.parse("www.example.com:4471"));
1683 1 : CATCH_REQUIRE(p.has_errors());
1684 1 : CATCH_REQUIRE(p.error_count() == 1);
1685 1 : CATCH_REQUIRE(p.error_messages() == "Unknown address in \"www.example.com\" (no DNS lookup was allowed).\n");
1686 1 : CATCH_REQUIRE(ips.size() == 0);
1687 1 : }
1688 3 : CATCH_END_SECTION()
1689 :
1690 3 : CATCH_START_SECTION("ipv4::addr: invalid port: service name not allowed")
1691 : {
1692 1 : addr::addr_parser p;
1693 1 : p.set_protocol(IPPROTO_TCP);
1694 1 : p.set_allow(addr::allow_t::ALLOW_ADDRESS_LOOKUP, false);
1695 3 : addr::addr_range::vector_t ips(p.parse("192.168.255.32:https"));
1696 1 : CATCH_REQUIRE(p.has_errors());
1697 1 : CATCH_REQUIRE(p.error_count() == 1);
1698 1 : CATCH_REQUIRE(p.error_messages() == "invalid port in \"https\" (no service name lookup allowed).\n");
1699 1 : CATCH_REQUIRE(ips.size() == 0);
1700 1 : }
1701 3 : CATCH_END_SECTION()
1702 21 : }
1703 :
1704 21 : CATCH_START_SECTION("ipv4::addr: IP as hostname")
1705 : {
1706 11 : for(int idx(0); idx < 10; ++idx)
1707 : {
1708 10 : struct sockaddr_in in = sockaddr_in();
1709 10 : in.sin_family = AF_INET;
1710 10 : in.sin_port = htons(rand());
1711 10 : in.sin_addr.s_addr = htonl(rand() ^ (rand() << 16));
1712 10 : addr::addr a(in);
1713 10 : struct sockaddr_in out;
1714 10 : a.get_ipv4(out);
1715 10 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
1716 10 : CATCH_REQUIRE(a.get_hostname().empty());
1717 10 : std::string const ip(a.to_ipv4or6_string(addr::STRING_IP_ADDRESS));
1718 10 : a.set_hostname(ip);
1719 10 : CATCH_REQUIRE(a.get_hostname() == ip);
1720 10 : CATCH_REQUIRE(a.is_hostname_an_ip());
1721 30 : a.set_hostname("no.an.ip");
1722 10 : CATCH_REQUIRE(a.get_hostname() == "no.an.ip");
1723 10 : CATCH_REQUIRE_FALSE(a.is_hostname_an_ip());
1724 10 : }
1725 : }
1726 21 : CATCH_END_SECTION()
1727 :
1728 21 : CATCH_START_SECTION("ipv4::addr: set interface")
1729 : {
1730 1 : addr::addr a;
1731 1 : CATCH_REQUIRE(a.get_interface().empty());
1732 3 : a.set_interface("eth0");
1733 1 : CATCH_REQUIRE(a.get_interface() == "eth0");
1734 3 : a.set_interface("epn3");
1735 1 : CATCH_REQUIRE(a.get_interface() == "epn3");
1736 1 : a.set_interface(std::string());
1737 1 : CATCH_REQUIRE(a.get_interface().empty());
1738 1 : }
1739 21 : CATCH_END_SECTION()
1740 21 : }
1741 :
1742 :
1743 5 : CATCH_TEST_CASE("ipv4::ports", "[ipv4]")
1744 : {
1745 5 : CATCH_START_SECTION("ipv4::addr: verify port names")
1746 : {
1747 : // test a few ports that we know are and are not defined in /etc/services
1748 : //
1749 1 : addr::addr a;
1750 :
1751 1 : struct sockaddr_in in = sockaddr_in();
1752 1 : in.sin_family = AF_INET;
1753 1 : in.sin_port = htons(rand());
1754 1 : SNAP_CATCH2_NAMESPACE::random(in.sin_addr.s_addr);
1755 :
1756 : // verify network type
1757 : //
1758 1 : a.set_ipv4(in);
1759 1 : CATCH_REQUIRE(a.is_ipv4());
1760 :
1761 : struct port_name_t
1762 : {
1763 : int f_port = 0;
1764 : char const * f_name = nullptr;
1765 : };
1766 1 : port_name_t names[] = {
1767 : { 21, "ftp" },
1768 : { 22, "ssh" },
1769 : { 23, "telnet" },
1770 : { 80, "http" },
1771 : { 443, "https" },
1772 : { 4004, "" },
1773 : };
1774 :
1775 7 : for(auto n : names)
1776 : {
1777 6 : a.set_port(n.f_port);
1778 6 : CATCH_REQUIRE(a.get_port_name() == n.f_name);
1779 : }
1780 1 : }
1781 5 : CATCH_END_SECTION()
1782 :
1783 5 : CATCH_START_SECTION("ipv4::addr: verify protocol names")
1784 : {
1785 : // test a few ports that we know are and are not defined in /etc/services
1786 : //
1787 1 : addr::addr a;
1788 :
1789 1 : struct sockaddr_in6 in6 = sockaddr_in6();
1790 1 : in6.sin6_family = AF_INET6;
1791 1 : in6.sin6_port = htons(rand());
1792 : do
1793 : {
1794 1 : SNAP_CATCH2_NAMESPACE::random(in6.sin6_addr.s6_addr32[0]);
1795 1 : SNAP_CATCH2_NAMESPACE::random(in6.sin6_addr.s6_addr32[1]);
1796 1 : SNAP_CATCH2_NAMESPACE::random(in6.sin6_addr.s6_addr32[2]);
1797 1 : SNAP_CATCH2_NAMESPACE::random(in6.sin6_addr.s6_addr32[3]);
1798 1 : a.set_ipv6(in6);
1799 : }
1800 1 : while(!a.is_valid() || a.is_ipv4());
1801 1 : CATCH_REQUIRE(!a.is_ipv4());
1802 :
1803 : struct protocol_name_t
1804 : {
1805 : int f_protocol = 0;
1806 : char const * f_name = nullptr;
1807 : };
1808 1 : protocol_name_t names[] = {
1809 : { 0, "ip" },
1810 : { 6, "tcp" },
1811 : { 17, "udp" },
1812 : };
1813 :
1814 4 : for(auto n : names)
1815 : {
1816 3 : a.set_protocol(n.f_protocol);
1817 3 : CATCH_REQUIRE(a.get_protocol_name() == n.f_name);
1818 : }
1819 :
1820 4 : for(auto n : names)
1821 : {
1822 3 : a.set_protocol(n.f_name);
1823 3 : CATCH_REQUIRE(a.get_protocol() == n.f_protocol);
1824 3 : CATCH_REQUIRE(a.get_protocol_name() == n.f_name);
1825 : }
1826 1 : }
1827 5 : CATCH_END_SECTION()
1828 :
1829 5 : CATCH_GIVEN("addr_parser() with IPv4 addresses and port")
1830 : {
1831 3 : CATCH_START_SECTION("ipv4::addr: verify port")
1832 : {
1833 65537 : for(int port(0); port < 65536; ++port)
1834 : {
1835 65536 : int proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1836 65536 : addr::addr_parser p;
1837 65536 : p.set_protocol(proto);
1838 65536 : addr::addr_range::vector_t ips(p.parse("192.168.12.199:" + std::to_string(port)));
1839 65536 : CATCH_REQUIRE_FALSE(p.has_errors());
1840 65536 : CATCH_REQUIRE(ips.size() == 1);
1841 65536 : addr::addr_range const & r(ips[0]);
1842 65536 : addr::addr f(r.get_from());
1843 65536 : CATCH_REQUIRE(f.is_ipv4());
1844 65536 : CATCH_REQUIRE(f.get_family() == AF_INET);
1845 65536 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1846 65536 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "192.168.12.199");
1847 65536 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "192.168.12.199");
1848 65536 : CATCH_REQUIRE(f.get_port() == port);
1849 65536 : CATCH_REQUIRE(f.get_protocol() == proto);
1850 65536 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
1851 65536 : CATCH_REQUIRE(f.is_lan());
1852 65536 : CATCH_REQUIRE(f.is_lan(true));
1853 65536 : CATCH_REQUIRE(f.is_lan(false));
1854 65536 : CATCH_REQUIRE_FALSE(f.is_wan());
1855 65536 : CATCH_REQUIRE_FALSE(f.is_wan(true));
1856 65536 : CATCH_REQUIRE_FALSE(f.is_wan(false));
1857 65536 : }
1858 : }
1859 3 : CATCH_END_SECTION()
1860 :
1861 3 : CATCH_START_SECTION("ipv4::addr: default address with various port")
1862 : {
1863 101 : for(int idx(0); idx < 100; ++idx)
1864 : {
1865 100 : uint16_t const port(rand());
1866 100 : addr::addr_parser p;
1867 100 : p.set_protocol(IPPROTO_TCP);
1868 300 : p.set_default_address("5.5.5.5");
1869 100 : CATCH_REQUIRE(p.get_default_address4() == "5.5.5.5");
1870 100 : CATCH_REQUIRE(p.get_default_address6() == "");
1871 100 : addr::addr_range::vector_t ips(p.parse(":" + std::to_string(static_cast<int>(port))));
1872 100 : CATCH_REQUIRE_FALSE(p.has_errors());
1873 100 : CATCH_REQUIRE(ips.size() == 1);
1874 100 : addr::addr_range const & r(ips[0]);
1875 100 : CATCH_REQUIRE(r.has_from());
1876 100 : CATCH_REQUIRE_FALSE(r.has_to());
1877 100 : CATCH_REQUIRE_FALSE(r.is_range());
1878 100 : CATCH_REQUIRE_FALSE(r.is_empty());
1879 100 : addr::addr f(r.get_from());
1880 100 : CATCH_REQUIRE(f.is_ipv4());
1881 100 : CATCH_REQUIRE(f.get_family() == AF_INET);
1882 100 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1883 100 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
1884 100 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
1885 100 : CATCH_REQUIRE(f.get_port() == port);
1886 100 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1887 100 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1888 100 : CATCH_REQUIRE_FALSE(f.is_lan());
1889 100 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1890 100 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1891 100 : CATCH_REQUIRE(f.is_wan());
1892 100 : CATCH_REQUIRE(f.is_wan(true));
1893 100 : CATCH_REQUIRE(f.is_wan(false));
1894 100 : }
1895 : }
1896 3 : CATCH_END_SECTION()
1897 :
1898 3 : CATCH_START_SECTION("ipv4::addr: address with default port")
1899 : {
1900 26 : for(int idx(0); idx < 25; ++idx)
1901 : {
1902 25 : std::uint16_t const port(rand());
1903 25 : addr::addr_parser p;
1904 25 : p.set_protocol(IPPROTO_TCP);
1905 25 : if((rand() & 1) == 0)
1906 : {
1907 11 : p.set_default_port(port);
1908 : }
1909 : else
1910 : {
1911 14 : std::string const port_str(std::to_string(static_cast<int>(port)));
1912 14 : p.set_default_port(port_str);
1913 14 : }
1914 25 : CATCH_REQUIRE(p.get_default_port() == port);
1915 75 : addr::addr_range::vector_t ips(p.parse("5.5.5.5"));
1916 25 : CATCH_REQUIRE_FALSE(p.has_errors());
1917 25 : CATCH_REQUIRE(ips.size() == 1);
1918 25 : addr::addr_range const & r(ips[0]);
1919 25 : CATCH_REQUIRE(r.has_from());
1920 25 : CATCH_REQUIRE_FALSE(r.has_to());
1921 25 : CATCH_REQUIRE_FALSE(r.is_range());
1922 25 : CATCH_REQUIRE_FALSE(r.is_empty());
1923 25 : addr::addr f(r.get_from());
1924 25 : CATCH_REQUIRE(f.is_ipv4());
1925 25 : CATCH_REQUIRE(f.get_family() == AF_INET);
1926 25 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1927 25 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
1928 25 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
1929 25 : CATCH_REQUIRE(f.get_port() == port);
1930 25 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1931 25 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1932 25 : CATCH_REQUIRE_FALSE(f.is_lan());
1933 25 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1934 25 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1935 25 : CATCH_REQUIRE(f.is_wan());
1936 25 : CATCH_REQUIRE(f.is_wan(true));
1937 25 : CATCH_REQUIRE(f.is_wan(false));
1938 25 : }
1939 :
1940 26 : for(int idx(0); idx < 25; ++idx)
1941 : {
1942 25 : std::uint16_t const port(rand());
1943 25 : addr::addr_parser p;
1944 25 : p.set_protocol(IPPROTO_TCP);
1945 25 : if((rand() & 1) == 0)
1946 : {
1947 13 : p.set_default_port(port);
1948 : }
1949 : else
1950 : {
1951 12 : std::string const port_str(std::to_string(static_cast<int>(port)));
1952 12 : p.set_default_port(port_str);
1953 12 : }
1954 25 : CATCH_REQUIRE(p.get_default_port() == port);
1955 75 : addr::addr_range::vector_t ips(p.parse("5.5.5.5:"));
1956 25 : CATCH_REQUIRE_FALSE(p.has_errors());
1957 25 : CATCH_REQUIRE(ips.size() == 1);
1958 25 : addr::addr_range const & r(ips[0]);
1959 25 : CATCH_REQUIRE(r.has_from());
1960 25 : CATCH_REQUIRE_FALSE(r.has_to());
1961 25 : CATCH_REQUIRE_FALSE(r.is_range());
1962 25 : CATCH_REQUIRE_FALSE(r.is_empty());
1963 25 : addr::addr f(r.get_from());
1964 25 : CATCH_REQUIRE(f.is_ipv4());
1965 25 : CATCH_REQUIRE(f.get_family() == AF_INET);
1966 25 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1967 25 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
1968 25 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
1969 25 : CATCH_REQUIRE(f.get_port() == port);
1970 25 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1971 25 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1972 25 : CATCH_REQUIRE_FALSE(f.is_lan());
1973 25 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1974 25 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1975 25 : CATCH_REQUIRE(f.is_wan());
1976 25 : CATCH_REQUIRE(f.is_wan(true));
1977 25 : CATCH_REQUIRE(f.is_wan(false));
1978 25 : }
1979 : }
1980 3 : CATCH_END_SECTION()
1981 5 : }
1982 5 : }
1983 :
1984 :
1985 9 : CATCH_TEST_CASE("ipv4::masks", "[ipv4]")
1986 : {
1987 9 : CATCH_GIVEN("addr_parser() of address:port/mask")
1988 : {
1989 9 : CATCH_START_SECTION("ipv4::addr: mask allowed, but no mask")
1990 : {
1991 1 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1992 1 : int const port(rand() & 0xFFFF);
1993 1 : addr::addr_parser p;
1994 1 : p.set_protocol(proto);
1995 1 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
1996 1 : addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port)));
1997 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1998 1 : CATCH_REQUIRE(ips.size() == 1);
1999 1 : addr::addr_range const & r(ips[0]);
2000 1 : addr::addr f(r.get_from());
2001 1 : CATCH_REQUIRE(f.is_ipv4());
2002 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
2003 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
2004 1 : std::string result("172.19.6.91:" + std::to_string(port) + "/32");
2005 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ALL) == result);
2006 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ALL) == result);
2007 1 : CATCH_REQUIRE(f.get_port() == port);
2008 1 : CATCH_REQUIRE(f.get_protocol() == proto);
2009 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
2010 1 : CATCH_REQUIRE(f.is_lan());
2011 1 : CATCH_REQUIRE(f.is_lan(true));
2012 1 : CATCH_REQUIRE(f.is_lan(false));
2013 1 : CATCH_REQUIRE_FALSE(f.is_wan());
2014 1 : CATCH_REQUIRE_FALSE(f.is_wan(true));
2015 1 : CATCH_REQUIRE_FALSE(f.is_wan(false));
2016 1 : CATCH_REQUIRE(f.get_mask_size() == 128);
2017 1 : }
2018 9 : CATCH_END_SECTION()
2019 :
2020 9 : CATCH_START_SECTION("ipv4::addr: empty mask")
2021 : {
2022 1 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
2023 1 : int const port(rand() & 0xFFFF);
2024 1 : addr::addr_parser p;
2025 1 : p.set_protocol(proto);
2026 1 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
2027 1 : addr::addr_range::vector_t ips(p.parse("172.18.5.91:" + std::to_string(port) + "/"));
2028 1 : CATCH_REQUIRE_FALSE(p.has_errors());
2029 1 : CATCH_REQUIRE(ips.size() == 1);
2030 1 : addr::addr_range const & r(ips[0]);
2031 1 : addr::addr f(r.get_from());
2032 1 : CATCH_REQUIRE(f.is_ipv4());
2033 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
2034 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
2035 1 : std::string result("172.18.5.91:" + std::to_string(port) + "/32");
2036 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ALL) == result);
2037 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ALL) == result);
2038 1 : CATCH_REQUIRE(f.get_port() == port);
2039 1 : CATCH_REQUIRE(f.get_protocol() == proto);
2040 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
2041 1 : CATCH_REQUIRE(f.is_lan());
2042 1 : CATCH_REQUIRE(f.is_lan(true));
2043 1 : CATCH_REQUIRE(f.is_lan(false));
2044 1 : CATCH_REQUIRE_FALSE(f.is_wan());
2045 1 : CATCH_REQUIRE_FALSE(f.is_wan(true));
2046 1 : CATCH_REQUIRE_FALSE(f.is_wan(false));
2047 1 : CATCH_REQUIRE(f.get_mask_size() == 128);
2048 1 : }
2049 9 : CATCH_END_SECTION()
2050 :
2051 9 : CATCH_START_SECTION("ipv4::addr: one number masks")
2052 : {
2053 34 : for(int idx(0); idx <= 32; ++idx)
2054 : {
2055 33 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
2056 33 : int const port(rand() & 0xFFFF);
2057 33 : addr::addr_parser p;
2058 33 : p.set_protocol(proto);
2059 33 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
2060 33 : addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port) + "/" + std::to_string(idx)));
2061 33 : CATCH_REQUIRE_FALSE(p.has_errors());
2062 33 : CATCH_REQUIRE(ips.size() == 1);
2063 33 : addr::addr_range const & r(ips[0]);
2064 33 : addr::addr f(r.get_from());
2065 33 : CATCH_REQUIRE(f.is_ipv4());
2066 33 : CATCH_REQUIRE(f.get_family() == AF_INET);
2067 33 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
2068 : //uint64_t const mask(std::numeric_limits<uint64_t>::max() << (32 - idx));
2069 : //std::string mask_str(
2070 : // std::to_string((mask >> 24) & 255)
2071 : // + "."
2072 : // + std::to_string((mask >> 16) & 255)
2073 : // + "."
2074 : // + std::to_string((mask >> 8) & 255)
2075 : // + "."
2076 : // + std::to_string((mask >> 0) & 255));
2077 33 : std::string result("172.17.3.91:" + std::to_string(port) + "/" + std::to_string(idx));
2078 33 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ALL) == result);
2079 33 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ALL) == result);
2080 33 : CATCH_REQUIRE(f.get_port() == port);
2081 33 : CATCH_REQUIRE(f.get_protocol() == proto);
2082 33 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
2083 33 : CATCH_REQUIRE(f.is_lan());
2084 33 : CATCH_REQUIRE(f.is_lan(true));
2085 33 : CATCH_REQUIRE(f.is_lan(false));
2086 33 : CATCH_REQUIRE_FALSE(f.is_wan());
2087 33 : CATCH_REQUIRE_FALSE(f.is_wan(true));
2088 33 : CATCH_REQUIRE_FALSE(f.is_wan(false));
2089 33 : CATCH_REQUIRE(f.get_mask_size() == 96 + idx);
2090 33 : }
2091 : }
2092 9 : CATCH_END_SECTION()
2093 :
2094 9 : CATCH_START_SECTION("ipv4::addr: address like mask")
2095 : {
2096 26 : for(int idx(0); idx < 25; ++idx)
2097 : {
2098 25 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
2099 25 : int const port(rand() & 0xFFFF);
2100 25 : addr::addr_parser p;
2101 25 : p.set_protocol(proto);
2102 25 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
2103 25 : p.set_allow(addr::allow_t::ALLOW_ADDRESS_MASK, true);
2104 : // when specified as an IP, the mask can be absolutely anything
2105 25 : uint8_t mask[4];
2106 : do
2107 : {
2108 125 : for(int j(0); j < 4; ++j)
2109 : {
2110 100 : mask[j] = rand();
2111 : }
2112 : }
2113 25 : while(mask[0] == 0 // make sure the mask is no just a number
2114 0 : && mask[1] == 0
2115 0 : && mask[2] == 0
2116 25 : && mask[3] == 0);
2117 25 : switch(mask[0])
2118 : {
2119 2 : case 0xFF:
2120 2 : mask[0] &= ~(1 << (rand() & 7));
2121 2 : break;
2122 :
2123 0 : case 0xFE:
2124 : case 0xFC:
2125 : case 0xF8:
2126 : case 0xF0:
2127 : case 0xE0:
2128 : case 0xC0:
2129 0 : mask[0] &= 0x7F;
2130 0 : break;
2131 :
2132 1 : case 0x80:
2133 1 : mask[0] |= 1 << (rand() % 6);
2134 1 : break;
2135 :
2136 : }
2137 25 : std::string const mask_str(
2138 50 : std::to_string(static_cast<int>(mask[0]))
2139 100 : + "."
2140 100 : + std::to_string(static_cast<int>(mask[1]))
2141 100 : + "."
2142 100 : + std::to_string(static_cast<int>(mask[2]))
2143 100 : + "."
2144 100 : + std::to_string(static_cast<int>(mask[3])));
2145 50 : addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port) + "/" + mask_str));
2146 25 : CATCH_REQUIRE_FALSE(p.has_errors());
2147 25 : CATCH_REQUIRE(ips.size() == 1);
2148 25 : addr::addr_range const & r(ips[0]);
2149 50 : addr::addr f(r.get_from());
2150 25 : CATCH_REQUIRE(f.is_ipv4());
2151 25 : CATCH_REQUIRE(f.get_family() == AF_INET);
2152 25 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
2153 50 : std::string result("172.17.3.91:" + std::to_string(port) + "/" + mask_str);
2154 25 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ALL) == result);
2155 25 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ALL) == result);
2156 25 : CATCH_REQUIRE(f.get_port() == port);
2157 25 : CATCH_REQUIRE(f.get_protocol() == proto);
2158 25 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
2159 25 : CATCH_REQUIRE(f.is_lan());
2160 25 : CATCH_REQUIRE(f.is_lan(true));
2161 25 : CATCH_REQUIRE(f.is_lan(false));
2162 25 : CATCH_REQUIRE_FALSE(f.is_wan());
2163 25 : CATCH_REQUIRE_FALSE(f.is_wan(true));
2164 25 : CATCH_REQUIRE_FALSE(f.is_wan(false));
2165 :
2166 : // above we made sure that the mask was not just a number so
2167 : // here we should always get -1
2168 : //
2169 25 : CATCH_REQUIRE(f.get_mask_size() == -1);
2170 25 : }
2171 : }
2172 9 : CATCH_END_SECTION()
2173 :
2174 9 : CATCH_START_SECTION("ipv4::addr: address like mask when not allowed")
2175 : {
2176 26 : for(int idx(0); idx < 25; ++idx)
2177 : {
2178 25 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
2179 25 : int const port(rand() & 0xFFFF);
2180 25 : addr::addr_parser p;
2181 25 : p.set_protocol(proto);
2182 25 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
2183 25 : p.set_allow(addr::allow_t::ALLOW_ADDRESS_MASK, false);
2184 : // when specified as an IP, the mask can be absolutely anything
2185 25 : uint8_t mask[4];
2186 : do
2187 : {
2188 125 : for(int j(0); j < 4; ++j)
2189 : {
2190 100 : mask[j] = rand();
2191 : }
2192 : }
2193 25 : while(mask[0] == 0 // make sure the mask is no just a number
2194 0 : && mask[1] == 0
2195 0 : && mask[2] == 0
2196 25 : && mask[3] == 0);
2197 25 : switch(mask[0])
2198 : {
2199 0 : case 0xFF:
2200 0 : mask[0] &= ~(1 << (rand() & 7));
2201 0 : break;
2202 :
2203 0 : case 0xFE:
2204 : case 0xFC:
2205 : case 0xF8:
2206 : case 0xF0:
2207 : case 0xE0:
2208 : case 0xC0:
2209 0 : mask[0] &= 0x7F;
2210 0 : break;
2211 :
2212 1 : case 0x80:
2213 1 : mask[0] |= 1 << (rand() % 6);
2214 1 : break;
2215 :
2216 : }
2217 25 : std::string const mask_str(
2218 50 : std::to_string(static_cast<int>(mask[0]))
2219 100 : + "."
2220 100 : + std::to_string(static_cast<int>(mask[1]))
2221 100 : + "."
2222 100 : + std::to_string(static_cast<int>(mask[2]))
2223 100 : + "."
2224 100 : + std::to_string(static_cast<int>(mask[3])));
2225 50 : addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port) + "/" + mask_str));
2226 25 : CATCH_REQUIRE(p.has_errors());
2227 25 : CATCH_REQUIRE(ips.size() == 0);
2228 25 : }
2229 : }
2230 9 : CATCH_END_SECTION()
2231 :
2232 9 : CATCH_START_SECTION("ipv4::addr: address like default mask")
2233 : {
2234 26 : for(int idx(0); idx < 25; ++idx)
2235 : {
2236 25 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
2237 25 : int const port(rand() & 0xFFFF);
2238 25 : addr::addr_parser p;
2239 25 : p.set_protocol(proto);
2240 25 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
2241 25 : p.set_allow(addr::allow_t::ALLOW_ADDRESS_MASK, true);
2242 : // when specified as an IP, the mask can be absolutely anything
2243 : // (here the mask is a string an it will be parsed by the
2244 : // parser if required)
2245 : //
2246 25 : uint8_t mask[4];
2247 125 : for(int j(0); j < 4; ++j)
2248 : {
2249 100 : mask[j] = rand();
2250 : }
2251 25 : std::string const mask_str(
2252 50 : std::to_string(static_cast<int>(mask[0]))
2253 100 : + "."
2254 100 : + std::to_string(static_cast<int>(mask[1]))
2255 100 : + "."
2256 100 : + std::to_string(static_cast<int>(mask[2]))
2257 100 : + "."
2258 75 : + std::to_string(static_cast<int>(mask[3])));
2259 25 : p.set_default_mask(mask_str);
2260 25 : addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port)));
2261 25 : CATCH_REQUIRE_FALSE(p.has_errors());
2262 25 : CATCH_REQUIRE(ips.size() == 1);
2263 25 : addr::addr_range const & r(ips[0]);
2264 25 : addr::addr f(r.get_from());
2265 25 : CATCH_REQUIRE(f.is_ipv4());
2266 25 : CATCH_REQUIRE(f.get_family() == AF_INET);
2267 25 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
2268 25 : std::string result("172.17.3.91:" + std::to_string(port) + "/" + mask_str);
2269 25 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ALL) == result);
2270 25 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ALL) == result);
2271 25 : CATCH_REQUIRE(f.get_port() == port);
2272 25 : CATCH_REQUIRE(f.get_protocol() == proto);
2273 25 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
2274 25 : CATCH_REQUIRE(f.is_lan());
2275 25 : CATCH_REQUIRE(f.is_lan(true));
2276 25 : CATCH_REQUIRE(f.is_lan(false));
2277 25 : CATCH_REQUIRE_FALSE(f.is_wan());
2278 25 : CATCH_REQUIRE_FALSE(f.is_wan(true));
2279 25 : CATCH_REQUIRE_FALSE(f.is_wan(false));
2280 25 : uint8_t verify_mask[16];
2281 25 : f.get_mask(verify_mask);
2282 325 : for(int j(0); j < 16 - 4; ++j)
2283 : {
2284 300 : CATCH_REQUIRE(verify_mask[j] == 255);
2285 : }
2286 125 : for(int j(12); j < 16; ++j)
2287 : {
2288 100 : CATCH_REQUIRE(verify_mask[j] == mask[j - 12]);
2289 : }
2290 25 : }
2291 : }
2292 9 : CATCH_END_SECTION()
2293 :
2294 9 : CATCH_START_SECTION("ipv4::addr: address like mask with a default")
2295 : {
2296 26 : for(int idx(0); idx < 25; ++idx)
2297 : {
2298 25 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
2299 25 : int const port(rand() & 0xFFFF);
2300 25 : addr::addr_parser p;
2301 25 : p.set_protocol(proto);
2302 25 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
2303 25 : p.set_allow(addr::allow_t::ALLOW_ADDRESS_MASK, true);
2304 :
2305 : // here we want a default and an IP with a specific mask
2306 : // to make sure that the specific mask has priority
2307 : //
2308 25 : uint8_t mask[4];
2309 125 : for(int j(0); j < 4; ++j)
2310 : {
2311 100 : mask[j] = rand();
2312 : }
2313 25 : std::string const mask_str(
2314 50 : std::to_string(static_cast<int>(mask[0]))
2315 100 : + "."
2316 100 : + std::to_string(static_cast<int>(mask[1]))
2317 100 : + "."
2318 100 : + std::to_string(static_cast<int>(mask[2]))
2319 100 : + "."
2320 75 : + std::to_string(static_cast<int>(mask[3])));
2321 :
2322 25 : uint8_t default_mask[4];
2323 125 : for(int j(0); j < 4; ++j)
2324 : {
2325 100 : default_mask[j] = rand();
2326 : }
2327 25 : std::string const default_mask_str(
2328 50 : std::to_string(static_cast<int>(default_mask[0]))
2329 100 : + "."
2330 100 : + std::to_string(static_cast<int>(default_mask[1]))
2331 100 : + "."
2332 100 : + std::to_string(static_cast<int>(default_mask[2]))
2333 100 : + "."
2334 75 : + std::to_string(static_cast<int>(default_mask[3])));
2335 25 : p.set_default_mask(default_mask_str);
2336 :
2337 25 : addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port) + "/" + mask_str));
2338 25 : CATCH_REQUIRE_FALSE(p.has_errors());
2339 25 : CATCH_REQUIRE(ips.size() == 1);
2340 25 : addr::addr_range const & r(ips[0]);
2341 25 : addr::addr f(r.get_from());
2342 25 : CATCH_REQUIRE(f.is_ipv4());
2343 25 : CATCH_REQUIRE(f.get_family() == AF_INET);
2344 25 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
2345 25 : std::string result("172.17.3.91:" + std::to_string(port) + "/" + mask_str);
2346 25 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ALL) == result);
2347 25 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ALL) == result);
2348 25 : CATCH_REQUIRE(f.get_port() == port);
2349 25 : CATCH_REQUIRE(f.get_protocol() == proto);
2350 25 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
2351 25 : CATCH_REQUIRE(f.is_lan());
2352 25 : CATCH_REQUIRE(f.is_lan(true));
2353 25 : CATCH_REQUIRE(f.is_lan(false));
2354 25 : CATCH_REQUIRE_FALSE(f.is_wan());
2355 25 : CATCH_REQUIRE_FALSE(f.is_wan(true));
2356 25 : CATCH_REQUIRE_FALSE(f.is_wan(false));
2357 25 : uint8_t verify_mask[16];
2358 25 : f.get_mask(verify_mask);
2359 325 : for(int j(0); j < 16 - 4; ++j)
2360 : {
2361 300 : CATCH_REQUIRE(verify_mask[j] == 255);
2362 : }
2363 125 : for(int j(12); j < 16; ++j)
2364 : {
2365 100 : CATCH_REQUIRE(verify_mask[j] == mask[j - 12]);
2366 : }
2367 25 : }
2368 : }
2369 9 : CATCH_END_SECTION()
2370 :
2371 9 : CATCH_START_SECTION("ipv4::addr: address like default mask")
2372 : {
2373 26 : for(int idx(0); idx < 25; ++idx)
2374 : {
2375 25 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
2376 25 : int const port(rand() & 0xFFFF);
2377 25 : addr::addr_parser p;
2378 25 : p.set_protocol(proto);
2379 25 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
2380 :
2381 : //p.set_allow(addr::allow_t::ALLOW_ADDRESS_MASK, true); -- if we forget this one, the parsing fails with an error
2382 :
2383 : // when specified as an IP, the mask can be absolutely anything
2384 : // (here the mask is a string an it will be parsed by the
2385 : // parser if required)
2386 : //
2387 25 : uint8_t mask[4];
2388 125 : for(int j(0); j < 4; ++j)
2389 : {
2390 100 : mask[j] = rand();
2391 : }
2392 25 : std::string const mask_str(
2393 50 : std::to_string(static_cast<int>(mask[0]))
2394 100 : + "."
2395 100 : + std::to_string(static_cast<int>(mask[1]))
2396 100 : + "."
2397 100 : + std::to_string(static_cast<int>(mask[2]))
2398 100 : + "."
2399 75 : + std::to_string(static_cast<int>(mask[3])));
2400 25 : p.set_default_mask(mask_str);
2401 25 : addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port)));
2402 25 : CATCH_REQUIRE(p.has_errors());
2403 25 : CATCH_REQUIRE(ips.size() == 0);
2404 25 : }
2405 : }
2406 9 : CATCH_END_SECTION()
2407 :
2408 9 : CATCH_START_SECTION("ipv4::addr: two addresses and a mask for a match / no match")
2409 : {
2410 1 : int const port1(rand() & 0xFFFF);
2411 1 : addr::addr_parser p;
2412 1 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
2413 :
2414 : // parse the IP with a mask
2415 : //
2416 1 : int proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
2417 1 : p.set_protocol(proto);
2418 1 : addr::addr_range::vector_t ips1(p.parse("192.168.0.0:" + std::to_string(port1) + "/16"));
2419 1 : CATCH_REQUIRE_FALSE(p.has_errors());
2420 1 : CATCH_REQUIRE(ips1.size() == 1);
2421 1 : addr::addr_range const & r1(ips1[0]);
2422 1 : addr::addr f1(r1.get_from());
2423 1 : CATCH_REQUIRE(f1.is_ipv4());
2424 1 : CATCH_REQUIRE(f1.get_family() == AF_INET);
2425 1 : CATCH_REQUIRE_FALSE(f1.get_family() == AF_INET6);
2426 1 : CATCH_REQUIRE(f1.to_ipv4_string(addr::STRING_IP_ALL) == "192.168.0.0:" + std::to_string(port1) + "/16");
2427 1 : CATCH_REQUIRE(f1.to_ipv4or6_string(addr::STRING_IP_ALL) == "192.168.0.0:" + std::to_string(port1) + "/16");
2428 1 : CATCH_REQUIRE(f1.get_port() == port1);
2429 1 : CATCH_REQUIRE(f1.get_protocol() == proto);
2430 1 : CATCH_REQUIRE(f1.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
2431 1 : CATCH_REQUIRE(f1.is_lan());
2432 1 : CATCH_REQUIRE(f1.is_lan(true));
2433 1 : CATCH_REQUIRE(f1.is_lan(false));
2434 1 : CATCH_REQUIRE_FALSE(f1.is_wan());
2435 1 : CATCH_REQUIRE_FALSE(f1.is_wan(true));
2436 1 : CATCH_REQUIRE_FALSE(f1.is_wan(false));
2437 :
2438 : // reuse parser
2439 : //
2440 1 : proto = rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP;
2441 1 : p.set_protocol(proto);
2442 1 : int const port2(rand() & 0xFFFF);
2443 1 : addr::addr_range::vector_t ips2(p.parse("192.168.5.36:" + std::to_string(port2)));
2444 1 : CATCH_REQUIRE_FALSE(p.has_errors());
2445 1 : CATCH_REQUIRE(ips2.size() == 1);
2446 1 : addr::addr_range const & r2(ips2[0]);
2447 1 : addr::addr f2(r2.get_from());
2448 1 : CATCH_REQUIRE(f2.is_ipv4());
2449 1 : CATCH_REQUIRE(f2.get_family() == AF_INET);
2450 1 : CATCH_REQUIRE_FALSE(f2.get_family() == AF_INET6);
2451 1 : CATCH_REQUIRE(f2.to_ipv4_string(addr::STRING_IP_ALL) == "192.168.5.36:" + std::to_string(port2) + "/32");
2452 1 : CATCH_REQUIRE(f2.to_ipv4or6_string(addr::STRING_IP_ALL) == "192.168.5.36:" + std::to_string(port2) + "/32");
2453 1 : CATCH_REQUIRE(f2.get_port() == port2);
2454 1 : CATCH_REQUIRE(f2.get_protocol() == proto);
2455 1 : CATCH_REQUIRE(f2.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
2456 1 : CATCH_REQUIRE(f2.is_lan());
2457 1 : CATCH_REQUIRE(f2.is_lan(true));
2458 1 : CATCH_REQUIRE(f2.is_lan(false));
2459 1 : CATCH_REQUIRE_FALSE(f2.is_wan());
2460 1 : CATCH_REQUIRE_FALSE(f2.is_wan(true));
2461 1 : CATCH_REQUIRE_FALSE(f2.is_wan(false));
2462 :
2463 : // 3rd with a mask along the full IP
2464 : //
2465 1 : proto = rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP;
2466 1 : p.set_protocol(proto);
2467 1 : int const port3(rand() & 0xFFFF);
2468 1 : addr::addr_range::vector_t ips3(p.parse("192.168.5.36:" + std::to_string(port3) + "/16"));
2469 1 : CATCH_REQUIRE_FALSE(p.has_errors());
2470 1 : CATCH_REQUIRE(ips3.size() == 1);
2471 1 : addr::addr_range const & r3(ips3[0]);
2472 1 : addr::addr f3(r3.get_from());
2473 1 : CATCH_REQUIRE(f3.is_ipv4());
2474 1 : CATCH_REQUIRE(f3.get_family() == AF_INET);
2475 1 : CATCH_REQUIRE_FALSE(f3.get_family() == AF_INET6);
2476 1 : CATCH_REQUIRE(f3.to_ipv4_string(addr::STRING_IP_ALL) == "192.168.5.36:" + std::to_string(port3) + "/16");
2477 1 : CATCH_REQUIRE(f3.to_ipv4or6_string(addr::STRING_IP_ALL) == "192.168.5.36:" + std::to_string(port3) + "/16");
2478 1 : CATCH_REQUIRE(f3.get_port() == port3);
2479 1 : CATCH_REQUIRE(f3.get_protocol() == proto);
2480 1 : CATCH_REQUIRE(f3.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
2481 1 : CATCH_REQUIRE(f3.is_lan());
2482 1 : CATCH_REQUIRE(f3.is_lan(true));
2483 1 : CATCH_REQUIRE(f3.is_lan(false));
2484 1 : CATCH_REQUIRE_FALSE(f3.is_wan());
2485 1 : CATCH_REQUIRE_FALSE(f3.is_wan(true));
2486 1 : CATCH_REQUIRE_FALSE(f3.is_wan(false));
2487 :
2488 : // just a side test
2489 : //
2490 1 : CATCH_REQUIRE(f1 != f2);
2491 1 : CATCH_REQUIRE(f1 != f3);
2492 1 : CATCH_REQUIRE(f2 == f3);
2493 :
2494 : // check whether p1 matches p2 and vice versa
2495 : //
2496 1 : CATCH_REQUIRE(f1.match(f2)); // f2 & mask1 == f1 & mask1
2497 1 : CATCH_REQUIRE(f1.match(f3)); // f3 & mask1 == f1 & mask1
2498 :
2499 1 : CATCH_REQUIRE_FALSE(f2.match(f1)); // f1 & mask2 != f2 & mask2
2500 1 : CATCH_REQUIRE(f2.match(f3)); // f3 & mask2 == f2 & mask2 (because f2 == f3 anyway)
2501 :
2502 1 : CATCH_REQUIRE(f3.match(f1)); // f1 & mask3 == f3 & mask3
2503 1 : CATCH_REQUIRE(f3.match(f2)); // f2 & mask3 == f3 & mask3
2504 :
2505 1 : f3.apply_mask();
2506 :
2507 1 : CATCH_REQUIRE(f1 != f2);
2508 1 : CATCH_REQUIRE(f1 == f3);
2509 1 : CATCH_REQUIRE(f2 != f3);
2510 :
2511 : // re-run the match() calls with f3 since it changed...
2512 : //
2513 1 : CATCH_REQUIRE(f1.match(f3)); // f3 & mask1 == f1 & mask1
2514 :
2515 1 : CATCH_REQUIRE_FALSE(f2.match(f3)); // f3 & mask2 == f2 & mask2 (because f2 != f3 anymore)
2516 :
2517 1 : CATCH_REQUIRE(f3.match(f1)); // f1 & mask3 == f3 & mask3
2518 1 : CATCH_REQUIRE(f3.match(f2)); // f2 & mask3 == f3 & mask3
2519 :
2520 1 : addr::addr fa; // by default an address is ANY and it matches everything
2521 1 : CATCH_REQUIRE(fa.match(f1, true));
2522 1 : CATCH_REQUIRE(fa.match(f2, true));
2523 1 : CATCH_REQUIRE(fa.match(f3, true));
2524 1 : std::uint8_t const verify_match[16] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 };
2525 1 : std::uint8_t any_mask[16] = {};
2526 1 : fa.get_mask(any_mask);
2527 1 : CATCH_REQUIRE(memcmp(verify_match, any_mask, 16) == 0);
2528 1 : }
2529 9 : CATCH_END_SECTION()
2530 9 : }
2531 9 : }
2532 :
2533 :
2534 6 : CATCH_TEST_CASE("ipv4::protocol", "[ipv4]")
2535 : {
2536 6 : CATCH_GIVEN("addr()")
2537 : {
2538 2 : addr::addr a;
2539 :
2540 2 : CATCH_START_SECTION("ipv4::addr: default protocol")
2541 : {
2542 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_TCP);
2543 : }
2544 2 : CATCH_END_SECTION()
2545 :
2546 2 : CATCH_START_SECTION("ipv4::addr: set_protocol()")
2547 : {
2548 : // setup a random protocol
2549 : //
2550 2 : int const start_protocol([]()
2551 : {
2552 1 : switch(rand() % 3)
2553 : {
2554 1 : case 0:
2555 1 : return IPPROTO_IP;
2556 :
2557 0 : case 1:
2558 0 : return IPPROTO_TCP;
2559 :
2560 : //case 2:
2561 0 : default:
2562 0 : return IPPROTO_UDP;
2563 :
2564 : }
2565 1 : }());
2566 1 : a.set_protocol(start_protocol);
2567 :
2568 : // test 100 invalid protocols
2569 : //
2570 101 : for(int idx(0); idx < 100; ++idx)
2571 : {
2572 : int invalid_protocol;
2573 : do
2574 : {
2575 100 : invalid_protocol = rand();
2576 : }
2577 : while(invalid_protocol == IPPROTO_IP
2578 100 : || invalid_protocol == IPPROTO_TCP
2579 200 : || invalid_protocol == IPPROTO_UDP);
2580 100 : CATCH_REQUIRE_THROWS_AS(a.set_protocol(invalid_protocol), addr::addr_invalid_argument);
2581 :
2582 : // make sure the protocol does not change on errors
2583 100 : CATCH_REQUIRE(a.get_protocol() == start_protocol);
2584 : }
2585 :
2586 : // null string is not allowed
2587 : //
2588 1 : CATCH_REQUIRE_THROWS_AS(a.set_protocol(nullptr), addr::addr_invalid_argument);
2589 :
2590 : // other "invalid" (unsupported, really) string protocols
2591 : //
2592 1 : CATCH_REQUIRE_THROWS_AS(a.set_protocol("unknown"), addr::addr_invalid_argument);
2593 1 : CATCH_REQUIRE_THROWS_AS(a.set_protocol("invalid"), addr::addr_invalid_argument);
2594 1 : CATCH_REQUIRE_THROWS_AS(a.set_protocol("other"), addr::addr_invalid_argument);
2595 :
2596 : // test all valid protocols (numeric)
2597 : //
2598 1 : a.set_protocol(IPPROTO_IP);
2599 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_IP);
2600 1 : a.set_protocol(IPPROTO_TCP);
2601 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_TCP);
2602 1 : a.set_protocol(IPPROTO_UDP);
2603 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_UDP);
2604 :
2605 : // test all valid protocols (ascii)
2606 : //
2607 1 : a.set_protocol("ip");
2608 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_IP);
2609 1 : a.set_protocol("tcp");
2610 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_TCP);
2611 1 : a.set_protocol("udp");
2612 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_UDP);
2613 : }
2614 2 : CATCH_END_SECTION()
2615 8 : }
2616 :
2617 6 : CATCH_GIVEN("addr_parser()")
2618 : {
2619 3 : addr::addr_parser p;
2620 :
2621 3 : CATCH_START_SECTION("ipv4::addr: verify default")
2622 : {
2623 1 : CATCH_REQUIRE(p.get_protocol() == -1);
2624 : }
2625 3 : CATCH_END_SECTION()
2626 :
2627 3 : CATCH_START_SECTION("ipv4::addr: test 3 allowed protocols")
2628 : {
2629 : // by string
2630 : //
2631 3 : p.set_protocol("ip");
2632 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_IP);
2633 3 : p.set_protocol("tcp");
2634 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_TCP);
2635 3 : p.set_protocol("udp");
2636 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_UDP);
2637 :
2638 : // numerically
2639 : //
2640 1 : p.set_protocol(IPPROTO_IP);
2641 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_IP);
2642 1 : p.set_protocol(IPPROTO_TCP);
2643 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_TCP);
2644 1 : p.set_protocol(IPPROTO_UDP);
2645 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_UDP);
2646 : }
2647 3 : CATCH_END_SECTION()
2648 :
2649 3 : CATCH_START_SECTION("ipv4::addr: verify clearing works")
2650 : {
2651 3 : p.set_protocol("ip");
2652 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_IP);
2653 1 : p.clear_protocol();
2654 1 : CATCH_REQUIRE(p.get_protocol() == -1);
2655 :
2656 3 : p.set_protocol("tcp");
2657 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_TCP);
2658 1 : p.clear_protocol();
2659 1 : CATCH_REQUIRE(p.get_protocol() == -1);
2660 :
2661 3 : p.set_protocol("udp");
2662 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_UDP);
2663 1 : p.clear_protocol();
2664 1 : CATCH_REQUIRE(p.get_protocol() == -1);
2665 : }
2666 3 : CATCH_END_SECTION()
2667 9 : }
2668 :
2669 6 : CATCH_GIVEN("addr_parser with any protocol")
2670 : {
2671 1 : addr::addr a;
2672 :
2673 1 : CATCH_START_SECTION("ipv4::addr: get address with all protocols")
2674 : {
2675 1 : addr::addr_parser p;
2676 : //p.set_protocol(...); -- by default we'll get all the protocols supported
2677 3 : addr::addr_range::vector_t ips(p.parse("127.0.0.1"));
2678 1 : CATCH_REQUIRE_FALSE(p.has_errors());
2679 1 : CATCH_REQUIRE(!ips.empty());
2680 4 : for(size_t idx(0); idx < ips.size(); ++idx)
2681 : {
2682 3 : addr::addr_range const & r(ips[idx]);
2683 3 : CATCH_REQUIRE(r.has_from());
2684 3 : CATCH_REQUIRE_FALSE(r.has_to());
2685 3 : CATCH_REQUIRE_FALSE(r.is_range());
2686 3 : CATCH_REQUIRE_FALSE(r.is_empty());
2687 3 : addr::addr f(r.get_from());
2688 3 : if(f.is_ipv4())
2689 : {
2690 3 : CATCH_REQUIRE(f.get_family() == AF_INET);
2691 3 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
2692 3 : CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "127.0.0.1");
2693 3 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "127.0.0.1");
2694 3 : CATCH_REQUIRE(f.get_port() == 0);
2695 : //CATCH_REQUIRE(f.get_protocol() == ...); -- may be TCP, UDP, IP
2696 3 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_LOOPBACK);
2697 3 : CATCH_REQUIRE(f.is_lan());
2698 3 : CATCH_REQUIRE(f.is_lan(true));
2699 3 : CATCH_REQUIRE(f.is_lan(false));
2700 3 : CATCH_REQUIRE_FALSE(f.is_wan());
2701 3 : CATCH_REQUIRE_FALSE(f.is_wan(true));
2702 3 : CATCH_REQUIRE_FALSE(f.is_wan(false));
2703 : }
2704 : else
2705 : {
2706 0 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET);
2707 0 : CATCH_REQUIRE(f.get_family() == AF_INET6);
2708 0 : CATCH_REQUIRE(f.to_ipv6_string(addr::STRING_IP_ADDRESS) == "::1");
2709 0 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "::1");
2710 0 : CATCH_REQUIRE(f.get_port() == 0);
2711 : //CATCH_REQUIRE(f.get_protocol() == ...); -- may be TCP, UDP, IP
2712 0 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_LOOPBACK);
2713 0 : CATCH_REQUIRE(f.is_lan());
2714 0 : CATCH_REQUIRE(f.is_lan(true));
2715 0 : CATCH_REQUIRE(f.is_lan(false));
2716 0 : CATCH_REQUIRE_FALSE(f.is_wan());
2717 0 : CATCH_REQUIRE_FALSE(f.is_wan(true));
2718 0 : CATCH_REQUIRE_FALSE(f.is_wan(false));
2719 : }
2720 3 : }
2721 1 : }
2722 1 : CATCH_END_SECTION()
2723 7 : }
2724 6 : }
2725 :
2726 :
2727 8 : CATCH_TEST_CASE("ipv4::network_type", "[ipv4]")
2728 : {
2729 8 : CATCH_GIVEN("addr()")
2730 : {
2731 8 : addr::addr a;
2732 :
2733 8 : CATCH_START_SECTION("ipv4::addr: any (0.0.0.0)")
2734 : {
2735 1 : struct sockaddr_in in = sockaddr_in();
2736 1 : in.sin_family = AF_INET;
2737 1 : in.sin_port = htons(rand());
2738 1 : in.sin_addr.s_addr = 0;
2739 :
2740 : // verify network type
2741 : //
2742 1 : a.set_ipv4(in);
2743 :
2744 1 : CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_ANY);
2745 3 : CATCH_REQUIRE(std::string(a.get_network_type_string()) == "Any");
2746 1 : CATCH_REQUIRE_FALSE(a.is_lan());
2747 1 : CATCH_REQUIRE_FALSE(a.is_lan(true));
2748 1 : CATCH_REQUIRE_FALSE(a.is_lan(false));
2749 1 : CATCH_REQUIRE(a.is_wan());
2750 1 : CATCH_REQUIRE(a.is_wan(true));
2751 1 : CATCH_REQUIRE_FALSE(a.is_wan(false));
2752 : }
2753 8 : CATCH_END_SECTION()
2754 :
2755 8 : CATCH_START_SECTION("ipv4::addr: private address 10.x.x.x/8")
2756 : {
2757 11 : for(int idx(0); idx < 10; ++idx)
2758 : {
2759 10 : struct sockaddr_in in = sockaddr_in();
2760 10 : in.sin_family = AF_INET;
2761 10 : in.sin_port = htons(rand());
2762 : uint32_t address((10 << 24)
2763 10 : | ((rand() & 255) << 16)
2764 10 : | ((rand() & 255) << 8)
2765 10 : | ((rand() & 255) << 0));
2766 10 : in.sin_addr.s_addr = htonl(address);
2767 :
2768 : // verify network type
2769 : //
2770 10 : a.set_ipv4(in);
2771 10 : CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
2772 30 : CATCH_REQUIRE(std::string(a.get_network_type_string()) == "Private");
2773 10 : CATCH_REQUIRE(a.is_lan());
2774 10 : CATCH_REQUIRE(a.is_lan(true));
2775 10 : CATCH_REQUIRE(a.is_lan(false));
2776 10 : CATCH_REQUIRE_FALSE(a.is_wan());
2777 10 : CATCH_REQUIRE_FALSE(a.is_wan(true));
2778 10 : CATCH_REQUIRE_FALSE(a.is_wan(false));
2779 : }
2780 : }
2781 8 : CATCH_END_SECTION()
2782 :
2783 8 : CATCH_START_SECTION("ipv4::addr: private address 172.16.x.x/12")
2784 : {
2785 11 : for(int idx(0); idx < 10; ++idx)
2786 : {
2787 10 : struct sockaddr_in in = sockaddr_in();
2788 10 : in.sin_family = AF_INET;
2789 10 : in.sin_port = htons(rand());
2790 : uint32_t address((172 << 24)
2791 10 : | (((rand() & 15) | 16) << 16)
2792 10 : | ((rand() & 255) << 8)
2793 10 : | ((rand() & 255) << 0));
2794 10 : in.sin_addr.s_addr = htonl(address);
2795 :
2796 : // verify network type
2797 : //
2798 10 : a.set_ipv4(in);
2799 10 : CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
2800 30 : CATCH_REQUIRE(std::string(a.get_network_type_string()) == "Private");
2801 10 : CATCH_REQUIRE(a.is_lan());
2802 10 : CATCH_REQUIRE(a.is_lan(true));
2803 10 : CATCH_REQUIRE(a.is_lan(false));
2804 10 : CATCH_REQUIRE_FALSE(a.is_wan());
2805 10 : CATCH_REQUIRE_FALSE(a.is_wan(true));
2806 10 : CATCH_REQUIRE_FALSE(a.is_wan(false));
2807 : }
2808 : }
2809 8 : CATCH_END_SECTION()
2810 :
2811 8 : CATCH_START_SECTION("ipv4::addr: private address 192.168.x.x/16")
2812 : {
2813 11 : for(int idx(0); idx < 10; ++idx)
2814 : {
2815 10 : struct sockaddr_in in = sockaddr_in();
2816 10 : in.sin_family = AF_INET;
2817 10 : in.sin_port = htons(rand());
2818 : uint32_t address((192 << 24)
2819 : | (168 << 16)
2820 10 : | ((rand() & 255) << 8)
2821 10 : | ((rand() & 255) << 0));
2822 10 : in.sin_addr.s_addr = htonl(address);
2823 :
2824 : // verify network type
2825 : //
2826 10 : a.set_ipv4(in);
2827 10 : CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
2828 30 : CATCH_REQUIRE(std::string(a.get_network_type_string()) == "Private");
2829 10 : CATCH_REQUIRE(a.is_lan());
2830 10 : CATCH_REQUIRE(a.is_lan(true));
2831 10 : CATCH_REQUIRE(a.is_lan(false));
2832 10 : CATCH_REQUIRE_FALSE(a.is_wan());
2833 10 : CATCH_REQUIRE_FALSE(a.is_wan(true));
2834 10 : CATCH_REQUIRE_FALSE(a.is_wan(false));
2835 : }
2836 : }
2837 8 : CATCH_END_SECTION()
2838 :
2839 8 : CATCH_START_SECTION("ipv4::addr: private address 100.66.x.x/10")
2840 : {
2841 11 : for(int idx(0); idx < 10; ++idx)
2842 : {
2843 10 : struct sockaddr_in in = sockaddr_in();
2844 10 : in.sin_family = AF_INET;
2845 10 : in.sin_port = htons(rand());
2846 : uint32_t address((100 << 24)
2847 10 : | (((rand() & 63) | 64) << 16)
2848 10 : | ((rand() & 255) << 8)
2849 10 : | ((rand() & 255) << 0));
2850 10 : in.sin_addr.s_addr = htonl(address);
2851 :
2852 : // verify network type
2853 : //
2854 10 : a.set_ipv4(in);
2855 10 : CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_CARRIER);
2856 30 : CATCH_REQUIRE(std::string(a.get_network_type_string()) == "Carrier");
2857 10 : CATCH_REQUIRE_FALSE(a.is_lan());
2858 10 : CATCH_REQUIRE(a.is_lan(true));
2859 10 : CATCH_REQUIRE_FALSE(a.is_lan(false));
2860 10 : CATCH_REQUIRE_FALSE(a.is_wan());
2861 10 : CATCH_REQUIRE_FALSE(a.is_wan(true));
2862 10 : CATCH_REQUIRE_FALSE(a.is_wan(false));
2863 : }
2864 : }
2865 8 : CATCH_END_SECTION()
2866 :
2867 8 : CATCH_START_SECTION("ipv4::addr: private address 169.254.x.x/16")
2868 : {
2869 11 : for(int idx(0); idx < 10; ++idx)
2870 : {
2871 10 : struct sockaddr_in in = sockaddr_in();
2872 10 : in.sin_family = AF_INET;
2873 10 : in.sin_port = htons(rand());
2874 : uint32_t address((169 << 24)
2875 : | (254 << 16)
2876 10 : | ((rand() & 255) << 8)
2877 10 : | ((rand() & 255) << 0));
2878 10 : in.sin_addr.s_addr = htonl(address);
2879 :
2880 : // verify network type
2881 : //
2882 10 : a.set_ipv4(in);
2883 10 : CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_LINK_LOCAL);
2884 30 : CATCH_REQUIRE(std::string(a.get_network_type_string()) == "Local Link");
2885 10 : CATCH_REQUIRE_FALSE(a.is_lan());
2886 10 : CATCH_REQUIRE(a.is_lan(true));
2887 10 : CATCH_REQUIRE_FALSE(a.is_lan(false));
2888 10 : CATCH_REQUIRE_FALSE(a.is_wan());
2889 10 : CATCH_REQUIRE_FALSE(a.is_wan(true));
2890 10 : CATCH_REQUIRE_FALSE(a.is_wan(false));
2891 : }
2892 : }
2893 8 : CATCH_END_SECTION()
2894 :
2895 8 : CATCH_START_SECTION("ipv4::addr: private address 224.x.x.x/4")
2896 : {
2897 11 : for(int idx(0); idx < 10; ++idx)
2898 : {
2899 10 : struct sockaddr_in in = sockaddr_in();
2900 10 : in.sin_family = AF_INET;
2901 10 : in.sin_port = htons(rand());
2902 10 : uint32_t address((((rand() & 15) | 224) << 24)
2903 10 : | ((rand() & 255) << 16)
2904 10 : | ((rand() & 255) << 8)
2905 10 : | ((rand() & 255) << 0));
2906 10 : in.sin_addr.s_addr = htonl(address);
2907 :
2908 : // verify network type
2909 : //
2910 10 : a.set_ipv4(in);
2911 10 : CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_MULTICAST);
2912 30 : CATCH_REQUIRE(std::string(a.get_network_type_string()) == "Multicast");
2913 10 : CATCH_REQUIRE_FALSE(a.is_lan());
2914 10 : CATCH_REQUIRE(a.is_lan(true));
2915 10 : CATCH_REQUIRE_FALSE(a.is_lan(false));
2916 10 : CATCH_REQUIRE_FALSE(a.is_wan());
2917 10 : CATCH_REQUIRE_FALSE(a.is_wan(true));
2918 10 : CATCH_REQUIRE_FALSE(a.is_wan(false));
2919 :
2920 : // make sure no interface uses that IP
2921 : //
2922 10 : CATCH_REQUIRE(addr::find_addr_interface(a, false) == nullptr);
2923 : }
2924 : }
2925 8 : CATCH_END_SECTION()
2926 :
2927 8 : CATCH_START_SECTION("ipv4::addr: private address 127.x.x.x/8")
2928 : {
2929 11 : for(int idx(0); idx < 10; ++idx)
2930 : {
2931 10 : struct sockaddr_in in = sockaddr_in();
2932 10 : in.sin_family = AF_INET;
2933 10 : in.sin_port = htons(rand());
2934 : uint32_t address((127 << 24)
2935 10 : | ((rand() & 255) << 16)
2936 10 : | ((rand() & 255) << 8)
2937 10 : | ((rand() & 255) << 0));
2938 10 : in.sin_addr.s_addr = htonl(address);
2939 :
2940 : // verify network type
2941 : //
2942 10 : a.set_ipv4(in);
2943 10 : CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_LOOPBACK);
2944 30 : CATCH_REQUIRE(std::string(a.get_network_type_string()) == "Loopback");
2945 10 : CATCH_REQUIRE(a.is_lan());
2946 10 : CATCH_REQUIRE(a.is_lan(true));
2947 10 : CATCH_REQUIRE(a.is_lan(false));
2948 10 : CATCH_REQUIRE_FALSE(a.is_wan());
2949 10 : CATCH_REQUIRE_FALSE(a.is_wan(true));
2950 10 : CATCH_REQUIRE_FALSE(a.is_wan(false));
2951 : }
2952 : }
2953 8 : CATCH_END_SECTION()
2954 16 : }
2955 8 : }
2956 :
2957 :
2958 7 : CATCH_TEST_CASE("ipv4::network", "[ipv4]")
2959 : {
2960 7 : CATCH_GIVEN("set_from_socket()")
2961 : {
2962 7 : CATCH_START_SECTION("ipv4::addr: invalid socket")
2963 : {
2964 1 : addr::addr a;
2965 1 : CATCH_REQUIRE_THROWS_AS(a.set_from_socket(-1, true), addr::addr_invalid_argument);
2966 1 : CATCH_REQUIRE_THROWS_AS(a.set_from_socket(-1, false), addr::addr_invalid_argument);
2967 1 : }
2968 7 : CATCH_END_SECTION()
2969 :
2970 7 : CATCH_START_SECTION("ipv4::addr: non-opened file descriptor")
2971 : {
2972 1 : addr::addr a;
2973 :
2974 : // unless we have a bug, there should not be any file descriptor
2975 : // currently open with an ID of 1,000
2976 : //
2977 1 : CATCH_REQUIRE_THROWS_AS(a.set_from_socket(1000, true), addr::addr_io_error);
2978 1 : CATCH_REQUIRE_THROWS_AS(a.set_from_socket(1000, false), addr::addr_io_error);
2979 1 : }
2980 7 : CATCH_END_SECTION()
2981 :
2982 7 : CATCH_START_SECTION("ipv4::addr: unknown socket type")
2983 : {
2984 1 : addr::addr a;
2985 :
2986 1 : int s(socket(AF_UNIX, SOCK_STREAM, 0));
2987 1 : CATCH_REQUIRE(s >= 0);
2988 1 : std::shared_ptr<int> auto_free(&s, socket_deleter);
2989 :
2990 : // unless we have a bug, there should not be any file descriptor
2991 : // currently open with an ID of 1,000
2992 : //
2993 1 : CATCH_REQUIRE_THROWS_AS(a.set_from_socket(s, true), addr::addr_io_error);
2994 1 : CATCH_REQUIRE_THROWS_AS(a.set_from_socket(s, false), addr::addr_invalid_state);
2995 1 : }
2996 7 : CATCH_END_SECTION()
2997 :
2998 7 : CATCH_START_SECTION("ipv4::addr/addr_parser: create a server (bind), but do not test it (yet)...")
2999 : {
3000 1 : addr::addr_parser p;
3001 3 : addr::addr_range::vector_t ips(p.parse("127.0.0.1:49999"));
3002 1 : CATCH_REQUIRE(ips.size() >= 1);
3003 :
3004 1 : addr::addr & a(ips[0].get_from());
3005 1 : int s(a.create_socket(addr::addr::SOCKET_FLAG_NONBLOCK | addr::addr::SOCKET_FLAG_CLOEXEC | addr::addr::SOCKET_FLAG_REUSE));
3006 1 : CATCH_REQUIRE(s >= 0);
3007 1 : std::shared_ptr<int> auto_free(&s, socket_deleter);
3008 :
3009 1 : CATCH_REQUIRE(a.bind(s) == 0);
3010 1 : }
3011 7 : CATCH_END_SECTION()
3012 :
3013 7 : CATCH_START_SECTION("ipv4::addr/addr_parser: connect() with TCP to 127.0.0.1")
3014 : {
3015 1 : if(SNAP_CATCH2_NAMESPACE::g_tcp_port != -1)
3016 : {
3017 1 : addr::addr_parser p;
3018 1 : addr::addr_range::vector_t ips(p.parse("127.0.0.1:" + std::to_string(SNAP_CATCH2_NAMESPACE::g_tcp_port)));
3019 1 : CATCH_REQUIRE(ips.size() >= 1);
3020 :
3021 1 : addr::addr & a(ips[0].get_from());
3022 1 : int s(a.create_socket(addr::addr::SOCKET_FLAG_CLOEXEC));// | addr::addr::SOCKET_FLAG_REUSE));
3023 1 : CATCH_REQUIRE(s >= 0);
3024 1 : std::shared_ptr<int> auto_free(&s, socket_deleter);
3025 :
3026 1 : CATCH_REQUIRE(a.connect(s) == 0);
3027 :
3028 : // get socket info from the other side (peer == true)
3029 : //
3030 1 : addr::addr b;
3031 1 : b.set_from_socket(s, true);
3032 1 : CATCH_REQUIRE(b.is_ipv4());
3033 1 : CATCH_REQUIRE(b.get_family() == AF_INET);
3034 1 : CATCH_REQUIRE_FALSE(b.get_family() == AF_INET6);
3035 1 : CATCH_REQUIRE(b.to_ipv4_string(addr::STRING_IP_ADDRESS) == "127.0.0.1");
3036 1 : CATCH_REQUIRE(b.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "127.0.0.1");
3037 :
3038 : // in this case we know what the port is since we specified
3039 : // that when connecting
3040 : //
3041 1 : CATCH_REQUIRE(b.get_port() == SNAP_CATCH2_NAMESPACE::g_tcp_port);
3042 :
3043 : // now try this side (peer == false)
3044 : //
3045 1 : addr::addr c;
3046 1 : c.set_from_socket(s, false);
3047 1 : CATCH_REQUIRE(c.is_ipv4());
3048 1 : CATCH_REQUIRE(c.get_family() == AF_INET);
3049 1 : CATCH_REQUIRE_FALSE(c.get_family() == AF_INET6);
3050 1 : CATCH_REQUIRE(c.to_ipv4_string(addr::STRING_IP_ADDRESS) == "127.0.0.1");
3051 1 : CATCH_REQUIRE(c.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "127.0.0.1");
3052 :
3053 : // we cannot be sure of the port, there is a range we could
3054 : // test better (more constraining) but for this test is
3055 : // certainly does not matter much; it has to be more than
3056 : // 1023, though
3057 : //
3058 1 : CATCH_REQUIRE(c.get_port() > 1023);
3059 1 : }
3060 : else
3061 : {
3062 : // avoid issue of no assertions
3063 : //
3064 0 : CATCH_REQUIRE(SNAP_CATCH2_NAMESPACE::g_tcp_port == -1);
3065 0 : std::cout << "connect to 127.0.0.1 test skipped as no TCP port was specified on the command line." << std::endl;
3066 : }
3067 : }
3068 7 : CATCH_END_SECTION()
3069 :
3070 7 : CATCH_START_SECTION("ipv4::addr/addr_parser: connect() with UDP to 127.0.0.1:53 which fails")
3071 : {
3072 1 : addr::addr_parser p;
3073 3 : p.set_protocol("udp");
3074 3 : addr::addr_range::vector_t ips(p.parse("127.0.0.1:53"));
3075 1 : CATCH_REQUIRE(ips.size() >= 1);
3076 :
3077 1 : addr::addr & a(ips[0].get_from());
3078 1 : int s(a.create_socket(addr::addr::SOCKET_FLAG_CLOEXEC));// | addr::addr::SOCKET_FLAG_REUSE));
3079 1 : CATCH_REQUIRE(s >= 0);
3080 1 : std::shared_ptr<int> auto_free(&s, socket_deleter);
3081 :
3082 : // addr::connect() does not support UDP
3083 : //
3084 1 : CATCH_REQUIRE(a.connect(s) == -1);
3085 :
3086 1 : addr::addr b;
3087 1 : CATCH_REQUIRE_THROWS_AS(b.set_from_socket(s, true), addr::addr_io_error);
3088 1 : CATCH_REQUIRE_FALSE(b.is_ipv4());
3089 1 : CATCH_REQUIRE_FALSE(b.get_family() == AF_INET);
3090 1 : CATCH_REQUIRE(b.get_family() == AF_INET6);
3091 1 : CATCH_REQUIRE(b.to_ipv6_string(addr::STRING_IP_ADDRESS) == "::");
3092 1 : CATCH_REQUIRE(b.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "::");
3093 1 : CATCH_REQUIRE(b.get_port() == 0);
3094 :
3095 1 : addr::addr c;
3096 1 : c.set_from_socket(s, false);
3097 1 : CATCH_REQUIRE(c.is_ipv4());
3098 1 : CATCH_REQUIRE(c.get_family() == AF_INET);
3099 1 : CATCH_REQUIRE_FALSE(c.get_family() == AF_INET6);
3100 1 : CATCH_REQUIRE(c.to_ipv4_string(addr::STRING_IP_ADDRESS) == "0.0.0.0");
3101 1 : CATCH_REQUIRE(c.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "0.0.0.0");
3102 1 : CATCH_REQUIRE(c.get_port() == 0);
3103 1 : }
3104 7 : CATCH_END_SECTION()
3105 :
3106 7 : CATCH_START_SECTION("ipv4::addr/addr_parser: bind() with UDP to 127.0.0.1:<auto> (as a \"client\") which works")
3107 : {
3108 1 : addr::addr_parser p;
3109 3 : p.set_protocol("udp");
3110 3 : addr::addr_range::vector_t ips(p.parse("127.0.0.1"));
3111 1 : CATCH_REQUIRE(ips.size() >= 1);
3112 :
3113 1 : addr::addr & a(ips[0].get_from());
3114 1 : int s(a.create_socket(addr::addr::SOCKET_FLAG_CLOEXEC));// | addr::addr::SOCKET_FLAG_REUSE));
3115 1 : CATCH_REQUIRE(s >= 0);
3116 1 : std::shared_ptr<int> auto_free(&s, socket_deleter);
3117 :
3118 : // succeeds, but the port is not known
3119 : //
3120 1 : CATCH_REQUIRE(a.bind(s) == 0);
3121 :
3122 : // this is a UDP socket, there is no other side so we get ANY
3123 : //
3124 1 : addr::addr b;
3125 1 : CATCH_REQUIRE_THROWS_AS(b.set_from_socket(s, true), addr::addr_io_error);
3126 1 : CATCH_REQUIRE_FALSE(b.is_ipv4());
3127 1 : CATCH_REQUIRE_FALSE(b.get_family() == AF_INET);
3128 1 : CATCH_REQUIRE(b.get_family() == AF_INET6);
3129 1 : CATCH_REQUIRE(b.to_ipv6_string(addr::STRING_IP_ADDRESS) == "::");
3130 1 : CATCH_REQUIRE(b.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "::");
3131 1 : CATCH_REQUIRE(b.get_port() == 0);
3132 :
3133 : // now try this side (peer == false) and again it is "any"
3134 : // since it failed connecting
3135 : //
3136 1 : addr::addr c;
3137 1 : c.set_from_socket(s, false);
3138 1 : CATCH_REQUIRE(c.is_ipv4());
3139 1 : CATCH_REQUIRE(c.get_family() == AF_INET);
3140 1 : CATCH_REQUIRE_FALSE(c.get_family() == AF_INET6);
3141 1 : CATCH_REQUIRE(c.to_ipv4_string(addr::STRING_IP_ADDRESS) == "127.0.0.1");
3142 1 : CATCH_REQUIRE(c.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "127.0.0.1");
3143 :
3144 : // if this worked, the port is > 1023 (it was auto-allocated)
3145 : //
3146 1 : CATCH_REQUIRE(c.get_port() > 1023);
3147 :
3148 : // since the a.bind() is expected to read that port, it should
3149 : // equal the one in `a`
3150 : //
3151 1 : CATCH_REQUIRE(a.get_port() == c.get_port());
3152 1 : }
3153 7 : CATCH_END_SECTION()
3154 7 : }
3155 7 : }
3156 :
3157 :
3158 14 : CATCH_TEST_CASE("ipv4::string_to_addr", "[ipv4]")
3159 : {
3160 14 : CATCH_GIVEN("string_to_addr() ipv4")
3161 : {
3162 14 : CATCH_START_SECTION("ipv4::string_to_addr: empty address without defaults")
3163 : {
3164 1 : addr::addr a(addr::string_to_addr(std::string()));
3165 :
3166 1 : CATCH_REQUIRE(a.is_ipv4());
3167 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
3168 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
3169 :
3170 1 : struct sockaddr_in in = sockaddr_in();
3171 1 : in.sin_family = AF_INET;
3172 1 : in.sin_port = 0;
3173 1 : in.sin_addr.s_addr = htonl((0 << 24) | (0 << 16) | (0 << 8) | (0 << 0));
3174 :
3175 : // test string_to_addr accuracy
3176 : //
3177 1 : struct sockaddr_in out;
3178 1 : a.get_ipv4(out);
3179 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
3180 :
3181 1 : uint8_t mask[16];
3182 1 : a.get_mask(mask);
3183 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
3184 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
3185 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
3186 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
3187 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
3188 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
3189 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
3190 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
3191 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
3192 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
3193 1 : CATCH_REQUIRE(mask[10] == 0xFF);
3194 1 : CATCH_REQUIRE(mask[11] == 0xFF);
3195 1 : CATCH_REQUIRE(mask[12] == 0xFF);
3196 1 : CATCH_REQUIRE(mask[13] == 0xFF);
3197 1 : CATCH_REQUIRE(mask[14] == 0xFF);
3198 1 : CATCH_REQUIRE(mask[15] == 0xFF);
3199 1 : }
3200 14 : CATCH_END_SECTION()
3201 :
3202 14 : CATCH_START_SECTION("ipv4::string_to_addr: explicit defaults")
3203 : {
3204 3 : addr::addr a(addr::string_to_addr("5.14.34.111", std::string(), -1, std::string(), false));
3205 :
3206 1 : CATCH_REQUIRE(a.is_ipv4());
3207 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
3208 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
3209 :
3210 1 : struct sockaddr_in in = sockaddr_in();
3211 1 : in.sin_family = AF_INET;
3212 1 : in.sin_port = 0;
3213 1 : in.sin_addr.s_addr = htonl((5 << 24) | (14 << 16) | (34 << 8) | (111 << 0));
3214 :
3215 : // test string_to_addr accuracy
3216 : //
3217 1 : struct sockaddr_in out;
3218 1 : a.get_ipv4(out);
3219 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
3220 :
3221 1 : uint8_t mask[16];
3222 1 : a.get_mask(mask);
3223 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
3224 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
3225 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
3226 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
3227 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
3228 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
3229 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
3230 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
3231 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
3232 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
3233 1 : CATCH_REQUIRE(mask[10] == 0xFF);
3234 1 : CATCH_REQUIRE(mask[11] == 0xFF);
3235 1 : CATCH_REQUIRE(mask[12] == 0xFF);
3236 1 : CATCH_REQUIRE(mask[13] == 0xFF);
3237 1 : CATCH_REQUIRE(mask[14] == 0xFF);
3238 1 : CATCH_REQUIRE(mask[15] == 0xFF);
3239 1 : }
3240 14 : CATCH_END_SECTION()
3241 :
3242 14 : CATCH_START_SECTION("ipv4::string_to_addr: defaults")
3243 : {
3244 3 : addr::addr a(addr::string_to_addr("7.149.104.211"));
3245 :
3246 1 : CATCH_REQUIRE(a.is_ipv4());
3247 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
3248 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
3249 :
3250 1 : struct sockaddr_in in = sockaddr_in();
3251 1 : in.sin_family = AF_INET;
3252 1 : in.sin_port = 0;
3253 1 : in.sin_addr.s_addr = htonl((7 << 24) | (149 << 16) | (104 << 8) | (211 << 0));
3254 :
3255 : // test string_to_addr accuracy
3256 : //
3257 1 : struct sockaddr_in out;
3258 1 : a.get_ipv4(out);
3259 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
3260 :
3261 1 : uint8_t mask[16];
3262 1 : a.get_mask(mask);
3263 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
3264 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
3265 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
3266 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
3267 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
3268 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
3269 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
3270 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
3271 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
3272 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
3273 1 : CATCH_REQUIRE(mask[10] == 0xFF);
3274 1 : CATCH_REQUIRE(mask[11] == 0xFF);
3275 1 : CATCH_REQUIRE(mask[12] == 0xFF);
3276 1 : CATCH_REQUIRE(mask[13] == 0xFF);
3277 1 : CATCH_REQUIRE(mask[14] == 0xFF);
3278 1 : CATCH_REQUIRE(mask[15] == 0xFF);
3279 1 : }
3280 14 : CATCH_END_SECTION()
3281 :
3282 14 : CATCH_START_SECTION("ipv4::string_to_addr: addr & default addr")
3283 : {
3284 5 : addr::addr a(addr::string_to_addr("37.149.174.11", "1.205.32.11"));
3285 :
3286 1 : CATCH_REQUIRE(a.is_ipv4());
3287 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
3288 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
3289 :
3290 1 : struct sockaddr_in in = sockaddr_in();
3291 1 : in.sin_family = AF_INET;
3292 1 : in.sin_port = 0;
3293 1 : in.sin_addr.s_addr = htonl((37 << 24) | (149 << 16) | (174 << 8) | (11 << 0));
3294 :
3295 : // test string_to_addr accuracy
3296 : //
3297 1 : struct sockaddr_in out;
3298 1 : a.get_ipv4(out);
3299 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
3300 :
3301 1 : uint8_t mask[16];
3302 1 : a.get_mask(mask);
3303 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
3304 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
3305 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
3306 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
3307 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
3308 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
3309 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
3310 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
3311 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
3312 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
3313 1 : CATCH_REQUIRE(mask[10] == 0xFF);
3314 1 : CATCH_REQUIRE(mask[11] == 0xFF);
3315 1 : CATCH_REQUIRE(mask[12] == 0xFF);
3316 1 : CATCH_REQUIRE(mask[13] == 0xFF);
3317 1 : CATCH_REQUIRE(mask[14] == 0xFF);
3318 1 : CATCH_REQUIRE(mask[15] == 0xFF);
3319 1 : }
3320 14 : CATCH_END_SECTION()
3321 :
3322 14 : CATCH_START_SECTION("ipv4::string_to_addr: no addr, expect default addr")
3323 : {
3324 5 : addr::addr a(addr::string_to_addr("", "1.205.32.11"));
3325 :
3326 1 : CATCH_REQUIRE(a.is_ipv4());
3327 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
3328 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
3329 :
3330 1 : struct sockaddr_in in = sockaddr_in();
3331 1 : in.sin_family = AF_INET;
3332 1 : in.sin_port = 0;
3333 1 : in.sin_addr.s_addr = htonl((1 << 24) | (205 << 16) | (32 << 8) | (11 << 0));
3334 :
3335 : // test string_to_addr accuracy
3336 : //
3337 1 : struct sockaddr_in out;
3338 1 : a.get_ipv4(out);
3339 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
3340 :
3341 1 : uint8_t mask[16];
3342 1 : a.get_mask(mask);
3343 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
3344 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
3345 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
3346 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
3347 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
3348 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
3349 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
3350 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
3351 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
3352 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
3353 1 : CATCH_REQUIRE(mask[10] == 0xFF);
3354 1 : CATCH_REQUIRE(mask[11] == 0xFF);
3355 1 : CATCH_REQUIRE(mask[12] == 0xFF);
3356 1 : CATCH_REQUIRE(mask[13] == 0xFF);
3357 1 : CATCH_REQUIRE(mask[14] == 0xFF);
3358 1 : CATCH_REQUIRE(mask[15] == 0xFF);
3359 1 : }
3360 14 : CATCH_END_SECTION()
3361 :
3362 14 : CATCH_START_SECTION("ipv4::string_to_addr: addr and port, with a default port")
3363 : {
3364 5 : addr::addr a(addr::string_to_addr("69.109.223.17:697", "1.205.32.11", 123));
3365 :
3366 1 : CATCH_REQUIRE(a.is_ipv4());
3367 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
3368 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
3369 :
3370 1 : struct sockaddr_in in = sockaddr_in();
3371 1 : in.sin_family = AF_INET;
3372 1 : in.sin_port = htons(697);
3373 1 : in.sin_addr.s_addr = htonl((69 << 24) | (109 << 16) | (223 << 8) | (17 << 0));
3374 :
3375 : // test string_to_addr accuracy
3376 : //
3377 1 : struct sockaddr_in out;
3378 1 : a.get_ipv4(out);
3379 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
3380 :
3381 1 : uint8_t mask[16];
3382 1 : a.get_mask(mask);
3383 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
3384 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
3385 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
3386 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
3387 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
3388 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
3389 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
3390 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
3391 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
3392 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
3393 1 : CATCH_REQUIRE(mask[10] == 0xFF);
3394 1 : CATCH_REQUIRE(mask[11] == 0xFF);
3395 1 : CATCH_REQUIRE(mask[12] == 0xFF);
3396 1 : CATCH_REQUIRE(mask[13] == 0xFF);
3397 1 : CATCH_REQUIRE(mask[14] == 0xFF);
3398 1 : CATCH_REQUIRE(mask[15] == 0xFF);
3399 1 : }
3400 14 : CATCH_END_SECTION()
3401 :
3402 14 : CATCH_START_SECTION("ipv4::string_to_addr: addr without port, with a default port")
3403 : {
3404 5 : addr::addr a(addr::string_to_addr("169.209.23.217", "1.205.32.11", 123));
3405 :
3406 1 : CATCH_REQUIRE(a.is_ipv4());
3407 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
3408 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
3409 :
3410 1 : struct sockaddr_in in = sockaddr_in();
3411 1 : in.sin_family = AF_INET;
3412 1 : in.sin_port = htons(123);
3413 1 : in.sin_addr.s_addr = htonl((169 << 24) | (209 << 16) | (23 << 8) | (217 << 0));
3414 :
3415 : // test string_to_addr accuracy
3416 : //
3417 1 : struct sockaddr_in out;
3418 1 : a.get_ipv4(out);
3419 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
3420 :
3421 1 : uint8_t mask[16];
3422 1 : a.get_mask(mask);
3423 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
3424 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
3425 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
3426 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
3427 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
3428 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
3429 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
3430 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
3431 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
3432 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
3433 1 : CATCH_REQUIRE(mask[10] == 0xFF);
3434 1 : CATCH_REQUIRE(mask[11] == 0xFF);
3435 1 : CATCH_REQUIRE(mask[12] == 0xFF);
3436 1 : CATCH_REQUIRE(mask[13] == 0xFF);
3437 1 : CATCH_REQUIRE(mask[14] == 0xFF);
3438 1 : CATCH_REQUIRE(mask[15] == 0xFF);
3439 1 : }
3440 14 : CATCH_END_SECTION()
3441 :
3442 14 : CATCH_START_SECTION("ipv4::string_to_addr: addr without port but protocol")
3443 : {
3444 7 : addr::addr a(addr::string_to_addr("4.5.123.7", "1.205.32.11", 60000, "tcp"));
3445 :
3446 1 : CATCH_REQUIRE(a.is_ipv4());
3447 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
3448 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
3449 :
3450 1 : struct sockaddr_in in = sockaddr_in();
3451 1 : in.sin_family = AF_INET;
3452 1 : in.sin_port = htons(60000);
3453 1 : in.sin_addr.s_addr = htonl((4 << 24) | (5 << 16) | (123 << 8) | (7 << 0));
3454 :
3455 : // test string_to_addr accuracy
3456 : //
3457 1 : struct sockaddr_in out;
3458 1 : a.get_ipv4(out);
3459 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
3460 :
3461 1 : uint8_t mask[16];
3462 1 : a.get_mask(mask);
3463 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
3464 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
3465 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
3466 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
3467 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
3468 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
3469 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
3470 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
3471 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
3472 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
3473 1 : CATCH_REQUIRE(mask[10] == 0xFF);
3474 1 : CATCH_REQUIRE(mask[11] == 0xFF);
3475 1 : CATCH_REQUIRE(mask[12] == 0xFF);
3476 1 : CATCH_REQUIRE(mask[13] == 0xFF);
3477 1 : CATCH_REQUIRE(mask[14] == 0xFF);
3478 1 : CATCH_REQUIRE(mask[15] == 0xFF);
3479 1 : }
3480 14 : CATCH_END_SECTION()
3481 :
3482 14 : CATCH_START_SECTION("ipv4::string_to_addr: addr with port and protocol")
3483 : {
3484 7 : addr::addr a(addr::string_to_addr("204.105.13.9:65", "1.205.32.11", 60000, "tcp"));
3485 :
3486 1 : CATCH_REQUIRE(a.is_ipv4());
3487 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
3488 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
3489 :
3490 1 : struct sockaddr_in in = sockaddr_in();
3491 1 : in.sin_family = AF_INET;
3492 1 : in.sin_port = htons(65);
3493 1 : in.sin_addr.s_addr = htonl((204 << 24) | (105 << 16) | (13 << 8) | (9 << 0));
3494 :
3495 : // test string_to_addr accuracy
3496 : //
3497 1 : struct sockaddr_in out;
3498 1 : a.get_ipv4(out);
3499 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
3500 :
3501 1 : uint8_t mask[16];
3502 1 : a.get_mask(mask);
3503 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
3504 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
3505 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
3506 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
3507 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
3508 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
3509 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
3510 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
3511 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
3512 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
3513 1 : CATCH_REQUIRE(mask[10] == 0xFF);
3514 1 : CATCH_REQUIRE(mask[11] == 0xFF);
3515 1 : CATCH_REQUIRE(mask[12] == 0xFF);
3516 1 : CATCH_REQUIRE(mask[13] == 0xFF);
3517 1 : CATCH_REQUIRE(mask[14] == 0xFF);
3518 1 : CATCH_REQUIRE(mask[15] == 0xFF);
3519 1 : }
3520 14 : CATCH_END_SECTION()
3521 :
3522 14 : CATCH_START_SECTION("ipv4::string_to_addr: addr with port and protocol but no mask, albeit allowed")
3523 : {
3524 7 : addr::addr a(addr::string_to_addr("94.95.131.18:765", "11.205.32.21", 54003, "tcp", true));
3525 :
3526 1 : CATCH_REQUIRE(a.is_ipv4());
3527 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
3528 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
3529 :
3530 1 : struct sockaddr_in in = sockaddr_in();
3531 1 : in.sin_family = AF_INET;
3532 1 : in.sin_port = htons(765);
3533 1 : in.sin_addr.s_addr = htonl((94 << 24) | (95 << 16) | (131 << 8) | (18 << 0));
3534 :
3535 : // test string_to_addr accuracy
3536 : //
3537 1 : struct sockaddr_in out;
3538 1 : a.get_ipv4(out);
3539 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
3540 :
3541 1 : uint8_t mask[16];
3542 1 : a.get_mask(mask);
3543 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
3544 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
3545 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
3546 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
3547 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
3548 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
3549 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
3550 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
3551 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
3552 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
3553 1 : CATCH_REQUIRE(mask[10] == 0xFF);
3554 1 : CATCH_REQUIRE(mask[11] == 0xFF);
3555 1 : CATCH_REQUIRE(mask[12] == 0xFF);
3556 1 : CATCH_REQUIRE(mask[13] == 0xFF);
3557 1 : CATCH_REQUIRE(mask[14] == 0xFF);
3558 1 : CATCH_REQUIRE(mask[15] == 0xFF);
3559 1 : }
3560 14 : CATCH_END_SECTION()
3561 :
3562 14 : CATCH_START_SECTION("ipv4::string_to_addr: addr with port and protocol and mask, albeit allowed")
3563 : {
3564 7 : addr::addr a(addr::string_to_addr("44.45.141.48:765/30", "11.205.32.21", 54003, "tcp", true));
3565 :
3566 1 : CATCH_REQUIRE(a.is_ipv4());
3567 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
3568 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
3569 :
3570 1 : struct sockaddr_in in = sockaddr_in();
3571 1 : in.sin_family = AF_INET;
3572 1 : in.sin_port = htons(765);
3573 1 : in.sin_addr.s_addr = htonl((44 << 24) | (45 << 16) | (141 << 8) | (48 << 0));
3574 :
3575 : // test string_to_addr accuracy
3576 : //
3577 1 : struct sockaddr_in out;
3578 1 : a.get_ipv4(out);
3579 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
3580 :
3581 1 : uint8_t mask[16];
3582 1 : a.get_mask(mask);
3583 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
3584 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
3585 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
3586 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
3587 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
3588 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
3589 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
3590 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
3591 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
3592 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
3593 1 : CATCH_REQUIRE(mask[10] == 0xFF);
3594 1 : CATCH_REQUIRE(mask[11] == 0xFF);
3595 1 : CATCH_REQUIRE(mask[12] == 0xFF);
3596 1 : CATCH_REQUIRE(mask[13] == 0xFF);
3597 1 : CATCH_REQUIRE(mask[14] == 0xFF);
3598 1 : CATCH_REQUIRE(mask[15] == 0xFC);
3599 1 : }
3600 14 : CATCH_END_SECTION()
3601 :
3602 14 : CATCH_START_SECTION("ipv4::string_to_addr: addr with port and protocol and mask, albeit allowed")
3603 : {
3604 7 : addr::addr a(addr::string_to_addr("160.0.0.0:1675/4", "11.205.32.21", 14003, "udp", true));
3605 :
3606 1 : CATCH_REQUIRE(a.is_ipv4());
3607 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
3608 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
3609 :
3610 1 : struct sockaddr_in in = sockaddr_in();
3611 1 : in.sin_family = AF_INET;
3612 1 : in.sin_port = htons(1675);
3613 1 : in.sin_addr.s_addr = htonl((160 << 24) | (0 << 16) | (0 << 8) | (0 << 0));
3614 :
3615 : // test string_to_addr accuracy
3616 : //
3617 1 : struct sockaddr_in out;
3618 1 : a.get_ipv4(out);
3619 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
3620 :
3621 1 : uint8_t mask[16];
3622 1 : a.get_mask(mask);
3623 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
3624 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
3625 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
3626 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
3627 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
3628 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
3629 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
3630 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
3631 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
3632 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
3633 1 : CATCH_REQUIRE(mask[10] == 0xFF);
3634 1 : CATCH_REQUIRE(mask[11] == 0xFF);
3635 1 : CATCH_REQUIRE(mask[12] == 0xF0);
3636 1 : CATCH_REQUIRE(mask[13] == 0x00);
3637 1 : CATCH_REQUIRE(mask[14] == 0x00);
3638 1 : CATCH_REQUIRE(mask[15] == 0x00);
3639 1 : }
3640 14 : CATCH_END_SECTION()
3641 :
3642 14 : CATCH_START_SECTION("ipv4::string_to_addr: addr with port and invalid protocol so we get an exception")
3643 : {
3644 12 : CATCH_REQUIRE_THROWS_AS(addr::string_to_addr("169.60.33.0:9322/24", std::string(), -1, "icmp", true),
3645 : addr::addr_invalid_argument);
3646 : }
3647 14 : CATCH_END_SECTION()
3648 :
3649 14 : CATCH_START_SECTION("ipv4::string_to_addr: definitely not a valid address")
3650 : {
3651 12 : CATCH_REQUIRE_THROWS_MATCHES(
3652 : addr::string_to_addr("not an address")
3653 : , addr::addr_invalid_argument
3654 : , Catch::Matchers::ExceptionMessage("addr_error: the address \"not an address\" could not be converted to a single address in string_to_addr(), found 0 entries instead."));
3655 : }
3656 14 : CATCH_END_SECTION()
3657 14 : }
3658 14 : }
3659 :
3660 :
3661 3 : CATCH_TEST_CASE("ipv4::udp", "[ipv4]")
3662 : {
3663 3 : constexpr int const TEST_PORT(4004);
3664 3 : constexpr int const TEST_PROTOCOL(IPPROTO_UDP);
3665 3 : constexpr int const TEST_COUNT(10);
3666 :
3667 3 : CATCH_START_SECTION("ipv4::udp: sendto() and recvfrom()")
3668 : {
3669 : class sr
3670 : {
3671 : public:
3672 1 : sr()
3673 1 : {
3674 1 : f_a.set_protocol(TEST_PROTOCOL);
3675 1 : f_a.set_ipv4_loopback();
3676 1 : f_a.set_port(TEST_PORT);
3677 1 : f_sa = f_a.create_socket(addr::addr::SOCKET_FLAG_CLOEXEC | addr::addr::SOCKET_FLAG_REUSE);
3678 1 : CATCH_REQUIRE(f_sa != -1);
3679 :
3680 1 : f_b.set_protocol(TEST_PROTOCOL);
3681 1 : f_b.set_ipv4_loopback();
3682 1 : f_b.set_port(TEST_PORT);
3683 1 : f_sb = f_b.create_socket(addr::addr::SOCKET_FLAG_CLOEXEC | addr::addr::SOCKET_FLAG_REUSE);
3684 1 : CATCH_REQUIRE(f_sb != -1);
3685 1 : f_b.bind(f_sb); // the receive has to be bound
3686 :
3687 11 : for(int i(0); i < TEST_COUNT; ++i)
3688 : {
3689 10 : std::size_t const size(rand() % 350 + 50);
3690 10 : f_buf[i].resize(size);
3691 2264 : for(std::size_t idx(0); idx < size; ++idx)
3692 : {
3693 2254 : f_buf[i][idx] = rand();
3694 : }
3695 : }
3696 1 : }
3697 :
3698 1 : void run()
3699 : {
3700 1 : int client_port(-1);
3701 11 : for(int i(0); i < TEST_COUNT; ++i)
3702 : {
3703 10 : sendto(i);
3704 :
3705 30 : std::vector<std::uint8_t> bb(f_buf[i].size());
3706 10 : int const r(f_b.recvfrom(f_sb, reinterpret_cast<char *>(bb.data()), bb.size()));
3707 10 : if(r == -1)
3708 : {
3709 0 : int const e(errno);
3710 0 : std::cerr << "--- recvfrom() returned an error: " << strerror(e) << std::endl;
3711 0 : return;
3712 : }
3713 :
3714 10 : CATCH_REQUIRE(r == static_cast<int>(f_buf[i].size()));
3715 10 : CATCH_REQUIRE(f_buf[i] == bb);
3716 10 : CATCH_REQUIRE(f_b.is_ipv4());
3717 10 : if(client_port == -1)
3718 : {
3719 1 : client_port = f_b.get_port();
3720 : }
3721 : else
3722 : {
3723 : // the ephemeral port does not change once we sent
3724 : // the first packet
3725 : //
3726 9 : CATCH_REQUIRE(f_b.get_port() == client_port);
3727 : }
3728 10 : CATCH_REQUIRE(f_b.get_network_type() == addr::network_type_t::NETWORK_TYPE_LOOPBACK);
3729 10 : }
3730 : }
3731 :
3732 10 : void sendto(int idx)
3733 : {
3734 10 : int const r(f_a.sendto(f_sa, reinterpret_cast<char const *>(f_buf[idx].data()), f_buf[idx].size()));
3735 10 : if(r == -1)
3736 : {
3737 0 : int const e(errno);
3738 0 : std::cerr << "--- sendto() returned an error: " << strerror(e) << std::endl;
3739 0 : return;
3740 : }
3741 10 : CATCH_REQUIRE(r == static_cast<int>(f_buf[idx].size()));
3742 : }
3743 :
3744 : addr::addr f_a = addr::addr();
3745 : addr::addr f_b = addr::addr();
3746 : int f_sa = -1;
3747 : int f_sb = -1;
3748 : std::vector<std::uint8_t> f_buf[TEST_COUNT] = {};
3749 : };
3750 :
3751 1 : sr run;
3752 1 : run.run();
3753 1 : }
3754 3 : CATCH_END_SECTION()
3755 :
3756 3 : CATCH_START_SECTION("ipv4::udp: sendto() with wrong protocol")
3757 : {
3758 1 : addr::addr a;
3759 1 : a.set_protocol(IPPROTO_TCP);
3760 1 : a.set_ipv4_loopback();
3761 1 : a.set_port(TEST_PORT);
3762 1 : int sa(a.create_socket(addr::addr::SOCKET_FLAG_CLOEXEC | addr::addr::SOCKET_FLAG_REUSE));
3763 1 : CATCH_REQUIRE(sa != -1);
3764 :
3765 1 : char buf[256];
3766 1 : int const r(a.sendto(sa, buf, sizeof(buf)));
3767 1 : int const e(errno);
3768 1 : CATCH_REQUIRE(r == -1);
3769 1 : CATCH_REQUIRE(e == EINVAL);
3770 :
3771 1 : close(sa);
3772 1 : }
3773 3 : CATCH_END_SECTION()
3774 :
3775 3 : CATCH_START_SECTION("ipv4::udp: recvfrom() with wrong protocol")
3776 : {
3777 1 : addr::addr a;
3778 1 : a.set_protocol(IPPROTO_TCP);
3779 1 : a.set_ipv4_loopback();
3780 1 : a.set_port(TEST_PORT);
3781 1 : int sa(a.create_socket(addr::addr::SOCKET_FLAG_CLOEXEC | addr::addr::SOCKET_FLAG_REUSE));
3782 1 : CATCH_REQUIRE(sa != -1);
3783 1 : a.bind(sa); // the receive has to be bound
3784 :
3785 1 : char buf[256];
3786 1 : int const r(a.recvfrom(sa, buf, sizeof(buf)));
3787 1 : int const e(errno);
3788 1 : CATCH_REQUIRE(r == -1);
3789 1 : CATCH_REQUIRE(e == EINVAL);
3790 :
3791 1 : close(sa);
3792 1 : }
3793 3 : CATCH_END_SECTION()
3794 3 : }
3795 :
3796 :
3797 : // vim: ts=4 sw=4 et
|