Line data Source code
1 : // Copyright (c) 2011-2022 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 : * strucure 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 17 : CATCH_TEST_CASE("ipv4::invalid_input", "[ipv4]")
88 : {
89 30 : CATCH_GIVEN("addr()")
90 : {
91 2 : addr::addr a;
92 :
93 2 : 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 0 : 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 25 : CATCH_REQUIRE_THROWS_AS(addr::addr(in), addr::addr_invalid_argument);
107 : }
108 : }
109 : CATCH_END_SECTION()
110 : }
111 :
112 30 : CATCH_GIVEN("addr_parser() with IPv4 settings")
113 : {
114 4 : addr::addr_parser a;
115 :
116 4 : CATCH_START_SECTION("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 0 : 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 : CATCH_END_SECTION()
143 :
144 4 : CATCH_START_SECTION("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 0 : 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 : CATCH_END_SECTION()
168 : }
169 :
170 30 : CATCH_GIVEN("addr_parser() with IPv4 addresses")
171 : {
172 4 : CATCH_START_SECTION("addr_parser(): bad address")
173 : {
174 2 : addr::addr_parser p;
175 2 : 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: 2 -- No such file or directory).\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 : }
184 : CATCH_END_SECTION()
185 :
186 4 : CATCH_START_SECTION("addr_parser(): required address")
187 : {
188 2 : addr::addr_parser p;
189 1 : p.set_protocol(IPPROTO_TCP);
190 1 : p.set_allow(addr::allow_t::ALLOW_REQUIRED_ADDRESS, true);
191 2 : 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 : }
200 : CATCH_END_SECTION()
201 : }
202 :
203 30 : CATCH_GIVEN("addr_parser() with IPv4 ports")
204 : {
205 6 : CATCH_START_SECTION("addr_parser(): required port")
206 : {
207 : // optional + required -> required
208 : {
209 2 : addr::addr_parser p;
210 1 : p.set_protocol(IPPROTO_TCP);
211 1 : p.set_allow(addr::allow_t::ALLOW_REQUIRED_PORT, true);
212 2 : 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 : }
221 :
222 : // only required -> required just the same
223 : {
224 2 : 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 2 : 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 : }
237 : }
238 : CATCH_END_SECTION()
239 :
240 6 : CATCH_START_SECTION("addr_parser(): port not allowed")
241 : {
242 2 : 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 2 : 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 : }
255 : CATCH_END_SECTION()
256 :
257 6 : CATCH_START_SECTION("addr_parser(): invalid port")
258 : {
259 2 : 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 0 : 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 50 : 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 : }
283 :
284 1 : CATCH_REQUIRE_THROWS_AS(p.set_default_port("not-a-number"), addr::addr_invalid_argument);
285 : }
286 : CATCH_END_SECTION()
287 : }
288 :
289 30 : CATCH_GIVEN("addr_parser() with invalid masks")
290 : {
291 10 : CATCH_START_SECTION("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 10 : addr::addr_parser p;
299 5 : p.set_protocol(proto);
300 5 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
301 10 : 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 number too large (" + std::to_string(mask) + ", expected a maximum of 128).\n");
305 5 : CATCH_REQUIRE(ips.size() == 0);
306 : }
307 : }
308 : CATCH_END_SECTION()
309 :
310 10 : CATCH_START_SECTION("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 10 : addr::addr_parser p;
318 5 : p.set_protocol(proto);
319 5 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
320 10 : 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 : }
326 : }
327 : CATCH_END_SECTION()
328 :
329 10 : CATCH_START_SECTION("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 10 : 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 10 : 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 : }
345 : }
346 : CATCH_END_SECTION()
347 :
348 10 : CATCH_START_SECTION("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 2 : 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 2 : addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port) + "/[1:2:3:4:5:6:7:8]"));
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 : }
362 : CATCH_END_SECTION()
363 :
364 10 : CATCH_START_SECTION("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 2 : 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 2 : addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port) + "/1:2:3:4:5:6:7:8"));
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 : }
378 : CATCH_END_SECTION()
379 : }
380 :
381 30 : CATCH_GIVEN("addr_parser() with invalid protocols")
382 : {
383 4 : CATCH_START_SECTION("addr_parser(): invalid names")
384 : {
385 2 : addr::addr_parser p;
386 :
387 : // not changing default protocol
388 : //
389 1 : CATCH_REQUIRE(p.get_protocol() == -1);
390 1 : 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 1 : p.set_protocol("tcp");
396 1 : CATCH_REQUIRE_THROWS_AS(p.set_protocol("another"), addr::addr_invalid_argument);
397 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_TCP);
398 : }
399 : CATCH_END_SECTION()
400 :
401 4 : CATCH_START_SECTION("addr_parser(): invalid numbers")
402 : {
403 101 : for(int idx(0); idx < 100; ++idx)
404 : {
405 : int protocol;
406 0 : do
407 : {
408 100 : protocol = rand();
409 : }
410 : while(protocol == IPPROTO_IP
411 100 : || protocol == IPPROTO_TCP
412 200 : || protocol == IPPROTO_UDP);
413 :
414 200 : 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 100 : 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 : }
425 : }
426 : CATCH_END_SECTION()
427 : }
428 15 : }
429 :
430 :
431 11 : CATCH_TEST_CASE("ipv4::address_defaults", "[ipv4][ipv6]")
432 : {
433 18 : CATCH_GIVEN("addr()")
434 : {
435 18 : addr::addr a;
436 :
437 18 : CATCH_START_SECTION("addr: 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 1 : CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::string_ip_t::STRING_IP_ONLY), addr::addr_invalid_state);
449 1 : CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::string_ip_t::STRING_IP_BRACKETS), addr::addr_invalid_state);
450 1 : CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::string_ip_t::STRING_IP_PORT), addr::addr_invalid_state);
451 1 : CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::string_ip_t::STRING_IP_MASK), addr::addr_invalid_state);
452 1 : CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::string_ip_t::STRING_IP_BRACKETS_MASK), addr::addr_invalid_state);
453 1 : CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::string_ip_t::STRING_IP_ALL), addr::addr_invalid_state);
454 : }
455 : CATCH_END_SECTION()
456 :
457 18 : CATCH_START_SECTION("addr: default network type (0.0.0.0)")
458 : {
459 1 : CATCH_REQUIRE(a.is_default());
460 1 : CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_ANY);
461 1 : CATCH_REQUIRE(a.get_network_type_string() == "Any");
462 1 : CATCH_REQUIRE_FALSE(a.is_lan());
463 1 : CATCH_REQUIRE_FALSE(a.is_lan(true));
464 1 : CATCH_REQUIRE_FALSE(a.is_lan(false));
465 1 : CATCH_REQUIRE(a.is_wan());
466 1 : CATCH_REQUIRE(a.is_wan(true));
467 1 : CATCH_REQUIRE_FALSE(a.is_wan(false));
468 : }
469 : CATCH_END_SECTION()
470 :
471 18 : CATCH_START_SECTION("addr: IPv6 ANY")
472 : {
473 1 : struct sockaddr_in6 in6;
474 1 : a.get_ipv6(in6);
475 1 : CATCH_REQUIRE(in6.sin6_addr.s6_addr32[0] == 0);
476 1 : CATCH_REQUIRE(in6.sin6_addr.s6_addr32[1] == 0);
477 1 : CATCH_REQUIRE(in6.sin6_addr.s6_addr32[2] == 0);
478 1 : CATCH_REQUIRE(in6.sin6_addr.s6_addr32[3] == 0);
479 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::string_ip_t::STRING_IP_ONLY) == "::");
480 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::string_ip_t::STRING_IP_BRACKETS) == "[::]");
481 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::string_ip_t::STRING_IP_PORT) == "[::]:0");
482 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::string_ip_t::STRING_IP_MASK) == "::/128");
483 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::string_ip_t::STRING_IP_BRACKETS_MASK) == "[::]/128");
484 1 : CATCH_REQUIRE(a.to_ipv6_string(addr::string_ip_t::STRING_IP_ALL) == "[::]:0/128");
485 : }
486 : CATCH_END_SECTION()
487 :
488 18 : CATCH_START_SECTION("addr: IPv4 or IPv6 string")
489 : {
490 1 : CATCH_REQUIRE(a.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ONLY) == "::");
491 1 : CATCH_REQUIRE(a.to_ipv4or6_string(addr::string_ip_t::STRING_IP_BRACKETS) == "[::]");
492 1 : CATCH_REQUIRE(a.to_ipv4or6_string(addr::string_ip_t::STRING_IP_PORT) == "[::]:0");
493 1 : CATCH_REQUIRE(a.to_ipv4or6_string(addr::string_ip_t::STRING_IP_MASK) == "::/128");
494 1 : CATCH_REQUIRE(a.to_ipv4or6_string(addr::string_ip_t::STRING_IP_BRACKETS_MASK) == "[::]/128");
495 1 : CATCH_REQUIRE(a.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ALL) == "[::]:0/128");
496 : }
497 : CATCH_END_SECTION()
498 :
499 18 : CATCH_START_SECTION("addr: interface determination")
500 : {
501 1 : CATCH_REQUIRE(addr::find_addr_interface(a, false) == nullptr);
502 1 : CATCH_REQUIRE(addr::find_addr_interface(a, true) != nullptr);
503 : }
504 : CATCH_END_SECTION()
505 :
506 18 : CATCH_START_SECTION("addr: default name/service/port/protocol")
507 : {
508 1 : CATCH_REQUIRE(a.get_name() == std::string());
509 1 : CATCH_REQUIRE(a.get_service() == std::string());
510 1 : CATCH_REQUIRE(a.get_port() == 0);
511 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_TCP);
512 : }
513 : CATCH_END_SECTION()
514 :
515 18 : CATCH_START_SECTION("addr: compare with self")
516 : {
517 1 : CATCH_REQUIRE(a == a);
518 1 : CATCH_REQUIRE_FALSE(a != a);
519 1 : CATCH_REQUIRE_FALSE(a < a);
520 1 : CATCH_REQUIRE(a <= a);
521 1 : CATCH_REQUIRE_FALSE(a > a);
522 1 : CATCH_REQUIRE(a >= a);
523 : }
524 : CATCH_END_SECTION()
525 :
526 18 : CATCH_START_SECTION("addr: compare with another 0.0.0.0")
527 : {
528 : {
529 2 : addr::addr b;
530 :
531 1 : CATCH_REQUIRE(a == b);
532 1 : CATCH_REQUIRE_FALSE(a != b);
533 1 : CATCH_REQUIRE_FALSE(a < b);
534 1 : CATCH_REQUIRE(a <= b);
535 1 : CATCH_REQUIRE_FALSE(a > b);
536 1 : CATCH_REQUIRE(a >= b);
537 : }
538 :
539 : {
540 1 : struct sockaddr_in6 in6 = sockaddr_in6();
541 1 : in6.sin6_family = AF_INET6;
542 1 : in6.sin6_port = htons(0);
543 1 : in6.sin6_addr.s6_addr32[0] = htonl(0);
544 1 : in6.sin6_addr.s6_addr32[1] = htonl(0);
545 1 : in6.sin6_addr.s6_addr32[2] = htonl(0);
546 1 : in6.sin6_addr.s6_addr32[3] = htonl(0);
547 2 : addr::addr b(in6);
548 :
549 1 : CATCH_REQUIRE(a == b);
550 1 : CATCH_REQUIRE_FALSE(a != b);
551 1 : CATCH_REQUIRE_FALSE(a < b);
552 1 : CATCH_REQUIRE(a <= b);
553 1 : CATCH_REQUIRE_FALSE(a > b);
554 1 : CATCH_REQUIRE(a >= b);
555 : }
556 :
557 : // ANY in IPv4 != ANY in IPv6...
558 : // (i.e. IPv4 sets addr.sin6_addr.s6_addr16[5] == 0xFFFF)
559 : {
560 1 : struct sockaddr_in in = sockaddr_in();
561 1 : in.sin_family = AF_INET;
562 1 : in.sin_port = htons(0);
563 1 : in.sin_addr.s_addr = htonl(0);
564 2 : addr::addr b(in);
565 :
566 1 : CATCH_REQUIRE_FALSE(a == b);
567 1 : CATCH_REQUIRE(a != b);
568 1 : CATCH_REQUIRE(a < b);
569 1 : CATCH_REQUIRE(a <= b);
570 1 : CATCH_REQUIRE_FALSE(a > b);
571 1 : CATCH_REQUIRE_FALSE(a >= b);
572 : }
573 : }
574 : CATCH_END_SECTION()
575 :
576 18 : CATCH_START_SECTION("addr: compare with IPv4 127.0.0.1")
577 : {
578 1 : struct sockaddr_in in = sockaddr_in();
579 1 : in.sin_family = AF_INET;
580 1 : in.sin_port = htons(80);
581 1 : in.sin_addr.s_addr = htonl((127 << 24) | 1);
582 2 : addr::addr b(in);
583 :
584 1 : CATCH_REQUIRE_FALSE(a == b);
585 1 : CATCH_REQUIRE(a != b);
586 1 : CATCH_REQUIRE(a < b);
587 1 : CATCH_REQUIRE(a <= b);
588 1 : CATCH_REQUIRE_FALSE(a > b);
589 1 : CATCH_REQUIRE_FALSE(a >= b);
590 : }
591 : CATCH_END_SECTION()
592 : }
593 9 : }
594 :
595 :
596 20 : CATCH_TEST_CASE("ipv4::address", "[ipv4]")
597 : {
598 36 : CATCH_GIVEN("addr() with an IPv4")
599 : {
600 6 : addr::addr a;
601 :
602 6 : CATCH_START_SECTION("addr: set_ipv4() / get_ipv4()")
603 : {
604 11 : for(int idx(0); idx < 10; ++idx)
605 : {
606 10 : struct sockaddr_in in = sockaddr_in();
607 10 : in.sin_family = AF_INET;
608 10 : in.sin_port = htons(rand());
609 10 : in.sin_addr.s_addr = htonl(rand() ^ (rand() << 16));
610 :
611 : // test constructor
612 : //
613 20 : addr::addr b(in);
614 10 : struct sockaddr_in out;
615 10 : b.get_ipv4(out);
616 10 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
617 :
618 : // test set
619 : //
620 10 : a.set_ipv4(in);
621 10 : a.get_ipv4(out);
622 10 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
623 : }
624 : }
625 : CATCH_END_SECTION()
626 :
627 6 : CATCH_START_SECTION("addr: set_ipv4() / to_ipv4_string()")
628 : {
629 11 : for(int idx(0); idx < 10; ++idx)
630 : {
631 10 : struct sockaddr_in in = sockaddr_in();
632 10 : in.sin_family = AF_INET;
633 10 : uint16_t const port(rand());
634 10 : in.sin_port = htons(port);
635 10 : uint32_t const address(rand() ^ (rand() << 16));
636 10 : in.sin_addr.s_addr = htonl(address);
637 :
638 10 : std::string ip(
639 20 : std::to_string((address >> 24) & 255)
640 30 : + "."
641 40 : + std::to_string((address >> 16) & 255)
642 30 : + "."
643 40 : + std::to_string((address >> 8) & 255)
644 30 : + "."
645 20 : + std::to_string((address >> 0) & 255)
646 40 : );
647 20 : std::string port_str(std::to_string(static_cast<int>(port)));
648 :
649 : // check IPv4 as a string
650 : //
651 10 : a.set_ipv4(in);
652 10 : CATCH_REQUIRE(a.to_ipv4_string(addr::string_ip_t::STRING_IP_ONLY) == ip);
653 10 : CATCH_REQUIRE(a.to_ipv4_string(addr::string_ip_t::STRING_IP_BRACKETS) == ip);
654 10 : CATCH_REQUIRE(a.to_ipv4_string(addr::string_ip_t::STRING_IP_PORT) == ip + ":" + port_str);
655 10 : CATCH_REQUIRE(a.to_ipv4_string(addr::string_ip_t::STRING_IP_MASK) == ip + "/32");
656 10 : CATCH_REQUIRE(a.to_ipv4_string(addr::string_ip_t::STRING_IP_BRACKETS_MASK) == ip + "/32");
657 10 : CATCH_REQUIRE(a.to_ipv4_string(addr::string_ip_t::STRING_IP_ALL) == ip + ":" + port_str + "/32");
658 :
659 : // if the mask is not a valid IPv4 mask, then we get an exception
660 : //
661 10 : std::uint8_t invalid_mask[16] = { 255, 255 };
662 10 : a.set_mask(invalid_mask);
663 10 : CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::string_ip_t::STRING_IP_ALL), addr::addr_unexpected_mask);
664 10 : invalid_mask[3] = 255;
665 10 : a.set_mask(invalid_mask);
666 10 : CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::string_ip_t::STRING_IP_ALL), addr::addr_unexpected_mask);
667 10 : std::uint8_t const valid_mask[16] = {
668 : 255, 255, 255, 255,
669 : 255, 255, 255, 255,
670 : 255, 255, 255, 255,
671 10 : static_cast<std::uint8_t>(rand()),
672 10 : static_cast<std::uint8_t>(rand()),
673 10 : static_cast<std::uint8_t>(rand()),
674 10 : static_cast<std::uint8_t>(rand()),
675 40 : };
676 10 : a.set_mask(valid_mask);
677 10 : a.set_mask_count(128);
678 : }
679 : }
680 : CATCH_END_SECTION()
681 :
682 6 : CATCH_START_SECTION("addr: name of various IPs")
683 : {
684 1 : struct sockaddr_in in = sockaddr_in();
685 1 : in.sin_family = AF_INET;
686 1 : in.sin_port = htons(rand());
687 1 : in.sin_addr.s_addr = 0;
688 :
689 : // verify network type
690 : //
691 1 : a.set_ipv4(in);
692 1 : CATCH_REQUIRE(a.get_name() == std::string()); // no name for "any" (TCP)
693 :
694 1 : a.set_protocol(IPPROTO_UDP);
695 1 : CATCH_REQUIRE(a.get_name() == std::string()); // no name for "any" (UDP)
696 :
697 1 : in.sin_addr.s_addr = htonl(0x7f000001);
698 1 : a.set_ipv4(in);
699 1 : char hostname[HOST_NAME_MAX + 1];
700 1 : hostname[HOST_NAME_MAX] = '\0';
701 1 : CATCH_REQUIRE(gethostname(hostname, sizeof(hostname)) == 0);
702 1 : CATCH_REQUIRE(hostname[0] != '\0');
703 2 : std::string localhost(a.get_name());
704 1 : bool const localhost_flag(localhost == hostname || localhost == "localhost");
705 1 : CATCH_REQUIRE(localhost_flag);
706 :
707 1 : CATCH_REQUIRE(addr::find_addr_interface(a, false) != nullptr);
708 : }
709 : CATCH_END_SECTION()
710 : }
711 :
712 36 : CATCH_GIVEN("addr_parser() with IPv4 addresses")
713 : {
714 14 : CATCH_START_SECTION("addr: verify basics")
715 : {
716 2 : addr::addr_parser p;
717 1 : p.set_protocol(IPPROTO_TCP);
718 1 : CATCH_REQUIRE(p.get_default_address4() == "");
719 1 : CATCH_REQUIRE(p.get_default_address6() == "");
720 1 : CATCH_REQUIRE(p.get_default_port() == -1);
721 1 : CATCH_REQUIRE(p.get_default_mask4() == "");
722 1 : CATCH_REQUIRE(p.get_default_mask6() == "");
723 2 : addr::addr_range::vector_t ips(p.parse("1.2.3.4"));
724 1 : CATCH_REQUIRE_FALSE(p.has_errors());
725 1 : CATCH_REQUIRE(ips.size() == 1);
726 1 : addr::addr_range const & r(ips[0]);
727 1 : CATCH_REQUIRE(r.has_from());
728 1 : CATCH_REQUIRE_FALSE(r.has_to());
729 1 : CATCH_REQUIRE_FALSE(r.is_range());
730 1 : CATCH_REQUIRE_FALSE(r.is_empty());
731 2 : addr::addr f(r.get_from());
732 1 : CATCH_REQUIRE(f.is_ipv4());
733 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
734 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
735 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
736 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
737 1 : CATCH_REQUIRE(f.get_port() == 0);
738 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
739 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
740 1 : CATCH_REQUIRE_FALSE(f.is_lan());
741 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
742 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
743 1 : CATCH_REQUIRE(f.is_wan());
744 1 : CATCH_REQUIRE(f.is_wan(true));
745 1 : CATCH_REQUIRE(f.is_wan(false));
746 1 : uint8_t mask[16] = {};
747 1 : f.get_mask(mask);
748 17 : for(int idx(0); idx < 16; ++idx)
749 : {
750 16 : CATCH_REQUIRE(mask[idx] == 255);
751 : }
752 : }
753 : CATCH_END_SECTION()
754 :
755 14 : CATCH_START_SECTION("addr: verify default address")
756 : {
757 2 : addr::addr_parser p;
758 :
759 1 : p.set_default_address("1.5.19.200");
760 1 : CATCH_REQUIRE(p.get_default_address4() == "1.5.19.200");
761 1 : CATCH_REQUIRE(p.get_default_address6() == "");
762 1 : p.set_default_address("");
763 1 : CATCH_REQUIRE(p.get_default_address4() == "");
764 1 : CATCH_REQUIRE(p.get_default_address6() == "");
765 :
766 1 : p.set_default_address("1.5.19.200");
767 1 : CATCH_REQUIRE(p.get_default_address4() == "1.5.19.200");
768 1 : CATCH_REQUIRE(p.get_default_address6() == "");
769 1 : p.set_default_address("[4:5:4:5:7:8:7:8]");
770 1 : CATCH_REQUIRE(p.get_default_address4() == "1.5.19.200");
771 1 : CATCH_REQUIRE(p.get_default_address6() == "4:5:4:5:7:8:7:8");
772 1 : p.set_default_address("");
773 1 : CATCH_REQUIRE(p.get_default_address4() == "");
774 1 : CATCH_REQUIRE(p.get_default_address6() == "");
775 : }
776 : CATCH_END_SECTION()
777 :
778 14 : CATCH_START_SECTION("addr: verify default mask")
779 : {
780 2 : addr::addr_parser p;
781 :
782 1 : p.set_default_mask("1.5.19.200");
783 1 : CATCH_REQUIRE(p.get_default_mask4() == "1.5.19.200");
784 1 : CATCH_REQUIRE(p.get_default_mask6() == "");
785 1 : p.set_default_mask("");
786 1 : CATCH_REQUIRE(p.get_default_mask4() == "");
787 1 : CATCH_REQUIRE(p.get_default_mask6() == "");
788 :
789 1 : p.set_default_mask("1.5.19.200");
790 1 : CATCH_REQUIRE(p.get_default_mask4() == "1.5.19.200");
791 1 : CATCH_REQUIRE(p.get_default_mask6() == "");
792 1 : p.set_default_mask("[4:5:4:5:7:8:7:8]");
793 1 : CATCH_REQUIRE(p.get_default_mask4() == "1.5.19.200");
794 1 : CATCH_REQUIRE(p.get_default_mask6() == "4:5:4:5:7:8:7:8");
795 1 : p.set_default_mask("");
796 1 : CATCH_REQUIRE(p.get_default_mask4() == "");
797 1 : CATCH_REQUIRE(p.get_default_mask6() == "");
798 : }
799 : CATCH_END_SECTION()
800 :
801 14 : CATCH_START_SECTION("addr: verify default allow flags")
802 : {
803 2 : addr::addr_parser p;
804 :
805 16 : for(int idx(0); idx < static_cast<int>(addr::allow_t::ALLOW_max); ++idx)
806 : {
807 15 : switch(static_cast<addr::allow_t>(idx))
808 : {
809 3 : case addr::allow_t::ALLOW_ADDRESS:
810 : case addr::allow_t::ALLOW_ADDRESS_LOOKUP:
811 : case addr::allow_t::ALLOW_PORT:
812 : // only these are true by default
813 : //
814 3 : CATCH_REQUIRE(p.get_allow(static_cast<addr::allow_t>(idx)));
815 3 : break;
816 :
817 12 : default:
818 12 : CATCH_REQUIRE_FALSE(p.get_allow(static_cast<addr::allow_t>(idx)));
819 12 : break;
820 :
821 : }
822 : }
823 : }
824 : CATCH_END_SECTION()
825 :
826 14 : CATCH_START_SECTION("addr: verify contradictory flags")
827 : {
828 2 : addr::addr_parser p;
829 :
830 : // by default these are set to false
831 : //
832 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS));
833 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES));
834 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_PORTS_COMMAS));
835 :
836 : // check setting MULTI_ADDRESSES_COMMAS to true
837 : //
838 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS, true);
839 1 : CATCH_REQUIRE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS));
840 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES));
841 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_PORTS_COMMAS));
842 :
843 : // add MULTI_ADDRESSES_SPACES
844 : //
845 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES, true);
846 1 : CATCH_REQUIRE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS));
847 1 : CATCH_REQUIRE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES));
848 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_PORTS_COMMAS));
849 :
850 : // add MULTI_PORTS_COMMAS
851 : //
852 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_PORTS_COMMAS, true);
853 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS));
854 1 : CATCH_REQUIRE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES));
855 1 : CATCH_REQUIRE(p.get_allow(addr::allow_t::ALLOW_MULTI_PORTS_COMMAS));
856 :
857 : // add MULTI_ADDRESSES_COMMAS again
858 : //
859 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS, true);
860 1 : CATCH_REQUIRE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS));
861 1 : CATCH_REQUIRE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES));
862 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_PORTS_COMMAS));
863 :
864 : // remove MULTI_ADDRESSES_SPACES
865 : //
866 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES, false);
867 1 : CATCH_REQUIRE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS));
868 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES));
869 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_PORTS_COMMAS));
870 :
871 : // back to MULTI_PORTS_COMMAS
872 : //
873 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_PORTS_COMMAS, true);
874 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS));
875 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES));
876 1 : CATCH_REQUIRE(p.get_allow(addr::allow_t::ALLOW_MULTI_PORTS_COMMAS));
877 :
878 : // add MULTI_ADDRESSES_COMMAS first now
879 : //
880 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS, true);
881 1 : CATCH_REQUIRE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS));
882 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES));
883 1 : CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_MULTI_PORTS_COMMAS));
884 : }
885 : CATCH_END_SECTION()
886 :
887 14 : CATCH_START_SECTION("addr: default address")
888 : {
889 2 : addr::addr_parser p;
890 1 : p.set_protocol(IPPROTO_TCP);
891 1 : p.set_default_address("5.5.5.5");
892 1 : CATCH_REQUIRE(p.get_default_address4() == "5.5.5.5");
893 1 : CATCH_REQUIRE(p.get_default_address6() == "");
894 2 : addr::addr_range::vector_t ips(p.parse(""));
895 1 : CATCH_REQUIRE_FALSE(p.has_errors());
896 1 : CATCH_REQUIRE(ips.size() == 1);
897 1 : addr::addr_range const & r(ips[0]);
898 1 : CATCH_REQUIRE(r.has_from());
899 1 : CATCH_REQUIRE_FALSE(r.has_to());
900 1 : CATCH_REQUIRE_FALSE(r.is_range());
901 1 : CATCH_REQUIRE_FALSE(r.is_empty());
902 2 : addr::addr f(r.get_from());
903 1 : CATCH_REQUIRE(f.is_ipv4());
904 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
905 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
906 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_ONLY) == "5.5.5.5");
907 1 : CATCH_REQUIRE(f.get_port() == 0);
908 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
909 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
910 1 : CATCH_REQUIRE_FALSE(f.is_lan());
911 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
912 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
913 1 : CATCH_REQUIRE(f.is_wan());
914 1 : CATCH_REQUIRE(f.is_wan(true));
915 1 : CATCH_REQUIRE(f.is_wan(false));
916 : }
917 : CATCH_END_SECTION()
918 :
919 14 : CATCH_START_SECTION("addr: address, no port allowed")
920 : {
921 : // specific address with a default
922 : {
923 2 : addr::addr_parser p;
924 1 : p.set_allow(addr::allow_t::ALLOW_PORT, false);
925 1 : p.set_protocol(IPPROTO_TCP);
926 1 : p.set_default_address("5.5.5.5");
927 1 : CATCH_REQUIRE(p.get_default_address4() == "5.5.5.5");
928 1 : CATCH_REQUIRE(p.get_default_address6() == "");
929 2 : addr::addr_range::vector_t ips(p.parse("9.9.9.9"));
930 1 : CATCH_REQUIRE_FALSE(p.has_errors());
931 1 : CATCH_REQUIRE(ips.size() == 1);
932 1 : addr::addr_range const & r(ips[0]);
933 1 : CATCH_REQUIRE(r.has_from());
934 1 : CATCH_REQUIRE_FALSE(r.has_to());
935 1 : CATCH_REQUIRE_FALSE(r.is_range());
936 1 : CATCH_REQUIRE_FALSE(r.is_empty());
937 2 : addr::addr f(r.get_from());
938 1 : CATCH_REQUIRE(f.is_ipv4());
939 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
940 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
941 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_ONLY) == "9.9.9.9");
942 1 : CATCH_REQUIRE(f.get_port() == 0);
943 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
944 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
945 1 : CATCH_REQUIRE_FALSE(f.is_lan());
946 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
947 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
948 1 : CATCH_REQUIRE(f.is_wan());
949 1 : CATCH_REQUIRE(f.is_wan(true));
950 1 : CATCH_REQUIRE(f.is_wan(false));
951 : }
952 :
953 : // only a default address
954 : {
955 2 : addr::addr_parser p;
956 1 : p.set_allow(addr::allow_t::ALLOW_PORT, false);
957 1 : p.set_protocol(IPPROTO_TCP);
958 1 : p.set_default_address("5.5.5.5");
959 1 : CATCH_REQUIRE(p.get_default_address4() == "5.5.5.5");
960 1 : CATCH_REQUIRE(p.get_default_address6() == "");
961 2 : addr::addr_range::vector_t ips(p.parse(""));
962 1 : CATCH_REQUIRE_FALSE(p.has_errors());
963 1 : CATCH_REQUIRE(ips.size() == 1);
964 1 : addr::addr_range const & r(ips[0]);
965 1 : CATCH_REQUIRE(r.has_from());
966 1 : CATCH_REQUIRE_FALSE(r.has_to());
967 1 : CATCH_REQUIRE_FALSE(r.is_range());
968 1 : CATCH_REQUIRE_FALSE(r.is_empty());
969 2 : addr::addr f(r.get_from());
970 1 : CATCH_REQUIRE(f.is_ipv4());
971 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
972 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
973 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_ONLY) == "5.5.5.5");
974 1 : CATCH_REQUIRE(f.get_port() == 0);
975 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
976 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
977 1 : CATCH_REQUIRE_FALSE(f.is_lan());
978 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
979 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
980 1 : CATCH_REQUIRE(f.is_wan());
981 1 : CATCH_REQUIRE(f.is_wan(true));
982 1 : CATCH_REQUIRE(f.is_wan(false));
983 : }
984 : }
985 : CATCH_END_SECTION()
986 : }
987 :
988 36 : CATCH_GIVEN("addr_parser() with multiple IPv4 addresses in one string")
989 : {
990 6 : CATCH_START_SECTION("addr: 3 IPs separated by commas")
991 : {
992 2 : addr::addr_parser p;
993 1 : p.set_protocol(IPPROTO_TCP);
994 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS, true);
995 2 : addr::addr_range::vector_t ips(p.parse("1.2.3.4:55,5.6.7.8,,,,10.11.12.99:77"));
996 1 : CATCH_REQUIRE_FALSE(p.has_errors());
997 1 : CATCH_REQUIRE(ips.size() == 3);
998 :
999 1 : uint8_t mask[16] = {};
1000 :
1001 : // 1.2.3.4:55
1002 : {
1003 1 : addr::addr_range const & r(ips[0]);
1004 1 : CATCH_REQUIRE(r.has_from());
1005 1 : CATCH_REQUIRE_FALSE(r.has_to());
1006 1 : CATCH_REQUIRE_FALSE(r.is_range());
1007 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1008 2 : addr::addr f(r.get_from());
1009 1 : CATCH_REQUIRE(f.is_ipv4());
1010 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1011 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1012 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
1013 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
1014 1 : CATCH_REQUIRE(f.get_port() == 55);
1015 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1016 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1017 1 : CATCH_REQUIRE_FALSE(f.is_lan());
1018 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1019 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1020 1 : CATCH_REQUIRE(f.is_wan());
1021 1 : CATCH_REQUIRE(f.is_wan(true));
1022 1 : CATCH_REQUIRE(f.is_wan(false));
1023 1 : f.get_mask(mask);
1024 17 : for(int idx(0); idx < 16; ++idx)
1025 : {
1026 16 : CATCH_REQUIRE(mask[idx] == 255);
1027 : }
1028 : }
1029 :
1030 : // 5.6.7.8
1031 : {
1032 1 : addr::addr_range const & r(ips[1]);
1033 1 : CATCH_REQUIRE(r.has_from());
1034 1 : CATCH_REQUIRE_FALSE(r.has_to());
1035 1 : CATCH_REQUIRE_FALSE(r.is_range());
1036 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1037 2 : addr::addr f(r.get_from());
1038 1 : CATCH_REQUIRE(f.is_ipv4());
1039 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1040 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1041 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_ONLY) == "5.6.7.8");
1042 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ONLY) == "5.6.7.8");
1043 1 : CATCH_REQUIRE(f.get_port() == 0);
1044 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1045 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1046 1 : CATCH_REQUIRE_FALSE(f.is_lan());
1047 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1048 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1049 1 : CATCH_REQUIRE(f.is_wan());
1050 1 : CATCH_REQUIRE(f.is_wan(true));
1051 1 : CATCH_REQUIRE(f.is_wan(false));
1052 1 : f.get_mask(mask);
1053 17 : for(int idx(0); idx < 16; ++idx)
1054 : {
1055 16 : CATCH_REQUIRE(mask[idx] == 255);
1056 : }
1057 : }
1058 :
1059 : // 10.11.12.99:77
1060 : {
1061 1 : addr::addr_range const & r(ips[2]);
1062 1 : CATCH_REQUIRE(r.has_from());
1063 1 : CATCH_REQUIRE_FALSE(r.has_to());
1064 1 : CATCH_REQUIRE_FALSE(r.is_range());
1065 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1066 2 : addr::addr f(r.get_from());
1067 1 : CATCH_REQUIRE(f.is_ipv4());
1068 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1069 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1070 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_ONLY) == "10.11.12.99");
1071 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ONLY) == "10.11.12.99");
1072 1 : CATCH_REQUIRE(f.get_port() == 77);
1073 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1074 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
1075 1 : CATCH_REQUIRE(f.is_lan());
1076 1 : CATCH_REQUIRE(f.is_lan(true));
1077 1 : CATCH_REQUIRE(f.is_lan(false));
1078 1 : CATCH_REQUIRE_FALSE(f.is_wan());
1079 1 : CATCH_REQUIRE_FALSE(f.is_wan(true));
1080 1 : CATCH_REQUIRE_FALSE(f.is_wan(false));
1081 1 : f.get_mask(mask);
1082 17 : for(int idx(0); idx < 16; ++idx)
1083 : {
1084 16 : CATCH_REQUIRE(mask[idx] == 255);
1085 : }
1086 : }
1087 : }
1088 : CATCH_END_SECTION()
1089 :
1090 6 : CATCH_START_SECTION("addr: 3 IPs separated by spaces")
1091 : {
1092 2 : addr::addr_parser p;
1093 1 : p.set_protocol(IPPROTO_TCP);
1094 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES, true);
1095 2 : addr::addr_range::vector_t ips(p.parse("1.2.3.4:55 5.6.7.8 10.11.12.99:77"));
1096 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1097 1 : CATCH_REQUIRE(ips.size() == 3);
1098 :
1099 1 : uint8_t mask[16] = {};
1100 :
1101 : // 1.2.3.4:55
1102 : {
1103 1 : addr::addr_range const & r(ips[0]);
1104 1 : CATCH_REQUIRE(r.has_from());
1105 1 : CATCH_REQUIRE_FALSE(r.has_to());
1106 1 : CATCH_REQUIRE_FALSE(r.is_range());
1107 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1108 2 : addr::addr f(r.get_from());
1109 1 : CATCH_REQUIRE(f.is_ipv4());
1110 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1111 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1112 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
1113 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
1114 1 : CATCH_REQUIRE(f.get_port() == 55);
1115 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1116 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1117 1 : CATCH_REQUIRE_FALSE(f.is_lan());
1118 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1119 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1120 1 : CATCH_REQUIRE(f.is_wan());
1121 1 : CATCH_REQUIRE(f.is_wan(true));
1122 1 : CATCH_REQUIRE(f.is_wan(false));
1123 1 : f.get_mask(mask);
1124 17 : for(int idx(0); idx < 16; ++idx)
1125 : {
1126 16 : CATCH_REQUIRE(mask[idx] == 255);
1127 : }
1128 : }
1129 :
1130 : // 5.6.7.8
1131 : {
1132 1 : addr::addr_range const & r(ips[1]);
1133 1 : CATCH_REQUIRE(r.has_from());
1134 1 : CATCH_REQUIRE_FALSE(r.has_to());
1135 1 : CATCH_REQUIRE_FALSE(r.is_range());
1136 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1137 2 : addr::addr f(r.get_from());
1138 1 : CATCH_REQUIRE(f.is_ipv4());
1139 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1140 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1141 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_ONLY) == "5.6.7.8");
1142 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ONLY) == "5.6.7.8");
1143 1 : CATCH_REQUIRE(f.get_port() == 0);
1144 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1145 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1146 1 : CATCH_REQUIRE_FALSE(f.is_lan());
1147 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1148 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1149 1 : CATCH_REQUIRE(f.is_wan());
1150 1 : CATCH_REQUIRE(f.is_wan(true));
1151 1 : CATCH_REQUIRE(f.is_wan(false));
1152 1 : f.get_mask(mask);
1153 17 : for(int idx(0); idx < 16; ++idx)
1154 : {
1155 16 : CATCH_REQUIRE(mask[idx] == 255);
1156 : }
1157 : }
1158 :
1159 : // 10.11.12.99:77
1160 : {
1161 1 : addr::addr_range const & r(ips[2]);
1162 1 : CATCH_REQUIRE(r.has_from());
1163 1 : CATCH_REQUIRE_FALSE(r.has_to());
1164 1 : CATCH_REQUIRE_FALSE(r.is_range());
1165 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1166 2 : addr::addr f(r.get_from());
1167 1 : CATCH_REQUIRE(f.is_ipv4());
1168 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1169 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1170 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_ONLY) == "10.11.12.99");
1171 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ONLY) == "10.11.12.99");
1172 1 : CATCH_REQUIRE(f.get_port() == 77);
1173 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1174 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
1175 1 : CATCH_REQUIRE(f.is_lan());
1176 1 : CATCH_REQUIRE(f.is_lan(true));
1177 1 : CATCH_REQUIRE(f.is_lan(false));
1178 1 : CATCH_REQUIRE_FALSE(f.is_wan());
1179 1 : CATCH_REQUIRE_FALSE(f.is_wan(true));
1180 1 : CATCH_REQUIRE_FALSE(f.is_wan(false));
1181 1 : f.get_mask(mask);
1182 17 : for(int idx(0); idx < 16; ++idx)
1183 : {
1184 16 : CATCH_REQUIRE(mask[idx] == 255);
1185 : }
1186 : }
1187 : }
1188 : CATCH_END_SECTION()
1189 :
1190 6 : CATCH_START_SECTION("addr: 3 IPs separated by commas and/or spaces")
1191 : {
1192 2 : addr::addr_parser p;
1193 1 : p.set_protocol(IPPROTO_TCP);
1194 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS, true);
1195 1 : p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_SPACES, true);
1196 2 : addr::addr_range::vector_t ips(p.parse(" 1.2.3.4:55,, 5.6.7.8 , 10.11.12.99:77 "));
1197 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1198 1 : CATCH_REQUIRE(ips.size() == 3);
1199 :
1200 1 : uint8_t mask[16] = {};
1201 :
1202 : // 1.2.3.4:55
1203 : {
1204 1 : addr::addr_range const & r(ips[0]);
1205 1 : CATCH_REQUIRE(r.has_from());
1206 1 : CATCH_REQUIRE_FALSE(r.has_to());
1207 1 : CATCH_REQUIRE_FALSE(r.is_range());
1208 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1209 2 : addr::addr f(r.get_from());
1210 1 : CATCH_REQUIRE(f.is_ipv4());
1211 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1212 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1213 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
1214 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ONLY) == "1.2.3.4");
1215 1 : CATCH_REQUIRE(f.get_port() == 55);
1216 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1217 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1218 1 : CATCH_REQUIRE_FALSE(f.is_lan());
1219 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1220 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1221 1 : CATCH_REQUIRE(f.is_wan());
1222 1 : CATCH_REQUIRE(f.is_wan(true));
1223 1 : CATCH_REQUIRE(f.is_wan(false));
1224 1 : f.get_mask(mask);
1225 17 : for(int idx(0); idx < 16; ++idx)
1226 : {
1227 16 : CATCH_REQUIRE(mask[idx] == 255);
1228 : }
1229 : }
1230 :
1231 : // 5.6.7.8
1232 : {
1233 1 : addr::addr_range const & r(ips[1]);
1234 1 : CATCH_REQUIRE(r.has_from());
1235 1 : CATCH_REQUIRE_FALSE(r.has_to());
1236 1 : CATCH_REQUIRE_FALSE(r.is_range());
1237 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1238 2 : addr::addr f(r.get_from());
1239 1 : CATCH_REQUIRE(f.is_ipv4());
1240 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1241 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1242 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_ONLY) == "5.6.7.8");
1243 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ONLY) == "5.6.7.8");
1244 1 : CATCH_REQUIRE(f.get_port() == 0);
1245 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1246 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1247 1 : CATCH_REQUIRE_FALSE(f.is_lan());
1248 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1249 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1250 1 : CATCH_REQUIRE(f.is_wan());
1251 1 : CATCH_REQUIRE(f.is_wan(true));
1252 1 : CATCH_REQUIRE(f.is_wan(false));
1253 1 : f.get_mask(mask);
1254 17 : for(int idx(0); idx < 16; ++idx)
1255 : {
1256 16 : CATCH_REQUIRE(mask[idx] == 255);
1257 : }
1258 : }
1259 :
1260 : // 10.11.12.99:77
1261 : {
1262 1 : addr::addr_range const & r(ips[2]);
1263 1 : CATCH_REQUIRE(r.has_from());
1264 1 : CATCH_REQUIRE_FALSE(r.has_to());
1265 1 : CATCH_REQUIRE_FALSE(r.is_range());
1266 1 : CATCH_REQUIRE_FALSE(r.is_empty());
1267 2 : addr::addr f(r.get_from());
1268 1 : CATCH_REQUIRE(f.is_ipv4());
1269 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1270 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1271 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_ONLY) == "10.11.12.99");
1272 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ONLY) == "10.11.12.99");
1273 1 : CATCH_REQUIRE(f.get_port() == 77);
1274 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1275 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
1276 1 : CATCH_REQUIRE(f.is_lan());
1277 1 : CATCH_REQUIRE(f.is_lan(true));
1278 1 : CATCH_REQUIRE(f.is_lan(false));
1279 1 : CATCH_REQUIRE_FALSE(f.is_wan());
1280 1 : CATCH_REQUIRE_FALSE(f.is_wan(true));
1281 1 : CATCH_REQUIRE_FALSE(f.is_wan(false));
1282 1 : f.get_mask(mask);
1283 17 : for(int idx(0); idx < 16; ++idx)
1284 : {
1285 16 : CATCH_REQUIRE(mask[idx] == 255);
1286 : }
1287 : }
1288 : }
1289 : CATCH_END_SECTION()
1290 : }
1291 :
1292 36 : CATCH_GIVEN("addr_parser() with numeric only IPv4 addresses")
1293 : {
1294 6 : CATCH_START_SECTION("addr: simple numeric IPv4")
1295 : {
1296 2 : addr::addr_parser p;
1297 1 : p.set_protocol(IPPROTO_TCP);
1298 1 : p.set_allow(addr::allow_t::ALLOW_ADDRESS_LOOKUP, false);
1299 2 : addr::addr_range::vector_t ips(p.parse("4.3.1.2:3003"));
1300 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1301 1 : CATCH_REQUIRE(ips.size() == 1);
1302 :
1303 1 : addr::addr_range const & r(ips[0]);
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 2 : 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_t::STRING_IP_ONLY) == "4.3.1.2");
1313 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ONLY) == "4.3.1.2");
1314 1 : CATCH_REQUIRE(f.get_port() == 3003);
1315 1 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1316 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1317 1 : CATCH_REQUIRE_FALSE(f.is_lan());
1318 1 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1319 1 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1320 1 : CATCH_REQUIRE(f.is_wan());
1321 1 : CATCH_REQUIRE(f.is_wan(true));
1322 1 : CATCH_REQUIRE(f.is_wan(false));
1323 1 : uint8_t mask[16] = {};
1324 1 : f.get_mask(mask);
1325 17 : for(int idx(0); idx < 16; ++idx)
1326 : {
1327 16 : CATCH_REQUIRE(mask[idx] == 255);
1328 : }
1329 : }
1330 : CATCH_END_SECTION()
1331 :
1332 6 : CATCH_START_SECTION("addr: invalid domain name address when we only accept numeric IPs")
1333 : {
1334 2 : addr::addr_parser p;
1335 1 : p.set_protocol(IPPROTO_TCP);
1336 1 : p.set_allow(addr::allow_t::ALLOW_ADDRESS_LOOKUP, false);
1337 2 : addr::addr_range::vector_t ips(p.parse("www.example.com:4471"));
1338 1 : CATCH_REQUIRE(p.has_errors());
1339 1 : CATCH_REQUIRE(p.error_count() == 1);
1340 1 : CATCH_REQUIRE(p.error_messages() == "Unknown address in \"www.example.com\" (no DNS lookup was allowed).\n");
1341 1 : CATCH_REQUIRE(ips.size() == 0);
1342 : }
1343 : CATCH_END_SECTION()
1344 :
1345 6 : CATCH_START_SECTION("addr: invalid port: service name not allowed")
1346 : {
1347 2 : addr::addr_parser p;
1348 1 : p.set_protocol(IPPROTO_TCP);
1349 1 : p.set_allow(addr::allow_t::ALLOW_ADDRESS_LOOKUP, false);
1350 2 : addr::addr_range::vector_t ips(p.parse("192.168.255.32:https"));
1351 1 : CATCH_REQUIRE(p.has_errors());
1352 1 : CATCH_REQUIRE(p.error_count() == 1);
1353 1 : CATCH_REQUIRE(p.error_messages() == "Invalid port in \"https\" (no service name lookup allowed).\n");
1354 1 : CATCH_REQUIRE(ips.size() == 0);
1355 : }
1356 : CATCH_END_SECTION()
1357 : }
1358 :
1359 36 : CATCH_START_SECTION("addr: IP as hostname")
1360 : {
1361 11 : for(int idx(0); idx < 10; ++idx)
1362 : {
1363 10 : struct sockaddr_in in = sockaddr_in();
1364 10 : in.sin_family = AF_INET;
1365 10 : in.sin_port = htons(rand());
1366 10 : in.sin_addr.s_addr = htonl(rand() ^ (rand() << 16));
1367 20 : addr::addr a(in);
1368 10 : struct sockaddr_in out;
1369 10 : a.get_ipv4(out);
1370 10 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
1371 10 : CATCH_REQUIRE(a.get_hostname().empty());
1372 20 : std::string const ip(a.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ONLY));
1373 10 : a.set_hostname(ip);
1374 10 : CATCH_REQUIRE(a.get_hostname() == ip);
1375 10 : CATCH_REQUIRE(a.is_hostname_an_ip());
1376 10 : a.set_hostname("no.an.ip");
1377 10 : CATCH_REQUIRE(a.get_hostname() == "no.an.ip");
1378 10 : CATCH_REQUIRE_FALSE(a.is_hostname_an_ip());
1379 : }
1380 : }
1381 : CATCH_END_SECTION()
1382 :
1383 36 : CATCH_START_SECTION("addr: set interface")
1384 : {
1385 2 : addr::addr a;
1386 1 : CATCH_REQUIRE(a.get_interface().empty());
1387 1 : a.set_interface("eth0");
1388 1 : CATCH_REQUIRE(a.get_interface() == "eth0");
1389 1 : a.set_interface("epn3");
1390 1 : CATCH_REQUIRE(a.get_interface() == "epn3");
1391 1 : a.set_interface(std::string());
1392 1 : CATCH_REQUIRE(a.get_interface().empty());
1393 : }
1394 : CATCH_END_SECTION()
1395 18 : }
1396 :
1397 :
1398 5 : CATCH_TEST_CASE("ipv4::ports", "[ipv4]")
1399 : {
1400 6 : CATCH_GIVEN("addr_parser() with IPv4 addresses and port")
1401 : {
1402 6 : CATCH_START_SECTION("addr: verify port")
1403 : {
1404 65537 : for(int port(0); port < 65536; ++port)
1405 : {
1406 65536 : int proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1407 131072 : addr::addr_parser p;
1408 65536 : p.set_protocol(proto);
1409 131072 : addr::addr_range::vector_t ips(p.parse("192.168.12.199:" + std::to_string(port)));
1410 65536 : CATCH_REQUIRE_FALSE(p.has_errors());
1411 65536 : CATCH_REQUIRE(ips.size() == 1);
1412 65536 : addr::addr_range const & r(ips[0]);
1413 131072 : addr::addr f(r.get_from());
1414 65536 : CATCH_REQUIRE(f.is_ipv4());
1415 65536 : CATCH_REQUIRE(f.get_family() == AF_INET);
1416 65536 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1417 65536 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_ONLY) == "192.168.12.199");
1418 65536 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ONLY) == "192.168.12.199");
1419 65536 : CATCH_REQUIRE(f.get_port() == port);
1420 65536 : CATCH_REQUIRE(f.get_protocol() == proto);
1421 65536 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
1422 65536 : CATCH_REQUIRE(f.is_lan());
1423 65536 : CATCH_REQUIRE(f.is_lan(true));
1424 65536 : CATCH_REQUIRE(f.is_lan(false));
1425 65536 : CATCH_REQUIRE_FALSE(f.is_wan());
1426 65536 : CATCH_REQUIRE_FALSE(f.is_wan(true));
1427 65536 : CATCH_REQUIRE_FALSE(f.is_wan(false));
1428 : }
1429 : }
1430 : CATCH_END_SECTION()
1431 :
1432 6 : CATCH_START_SECTION("addr: default address with various port")
1433 : {
1434 101 : for(int idx(0); idx < 100; ++idx)
1435 : {
1436 100 : uint16_t const port(rand());
1437 200 : addr::addr_parser p;
1438 100 : p.set_protocol(IPPROTO_TCP);
1439 100 : p.set_default_address("5.5.5.5");
1440 100 : CATCH_REQUIRE(p.get_default_address4() == "5.5.5.5");
1441 100 : CATCH_REQUIRE(p.get_default_address6() == "");
1442 200 : addr::addr_range::vector_t ips(p.parse(":" + std::to_string(static_cast<int>(port))));
1443 100 : CATCH_REQUIRE_FALSE(p.has_errors());
1444 100 : CATCH_REQUIRE(ips.size() == 1);
1445 100 : addr::addr_range const & r(ips[0]);
1446 100 : CATCH_REQUIRE(r.has_from());
1447 100 : CATCH_REQUIRE_FALSE(r.has_to());
1448 100 : CATCH_REQUIRE_FALSE(r.is_range());
1449 100 : CATCH_REQUIRE_FALSE(r.is_empty());
1450 200 : addr::addr f(r.get_from());
1451 100 : CATCH_REQUIRE(f.is_ipv4());
1452 100 : CATCH_REQUIRE(f.get_family() == AF_INET);
1453 100 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1454 100 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
1455 100 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
1456 100 : CATCH_REQUIRE(f.get_port() == port);
1457 100 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1458 100 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1459 100 : CATCH_REQUIRE_FALSE(f.is_lan());
1460 100 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1461 100 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1462 100 : CATCH_REQUIRE(f.is_wan());
1463 100 : CATCH_REQUIRE(f.is_wan(true));
1464 100 : CATCH_REQUIRE(f.is_wan(false));
1465 : }
1466 : }
1467 : CATCH_END_SECTION()
1468 :
1469 6 : CATCH_START_SECTION("addr: address with default port")
1470 : {
1471 26 : for(int idx(0); idx < 25; ++idx)
1472 : {
1473 25 : std::uint16_t const port(rand());
1474 50 : addr::addr_parser p;
1475 25 : p.set_protocol(IPPROTO_TCP);
1476 25 : if((rand() & 1) == 0)
1477 : {
1478 14 : p.set_default_port(port);
1479 : }
1480 : else
1481 : {
1482 22 : std::string const port_str(std::to_string(static_cast<int>(port)));
1483 11 : p.set_default_port(port_str);
1484 : }
1485 25 : CATCH_REQUIRE(p.get_default_port() == port);
1486 50 : addr::addr_range::vector_t ips(p.parse("5.5.5.5"));
1487 25 : CATCH_REQUIRE_FALSE(p.has_errors());
1488 25 : CATCH_REQUIRE(ips.size() == 1);
1489 25 : addr::addr_range const & r(ips[0]);
1490 25 : CATCH_REQUIRE(r.has_from());
1491 25 : CATCH_REQUIRE_FALSE(r.has_to());
1492 25 : CATCH_REQUIRE_FALSE(r.is_range());
1493 25 : CATCH_REQUIRE_FALSE(r.is_empty());
1494 50 : addr::addr f(r.get_from());
1495 25 : CATCH_REQUIRE(f.is_ipv4());
1496 25 : CATCH_REQUIRE(f.get_family() == AF_INET);
1497 25 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1498 25 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
1499 25 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
1500 25 : CATCH_REQUIRE(f.get_port() == port);
1501 25 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1502 25 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1503 25 : CATCH_REQUIRE_FALSE(f.is_lan());
1504 25 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1505 25 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1506 25 : CATCH_REQUIRE(f.is_wan());
1507 25 : CATCH_REQUIRE(f.is_wan(true));
1508 25 : CATCH_REQUIRE(f.is_wan(false));
1509 : }
1510 :
1511 26 : for(int idx(0); idx < 25; ++idx)
1512 : {
1513 25 : std::uint16_t const port(rand());
1514 50 : addr::addr_parser p;
1515 25 : p.set_protocol(IPPROTO_TCP);
1516 25 : if((rand() & 1) == 0)
1517 : {
1518 11 : p.set_default_port(port);
1519 : }
1520 : else
1521 : {
1522 28 : std::string const port_str(std::to_string(static_cast<int>(port)));
1523 14 : p.set_default_port(port_str);
1524 : }
1525 25 : CATCH_REQUIRE(p.get_default_port() == port);
1526 50 : addr::addr_range::vector_t ips(p.parse("5.5.5.5:"));
1527 25 : CATCH_REQUIRE_FALSE(p.has_errors());
1528 25 : CATCH_REQUIRE(ips.size() == 1);
1529 25 : addr::addr_range const & r(ips[0]);
1530 25 : CATCH_REQUIRE(r.has_from());
1531 25 : CATCH_REQUIRE_FALSE(r.has_to());
1532 25 : CATCH_REQUIRE_FALSE(r.is_range());
1533 25 : CATCH_REQUIRE_FALSE(r.is_empty());
1534 50 : addr::addr f(r.get_from());
1535 25 : CATCH_REQUIRE(f.is_ipv4());
1536 25 : CATCH_REQUIRE(f.get_family() == AF_INET);
1537 25 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1538 25 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
1539 25 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
1540 25 : CATCH_REQUIRE(f.get_port() == port);
1541 25 : CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
1542 25 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
1543 25 : CATCH_REQUIRE_FALSE(f.is_lan());
1544 25 : CATCH_REQUIRE_FALSE(f.is_lan(true));
1545 25 : CATCH_REQUIRE_FALSE(f.is_lan(false));
1546 25 : CATCH_REQUIRE(f.is_wan());
1547 25 : CATCH_REQUIRE(f.is_wan(true));
1548 25 : CATCH_REQUIRE(f.is_wan(false));
1549 : }
1550 : }
1551 : CATCH_END_SECTION()
1552 : }
1553 3 : }
1554 :
1555 :
1556 9 : CATCH_TEST_CASE("ipv4::masks", "[ipv4]")
1557 : {
1558 14 : CATCH_GIVEN("addr_parser() of address:port/mask")
1559 : {
1560 14 : CATCH_START_SECTION("addr: mask allowed, but no mask")
1561 : {
1562 1 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1563 1 : int const port(rand() & 0xFFFF);
1564 2 : addr::addr_parser p;
1565 1 : p.set_protocol(proto);
1566 1 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
1567 2 : addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port)));
1568 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1569 1 : CATCH_REQUIRE(ips.size() == 1);
1570 1 : addr::addr_range const & r(ips[0]);
1571 2 : addr::addr f(r.get_from());
1572 1 : CATCH_REQUIRE(f.is_ipv4());
1573 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1574 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1575 2 : std::string result("172.19.6.91:" + std::to_string(port) + "/32");
1576 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_ALL) == result);
1577 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ALL) == result);
1578 1 : CATCH_REQUIRE(f.get_port() == port);
1579 1 : CATCH_REQUIRE(f.get_protocol() == proto);
1580 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
1581 1 : CATCH_REQUIRE(f.is_lan());
1582 1 : CATCH_REQUIRE(f.is_lan(true));
1583 1 : CATCH_REQUIRE(f.is_lan(false));
1584 1 : CATCH_REQUIRE_FALSE(f.is_wan());
1585 1 : CATCH_REQUIRE_FALSE(f.is_wan(true));
1586 1 : CATCH_REQUIRE_FALSE(f.is_wan(false));
1587 1 : CATCH_REQUIRE(f.get_mask_size() == 128);
1588 : }
1589 : CATCH_END_SECTION()
1590 :
1591 14 : CATCH_START_SECTION("addr: empty mask")
1592 : {
1593 1 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1594 1 : int const port(rand() & 0xFFFF);
1595 2 : addr::addr_parser p;
1596 1 : p.set_protocol(proto);
1597 1 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
1598 2 : addr::addr_range::vector_t ips(p.parse("172.18.5.91:" + std::to_string(port) + "/"));
1599 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1600 1 : CATCH_REQUIRE(ips.size() == 1);
1601 1 : addr::addr_range const & r(ips[0]);
1602 2 : addr::addr f(r.get_from());
1603 1 : CATCH_REQUIRE(f.is_ipv4());
1604 1 : CATCH_REQUIRE(f.get_family() == AF_INET);
1605 1 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1606 2 : std::string result("172.18.5.91:" + std::to_string(port) + "/32");
1607 1 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_ALL) == result);
1608 1 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ALL) == result);
1609 1 : CATCH_REQUIRE(f.get_port() == port);
1610 1 : CATCH_REQUIRE(f.get_protocol() == proto);
1611 1 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
1612 1 : CATCH_REQUIRE(f.is_lan());
1613 1 : CATCH_REQUIRE(f.is_lan(true));
1614 1 : CATCH_REQUIRE(f.is_lan(false));
1615 1 : CATCH_REQUIRE_FALSE(f.is_wan());
1616 1 : CATCH_REQUIRE_FALSE(f.is_wan(true));
1617 1 : CATCH_REQUIRE_FALSE(f.is_wan(false));
1618 1 : CATCH_REQUIRE(f.get_mask_size() == 128);
1619 : }
1620 : CATCH_END_SECTION()
1621 :
1622 14 : CATCH_START_SECTION("addr: one number masks")
1623 : {
1624 34 : for(int idx(0); idx <= 32; ++idx)
1625 : {
1626 33 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1627 33 : int const port(rand() & 0xFFFF);
1628 66 : addr::addr_parser p;
1629 33 : p.set_protocol(proto);
1630 33 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
1631 66 : addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port) + "/" + std::to_string(idx)));
1632 33 : CATCH_REQUIRE_FALSE(p.has_errors());
1633 33 : CATCH_REQUIRE(ips.size() == 1);
1634 33 : addr::addr_range const & r(ips[0]);
1635 66 : addr::addr f(r.get_from());
1636 33 : CATCH_REQUIRE(f.is_ipv4());
1637 33 : CATCH_REQUIRE(f.get_family() == AF_INET);
1638 33 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1639 : //uint64_t const mask(std::numeric_limits<uint64_t>::max() << (32 - idx));
1640 : //std::string mask_str(
1641 : // std::to_string((mask >> 24) & 255)
1642 : // + "."
1643 : // + std::to_string((mask >> 16) & 255)
1644 : // + "."
1645 : // + std::to_string((mask >> 8) & 255)
1646 : // + "."
1647 : // + std::to_string((mask >> 0) & 255));
1648 66 : std::string result("172.17.3.91:" + std::to_string(port) + "/" + std::to_string(idx));
1649 33 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_ALL) == result);
1650 33 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ALL) == result);
1651 33 : CATCH_REQUIRE(f.get_port() == port);
1652 33 : CATCH_REQUIRE(f.get_protocol() == proto);
1653 33 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
1654 33 : CATCH_REQUIRE(f.is_lan());
1655 33 : CATCH_REQUIRE(f.is_lan(true));
1656 33 : CATCH_REQUIRE(f.is_lan(false));
1657 33 : CATCH_REQUIRE_FALSE(f.is_wan());
1658 33 : CATCH_REQUIRE_FALSE(f.is_wan(true));
1659 33 : CATCH_REQUIRE_FALSE(f.is_wan(false));
1660 33 : CATCH_REQUIRE(f.get_mask_size() == 96 + idx);
1661 : }
1662 : }
1663 : CATCH_END_SECTION()
1664 :
1665 14 : CATCH_START_SECTION("addr: address like mask")
1666 : {
1667 26 : for(int idx(0); idx < 25; ++idx)
1668 : {
1669 25 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1670 25 : int const port(rand() & 0xFFFF);
1671 50 : addr::addr_parser p;
1672 25 : p.set_protocol(proto);
1673 25 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
1674 25 : p.set_allow(addr::allow_t::ALLOW_ADDRESS_MASK, true);
1675 : // when specified as an IP, the mask can be absolutely anything
1676 25 : uint8_t mask[4];
1677 0 : do
1678 : {
1679 125 : for(int j(0); j < 4; ++j)
1680 : {
1681 100 : mask[j] = rand();
1682 : }
1683 : }
1684 25 : while(mask[0] == 0 // make sure the mask is no just a number
1685 0 : && mask[1] == 0
1686 0 : && mask[2] == 0
1687 25 : && mask[3] == 0);
1688 25 : switch(mask[0])
1689 : {
1690 0 : case 0xFF:
1691 0 : mask[0] &= ~(1 << (rand() & 7));
1692 0 : break;
1693 :
1694 0 : case 0xFE:
1695 : case 0xFC:
1696 : case 0xF8:
1697 : case 0xF0:
1698 : case 0xE0:
1699 : case 0xC0:
1700 0 : mask[0] &= 0x7F;
1701 0 : break;
1702 :
1703 0 : case 0x80:
1704 0 : mask[0] |= 1 << (rand() % 6);
1705 0 : break;
1706 :
1707 : }
1708 25 : std::string const mask_str(
1709 50 : std::to_string(static_cast<int>(mask[0]))
1710 75 : + "."
1711 100 : + std::to_string(static_cast<int>(mask[1]))
1712 75 : + "."
1713 100 : + std::to_string(static_cast<int>(mask[2]))
1714 75 : + "."
1715 100 : + std::to_string(static_cast<int>(mask[3])));
1716 50 : addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port) + "/" + mask_str));
1717 25 : CATCH_REQUIRE_FALSE(p.has_errors());
1718 25 : CATCH_REQUIRE(ips.size() == 1);
1719 25 : addr::addr_range const & r(ips[0]);
1720 50 : addr::addr f(r.get_from());
1721 25 : CATCH_REQUIRE(f.is_ipv4());
1722 25 : CATCH_REQUIRE(f.get_family() == AF_INET);
1723 25 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1724 50 : std::string result("172.17.3.91:" + std::to_string(port) + "/" + mask_str);
1725 25 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_ALL) == result);
1726 25 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ALL) == result);
1727 25 : CATCH_REQUIRE(f.get_port() == port);
1728 25 : CATCH_REQUIRE(f.get_protocol() == proto);
1729 25 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
1730 25 : CATCH_REQUIRE(f.is_lan());
1731 25 : CATCH_REQUIRE(f.is_lan(true));
1732 25 : CATCH_REQUIRE(f.is_lan(false));
1733 25 : CATCH_REQUIRE_FALSE(f.is_wan());
1734 25 : CATCH_REQUIRE_FALSE(f.is_wan(true));
1735 25 : CATCH_REQUIRE_FALSE(f.is_wan(false));
1736 :
1737 : // above we made sure that the mask was not just a number so
1738 : // here we should always get -1
1739 : //
1740 25 : CATCH_REQUIRE(f.get_mask_size() == -1);
1741 : }
1742 : }
1743 : CATCH_END_SECTION()
1744 :
1745 14 : CATCH_START_SECTION("addr: address like default mask")
1746 : {
1747 26 : for(int idx(0); idx < 25; ++idx)
1748 : {
1749 25 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1750 25 : int const port(rand() & 0xFFFF);
1751 50 : addr::addr_parser p;
1752 25 : p.set_protocol(proto);
1753 25 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
1754 25 : p.set_allow(addr::allow_t::ALLOW_ADDRESS_MASK, true);
1755 : // when specified as an IP, the mask can be absolutely anything
1756 : // (here the mask is a string an it will be parsed by the
1757 : // parser if required)
1758 : //
1759 25 : uint8_t mask[4];
1760 125 : for(int j(0); j < 4; ++j)
1761 : {
1762 100 : mask[j] = rand();
1763 : }
1764 25 : std::string const mask_str(
1765 50 : std::to_string(static_cast<int>(mask[0]))
1766 75 : + "."
1767 100 : + std::to_string(static_cast<int>(mask[1]))
1768 75 : + "."
1769 100 : + std::to_string(static_cast<int>(mask[2]))
1770 75 : + "."
1771 100 : + std::to_string(static_cast<int>(mask[3])));
1772 25 : p.set_default_mask(mask_str);
1773 50 : addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port)));
1774 25 : CATCH_REQUIRE_FALSE(p.has_errors());
1775 25 : CATCH_REQUIRE(ips.size() == 1);
1776 25 : addr::addr_range const & r(ips[0]);
1777 50 : addr::addr f(r.get_from());
1778 25 : CATCH_REQUIRE(f.is_ipv4());
1779 25 : CATCH_REQUIRE(f.get_family() == AF_INET);
1780 25 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1781 50 : std::string result("172.17.3.91:" + std::to_string(port) + "/" + mask_str);
1782 25 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_ALL) == result);
1783 25 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ALL) == result);
1784 25 : CATCH_REQUIRE(f.get_port() == port);
1785 25 : CATCH_REQUIRE(f.get_protocol() == proto);
1786 25 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
1787 25 : CATCH_REQUIRE(f.is_lan());
1788 25 : CATCH_REQUIRE(f.is_lan(true));
1789 25 : CATCH_REQUIRE(f.is_lan(false));
1790 25 : CATCH_REQUIRE_FALSE(f.is_wan());
1791 25 : CATCH_REQUIRE_FALSE(f.is_wan(true));
1792 25 : CATCH_REQUIRE_FALSE(f.is_wan(false));
1793 25 : uint8_t verify_mask[16];
1794 25 : f.get_mask(verify_mask);
1795 325 : for(int j(0); j < 16 - 4; ++j)
1796 : {
1797 300 : CATCH_REQUIRE(verify_mask[j] == 255);
1798 : }
1799 125 : for(int j(12); j < 16; ++j)
1800 : {
1801 100 : CATCH_REQUIRE(verify_mask[j] == mask[j - 12]);
1802 : }
1803 : }
1804 : }
1805 : CATCH_END_SECTION()
1806 :
1807 14 : CATCH_START_SECTION("addr: address like mask with a default")
1808 : {
1809 26 : for(int idx(0); idx < 25; ++idx)
1810 : {
1811 25 : int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1812 25 : int const port(rand() & 0xFFFF);
1813 50 : addr::addr_parser p;
1814 25 : p.set_protocol(proto);
1815 25 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
1816 25 : p.set_allow(addr::allow_t::ALLOW_ADDRESS_MASK, true);
1817 :
1818 : // here we want a default and an IP with a specific mask
1819 : // to make sure that the specific mask has priority
1820 : //
1821 25 : uint8_t mask[4];
1822 125 : for(int j(0); j < 4; ++j)
1823 : {
1824 100 : mask[j] = rand();
1825 : }
1826 25 : std::string const mask_str(
1827 50 : std::to_string(static_cast<int>(mask[0]))
1828 75 : + "."
1829 100 : + std::to_string(static_cast<int>(mask[1]))
1830 75 : + "."
1831 100 : + std::to_string(static_cast<int>(mask[2]))
1832 75 : + "."
1833 100 : + std::to_string(static_cast<int>(mask[3])));
1834 :
1835 25 : uint8_t default_mask[4];
1836 125 : for(int j(0); j < 4; ++j)
1837 : {
1838 100 : default_mask[j] = rand();
1839 : }
1840 25 : std::string const default_mask_str(
1841 50 : std::to_string(static_cast<int>(default_mask[0]))
1842 75 : + "."
1843 100 : + std::to_string(static_cast<int>(default_mask[1]))
1844 75 : + "."
1845 100 : + std::to_string(static_cast<int>(default_mask[2]))
1846 75 : + "."
1847 100 : + std::to_string(static_cast<int>(default_mask[3])));
1848 25 : p.set_default_mask(default_mask_str);
1849 :
1850 50 : addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port) + "/" + mask_str));
1851 25 : CATCH_REQUIRE_FALSE(p.has_errors());
1852 25 : CATCH_REQUIRE(ips.size() == 1);
1853 25 : addr::addr_range const & r(ips[0]);
1854 50 : addr::addr f(r.get_from());
1855 25 : CATCH_REQUIRE(f.is_ipv4());
1856 25 : CATCH_REQUIRE(f.get_family() == AF_INET);
1857 25 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
1858 50 : std::string result("172.17.3.91:" + std::to_string(port) + "/" + mask_str);
1859 25 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_ALL) == result);
1860 25 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ALL) == result);
1861 25 : CATCH_REQUIRE(f.get_port() == port);
1862 25 : CATCH_REQUIRE(f.get_protocol() == proto);
1863 25 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
1864 25 : CATCH_REQUIRE(f.is_lan());
1865 25 : CATCH_REQUIRE(f.is_lan(true));
1866 25 : CATCH_REQUIRE(f.is_lan(false));
1867 25 : CATCH_REQUIRE_FALSE(f.is_wan());
1868 25 : CATCH_REQUIRE_FALSE(f.is_wan(true));
1869 25 : CATCH_REQUIRE_FALSE(f.is_wan(false));
1870 25 : uint8_t verify_mask[16];
1871 25 : f.get_mask(verify_mask);
1872 325 : for(int j(0); j < 16 - 4; ++j)
1873 : {
1874 300 : CATCH_REQUIRE(verify_mask[j] == 255);
1875 : }
1876 125 : for(int j(12); j < 16; ++j)
1877 : {
1878 100 : CATCH_REQUIRE(verify_mask[j] == mask[j - 12]);
1879 : }
1880 : }
1881 : }
1882 : CATCH_END_SECTION()
1883 :
1884 14 : CATCH_START_SECTION("addr: two addresses and a mask for a match / no match")
1885 : {
1886 1 : int const port1(rand() & 0xFFFF);
1887 2 : addr::addr_parser p;
1888 1 : p.set_allow(addr::allow_t::ALLOW_MASK, true);
1889 :
1890 : // parse the IP with a mask
1891 : //
1892 1 : int proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
1893 1 : p.set_protocol(proto);
1894 2 : addr::addr_range::vector_t ips1(p.parse("192.168.0.0:" + std::to_string(port1) + "/16"));
1895 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1896 1 : CATCH_REQUIRE(ips1.size() == 1);
1897 1 : addr::addr_range const & r1(ips1[0]);
1898 2 : addr::addr f1(r1.get_from());
1899 1 : CATCH_REQUIRE(f1.is_ipv4());
1900 1 : CATCH_REQUIRE(f1.get_family() == AF_INET);
1901 1 : CATCH_REQUIRE_FALSE(f1.get_family() == AF_INET6);
1902 1 : CATCH_REQUIRE(f1.to_ipv4_string(addr::string_ip_t::STRING_IP_ALL) == "192.168.0.0:" + std::to_string(port1) + "/16");
1903 1 : CATCH_REQUIRE(f1.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ALL) == "192.168.0.0:" + std::to_string(port1) + "/16");
1904 1 : CATCH_REQUIRE(f1.get_port() == port1);
1905 1 : CATCH_REQUIRE(f1.get_protocol() == proto);
1906 1 : CATCH_REQUIRE(f1.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
1907 1 : CATCH_REQUIRE(f1.is_lan());
1908 1 : CATCH_REQUIRE(f1.is_lan(true));
1909 1 : CATCH_REQUIRE(f1.is_lan(false));
1910 1 : CATCH_REQUIRE_FALSE(f1.is_wan());
1911 1 : CATCH_REQUIRE_FALSE(f1.is_wan(true));
1912 1 : CATCH_REQUIRE_FALSE(f1.is_wan(false));
1913 :
1914 : // reuse parser
1915 : //
1916 1 : proto = rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP;
1917 1 : p.set_protocol(proto);
1918 1 : int const port2(rand() & 0xFFFF);
1919 2 : addr::addr_range::vector_t ips2(p.parse("192.168.5.36:" + std::to_string(port2)));
1920 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1921 1 : CATCH_REQUIRE(ips2.size() == 1);
1922 1 : addr::addr_range const & r2(ips2[0]);
1923 2 : addr::addr f2(r2.get_from());
1924 1 : CATCH_REQUIRE(f2.is_ipv4());
1925 1 : CATCH_REQUIRE(f2.get_family() == AF_INET);
1926 1 : CATCH_REQUIRE_FALSE(f2.get_family() == AF_INET6);
1927 1 : CATCH_REQUIRE(f2.to_ipv4_string(addr::string_ip_t::STRING_IP_ALL) == "192.168.5.36:" + std::to_string(port2) + "/32");
1928 1 : CATCH_REQUIRE(f2.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ALL) == "192.168.5.36:" + std::to_string(port2) + "/32");
1929 1 : CATCH_REQUIRE(f2.get_port() == port2);
1930 1 : CATCH_REQUIRE(f2.get_protocol() == proto);
1931 1 : CATCH_REQUIRE(f2.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
1932 1 : CATCH_REQUIRE(f2.is_lan());
1933 1 : CATCH_REQUIRE(f2.is_lan(true));
1934 1 : CATCH_REQUIRE(f2.is_lan(false));
1935 1 : CATCH_REQUIRE_FALSE(f2.is_wan());
1936 1 : CATCH_REQUIRE_FALSE(f2.is_wan(true));
1937 1 : CATCH_REQUIRE_FALSE(f2.is_wan(false));
1938 :
1939 : // 3rd with a mask along the full IP
1940 : //
1941 1 : proto = rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP;
1942 1 : p.set_protocol(proto);
1943 1 : int const port3(rand() & 0xFFFF);
1944 2 : addr::addr_range::vector_t ips3(p.parse("192.168.5.36:" + std::to_string(port3) + "/16"));
1945 1 : CATCH_REQUIRE_FALSE(p.has_errors());
1946 1 : CATCH_REQUIRE(ips3.size() == 1);
1947 1 : addr::addr_range const & r3(ips3[0]);
1948 2 : addr::addr f3(r3.get_from());
1949 1 : CATCH_REQUIRE(f3.is_ipv4());
1950 1 : CATCH_REQUIRE(f3.get_family() == AF_INET);
1951 1 : CATCH_REQUIRE_FALSE(f3.get_family() == AF_INET6);
1952 1 : CATCH_REQUIRE(f3.to_ipv4_string(addr::string_ip_t::STRING_IP_ALL) == "192.168.5.36:" + std::to_string(port3) + "/16");
1953 1 : CATCH_REQUIRE(f3.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ALL) == "192.168.5.36:" + std::to_string(port3) + "/16");
1954 1 : CATCH_REQUIRE(f3.get_port() == port3);
1955 1 : CATCH_REQUIRE(f3.get_protocol() == proto);
1956 1 : CATCH_REQUIRE(f3.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
1957 1 : CATCH_REQUIRE(f3.is_lan());
1958 1 : CATCH_REQUIRE(f3.is_lan(true));
1959 1 : CATCH_REQUIRE(f3.is_lan(false));
1960 1 : CATCH_REQUIRE_FALSE(f3.is_wan());
1961 1 : CATCH_REQUIRE_FALSE(f3.is_wan(true));
1962 1 : CATCH_REQUIRE_FALSE(f3.is_wan(false));
1963 :
1964 : // just a side test
1965 : //
1966 1 : CATCH_REQUIRE(f1 != f2);
1967 1 : CATCH_REQUIRE(f1 != f3);
1968 1 : CATCH_REQUIRE(f2 == f3);
1969 :
1970 : // check whether p1 matches p2 and vice versa
1971 : //
1972 1 : CATCH_REQUIRE(f1.match(f2)); // f2 & mask1 == f1 & mask1
1973 1 : CATCH_REQUIRE(f1.match(f3)); // f3 & mask1 == f1 & mask1
1974 :
1975 1 : CATCH_REQUIRE_FALSE(f2.match(f1)); // f1 & mask2 != f2 & mask2
1976 1 : CATCH_REQUIRE(f2.match(f3)); // f3 & mask2 == f2 & mask2 (because f2 == f3 anyway)
1977 :
1978 1 : CATCH_REQUIRE(f3.match(f1)); // f1 & mask3 == f3 & mask3
1979 1 : CATCH_REQUIRE(f3.match(f2)); // f2 & mask3 == f3 & mask3
1980 :
1981 1 : f3.apply_mask();
1982 :
1983 1 : CATCH_REQUIRE(f1 != f2);
1984 1 : CATCH_REQUIRE(f1 == f3);
1985 1 : CATCH_REQUIRE(f2 != f3);
1986 :
1987 : // re-run the match() calls with f3 since it changed...
1988 : //
1989 1 : CATCH_REQUIRE(f1.match(f3)); // f3 & mask1 == f1 & mask1
1990 :
1991 1 : CATCH_REQUIRE_FALSE(f2.match(f3)); // f3 & mask2 == f2 & mask2 (because f2 != f3 anymore)
1992 :
1993 1 : CATCH_REQUIRE(f3.match(f1)); // f1 & mask3 == f3 & mask3
1994 1 : CATCH_REQUIRE(f3.match(f2)); // f2 & mask3 == f3 & mask3
1995 :
1996 2 : addr::addr fa; // by default an address is ANY and it matches everything
1997 1 : CATCH_REQUIRE(fa.match(f1, true));
1998 1 : CATCH_REQUIRE(fa.match(f2, true));
1999 1 : CATCH_REQUIRE(fa.match(f3, true));
2000 1 : std::uint8_t const verify_match[16] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 };
2001 1 : std::uint8_t any_mask[16] = {};
2002 1 : fa.get_mask(any_mask);
2003 1 : CATCH_REQUIRE(memcmp(verify_match, any_mask, 16) == 0);
2004 : }
2005 : CATCH_END_SECTION()
2006 : }
2007 7 : }
2008 :
2009 :
2010 8 : CATCH_TEST_CASE("ipv4::protocol", "[ipv4]")
2011 : {
2012 12 : CATCH_GIVEN("addr()")
2013 : {
2014 4 : addr::addr a;
2015 :
2016 4 : CATCH_START_SECTION("addr: default protocol")
2017 : {
2018 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_TCP);
2019 : }
2020 : CATCH_END_SECTION()
2021 :
2022 4 : CATCH_START_SECTION("addr: set_protocol()")
2023 : {
2024 : // setup a random protocol
2025 : //
2026 1 : int const start_protocol([]()
2027 : {
2028 1 : switch(rand() % 3)
2029 : {
2030 0 : case 0:
2031 0 : return IPPROTO_IP;
2032 :
2033 0 : case 1:
2034 0 : return IPPROTO_TCP;
2035 :
2036 : //case 2:
2037 1 : default:
2038 1 : return IPPROTO_UDP;
2039 :
2040 : }
2041 1 : }());
2042 1 : a.set_protocol(start_protocol);
2043 :
2044 : // test 100 invalid protocols
2045 : //
2046 101 : for(int idx(0); idx < 100; ++idx)
2047 : {
2048 : int invalid_protocol;
2049 0 : do
2050 : {
2051 100 : invalid_protocol = rand();
2052 : }
2053 : while(invalid_protocol == IPPROTO_IP
2054 100 : || invalid_protocol == IPPROTO_TCP
2055 200 : || invalid_protocol == IPPROTO_UDP);
2056 100 : CATCH_REQUIRE_THROWS_AS(a.set_protocol(invalid_protocol), addr::addr_invalid_argument);
2057 :
2058 : // make sure the protocol does not change on errors
2059 100 : CATCH_REQUIRE(a.get_protocol() == start_protocol);
2060 : }
2061 :
2062 : // null string is not allowed
2063 : //
2064 1 : CATCH_REQUIRE_THROWS_AS(a.set_protocol(nullptr), addr::addr_invalid_argument);
2065 :
2066 : // other "invalid" (unsupported, really) string protocols
2067 : //
2068 1 : CATCH_REQUIRE_THROWS_AS(a.set_protocol("unknown"), addr::addr_invalid_argument);
2069 1 : CATCH_REQUIRE_THROWS_AS(a.set_protocol("invalid"), addr::addr_invalid_argument);
2070 1 : CATCH_REQUIRE_THROWS_AS(a.set_protocol("other"), addr::addr_invalid_argument);
2071 :
2072 : // test all valid protocols (numeric)
2073 : //
2074 1 : a.set_protocol(IPPROTO_IP);
2075 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_IP);
2076 1 : a.set_protocol(IPPROTO_TCP);
2077 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_TCP);
2078 1 : a.set_protocol(IPPROTO_UDP);
2079 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_UDP);
2080 :
2081 : // test all valid protocols (ascii)
2082 : //
2083 1 : a.set_protocol("ip");
2084 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_IP);
2085 1 : a.set_protocol("tcp");
2086 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_TCP);
2087 1 : a.set_protocol("udp");
2088 1 : CATCH_REQUIRE(a.get_protocol() == IPPROTO_UDP);
2089 : }
2090 : CATCH_END_SECTION()
2091 : }
2092 :
2093 12 : CATCH_GIVEN("addr_parser()")
2094 : {
2095 6 : addr::addr_parser p;
2096 :
2097 6 : CATCH_START_SECTION("addr: verify default")
2098 : {
2099 1 : CATCH_REQUIRE(p.get_protocol() == -1);
2100 : }
2101 : CATCH_END_SECTION()
2102 :
2103 6 : CATCH_START_SECTION("addr: test 3 allowed protocols")
2104 : {
2105 : // by string
2106 : //
2107 1 : p.set_protocol("ip");
2108 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_IP);
2109 1 : p.set_protocol("tcp");
2110 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_TCP);
2111 1 : p.set_protocol("udp");
2112 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_UDP);
2113 :
2114 : // numerically
2115 : //
2116 1 : p.set_protocol(IPPROTO_IP);
2117 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_IP);
2118 1 : p.set_protocol(IPPROTO_TCP);
2119 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_TCP);
2120 1 : p.set_protocol(IPPROTO_UDP);
2121 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_UDP);
2122 : }
2123 : CATCH_END_SECTION()
2124 :
2125 6 : CATCH_START_SECTION("addr: verify clearing works")
2126 : {
2127 1 : p.set_protocol("ip");
2128 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_IP);
2129 1 : p.clear_protocol();
2130 1 : CATCH_REQUIRE(p.get_protocol() == -1);
2131 :
2132 1 : p.set_protocol("tcp");
2133 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_TCP);
2134 1 : p.clear_protocol();
2135 1 : CATCH_REQUIRE(p.get_protocol() == -1);
2136 :
2137 1 : p.set_protocol("udp");
2138 1 : CATCH_REQUIRE(p.get_protocol() == IPPROTO_UDP);
2139 1 : p.clear_protocol();
2140 1 : CATCH_REQUIRE(p.get_protocol() == -1);
2141 : }
2142 : CATCH_END_SECTION()
2143 : }
2144 :
2145 12 : CATCH_GIVEN("addr_parser with any protocol")
2146 : {
2147 2 : addr::addr a;
2148 :
2149 2 : CATCH_START_SECTION("addr: get address with all protocols")
2150 : {
2151 2 : addr::addr_parser p;
2152 : //p.set_protocol(...); -- by default we'll get all the protocols supported
2153 2 : addr::addr_range::vector_t ips(p.parse("127.0.0.1"));
2154 1 : CATCH_REQUIRE_FALSE(p.has_errors());
2155 1 : CATCH_REQUIRE(!ips.empty());
2156 4 : for(size_t idx(0); idx < ips.size(); ++idx)
2157 : {
2158 3 : addr::addr_range const & r(ips[idx]);
2159 3 : CATCH_REQUIRE(r.has_from());
2160 3 : CATCH_REQUIRE_FALSE(r.has_to());
2161 3 : CATCH_REQUIRE_FALSE(r.is_range());
2162 3 : CATCH_REQUIRE_FALSE(r.is_empty());
2163 6 : addr::addr f(r.get_from());
2164 3 : if(f.is_ipv4())
2165 : {
2166 3 : CATCH_REQUIRE(f.get_family() == AF_INET);
2167 3 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
2168 3 : CATCH_REQUIRE(f.to_ipv4_string(addr::string_ip_t::STRING_IP_ONLY) == "127.0.0.1");
2169 3 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ONLY) == "127.0.0.1");
2170 3 : CATCH_REQUIRE(f.get_port() == 0);
2171 : //CATCH_REQUIRE(f.get_protocol() == ...); -- may be TCP, UDP, IP
2172 3 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_LOOPBACK);
2173 3 : CATCH_REQUIRE(f.is_lan());
2174 3 : CATCH_REQUIRE(f.is_lan(true));
2175 3 : CATCH_REQUIRE(f.is_lan(false));
2176 3 : CATCH_REQUIRE_FALSE(f.is_wan());
2177 3 : CATCH_REQUIRE_FALSE(f.is_wan(true));
2178 3 : CATCH_REQUIRE_FALSE(f.is_wan(false));
2179 : }
2180 : else
2181 : {
2182 0 : CATCH_REQUIRE_FALSE(f.get_family() == AF_INET);
2183 0 : CATCH_REQUIRE(f.get_family() == AF_INET6);
2184 0 : CATCH_REQUIRE(f.to_ipv6_string(addr::string_ip_t::STRING_IP_ONLY) == "::1");
2185 0 : CATCH_REQUIRE(f.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ONLY) == "::1");
2186 0 : CATCH_REQUIRE(f.get_port() == 0);
2187 : //CATCH_REQUIRE(f.get_protocol() == ...); -- may be TCP, UDP, IP
2188 0 : CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_LOOPBACK);
2189 0 : CATCH_REQUIRE(f.is_lan());
2190 0 : CATCH_REQUIRE(f.is_lan(true));
2191 0 : CATCH_REQUIRE(f.is_lan(false));
2192 0 : CATCH_REQUIRE_FALSE(f.is_wan());
2193 0 : CATCH_REQUIRE_FALSE(f.is_wan(true));
2194 0 : CATCH_REQUIRE_FALSE(f.is_wan(false));
2195 : }
2196 : }
2197 : }
2198 : CATCH_END_SECTION()
2199 : }
2200 6 : }
2201 :
2202 :
2203 10 : CATCH_TEST_CASE("ipv4::network_type", "[ipv4]")
2204 : {
2205 16 : CATCH_GIVEN("addr()")
2206 : {
2207 16 : addr::addr a;
2208 :
2209 16 : CATCH_START_SECTION("addr: any (0.0.0.0)")
2210 : {
2211 1 : struct sockaddr_in in = sockaddr_in();
2212 1 : in.sin_family = AF_INET;
2213 1 : in.sin_port = htons(rand());
2214 1 : in.sin_addr.s_addr = 0;
2215 :
2216 : // verify network type
2217 : //
2218 1 : a.set_ipv4(in);
2219 :
2220 1 : CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_ANY);
2221 1 : CATCH_REQUIRE(a.get_network_type_string() == "Any");
2222 1 : CATCH_REQUIRE_FALSE(a.is_lan());
2223 1 : CATCH_REQUIRE_FALSE(a.is_lan(true));
2224 1 : CATCH_REQUIRE_FALSE(a.is_lan(false));
2225 1 : CATCH_REQUIRE(a.is_wan());
2226 1 : CATCH_REQUIRE(a.is_wan(true));
2227 1 : CATCH_REQUIRE_FALSE(a.is_wan(false));
2228 : }
2229 : CATCH_END_SECTION()
2230 :
2231 16 : CATCH_START_SECTION("addr: private address 10.x.x.x/8")
2232 : {
2233 11 : for(int idx(0); idx < 10; ++idx)
2234 : {
2235 10 : struct sockaddr_in in = sockaddr_in();
2236 10 : in.sin_family = AF_INET;
2237 10 : in.sin_port = htons(rand());
2238 : uint32_t address((10 << 24)
2239 10 : | ((rand() & 255) << 16)
2240 10 : | ((rand() & 255) << 8)
2241 10 : | ((rand() & 255) << 0));
2242 10 : in.sin_addr.s_addr = htonl(address);
2243 :
2244 : // verify network type
2245 : //
2246 10 : a.set_ipv4(in);
2247 10 : CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
2248 10 : CATCH_REQUIRE(a.get_network_type_string() == "Private");
2249 10 : CATCH_REQUIRE(a.is_lan());
2250 10 : CATCH_REQUIRE(a.is_lan(true));
2251 10 : CATCH_REQUIRE(a.is_lan(false));
2252 10 : CATCH_REQUIRE_FALSE(a.is_wan());
2253 10 : CATCH_REQUIRE_FALSE(a.is_wan(true));
2254 10 : CATCH_REQUIRE_FALSE(a.is_wan(false));
2255 : }
2256 : }
2257 : CATCH_END_SECTION()
2258 :
2259 16 : CATCH_START_SECTION("addr: private address 172.16.x.x/12")
2260 : {
2261 11 : for(int idx(0); idx < 10; ++idx)
2262 : {
2263 10 : struct sockaddr_in in = sockaddr_in();
2264 10 : in.sin_family = AF_INET;
2265 10 : in.sin_port = htons(rand());
2266 : uint32_t address((172 << 24)
2267 10 : | (((rand() & 15) | 16) << 16)
2268 10 : | ((rand() & 255) << 8)
2269 10 : | ((rand() & 255) << 0));
2270 10 : in.sin_addr.s_addr = htonl(address);
2271 :
2272 : // verify network type
2273 : //
2274 10 : a.set_ipv4(in);
2275 10 : CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
2276 10 : CATCH_REQUIRE(a.get_network_type_string() == "Private");
2277 10 : CATCH_REQUIRE(a.is_lan());
2278 10 : CATCH_REQUIRE(a.is_lan(true));
2279 10 : CATCH_REQUIRE(a.is_lan(false));
2280 10 : CATCH_REQUIRE_FALSE(a.is_wan());
2281 10 : CATCH_REQUIRE_FALSE(a.is_wan(true));
2282 10 : CATCH_REQUIRE_FALSE(a.is_wan(false));
2283 : }
2284 : }
2285 : CATCH_END_SECTION()
2286 :
2287 16 : CATCH_START_SECTION("addr: private address 192.168.x.x/16")
2288 : {
2289 11 : for(int idx(0); idx < 10; ++idx)
2290 : {
2291 10 : struct sockaddr_in in = sockaddr_in();
2292 10 : in.sin_family = AF_INET;
2293 10 : in.sin_port = htons(rand());
2294 : uint32_t address((192 << 24)
2295 : | (168 << 16)
2296 10 : | ((rand() & 255) << 8)
2297 10 : | ((rand() & 255) << 0));
2298 10 : in.sin_addr.s_addr = htonl(address);
2299 :
2300 : // verify network type
2301 : //
2302 10 : a.set_ipv4(in);
2303 10 : CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
2304 10 : CATCH_REQUIRE(a.get_network_type_string() == "Private");
2305 10 : CATCH_REQUIRE(a.is_lan());
2306 10 : CATCH_REQUIRE(a.is_lan(true));
2307 10 : CATCH_REQUIRE(a.is_lan(false));
2308 10 : CATCH_REQUIRE_FALSE(a.is_wan());
2309 10 : CATCH_REQUIRE_FALSE(a.is_wan(true));
2310 10 : CATCH_REQUIRE_FALSE(a.is_wan(false));
2311 : }
2312 : }
2313 : CATCH_END_SECTION()
2314 :
2315 16 : CATCH_START_SECTION("addr: private address 100.66.x.x/10")
2316 : {
2317 11 : for(int idx(0); idx < 10; ++idx)
2318 : {
2319 10 : struct sockaddr_in in = sockaddr_in();
2320 10 : in.sin_family = AF_INET;
2321 10 : in.sin_port = htons(rand());
2322 : uint32_t address((100 << 24)
2323 10 : | (((rand() & 63) | 64) << 16)
2324 10 : | ((rand() & 255) << 8)
2325 10 : | ((rand() & 255) << 0));
2326 10 : in.sin_addr.s_addr = htonl(address);
2327 :
2328 : // verify network type
2329 : //
2330 10 : a.set_ipv4(in);
2331 10 : CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_CARRIER);
2332 10 : CATCH_REQUIRE(a.get_network_type_string() == "Carrier");
2333 10 : CATCH_REQUIRE_FALSE(a.is_lan());
2334 10 : CATCH_REQUIRE(a.is_lan(true));
2335 10 : CATCH_REQUIRE_FALSE(a.is_lan(false));
2336 10 : CATCH_REQUIRE_FALSE(a.is_wan());
2337 10 : CATCH_REQUIRE_FALSE(a.is_wan(true));
2338 10 : CATCH_REQUIRE_FALSE(a.is_wan(false));
2339 : }
2340 : }
2341 : CATCH_END_SECTION()
2342 :
2343 16 : CATCH_START_SECTION("addr: private address 169.254.x.x/16")
2344 : {
2345 11 : for(int idx(0); idx < 10; ++idx)
2346 : {
2347 10 : struct sockaddr_in in = sockaddr_in();
2348 10 : in.sin_family = AF_INET;
2349 10 : in.sin_port = htons(rand());
2350 : uint32_t address((169 << 24)
2351 : | (254 << 16)
2352 10 : | ((rand() & 255) << 8)
2353 10 : | ((rand() & 255) << 0));
2354 10 : in.sin_addr.s_addr = htonl(address);
2355 :
2356 : // verify network type
2357 : //
2358 10 : a.set_ipv4(in);
2359 10 : CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_LINK_LOCAL);
2360 10 : CATCH_REQUIRE(a.get_network_type_string() == "Local Link");
2361 10 : CATCH_REQUIRE_FALSE(a.is_lan());
2362 10 : CATCH_REQUIRE(a.is_lan(true));
2363 10 : CATCH_REQUIRE_FALSE(a.is_lan(false));
2364 10 : CATCH_REQUIRE_FALSE(a.is_wan());
2365 10 : CATCH_REQUIRE_FALSE(a.is_wan(true));
2366 10 : CATCH_REQUIRE_FALSE(a.is_wan(false));
2367 : }
2368 : }
2369 : CATCH_END_SECTION()
2370 :
2371 16 : CATCH_START_SECTION("addr: private address 224.x.x.x/4")
2372 : {
2373 11 : for(int idx(0); idx < 10; ++idx)
2374 : {
2375 10 : struct sockaddr_in in = sockaddr_in();
2376 10 : in.sin_family = AF_INET;
2377 10 : in.sin_port = htons(rand());
2378 10 : uint32_t address((((rand() & 15) | 224) << 24)
2379 10 : | ((rand() & 255) << 16)
2380 10 : | ((rand() & 255) << 8)
2381 10 : | ((rand() & 255) << 0));
2382 10 : in.sin_addr.s_addr = htonl(address);
2383 :
2384 : // verify network type
2385 : //
2386 10 : a.set_ipv4(in);
2387 10 : CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_MULTICAST);
2388 10 : CATCH_REQUIRE(a.get_network_type_string() == "Multicast");
2389 10 : CATCH_REQUIRE_FALSE(a.is_lan());
2390 10 : CATCH_REQUIRE(a.is_lan(true));
2391 10 : CATCH_REQUIRE_FALSE(a.is_lan(false));
2392 10 : CATCH_REQUIRE_FALSE(a.is_wan());
2393 10 : CATCH_REQUIRE_FALSE(a.is_wan(true));
2394 10 : CATCH_REQUIRE_FALSE(a.is_wan(false));
2395 :
2396 : // make sure no interface uses that IP
2397 : //
2398 10 : CATCH_REQUIRE(addr::find_addr_interface(a, false) == nullptr);
2399 : }
2400 : }
2401 : CATCH_END_SECTION()
2402 :
2403 16 : CATCH_START_SECTION("addr: private address 127.x.x.x/8")
2404 : {
2405 11 : for(int idx(0); idx < 10; ++idx)
2406 : {
2407 10 : struct sockaddr_in in = sockaddr_in();
2408 10 : in.sin_family = AF_INET;
2409 10 : in.sin_port = htons(rand());
2410 : uint32_t address((127 << 24)
2411 10 : | ((rand() & 255) << 16)
2412 10 : | ((rand() & 255) << 8)
2413 10 : | ((rand() & 255) << 0));
2414 10 : in.sin_addr.s_addr = htonl(address);
2415 :
2416 : // verify network type
2417 : //
2418 10 : a.set_ipv4(in);
2419 10 : CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_LOOPBACK);
2420 10 : CATCH_REQUIRE(a.get_network_type_string() == "Loopback");
2421 10 : CATCH_REQUIRE(a.is_lan());
2422 10 : CATCH_REQUIRE(a.is_lan(true));
2423 10 : CATCH_REQUIRE(a.is_lan(false));
2424 10 : CATCH_REQUIRE_FALSE(a.is_wan());
2425 10 : CATCH_REQUIRE_FALSE(a.is_wan(true));
2426 10 : CATCH_REQUIRE_FALSE(a.is_wan(false));
2427 : }
2428 : }
2429 : CATCH_END_SECTION()
2430 : }
2431 8 : }
2432 :
2433 :
2434 9 : CATCH_TEST_CASE("ipv4::network", "[ipv4]")
2435 : {
2436 14 : CATCH_GIVEN("set_from_socket()")
2437 : {
2438 14 : CATCH_START_SECTION("addr: invalid socket")
2439 : {
2440 2 : addr::addr a;
2441 1 : CATCH_REQUIRE_THROWS_AS(a.set_from_socket(-1, true), addr::addr_invalid_argument);
2442 1 : CATCH_REQUIRE_THROWS_AS(a.set_from_socket(-1, false), addr::addr_invalid_argument);
2443 : }
2444 : CATCH_END_SECTION()
2445 :
2446 14 : CATCH_START_SECTION("addr: non-opened file descriptor")
2447 : {
2448 2 : addr::addr a;
2449 :
2450 : // unless we have a bug, there should not be any file descriptor
2451 : // currently open with an ID of 1,000
2452 : //
2453 1 : CATCH_REQUIRE_THROWS_AS(a.set_from_socket(1000, true), addr::addr_io_error);
2454 1 : CATCH_REQUIRE_THROWS_AS(a.set_from_socket(1000, false), addr::addr_io_error);
2455 : }
2456 : CATCH_END_SECTION()
2457 :
2458 14 : CATCH_START_SECTION("addr: unknown socket type")
2459 : {
2460 2 : addr::addr a;
2461 :
2462 1 : int s(socket(AF_UNIX, SOCK_STREAM, 0));
2463 1 : CATCH_REQUIRE(s >= 0);
2464 2 : std::shared_ptr<int> auto_free(&s, socket_deleter);
2465 :
2466 : // unless we have a bug, there should not be any file descriptor
2467 : // currently open with an ID of 1,000
2468 : //
2469 1 : CATCH_REQUIRE_THROWS_AS(a.set_from_socket(s, true), addr::addr_io_error);
2470 1 : CATCH_REQUIRE_THROWS_AS(a.set_from_socket(s, false), addr::addr_invalid_state);
2471 : }
2472 : CATCH_END_SECTION()
2473 :
2474 14 : CATCH_START_SECTION("addr/addr_parser: create a server (bind), but do not test it (yet)...")
2475 : {
2476 2 : addr::addr_parser p;
2477 2 : addr::addr_range::vector_t ips(p.parse("127.0.0.1:49999"));
2478 1 : CATCH_REQUIRE(ips.size() >= 1);
2479 :
2480 1 : addr::addr & a(ips[0].get_from());
2481 1 : int s(a.create_socket(addr::addr::SOCKET_FLAG_NONBLOCK | addr::addr::SOCKET_FLAG_CLOEXEC | addr::addr::SOCKET_FLAG_REUSE));
2482 1 : CATCH_REQUIRE(s >= 0);
2483 2 : std::shared_ptr<int> auto_free(&s, socket_deleter);
2484 :
2485 1 : CATCH_REQUIRE(a.bind(s) == 0);
2486 : }
2487 : CATCH_END_SECTION()
2488 :
2489 14 : CATCH_START_SECTION("addr/addr_parser: connect() with TCP to 127.0.0.1")
2490 : {
2491 1 : if(SNAP_CATCH2_NAMESPACE::g_tcp_port != -1)
2492 : {
2493 2 : addr::addr_parser p;
2494 2 : addr::addr_range::vector_t ips(p.parse("127.0.0.1:" + std::to_string(SNAP_CATCH2_NAMESPACE::g_tcp_port)));
2495 1 : CATCH_REQUIRE(ips.size() >= 1);
2496 :
2497 1 : addr::addr & a(ips[0].get_from());
2498 1 : int s(a.create_socket(addr::addr::SOCKET_FLAG_CLOEXEC));// | addr::addr::SOCKET_FLAG_REUSE));
2499 1 : CATCH_REQUIRE(s >= 0);
2500 2 : std::shared_ptr<int> auto_free(&s, socket_deleter);
2501 :
2502 1 : CATCH_REQUIRE(a.connect(s) == 0);
2503 :
2504 : // get socket info from the other side (peer == true)
2505 : //
2506 2 : addr::addr b;
2507 1 : b.set_from_socket(s, true);
2508 1 : CATCH_REQUIRE(b.is_ipv4());
2509 1 : CATCH_REQUIRE(b.get_family() == AF_INET);
2510 1 : CATCH_REQUIRE_FALSE(b.get_family() == AF_INET6);
2511 1 : CATCH_REQUIRE(b.to_ipv4_string(addr::string_ip_t::STRING_IP_ONLY) == "127.0.0.1");
2512 1 : CATCH_REQUIRE(b.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ONLY) == "127.0.0.1");
2513 :
2514 : // in this case we know what the port is since we specified
2515 : // that when connecting
2516 : //
2517 1 : CATCH_REQUIRE(b.get_port() == SNAP_CATCH2_NAMESPACE::g_tcp_port);
2518 :
2519 : // now try this side (peer == false)
2520 : //
2521 2 : addr::addr c;
2522 1 : c.set_from_socket(s, false);
2523 1 : CATCH_REQUIRE(c.is_ipv4());
2524 1 : CATCH_REQUIRE(c.get_family() == AF_INET);
2525 1 : CATCH_REQUIRE_FALSE(c.get_family() == AF_INET6);
2526 1 : CATCH_REQUIRE(c.to_ipv4_string(addr::string_ip_t::STRING_IP_ONLY) == "127.0.0.1");
2527 1 : CATCH_REQUIRE(c.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ONLY) == "127.0.0.1");
2528 :
2529 : // we cannot be sure of the port, there is a range we could
2530 : // test better (more constraining) but for this test is
2531 : // certainly does not matter much; it has to be more than
2532 : // 1023, though
2533 : //
2534 1 : CATCH_REQUIRE(c.get_port() > 1023);
2535 : }
2536 : else
2537 : {
2538 : // avoid issue of no assertions
2539 : //
2540 0 : CATCH_REQUIRE(SNAP_CATCH2_NAMESPACE::g_tcp_port == -1);
2541 0 : std::cout << "connect to 127.0.0.1 test skipped as no TCP port was specified on the command line." << std::endl;
2542 : }
2543 : }
2544 : CATCH_END_SECTION()
2545 :
2546 14 : CATCH_START_SECTION("addr/addr_parser: connect() with UDP to 127.0.0.1:53 which fails")
2547 : {
2548 2 : addr::addr_parser p;
2549 1 : p.set_protocol("udp");
2550 2 : addr::addr_range::vector_t ips(p.parse("127.0.0.1:53"));
2551 1 : CATCH_REQUIRE(ips.size() >= 1);
2552 :
2553 1 : addr::addr & a(ips[0].get_from());
2554 1 : int s(a.create_socket(addr::addr::SOCKET_FLAG_CLOEXEC));// | addr::addr::SOCKET_FLAG_REUSE));
2555 1 : CATCH_REQUIRE(s >= 0);
2556 2 : std::shared_ptr<int> auto_free(&s, socket_deleter);
2557 :
2558 : // addr::connect() does not support UDP
2559 : //
2560 1 : CATCH_REQUIRE(a.connect(s) == -1);
2561 :
2562 2 : addr::addr b;
2563 1 : CATCH_REQUIRE_THROWS_AS(b.set_from_socket(s, true), addr::addr_io_error);
2564 1 : CATCH_REQUIRE_FALSE(b.is_ipv4());
2565 1 : CATCH_REQUIRE_FALSE(b.get_family() == AF_INET);
2566 1 : CATCH_REQUIRE(b.get_family() == AF_INET6);
2567 1 : CATCH_REQUIRE(b.to_ipv6_string(addr::string_ip_t::STRING_IP_ONLY) == "::");
2568 1 : CATCH_REQUIRE(b.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ONLY) == "::");
2569 1 : CATCH_REQUIRE(b.get_port() == 0);
2570 :
2571 2 : addr::addr c;
2572 1 : c.set_from_socket(s, false);
2573 1 : CATCH_REQUIRE(c.is_ipv4());
2574 1 : CATCH_REQUIRE(c.get_family() == AF_INET);
2575 1 : CATCH_REQUIRE_FALSE(c.get_family() == AF_INET6);
2576 1 : CATCH_REQUIRE(c.to_ipv4_string(addr::string_ip_t::STRING_IP_ONLY) == "0.0.0.0");
2577 1 : CATCH_REQUIRE(c.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ONLY) == "0.0.0.0");
2578 1 : CATCH_REQUIRE(c.get_port() == 0);
2579 : }
2580 : CATCH_END_SECTION()
2581 :
2582 14 : CATCH_START_SECTION("addr/addr_parser: bind() with UDP to 127.0.0.1:<auto> (as a \"client\") which works")
2583 : {
2584 2 : addr::addr_parser p;
2585 1 : p.set_protocol("udp");
2586 2 : addr::addr_range::vector_t ips(p.parse("127.0.0.1"));
2587 1 : CATCH_REQUIRE(ips.size() >= 1);
2588 :
2589 1 : addr::addr & a(ips[0].get_from());
2590 1 : int s(a.create_socket(addr::addr::SOCKET_FLAG_CLOEXEC));// | addr::addr::SOCKET_FLAG_REUSE));
2591 1 : CATCH_REQUIRE(s >= 0);
2592 2 : std::shared_ptr<int> auto_free(&s, socket_deleter);
2593 :
2594 : // succeeds, but the port is not known
2595 : //
2596 1 : CATCH_REQUIRE(a.bind(s) == 0);
2597 :
2598 : // this is a UDP socket, there is no other side so we get ANY
2599 : //
2600 2 : addr::addr b;
2601 1 : CATCH_REQUIRE_THROWS_AS(b.set_from_socket(s, true), addr::addr_io_error);
2602 1 : CATCH_REQUIRE_FALSE(b.is_ipv4());
2603 1 : CATCH_REQUIRE_FALSE(b.get_family() == AF_INET);
2604 1 : CATCH_REQUIRE(b.get_family() == AF_INET6);
2605 1 : CATCH_REQUIRE(b.to_ipv6_string(addr::string_ip_t::STRING_IP_ONLY) == "::");
2606 1 : CATCH_REQUIRE(b.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ONLY) == "::");
2607 1 : CATCH_REQUIRE(b.get_port() == 0);
2608 :
2609 : // now try this side (peer == false) and again it is "any"
2610 : // since it failed connecting
2611 : //
2612 2 : addr::addr c;
2613 1 : c.set_from_socket(s, false);
2614 1 : CATCH_REQUIRE(c.is_ipv4());
2615 1 : CATCH_REQUIRE(c.get_family() == AF_INET);
2616 1 : CATCH_REQUIRE_FALSE(c.get_family() == AF_INET6);
2617 1 : CATCH_REQUIRE(c.to_ipv4_string(addr::string_ip_t::STRING_IP_ONLY) == "127.0.0.1");
2618 1 : CATCH_REQUIRE(c.to_ipv4or6_string(addr::string_ip_t::STRING_IP_ONLY) == "127.0.0.1");
2619 :
2620 : // if this worked, the port is > 1023 (it was auto-allocated)
2621 : //
2622 1 : CATCH_REQUIRE(c.get_port() > 1023);
2623 :
2624 : // since the a.bind() is expected to read that port, it should
2625 : // equal the one in `a`
2626 : //
2627 1 : CATCH_REQUIRE(a.get_port() == c.get_port());
2628 : }
2629 : CATCH_END_SECTION()
2630 : }
2631 7 : }
2632 :
2633 :
2634 15 : CATCH_TEST_CASE("ipv4::string_to_addr", "[ipv4]")
2635 : {
2636 26 : CATCH_GIVEN("string_to_addr() ipv4")
2637 : {
2638 26 : CATCH_START_SECTION("string_to_addr: empty address without defaults")
2639 : {
2640 2 : addr::addr a(addr::string_to_addr(std::string()));
2641 :
2642 1 : CATCH_REQUIRE(a.is_ipv4());
2643 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
2644 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
2645 :
2646 1 : struct sockaddr_in in = sockaddr_in();
2647 1 : in.sin_family = AF_INET;
2648 1 : in.sin_port = 0;
2649 1 : in.sin_addr.s_addr = htonl((0 << 24) | (0 << 16) | (0 << 8) | (0 << 0));
2650 :
2651 : // test string_to_addr accuracy
2652 : //
2653 1 : struct sockaddr_in out;
2654 1 : a.get_ipv4(out);
2655 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
2656 :
2657 1 : uint8_t mask[16];
2658 1 : a.get_mask(mask);
2659 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
2660 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
2661 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
2662 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
2663 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
2664 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
2665 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
2666 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
2667 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
2668 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
2669 1 : CATCH_REQUIRE(mask[10] == 0xFF);
2670 1 : CATCH_REQUIRE(mask[11] == 0xFF);
2671 1 : CATCH_REQUIRE(mask[12] == 0xFF);
2672 1 : CATCH_REQUIRE(mask[13] == 0xFF);
2673 1 : CATCH_REQUIRE(mask[14] == 0xFF);
2674 1 : CATCH_REQUIRE(mask[15] == 0xFF);
2675 : }
2676 : CATCH_END_SECTION()
2677 :
2678 26 : CATCH_START_SECTION("string_to_addr: explicit defaults")
2679 : {
2680 2 : addr::addr a(addr::string_to_addr("5.14.34.111", std::string(), -1, std::string(), false));
2681 :
2682 1 : CATCH_REQUIRE(a.is_ipv4());
2683 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
2684 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
2685 :
2686 1 : struct sockaddr_in in = sockaddr_in();
2687 1 : in.sin_family = AF_INET;
2688 1 : in.sin_port = 0;
2689 1 : in.sin_addr.s_addr = htonl((5 << 24) | (14 << 16) | (34 << 8) | (111 << 0));
2690 :
2691 : // test string_to_addr accuracy
2692 : //
2693 1 : struct sockaddr_in out;
2694 1 : a.get_ipv4(out);
2695 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
2696 :
2697 1 : uint8_t mask[16];
2698 1 : a.get_mask(mask);
2699 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
2700 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
2701 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
2702 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
2703 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
2704 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
2705 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
2706 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
2707 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
2708 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
2709 1 : CATCH_REQUIRE(mask[10] == 0xFF);
2710 1 : CATCH_REQUIRE(mask[11] == 0xFF);
2711 1 : CATCH_REQUIRE(mask[12] == 0xFF);
2712 1 : CATCH_REQUIRE(mask[13] == 0xFF);
2713 1 : CATCH_REQUIRE(mask[14] == 0xFF);
2714 1 : CATCH_REQUIRE(mask[15] == 0xFF);
2715 : }
2716 : CATCH_END_SECTION()
2717 :
2718 26 : CATCH_START_SECTION("string_to_addr: defaults")
2719 : {
2720 2 : addr::addr a(addr::string_to_addr("7.149.104.211"));
2721 :
2722 1 : CATCH_REQUIRE(a.is_ipv4());
2723 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
2724 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
2725 :
2726 1 : struct sockaddr_in in = sockaddr_in();
2727 1 : in.sin_family = AF_INET;
2728 1 : in.sin_port = 0;
2729 1 : in.sin_addr.s_addr = htonl((7 << 24) | (149 << 16) | (104 << 8) | (211 << 0));
2730 :
2731 : // test string_to_addr accuracy
2732 : //
2733 1 : struct sockaddr_in out;
2734 1 : a.get_ipv4(out);
2735 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
2736 :
2737 1 : uint8_t mask[16];
2738 1 : a.get_mask(mask);
2739 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
2740 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
2741 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
2742 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
2743 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
2744 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
2745 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
2746 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
2747 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
2748 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
2749 1 : CATCH_REQUIRE(mask[10] == 0xFF);
2750 1 : CATCH_REQUIRE(mask[11] == 0xFF);
2751 1 : CATCH_REQUIRE(mask[12] == 0xFF);
2752 1 : CATCH_REQUIRE(mask[13] == 0xFF);
2753 1 : CATCH_REQUIRE(mask[14] == 0xFF);
2754 1 : CATCH_REQUIRE(mask[15] == 0xFF);
2755 : }
2756 : CATCH_END_SECTION()
2757 :
2758 26 : CATCH_START_SECTION("string_to_addr: addr & default addr")
2759 : {
2760 2 : addr::addr a(addr::string_to_addr("37.149.174.11", "1.205.32.11"));
2761 :
2762 1 : CATCH_REQUIRE(a.is_ipv4());
2763 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
2764 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
2765 :
2766 1 : struct sockaddr_in in = sockaddr_in();
2767 1 : in.sin_family = AF_INET;
2768 1 : in.sin_port = 0;
2769 1 : in.sin_addr.s_addr = htonl((37 << 24) | (149 << 16) | (174 << 8) | (11 << 0));
2770 :
2771 : // test string_to_addr accuracy
2772 : //
2773 1 : struct sockaddr_in out;
2774 1 : a.get_ipv4(out);
2775 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
2776 :
2777 1 : uint8_t mask[16];
2778 1 : a.get_mask(mask);
2779 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
2780 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
2781 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
2782 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
2783 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
2784 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
2785 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
2786 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
2787 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
2788 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
2789 1 : CATCH_REQUIRE(mask[10] == 0xFF);
2790 1 : CATCH_REQUIRE(mask[11] == 0xFF);
2791 1 : CATCH_REQUIRE(mask[12] == 0xFF);
2792 1 : CATCH_REQUIRE(mask[13] == 0xFF);
2793 1 : CATCH_REQUIRE(mask[14] == 0xFF);
2794 1 : CATCH_REQUIRE(mask[15] == 0xFF);
2795 : }
2796 : CATCH_END_SECTION()
2797 :
2798 26 : CATCH_START_SECTION("string_to_addr: no addr, expect default addr")
2799 : {
2800 2 : addr::addr a(addr::string_to_addr("", "1.205.32.11"));
2801 :
2802 1 : CATCH_REQUIRE(a.is_ipv4());
2803 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
2804 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
2805 :
2806 1 : struct sockaddr_in in = sockaddr_in();
2807 1 : in.sin_family = AF_INET;
2808 1 : in.sin_port = 0;
2809 1 : in.sin_addr.s_addr = htonl((1 << 24) | (205 << 16) | (32 << 8) | (11 << 0));
2810 :
2811 : // test string_to_addr accuracy
2812 : //
2813 1 : struct sockaddr_in out;
2814 1 : a.get_ipv4(out);
2815 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
2816 :
2817 1 : uint8_t mask[16];
2818 1 : a.get_mask(mask);
2819 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
2820 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
2821 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
2822 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
2823 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
2824 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
2825 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
2826 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
2827 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
2828 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
2829 1 : CATCH_REQUIRE(mask[10] == 0xFF);
2830 1 : CATCH_REQUIRE(mask[11] == 0xFF);
2831 1 : CATCH_REQUIRE(mask[12] == 0xFF);
2832 1 : CATCH_REQUIRE(mask[13] == 0xFF);
2833 1 : CATCH_REQUIRE(mask[14] == 0xFF);
2834 1 : CATCH_REQUIRE(mask[15] == 0xFF);
2835 : }
2836 : CATCH_END_SECTION()
2837 :
2838 26 : CATCH_START_SECTION("string_to_addr: addr and port, with a default port")
2839 : {
2840 2 : addr::addr a(addr::string_to_addr("69.109.223.17:697", "1.205.32.11", 123));
2841 :
2842 1 : CATCH_REQUIRE(a.is_ipv4());
2843 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
2844 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
2845 :
2846 1 : struct sockaddr_in in = sockaddr_in();
2847 1 : in.sin_family = AF_INET;
2848 1 : in.sin_port = htons(697);
2849 1 : in.sin_addr.s_addr = htonl((69 << 24) | (109 << 16) | (223 << 8) | (17 << 0));
2850 :
2851 : // test string_to_addr accuracy
2852 : //
2853 1 : struct sockaddr_in out;
2854 1 : a.get_ipv4(out);
2855 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
2856 :
2857 1 : uint8_t mask[16];
2858 1 : a.get_mask(mask);
2859 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
2860 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
2861 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
2862 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
2863 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
2864 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
2865 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
2866 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
2867 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
2868 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
2869 1 : CATCH_REQUIRE(mask[10] == 0xFF);
2870 1 : CATCH_REQUIRE(mask[11] == 0xFF);
2871 1 : CATCH_REQUIRE(mask[12] == 0xFF);
2872 1 : CATCH_REQUIRE(mask[13] == 0xFF);
2873 1 : CATCH_REQUIRE(mask[14] == 0xFF);
2874 1 : CATCH_REQUIRE(mask[15] == 0xFF);
2875 : }
2876 : CATCH_END_SECTION()
2877 :
2878 26 : CATCH_START_SECTION("string_to_addr: addr without port, with a default port")
2879 : {
2880 2 : addr::addr a(addr::string_to_addr("169.209.23.217", "1.205.32.11", 123));
2881 :
2882 1 : CATCH_REQUIRE(a.is_ipv4());
2883 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
2884 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
2885 :
2886 1 : struct sockaddr_in in = sockaddr_in();
2887 1 : in.sin_family = AF_INET;
2888 1 : in.sin_port = htons(123);
2889 1 : in.sin_addr.s_addr = htonl((169 << 24) | (209 << 16) | (23 << 8) | (217 << 0));
2890 :
2891 : // test string_to_addr accuracy
2892 : //
2893 1 : struct sockaddr_in out;
2894 1 : a.get_ipv4(out);
2895 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
2896 :
2897 1 : uint8_t mask[16];
2898 1 : a.get_mask(mask);
2899 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
2900 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
2901 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
2902 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
2903 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
2904 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
2905 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
2906 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
2907 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
2908 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
2909 1 : CATCH_REQUIRE(mask[10] == 0xFF);
2910 1 : CATCH_REQUIRE(mask[11] == 0xFF);
2911 1 : CATCH_REQUIRE(mask[12] == 0xFF);
2912 1 : CATCH_REQUIRE(mask[13] == 0xFF);
2913 1 : CATCH_REQUIRE(mask[14] == 0xFF);
2914 1 : CATCH_REQUIRE(mask[15] == 0xFF);
2915 : }
2916 : CATCH_END_SECTION()
2917 :
2918 26 : CATCH_START_SECTION("string_to_addr: addr without port but protocol")
2919 : {
2920 2 : addr::addr a(addr::string_to_addr("4.5.123.7", "1.205.32.11", 60000, "tcp"));
2921 :
2922 1 : CATCH_REQUIRE(a.is_ipv4());
2923 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
2924 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
2925 :
2926 1 : struct sockaddr_in in = sockaddr_in();
2927 1 : in.sin_family = AF_INET;
2928 1 : in.sin_port = htons(60000);
2929 1 : in.sin_addr.s_addr = htonl((4 << 24) | (5 << 16) | (123 << 8) | (7 << 0));
2930 :
2931 : // test string_to_addr accuracy
2932 : //
2933 1 : struct sockaddr_in out;
2934 1 : a.get_ipv4(out);
2935 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
2936 :
2937 1 : uint8_t mask[16];
2938 1 : a.get_mask(mask);
2939 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
2940 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
2941 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
2942 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
2943 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
2944 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
2945 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
2946 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
2947 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
2948 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
2949 1 : CATCH_REQUIRE(mask[10] == 0xFF);
2950 1 : CATCH_REQUIRE(mask[11] == 0xFF);
2951 1 : CATCH_REQUIRE(mask[12] == 0xFF);
2952 1 : CATCH_REQUIRE(mask[13] == 0xFF);
2953 1 : CATCH_REQUIRE(mask[14] == 0xFF);
2954 1 : CATCH_REQUIRE(mask[15] == 0xFF);
2955 : }
2956 : CATCH_END_SECTION()
2957 :
2958 26 : CATCH_START_SECTION("string_to_addr: addr with port and protocol")
2959 : {
2960 2 : addr::addr a(addr::string_to_addr("204.105.13.9:65", "1.205.32.11", 60000, "tcp"));
2961 :
2962 1 : CATCH_REQUIRE(a.is_ipv4());
2963 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
2964 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
2965 :
2966 1 : struct sockaddr_in in = sockaddr_in();
2967 1 : in.sin_family = AF_INET;
2968 1 : in.sin_port = htons(65);
2969 1 : in.sin_addr.s_addr = htonl((204 << 24) | (105 << 16) | (13 << 8) | (9 << 0));
2970 :
2971 : // test string_to_addr accuracy
2972 : //
2973 1 : struct sockaddr_in out;
2974 1 : a.get_ipv4(out);
2975 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
2976 :
2977 1 : uint8_t mask[16];
2978 1 : a.get_mask(mask);
2979 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
2980 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
2981 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
2982 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
2983 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
2984 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
2985 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
2986 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
2987 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
2988 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
2989 1 : CATCH_REQUIRE(mask[10] == 0xFF);
2990 1 : CATCH_REQUIRE(mask[11] == 0xFF);
2991 1 : CATCH_REQUIRE(mask[12] == 0xFF);
2992 1 : CATCH_REQUIRE(mask[13] == 0xFF);
2993 1 : CATCH_REQUIRE(mask[14] == 0xFF);
2994 1 : CATCH_REQUIRE(mask[15] == 0xFF);
2995 : }
2996 : CATCH_END_SECTION()
2997 :
2998 26 : CATCH_START_SECTION("string_to_addr: addr with port and protocol but no mask, albeit allowed")
2999 : {
3000 2 : addr::addr a(addr::string_to_addr("94.95.131.18:765", "11.205.32.21", 54003, "tcp", true));
3001 :
3002 1 : CATCH_REQUIRE(a.is_ipv4());
3003 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
3004 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
3005 :
3006 1 : struct sockaddr_in in = sockaddr_in();
3007 1 : in.sin_family = AF_INET;
3008 1 : in.sin_port = htons(765);
3009 1 : in.sin_addr.s_addr = htonl((94 << 24) | (95 << 16) | (131 << 8) | (18 << 0));
3010 :
3011 : // test string_to_addr accuracy
3012 : //
3013 1 : struct sockaddr_in out;
3014 1 : a.get_ipv4(out);
3015 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
3016 :
3017 1 : uint8_t mask[16];
3018 1 : a.get_mask(mask);
3019 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
3020 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
3021 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
3022 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
3023 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
3024 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
3025 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
3026 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
3027 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
3028 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
3029 1 : CATCH_REQUIRE(mask[10] == 0xFF);
3030 1 : CATCH_REQUIRE(mask[11] == 0xFF);
3031 1 : CATCH_REQUIRE(mask[12] == 0xFF);
3032 1 : CATCH_REQUIRE(mask[13] == 0xFF);
3033 1 : CATCH_REQUIRE(mask[14] == 0xFF);
3034 1 : CATCH_REQUIRE(mask[15] == 0xFF);
3035 : }
3036 : CATCH_END_SECTION()
3037 :
3038 26 : CATCH_START_SECTION("string_to_addr: addr with port and protocol and mask, albeit allowed")
3039 : {
3040 2 : addr::addr a(addr::string_to_addr("44.45.141.48:765/30", "11.205.32.21", 54003, "tcp", true));
3041 :
3042 1 : CATCH_REQUIRE(a.is_ipv4());
3043 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
3044 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
3045 :
3046 1 : struct sockaddr_in in = sockaddr_in();
3047 1 : in.sin_family = AF_INET;
3048 1 : in.sin_port = htons(765);
3049 1 : in.sin_addr.s_addr = htonl((44 << 24) | (45 << 16) | (141 << 8) | (48 << 0));
3050 :
3051 : // test string_to_addr accuracy
3052 : //
3053 1 : struct sockaddr_in out;
3054 1 : a.get_ipv4(out);
3055 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
3056 :
3057 1 : uint8_t mask[16];
3058 1 : a.get_mask(mask);
3059 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
3060 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
3061 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
3062 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
3063 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
3064 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
3065 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
3066 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
3067 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
3068 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
3069 1 : CATCH_REQUIRE(mask[10] == 0xFF);
3070 1 : CATCH_REQUIRE(mask[11] == 0xFF);
3071 1 : CATCH_REQUIRE(mask[12] == 0xFF);
3072 1 : CATCH_REQUIRE(mask[13] == 0xFF);
3073 1 : CATCH_REQUIRE(mask[14] == 0xFF);
3074 1 : CATCH_REQUIRE(mask[15] == 0xFC);
3075 : }
3076 : CATCH_END_SECTION()
3077 :
3078 26 : CATCH_START_SECTION("string_to_addr: addr with port and protocol and mask, albeit allowed")
3079 : {
3080 2 : addr::addr a(addr::string_to_addr("160.0.0.0:1675/4", "11.205.32.21", 14003, "udp", true));
3081 :
3082 1 : CATCH_REQUIRE(a.is_ipv4());
3083 1 : CATCH_REQUIRE(a.get_family() == AF_INET);
3084 1 : CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
3085 :
3086 1 : struct sockaddr_in in = sockaddr_in();
3087 1 : in.sin_family = AF_INET;
3088 1 : in.sin_port = htons(1675);
3089 1 : in.sin_addr.s_addr = htonl((160 << 24) | (0 << 16) | (0 << 8) | (0 << 0));
3090 :
3091 : // test string_to_addr accuracy
3092 : //
3093 1 : struct sockaddr_in out;
3094 1 : a.get_ipv4(out);
3095 1 : CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
3096 :
3097 1 : uint8_t mask[16];
3098 1 : a.get_mask(mask);
3099 1 : CATCH_REQUIRE(mask[ 0] == 0xFF);
3100 1 : CATCH_REQUIRE(mask[ 1] == 0xFF);
3101 1 : CATCH_REQUIRE(mask[ 2] == 0xFF);
3102 1 : CATCH_REQUIRE(mask[ 3] == 0xFF);
3103 1 : CATCH_REQUIRE(mask[ 4] == 0xFF);
3104 1 : CATCH_REQUIRE(mask[ 5] == 0xFF);
3105 1 : CATCH_REQUIRE(mask[ 6] == 0xFF);
3106 1 : CATCH_REQUIRE(mask[ 7] == 0xFF);
3107 1 : CATCH_REQUIRE(mask[ 8] == 0xFF);
3108 1 : CATCH_REQUIRE(mask[ 9] == 0xFF);
3109 1 : CATCH_REQUIRE(mask[10] == 0xFF);
3110 1 : CATCH_REQUIRE(mask[11] == 0xFF);
3111 1 : CATCH_REQUIRE(mask[12] == 0xF0);
3112 1 : CATCH_REQUIRE(mask[13] == 0x00);
3113 1 : CATCH_REQUIRE(mask[14] == 0x00);
3114 1 : CATCH_REQUIRE(mask[15] == 0x00);
3115 : }
3116 : CATCH_END_SECTION()
3117 :
3118 26 : CATCH_START_SECTION("string_to_addr: addr with port and invalid protocol so we get an exception")
3119 : {
3120 1 : CATCH_REQUIRE_THROWS_AS(addr::string_to_addr("169.60.33.0:9322/24", std::string(), -1, "icmp", true),
3121 : addr::addr_invalid_argument);
3122 : }
3123 : CATCH_END_SECTION()
3124 : }
3125 19 : }
3126 :
3127 :
3128 : // vim: ts=4 sw=4 et
|