LCOV - code coverage report
Current view: top level - tests - catch_ipv4.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 2534 2572 98.5 %
Date: 2024-06-03 22:21:57 Functions: 11 11 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2011-2023  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          15 : CATCH_TEST_CASE("ipv4::invalid_input", "[ipv4]")
      88             : {
      89          15 :     CATCH_GIVEN("addr()")
      90             :     {
      91           1 :         addr::addr a;
      92             : 
      93           1 :         CATCH_START_SECTION("ipv4::invalid_input: set IPv4 with an invalid family")
      94             :         {
      95          26 :             for(int idx(0); idx < 25; ++idx)
      96             :             {
      97          25 :                 struct sockaddr_in in = sockaddr_in();
      98             :                 do
      99             :                 {
     100          25 :                     in.sin_family = rand();
     101             :                 }
     102          25 :                 while(in.sin_family == AF_INET);
     103          25 :                 in.sin_port = htons(rand());
     104          25 :                 in.sin_addr.s_addr = htonl(rand() ^ (rand() << 16));
     105          25 :                 CATCH_REQUIRE_THROWS_AS(a.set_ipv4(in), addr::addr_invalid_argument);
     106          25 :                 CATCH_REQUIRE_THROWS_AS(addr::addr(in), addr::addr_invalid_argument);
     107             :             }
     108             :         }
     109           1 :         CATCH_END_SECTION()
     110          16 :     }
     111             : 
     112          15 :     CATCH_GIVEN("addr_parser() with IPv4 settings")
     113             :     {
     114           2 :         addr::addr_parser a;
     115             : 
     116           2 :         CATCH_START_SECTION("addr_parser(): invalid allow flags (too small)")
     117             :         {
     118          11 :             for(int idx(0); idx < 10; ++idx)
     119             :             {
     120             :                 // test with a negative number
     121             :                 //
     122             :                 int n;
     123             :                 do
     124             :                 {
     125          10 :                     n = rand();
     126             :                 }
     127          10 :                 while(n == 0);
     128          10 :                 if(n > 0)
     129             :                 {
     130             :                     // all positive numbers have a corresponding negative
     131             :                     // number so this always flips the sign as expected
     132             :                     //
     133          10 :                     n = -n;
     134             :                 }
     135          10 :                 addr::allow_t const flag(static_cast<addr::allow_t>(n));
     136             : 
     137          10 :                 CATCH_REQUIRE_THROWS_AS(a.set_allow(flag, true), addr::addr_invalid_argument);
     138          10 :                 CATCH_REQUIRE_THROWS_AS(a.set_allow(flag, false), addr::addr_invalid_argument);
     139          10 :                 CATCH_REQUIRE_THROWS_AS(a.get_allow(flag), addr::addr_invalid_argument);
     140             :             }
     141             :         }
     142           2 :         CATCH_END_SECTION()
     143             : 
     144           2 :         CATCH_START_SECTION("addr_parser(): invalid allow flags (too large)")
     145             :         {
     146          11 :             for(int idx(0); idx < 10; ++idx)
     147             :             {
     148             :                 // test with a negative number
     149             :                 //
     150             :                 int n;
     151             :                 do
     152             :                 {
     153          10 :                     n = rand();
     154          10 :                     if(n < 0)
     155             :                     {
     156           0 :                         n = -n;
     157             :                     }
     158             :                 }
     159          10 :                 while(n < static_cast<int>(addr::allow_t::ALLOW_max));
     160          10 :                 addr::allow_t const flag(static_cast<addr::allow_t>(n));
     161             : 
     162          10 :                 CATCH_REQUIRE_THROWS_AS(a.set_allow(flag, true), addr::addr_invalid_argument);
     163          10 :                 CATCH_REQUIRE_THROWS_AS(a.set_allow(flag, false), addr::addr_invalid_argument);
     164          10 :                 CATCH_REQUIRE_THROWS_AS(a.get_allow(flag), addr::addr_invalid_argument);
     165             :             }
     166             :         }
     167           2 :         CATCH_END_SECTION()
     168          17 :     }
     169             : 
     170          15 :     CATCH_GIVEN("addr_parser() with IPv4 addresses")
     171             :     {
     172           2 :         CATCH_START_SECTION("addr_parser(): bad address")
     173             :         {
     174           1 :             addr::addr_parser p;
     175           3 :             addr::addr_range::vector_t ips(p.parse("{bad-ip}"));
     176           1 :             CATCH_REQUIRE(p.has_errors());
     177           1 :             CATCH_REQUIRE(p.error_count() == 1);
     178           1 :             CATCH_REQUIRE(p.error_messages() == "Invalid address in \"{bad-ip}\" error -2 -- Name or service not known (errno: 22 -- Invalid argument).\n");
     179           1 :             CATCH_REQUIRE(p.has_errors());
     180           1 :             p.clear_errors();
     181           1 :             CATCH_REQUIRE_FALSE(p.has_errors());
     182           1 :             CATCH_REQUIRE(ips.size() == 0);
     183           1 :         }
     184           2 :         CATCH_END_SECTION()
     185             : 
     186           2 :         CATCH_START_SECTION("addr_parser(): required address")
     187             :         {
     188           1 :             addr::addr_parser p;
     189           1 :             p.set_protocol(IPPROTO_TCP);
     190           1 :             p.set_allow(addr::allow_t::ALLOW_REQUIRED_ADDRESS, true);
     191           3 :             addr::addr_range::vector_t ips(p.parse(""));
     192           1 :             CATCH_REQUIRE(p.has_errors());
     193           1 :             CATCH_REQUIRE(p.error_count() == 1);
     194           1 :             CATCH_REQUIRE(p.error_messages() == "Required address is missing.\n");
     195           1 :             CATCH_REQUIRE(p.has_errors());
     196           1 :             p.clear_errors();
     197           1 :             CATCH_REQUIRE_FALSE(p.has_errors());
     198           1 :             CATCH_REQUIRE(ips.size() == 0);
     199           1 :         }
     200           2 :         CATCH_END_SECTION()
     201          15 :     }
     202             : 
     203          15 :     CATCH_GIVEN("addr_parser() with IPv4 ports")
     204             :     {
     205           3 :         CATCH_START_SECTION("addr_parser(): required port")
     206             :         {
     207             :             // optional + required -> required
     208             :             {
     209           1 :                 addr::addr_parser p;
     210           1 :                 p.set_protocol(IPPROTO_TCP);
     211           1 :                 p.set_allow(addr::allow_t::ALLOW_REQUIRED_PORT, true);
     212           3 :                 addr::addr_range::vector_t ips(p.parse("1.2.3.4"));
     213           1 :                 CATCH_REQUIRE(p.has_errors());
     214           1 :                 CATCH_REQUIRE(p.error_count() == 1);
     215           1 :                 CATCH_REQUIRE(p.error_messages() == "Required port is missing.\n");
     216           1 :                 CATCH_REQUIRE(p.has_errors());
     217           1 :                 p.clear_errors();
     218           1 :                 CATCH_REQUIRE_FALSE(p.has_errors());
     219           1 :                 CATCH_REQUIRE(ips.size() == 0);
     220           1 :             }
     221             : 
     222             :             // only required -> required just the same
     223             :             {
     224           1 :                 addr::addr_parser p;
     225           1 :                 p.set_protocol(IPPROTO_TCP);
     226           1 :                 p.set_allow(addr::allow_t::ALLOW_PORT, false);
     227           1 :                 p.set_allow(addr::allow_t::ALLOW_REQUIRED_PORT, true);
     228           3 :                 addr::addr_range::vector_t ips(p.parse("1.2.3.4"));
     229           1 :                 CATCH_REQUIRE(p.has_errors());
     230           1 :                 CATCH_REQUIRE(p.error_count() == 1);
     231           1 :                 CATCH_REQUIRE(p.error_messages() == "Required port is missing.\n");
     232           1 :                 CATCH_REQUIRE(p.has_errors());
     233           1 :                 p.clear_errors();
     234           1 :                 CATCH_REQUIRE_FALSE(p.has_errors());
     235           1 :                 CATCH_REQUIRE(ips.size() == 0);
     236           1 :             }
     237             :         }
     238           3 :         CATCH_END_SECTION()
     239             : 
     240           3 :         CATCH_START_SECTION("addr_parser(): port not allowed")
     241             :         {
     242           1 :             addr::addr_parser p;
     243           1 :             p.set_protocol(IPPROTO_TCP);
     244           1 :             p.set_allow(addr::allow_t::ALLOW_PORT, false);
     245           1 :             CATCH_REQUIRE_FALSE(p.get_allow(addr::allow_t::ALLOW_REQUIRED_PORT));
     246           3 :             addr::addr_range::vector_t ips(p.parse("1.2.3.4:123"));
     247           1 :             CATCH_REQUIRE(p.has_errors());
     248           1 :             CATCH_REQUIRE(p.error_count() == 1);
     249           1 :             CATCH_REQUIRE(p.error_messages() == "Port not allowed (1.2.3.4:123).\n");
     250           1 :             CATCH_REQUIRE(p.has_errors());
     251           1 :             p.clear_errors();
     252           1 :             CATCH_REQUIRE_FALSE(p.has_errors());
     253           1 :             CATCH_REQUIRE(ips.size() == 0);
     254           1 :         }
     255           3 :         CATCH_END_SECTION()
     256             : 
     257           3 :         CATCH_START_SECTION("addr_parser(): invalid port")
     258             :         {
     259           1 :             addr::addr_parser p;
     260             : 
     261             :             // so to a different default value
     262             :             //
     263           1 :             int const default_port(rand() & 0xFFFF);
     264           1 :             p.set_default_port(default_port);
     265             : 
     266          26 :             for(int idx(0); idx < 25; ++idx)
     267             :             {
     268          25 :                 int port(0);
     269             :                 do
     270             :                 {
     271          25 :                     port = rand() ^ (rand() << 16);
     272             :                 }
     273          25 :                 while(port >= -1 && port <= 65535); // -1 is valid here, it represents "no default port defined"
     274          25 :                 CATCH_REQUIRE_THROWS_AS(p.set_default_port(port), addr::addr_invalid_argument);
     275             : 
     276          25 :                 std::string const port_str(std::to_string(port));
     277          25 :                 CATCH_REQUIRE_THROWS_AS(p.set_default_port(port_str), addr::addr_invalid_argument);
     278             : 
     279             :                 // verify port unchanged
     280             :                 //
     281          25 :                 CATCH_REQUIRE(p.get_default_port() == default_port);
     282          25 :             }
     283             : 
     284           5 :             CATCH_REQUIRE_THROWS_AS(p.set_default_port("not-a-number"), addr::addr_invalid_argument);
     285           1 :         }
     286           3 :         CATCH_END_SECTION()
     287          15 :     }
     288             : 
     289          15 :     CATCH_GIVEN("addr_parser() with invalid masks")
     290             :     {
     291           5 :         CATCH_START_SECTION("addr_parser(): really large numbers (over 1000)")
     292             :         {
     293           6 :             for(int idx(0); idx < 5; ++idx)
     294             :             {
     295           5 :                 int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
     296           5 :                 int const port(rand() & 0xFFFF);
     297           5 :                 int const mask((rand() & 0xFF) + 10001);
     298           5 :                 addr::addr_parser p;
     299           5 :                 p.set_protocol(proto);
     300           5 :                 p.set_allow(addr::allow_t::ALLOW_MASK, true);
     301          30 :                 addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port) + "/" + std::to_string(mask)));
     302           5 :                 CATCH_REQUIRE(p.has_errors());
     303           5 :                 CATCH_REQUIRE(p.error_count() == 1);
     304           5 :                 CATCH_REQUIRE(p.error_messages() == "Mask size too large (" + std::to_string(mask) + ", expected a maximum of 128).\n");
     305           5 :                 CATCH_REQUIRE(ips.size() == 0);
     306           5 :             }
     307             :         }
     308           5 :         CATCH_END_SECTION()
     309             : 
     310           5 :         CATCH_START_SECTION("addr_parser(): ipv4 mask is limited between 0 and 32")
     311             :         {
     312           6 :             for(int idx(0); idx < 5; ++idx)
     313             :             {
     314           5 :                 int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
     315           5 :                 int const port(rand() & 0xFFFF);
     316           5 :                 int const mask((rand() & 0xFF) + 33);
     317           5 :                 addr::addr_parser p;
     318           5 :                 p.set_protocol(proto);
     319           5 :                 p.set_allow(addr::allow_t::ALLOW_MASK, true);
     320          30 :                 addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port) + "/" + std::to_string(mask)));
     321           5 :                 CATCH_REQUIRE(p.has_errors());
     322           5 :                 CATCH_REQUIRE(p.error_count() == 1);
     323           5 :                 CATCH_REQUIRE(p.error_messages() == "Unsupported mask size (" + std::to_string(mask) + ", expected 32 at the most for an IPv4).\n");
     324           5 :                 CATCH_REQUIRE(ips.size() == 0);
     325           5 :             }
     326             :         }
     327           5 :         CATCH_END_SECTION()
     328             : 
     329           5 :         CATCH_START_SECTION("addr_parser(): ipv4 mask cannot use name")
     330             :         {
     331           6 :             for(int idx(0); idx < 5; ++idx)
     332             :             {
     333           5 :                 int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
     334           5 :                 int const port(rand() & 0xFFFF);
     335           5 :                 addr::addr_parser p;
     336           5 :                 p.set_protocol(proto);
     337           5 :                 p.set_allow(addr::allow_t::ALLOW_MASK, true);
     338           5 :                 p.set_allow(addr::allow_t::ALLOW_ADDRESS_MASK, true);
     339          20 :                 addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port) + "/localhost"));
     340           5 :                 CATCH_REQUIRE(p.has_errors());
     341           5 :                 CATCH_REQUIRE(p.error_count() == 1);
     342           5 :                 CATCH_REQUIRE(p.error_messages() == "Invalid mask in \"/localhost\", error -2 -- Name or service not known (errno: 0 -- Success).\n");
     343           5 :                 CATCH_REQUIRE(ips.size() == 0);
     344           5 :             }
     345             :         }
     346           5 :         CATCH_END_SECTION()
     347             : 
     348           5 :         CATCH_START_SECTION("addr_parser(): ipv4 mask mismatch (mask uses ipv6)")
     349             :         {
     350           1 :             int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
     351           1 :             int const port(rand() & 0xFFFF);
     352           1 :             addr::addr_parser p;
     353           1 :             p.set_protocol(proto);
     354           1 :             p.set_allow(addr::allow_t::ALLOW_MASK, true);
     355           1 :             p.set_allow(addr::allow_t::ALLOW_ADDRESS_MASK, true);
     356           4 :             addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port) + "/[1:2:3:4:5:6:7:8]"));
     357           1 :             CATCH_REQUIRE(p.has_errors());
     358           1 :             CATCH_REQUIRE(p.error_count() == 1);
     359           1 :             CATCH_REQUIRE(p.error_messages() == "The address uses the IPv4 syntax, the mask cannot use IPv6.\n");
     360           1 :             CATCH_REQUIRE(ips.size() == 0);
     361           1 :         }
     362           5 :         CATCH_END_SECTION()
     363             : 
     364           5 :         CATCH_START_SECTION("addr_parser(): ipv4 mask mismatch (mask uses ipv6 without [...])")
     365             :         {
     366           1 :             int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
     367           1 :             int const port(rand() & 0xFFFF);
     368           1 :             addr::addr_parser p;
     369           1 :             p.set_protocol(proto);
     370           1 :             p.set_allow(addr::allow_t::ALLOW_MASK, true);
     371           1 :             p.set_allow(addr::allow_t::ALLOW_ADDRESS_MASK, true);
     372           4 :             addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port) + "/1:2:3:4:5:6:7:8"));
     373           1 :             CATCH_REQUIRE(p.has_errors());
     374           1 :             CATCH_REQUIRE(p.error_count() == 1);
     375           1 :             CATCH_REQUIRE(p.error_messages() == "Incompatible address between the address and mask address (first was an IPv4 second an IPv6).\n");
     376           1 :             CATCH_REQUIRE(ips.size() == 0);
     377           1 :         }
     378           5 :         CATCH_END_SECTION()
     379          15 :     }
     380             : 
     381          15 :     CATCH_GIVEN("addr_parser() with invalid protocols")
     382             :     {
     383           2 :         CATCH_START_SECTION("addr_parser(): invalid names")
     384             :         {
     385           1 :             addr::addr_parser p;
     386             : 
     387             :             // not changing default protocol
     388             :             //
     389           1 :             CATCH_REQUIRE(p.get_protocol() == -1);
     390           5 :             CATCH_REQUIRE_THROWS_AS(p.set_protocol("unknown"), addr::addr_invalid_argument);
     391           1 :             CATCH_REQUIRE(p.get_protocol() == -1);
     392             : 
     393             :             // change protocol to another valid value first
     394             :             //
     395           1 :             p.set_protocol("tcp");
     396           5 :             CATCH_REQUIRE_THROWS_AS(p.set_protocol("another"), addr::addr_invalid_argument);
     397           1 :             CATCH_REQUIRE(p.get_protocol() == IPPROTO_TCP);
     398           1 :         }
     399           2 :         CATCH_END_SECTION()
     400             : 
     401           2 :         CATCH_START_SECTION("addr_parser(): invalid numbers")
     402             :         {
     403         101 :             for(int idx(0); idx < 100; ++idx)
     404             :             {
     405             :                 int protocol;
     406             :                 do
     407             :                 {
     408         100 :                     protocol = rand();
     409             :                 }
     410             :                 while(protocol == IPPROTO_IP
     411         100 :                    || protocol == IPPROTO_TCP
     412         200 :                    || protocol == IPPROTO_UDP);
     413             : 
     414         100 :                 addr::addr_parser p;
     415             : 
     416         100 :                 CATCH_REQUIRE_THROWS_AS(p.set_protocol(protocol), addr::addr_invalid_argument);
     417         100 :                 CATCH_REQUIRE(p.get_protocol() == -1);
     418             : 
     419             :                 // change protocol to another valid value first
     420             :                 //
     421         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         100 :             }
     425             :         }
     426           2 :         CATCH_END_SECTION()
     427          15 :     }
     428          15 : }
     429             : 
     430             : 
     431           9 : CATCH_TEST_CASE("ipv4::address_defaults", "[ipv4][ipv6]")
     432             : {
     433           9 :     CATCH_GIVEN("addr()")
     434             :     {
     435           9 :         addr::addr a;
     436             : 
     437           9 :         CATCH_START_SECTION("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_ADDRESS),                                                               addr::addr_invalid_state);
     449           1 :             CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS),                                                       addr::addr_invalid_state);
     450           1 :             CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT),                                addr::addr_invalid_state);
     451           1 :             CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::STRING_IP_ADDRESS | addr::STRING_IP_PORT | addr::STRING_IP_MASK),                 addr::addr_invalid_state);
     452           1 :             CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT | addr::STRING_IP_BRACKET_MASK), addr::addr_invalid_state);
     453           1 :             CATCH_REQUIRE_THROWS_AS(a.to_ipv4_string(addr::STRING_IP_ALL),                                                                   addr::addr_invalid_state);
     454             :         }
     455           9 :         CATCH_END_SECTION()
     456             : 
     457           9 :         CATCH_START_SECTION("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           9 :         CATCH_END_SECTION()
     470             : 
     471           9 :         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_ADDRESS)                                         == "::");
     480           1 :             CATCH_REQUIRE(a.to_ipv6_string(addr::STRING_IP_BRACKET_ADDRESS)                                 == "[::]");
     481           1 :             CATCH_REQUIRE(a.to_ipv6_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT)          == "[::]:0");
     482           1 :             CATCH_REQUIRE(a.to_ipv6_string(addr::STRING_IP_ADDRESS | addr::STRING_IP_MASK)                  == "::/128");
     483           1 :             CATCH_REQUIRE(a.to_ipv6_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_BRACKET_MASK)  == "[::]/128");
     484           1 :             CATCH_REQUIRE(a.to_ipv6_string(addr::STRING_IP_ALL)                                             == "[::]:0/128");
     485             :         }
     486           9 :         CATCH_END_SECTION()
     487             : 
     488           9 :         CATCH_START_SECTION("addr: IPv4 or IPv6 string")
     489             :         {
     490           1 :             CATCH_REQUIRE(a.to_ipv4or6_string(addr::STRING_IP_ADDRESS)                                          == "::");
     491           1 :             CATCH_REQUIRE(a.to_ipv4or6_string(addr::STRING_IP_BRACKET_ADDRESS)                                  == "[::]");
     492           1 :             CATCH_REQUIRE(a.to_ipv4or6_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT)           == "[::]:0");
     493           1 :             CATCH_REQUIRE(a.to_ipv4or6_string(addr::STRING_IP_ADDRESS | addr::STRING_IP_MASK)                   == "::/128");
     494           1 :             CATCH_REQUIRE(a.to_ipv4or6_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_BRACKET_MASK)   == "[::]/128");
     495           1 :             CATCH_REQUIRE(a.to_ipv4or6_string(addr::STRING_IP_ALL)                                              == "[::]:0/128");
     496             :         }
     497           9 :         CATCH_END_SECTION()
     498             : 
     499           9 :         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           9 :         CATCH_END_SECTION()
     505             : 
     506           9 :         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           9 :         CATCH_END_SECTION()
     514             : 
     515           9 :         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           9 :         CATCH_END_SECTION()
     525             : 
     526           9 :         CATCH_START_SECTION("addr: compare with another 0.0.0.0")
     527             :         {
     528             :             {
     529           1 :                 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           1 :             }
     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           1 :                 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           1 :             }
     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           1 :                 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           1 :             }
     573             :         }
     574           9 :         CATCH_END_SECTION()
     575             : 
     576           9 :         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           1 :             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           1 :         }
     591           9 :         CATCH_END_SECTION()
     592          18 :     }
     593           9 : }
     594             : 
     595             : 
     596          21 : CATCH_TEST_CASE("ipv4::address", "[ipv4]")
     597             : {
     598          21 :     CATCH_GIVEN("addr() with an IPv4")
     599             :     {
     600           3 :         addr::addr a;
     601             : 
     602           3 :         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          10 :                 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          10 :             }
     624             :         }
     625           3 :         CATCH_END_SECTION()
     626             : 
     627           3 :         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          30 :                         );
     647          10 :                 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_ADDRESS)                                         == ip);
     653          10 :                 CATCH_REQUIRE(a.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS)                                 == ip);
     654          10 :                 CATCH_REQUIRE(a.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT)          == ip + ":" + port_str);
     655          10 :                 CATCH_REQUIRE(a.to_ipv4_string(addr::STRING_IP_ADDRESS | addr::STRING_IP_MASK)                  == ip + "/32");
     656          10 :                 CATCH_REQUIRE(a.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_BRACKET_MASK)  == ip + "/32");
     657          10 :                 CATCH_REQUIRE(a.to_ipv4_string(addr::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_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_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          10 :                     };
     676          10 :                 a.set_mask(valid_mask);
     677          10 :                 a.set_mask_count(128);
     678          10 :             }
     679             :         }
     680           3 :         CATCH_END_SECTION()
     681             : 
     682           3 :         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           1 :             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           1 :         }
     709           3 :         CATCH_END_SECTION()
     710          24 :     }
     711             : 
     712          21 :     CATCH_GIVEN("addr_parser() with IPv4 addresses")
     713             :     {
     714           7 :         CATCH_START_SECTION("addr: verify basics")
     715             :         {
     716           1 :             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           3 :             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           1 :             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_ADDRESS) == "1.2.3.4");
     736           1 :             CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "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           1 :         }
     753           7 :         CATCH_END_SECTION()
     754             : 
     755           7 :         CATCH_START_SECTION("addr: verify default address")
     756             :         {
     757           1 :             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           1 :         }
     776           7 :         CATCH_END_SECTION()
     777             : 
     778           7 :         CATCH_START_SECTION("addr: verify default mask")
     779             :         {
     780           1 :             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           1 :         }
     799           7 :         CATCH_END_SECTION()
     800             : 
     801           7 :         CATCH_START_SECTION("addr: verify default allow flags")
     802             :         {
     803           1 :             addr::addr_parser p;
     804             : 
     805          17 :             for(int idx(0); idx < static_cast<int>(addr::allow_t::ALLOW_max); ++idx)
     806             :             {
     807          16 :                 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          13 :                 default:
     818          13 :                     CATCH_REQUIRE_FALSE(p.get_allow(static_cast<addr::allow_t>(idx)));
     819          13 :                     break;
     820             : 
     821             :                 }
     822             :             }
     823           1 :         }
     824           7 :         CATCH_END_SECTION()
     825             : 
     826           7 :         CATCH_START_SECTION("addr: verify contradictory flags")
     827             :         {
     828           1 :             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           1 :         }
     885           7 :         CATCH_END_SECTION()
     886             : 
     887           7 :         CATCH_START_SECTION("addr: default address")
     888             :         {
     889           1 :             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           3 :             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           1 :             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_ADDRESS) == "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           1 :         }
     917           7 :         CATCH_END_SECTION()
     918             : 
     919           7 :         CATCH_START_SECTION("addr: address, no port allowed")
     920             :         {
     921             :             // specific address with a default
     922             :             {
     923           1 :                 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           3 :                 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           1 :                 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_ADDRESS) == "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           1 :             }
     952             : 
     953             :             // only a default address
     954             :             {
     955           1 :                 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           3 :                 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           1 :                 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_ADDRESS) == "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           1 :             }
     984             :         }
     985           7 :         CATCH_END_SECTION()
     986          21 :     }
     987             : 
     988          21 :     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           1 :             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           3 :             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           1 :                 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_ADDRESS) == "1.2.3.4");
    1013           1 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "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           1 :             }
    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           1 :                 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_ADDRESS) == "5.6.7.8");
    1042           1 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "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           1 :             }
    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           1 :                 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_ADDRESS) == "10.11.12.99");
    1071           1 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "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           1 :             }
    1087           1 :         }
    1088           6 :         CATCH_END_SECTION()
    1089             : 
    1090           6 :         CATCH_START_SECTION("addr: 3 IPs separated by spaces")
    1091             :         {
    1092           1 :             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           3 :             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           1 :                 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_ADDRESS) == "1.2.3.4");
    1113           1 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "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           1 :             }
    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           1 :                 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_ADDRESS) == "5.6.7.8");
    1142           1 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "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           1 :             }
    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           1 :                 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_ADDRESS) == "10.11.12.99");
    1171           1 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "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           1 :             }
    1187           1 :         }
    1188           6 :         CATCH_END_SECTION()
    1189             : 
    1190           6 :         CATCH_START_SECTION("addr: 3 IPs separated by commas and/or spaces")
    1191             :         {
    1192           1 :             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           3 :             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           1 :                 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_ADDRESS) == "1.2.3.4");
    1214           1 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "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           1 :             }
    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           1 :                 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_ADDRESS) == "5.6.7.8");
    1243           1 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "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           1 :             }
    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           1 :                 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_ADDRESS) == "10.11.12.99");
    1272           1 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "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           1 :             }
    1288           1 :         }
    1289           6 :         CATCH_END_SECTION()
    1290             : 
    1291           6 :         CATCH_START_SECTION("addr: 3 IPs with hash (#) comments")
    1292             :         {
    1293           1 :             addr::addr_parser p;
    1294           1 :             p.set_protocol(IPPROTO_TCP);
    1295           1 :             p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS, true);
    1296           1 :             p.set_allow(addr::allow_t::ALLOW_COMMENT_HASH, true);
    1297           3 :             addr::addr_range::vector_t ips(p.parse("1.2.3.4:55#first,5.6.7.8#second,10.11.12.99:77#third"));
    1298           1 :             CATCH_REQUIRE_FALSE(p.has_errors());
    1299           1 :             CATCH_REQUIRE(ips.size() == 3);
    1300             : 
    1301           1 :             uint8_t mask[16] = {};
    1302             : 
    1303             :             // 1.2.3.4:55
    1304             :             {
    1305           1 :                 addr::addr_range const & r(ips[0]);
    1306           1 :                 CATCH_REQUIRE(r.has_from());
    1307           1 :                 CATCH_REQUIRE_FALSE(r.has_to());
    1308           1 :                 CATCH_REQUIRE_FALSE(r.is_range());
    1309           1 :                 CATCH_REQUIRE_FALSE(r.is_empty());
    1310           1 :                 addr::addr f(r.get_from());
    1311           1 :                 CATCH_REQUIRE(f.is_ipv4());
    1312           1 :                 CATCH_REQUIRE(f.get_family() == AF_INET);
    1313           1 :                 CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
    1314           1 :                 CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "1.2.3.4");
    1315           1 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "1.2.3.4");
    1316           1 :                 CATCH_REQUIRE(f.get_port() == 55);
    1317           1 :                 CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
    1318           1 :                 CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
    1319           1 :                 CATCH_REQUIRE_FALSE(f.is_lan());
    1320           1 :                 CATCH_REQUIRE_FALSE(f.is_lan(true));
    1321           1 :                 CATCH_REQUIRE_FALSE(f.is_lan(false));
    1322           1 :                 CATCH_REQUIRE(f.is_wan());
    1323           1 :                 CATCH_REQUIRE(f.is_wan(true));
    1324           1 :                 CATCH_REQUIRE(f.is_wan(false));
    1325           1 :                 f.get_mask(mask);
    1326          17 :                 for(int idx(0); idx < 16; ++idx)
    1327             :                 {
    1328          16 :                     CATCH_REQUIRE(mask[idx] == 255);
    1329             :                 }
    1330           1 :             }
    1331             : 
    1332             :             // 5.6.7.8
    1333             :             {
    1334           1 :                 addr::addr_range const & r(ips[1]);
    1335           1 :                 CATCH_REQUIRE(r.has_from());
    1336           1 :                 CATCH_REQUIRE_FALSE(r.has_to());
    1337           1 :                 CATCH_REQUIRE_FALSE(r.is_range());
    1338           1 :                 CATCH_REQUIRE_FALSE(r.is_empty());
    1339           1 :                 addr::addr f(r.get_from());
    1340           1 :                 CATCH_REQUIRE(f.is_ipv4());
    1341           1 :                 CATCH_REQUIRE(f.get_family() == AF_INET);
    1342           1 :                 CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
    1343           1 :                 CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "5.6.7.8");
    1344           1 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "5.6.7.8");
    1345           1 :                 CATCH_REQUIRE(f.get_port() == 0);
    1346           1 :                 CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
    1347           1 :                 CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
    1348           1 :                 CATCH_REQUIRE_FALSE(f.is_lan());
    1349           1 :                 CATCH_REQUIRE_FALSE(f.is_lan(true));
    1350           1 :                 CATCH_REQUIRE_FALSE(f.is_lan(false));
    1351           1 :                 CATCH_REQUIRE(f.is_wan());
    1352           1 :                 CATCH_REQUIRE(f.is_wan(true));
    1353           1 :                 CATCH_REQUIRE(f.is_wan(false));
    1354           1 :                 f.get_mask(mask);
    1355          17 :                 for(int idx(0); idx < 16; ++idx)
    1356             :                 {
    1357          16 :                     CATCH_REQUIRE(mask[idx] == 255);
    1358             :                 }
    1359           1 :             }
    1360             : 
    1361             :             // 10.11.12.99:77
    1362             :             {
    1363           1 :                 addr::addr_range const & r(ips[2]);
    1364           1 :                 CATCH_REQUIRE(r.has_from());
    1365           1 :                 CATCH_REQUIRE_FALSE(r.has_to());
    1366           1 :                 CATCH_REQUIRE_FALSE(r.is_range());
    1367           1 :                 CATCH_REQUIRE_FALSE(r.is_empty());
    1368           1 :                 addr::addr f(r.get_from());
    1369           1 :                 CATCH_REQUIRE(f.is_ipv4());
    1370           1 :                 CATCH_REQUIRE(f.get_family() == AF_INET);
    1371           1 :                 CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
    1372           1 :                 CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "10.11.12.99");
    1373           1 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "10.11.12.99");
    1374           1 :                 CATCH_REQUIRE(f.get_port() == 77);
    1375           1 :                 CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
    1376           1 :                 CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
    1377           1 :                 CATCH_REQUIRE(f.is_lan());
    1378           1 :                 CATCH_REQUIRE(f.is_lan(true));
    1379           1 :                 CATCH_REQUIRE(f.is_lan(false));
    1380           1 :                 CATCH_REQUIRE_FALSE(f.is_wan());
    1381           1 :                 CATCH_REQUIRE_FALSE(f.is_wan(true));
    1382           1 :                 CATCH_REQUIRE_FALSE(f.is_wan(false));
    1383           1 :                 f.get_mask(mask);
    1384          17 :                 for(int idx(0); idx < 16; ++idx)
    1385             :                 {
    1386          16 :                     CATCH_REQUIRE(mask[idx] == 255);
    1387             :                 }
    1388           1 :             }
    1389           1 :         }
    1390           6 :         CATCH_END_SECTION()
    1391             : 
    1392           6 :         CATCH_START_SECTION("addr: 3 IPs with semicolon (;) comments")
    1393             :         {
    1394           1 :             addr::addr_parser p;
    1395           1 :             p.set_protocol(IPPROTO_TCP);
    1396           1 :             p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS, true);
    1397           1 :             p.set_allow(addr::allow_t::ALLOW_COMMENT_SEMICOLON, true);
    1398           3 :             addr::addr_range::vector_t ips(p.parse("1.2.3.4:55;first,5.6.7.8;second,10.11.12.99:77;third"));
    1399           1 :             CATCH_REQUIRE_FALSE(p.has_errors());
    1400           1 :             CATCH_REQUIRE(ips.size() == 3);
    1401             : 
    1402           1 :             uint8_t mask[16] = {};
    1403             : 
    1404             :             // 1.2.3.4:55
    1405             :             {
    1406           1 :                 addr::addr_range const & r(ips[0]);
    1407           1 :                 CATCH_REQUIRE(r.has_from());
    1408           1 :                 CATCH_REQUIRE_FALSE(r.has_to());
    1409           1 :                 CATCH_REQUIRE_FALSE(r.is_range());
    1410           1 :                 CATCH_REQUIRE_FALSE(r.is_empty());
    1411           1 :                 addr::addr f(r.get_from());
    1412           1 :                 CATCH_REQUIRE(f.is_ipv4());
    1413           1 :                 CATCH_REQUIRE(f.get_family() == AF_INET);
    1414           1 :                 CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
    1415           1 :                 CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "1.2.3.4");
    1416           1 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "1.2.3.4");
    1417           1 :                 CATCH_REQUIRE(f.get_port() == 55);
    1418           1 :                 CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
    1419           1 :                 CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
    1420           1 :                 CATCH_REQUIRE_FALSE(f.is_lan());
    1421           1 :                 CATCH_REQUIRE_FALSE(f.is_lan(true));
    1422           1 :                 CATCH_REQUIRE_FALSE(f.is_lan(false));
    1423           1 :                 CATCH_REQUIRE(f.is_wan());
    1424           1 :                 CATCH_REQUIRE(f.is_wan(true));
    1425           1 :                 CATCH_REQUIRE(f.is_wan(false));
    1426           1 :                 f.get_mask(mask);
    1427          17 :                 for(int idx(0); idx < 16; ++idx)
    1428             :                 {
    1429          16 :                     CATCH_REQUIRE(mask[idx] == 255);
    1430             :                 }
    1431           1 :             }
    1432             : 
    1433             :             // 5.6.7.8
    1434             :             {
    1435           1 :                 addr::addr_range const & r(ips[1]);
    1436           1 :                 CATCH_REQUIRE(r.has_from());
    1437           1 :                 CATCH_REQUIRE_FALSE(r.has_to());
    1438           1 :                 CATCH_REQUIRE_FALSE(r.is_range());
    1439           1 :                 CATCH_REQUIRE_FALSE(r.is_empty());
    1440           1 :                 addr::addr f(r.get_from());
    1441           1 :                 CATCH_REQUIRE(f.is_ipv4());
    1442           1 :                 CATCH_REQUIRE(f.get_family() == AF_INET);
    1443           1 :                 CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
    1444           1 :                 CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "5.6.7.8");
    1445           1 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "5.6.7.8");
    1446           1 :                 CATCH_REQUIRE(f.get_port() == 0);
    1447           1 :                 CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
    1448           1 :                 CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
    1449           1 :                 CATCH_REQUIRE_FALSE(f.is_lan());
    1450           1 :                 CATCH_REQUIRE_FALSE(f.is_lan(true));
    1451           1 :                 CATCH_REQUIRE_FALSE(f.is_lan(false));
    1452           1 :                 CATCH_REQUIRE(f.is_wan());
    1453           1 :                 CATCH_REQUIRE(f.is_wan(true));
    1454           1 :                 CATCH_REQUIRE(f.is_wan(false));
    1455           1 :                 f.get_mask(mask);
    1456          17 :                 for(int idx(0); idx < 16; ++idx)
    1457             :                 {
    1458          16 :                     CATCH_REQUIRE(mask[idx] == 255);
    1459             :                 }
    1460           1 :             }
    1461             : 
    1462             :             // 10.11.12.99:77
    1463             :             {
    1464           1 :                 addr::addr_range const & r(ips[2]);
    1465           1 :                 CATCH_REQUIRE(r.has_from());
    1466           1 :                 CATCH_REQUIRE_FALSE(r.has_to());
    1467           1 :                 CATCH_REQUIRE_FALSE(r.is_range());
    1468           1 :                 CATCH_REQUIRE_FALSE(r.is_empty());
    1469           1 :                 addr::addr f(r.get_from());
    1470           1 :                 CATCH_REQUIRE(f.is_ipv4());
    1471           1 :                 CATCH_REQUIRE(f.get_family() == AF_INET);
    1472           1 :                 CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
    1473           1 :                 CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "10.11.12.99");
    1474           1 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "10.11.12.99");
    1475           1 :                 CATCH_REQUIRE(f.get_port() == 77);
    1476           1 :                 CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
    1477           1 :                 CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
    1478           1 :                 CATCH_REQUIRE(f.is_lan());
    1479           1 :                 CATCH_REQUIRE(f.is_lan(true));
    1480           1 :                 CATCH_REQUIRE(f.is_lan(false));
    1481           1 :                 CATCH_REQUIRE_FALSE(f.is_wan());
    1482           1 :                 CATCH_REQUIRE_FALSE(f.is_wan(true));
    1483           1 :                 CATCH_REQUIRE_FALSE(f.is_wan(false));
    1484           1 :                 f.get_mask(mask);
    1485          17 :                 for(int idx(0); idx < 16; ++idx)
    1486             :                 {
    1487          16 :                     CATCH_REQUIRE(mask[idx] == 255);
    1488             :                 }
    1489           1 :             }
    1490           1 :         }
    1491           6 :         CATCH_END_SECTION()
    1492             : 
    1493           6 :         CATCH_START_SECTION("addr: 3 IPs with hash (#) and semicolon (;) comments")
    1494             :         {
    1495           1 :             addr::addr_parser p;
    1496           1 :             p.set_protocol(IPPROTO_TCP);
    1497           1 :             p.set_allow(addr::allow_t::ALLOW_MULTI_ADDRESSES_COMMAS, true);
    1498           1 :             p.set_allow(addr::allow_t::ALLOW_COMMENT_HASH, true);
    1499           1 :             p.set_allow(addr::allow_t::ALLOW_COMMENT_SEMICOLON, true);
    1500           3 :             addr::addr_range::vector_t ips(p.parse("1.2.3.4:55;first,5.6.7.8#second,10.11.12.99:77;third"));
    1501           1 :             CATCH_REQUIRE_FALSE(p.has_errors());
    1502           1 :             CATCH_REQUIRE(ips.size() == 3);
    1503             : 
    1504           1 :             uint8_t mask[16] = {};
    1505             : 
    1506             :             // 1.2.3.4:55
    1507             :             {
    1508           1 :                 addr::addr_range const & r(ips[0]);
    1509           1 :                 CATCH_REQUIRE(r.has_from());
    1510           1 :                 CATCH_REQUIRE_FALSE(r.has_to());
    1511           1 :                 CATCH_REQUIRE_FALSE(r.is_range());
    1512           1 :                 CATCH_REQUIRE_FALSE(r.is_empty());
    1513           1 :                 addr::addr f(r.get_from());
    1514           1 :                 CATCH_REQUIRE(f.is_ipv4());
    1515           1 :                 CATCH_REQUIRE(f.get_family() == AF_INET);
    1516           1 :                 CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
    1517           1 :                 CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "1.2.3.4");
    1518           1 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "1.2.3.4");
    1519           1 :                 CATCH_REQUIRE(f.get_port() == 55);
    1520           1 :                 CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
    1521           1 :                 CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
    1522           1 :                 CATCH_REQUIRE_FALSE(f.is_lan());
    1523           1 :                 CATCH_REQUIRE_FALSE(f.is_lan(true));
    1524           1 :                 CATCH_REQUIRE_FALSE(f.is_lan(false));
    1525           1 :                 CATCH_REQUIRE(f.is_wan());
    1526           1 :                 CATCH_REQUIRE(f.is_wan(true));
    1527           1 :                 CATCH_REQUIRE(f.is_wan(false));
    1528           1 :                 f.get_mask(mask);
    1529          17 :                 for(int idx(0); idx < 16; ++idx)
    1530             :                 {
    1531          16 :                     CATCH_REQUIRE(mask[idx] == 255);
    1532             :                 }
    1533           1 :             }
    1534             : 
    1535             :             // 5.6.7.8
    1536             :             {
    1537           1 :                 addr::addr_range const & r(ips[1]);
    1538           1 :                 CATCH_REQUIRE(r.has_from());
    1539           1 :                 CATCH_REQUIRE_FALSE(r.has_to());
    1540           1 :                 CATCH_REQUIRE_FALSE(r.is_range());
    1541           1 :                 CATCH_REQUIRE_FALSE(r.is_empty());
    1542           1 :                 addr::addr f(r.get_from());
    1543           1 :                 CATCH_REQUIRE(f.is_ipv4());
    1544           1 :                 CATCH_REQUIRE(f.get_family() == AF_INET);
    1545           1 :                 CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
    1546           1 :                 CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "5.6.7.8");
    1547           1 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "5.6.7.8");
    1548           1 :                 CATCH_REQUIRE(f.get_port() == 0);
    1549           1 :                 CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
    1550           1 :                 CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
    1551           1 :                 CATCH_REQUIRE_FALSE(f.is_lan());
    1552           1 :                 CATCH_REQUIRE_FALSE(f.is_lan(true));
    1553           1 :                 CATCH_REQUIRE_FALSE(f.is_lan(false));
    1554           1 :                 CATCH_REQUIRE(f.is_wan());
    1555           1 :                 CATCH_REQUIRE(f.is_wan(true));
    1556           1 :                 CATCH_REQUIRE(f.is_wan(false));
    1557           1 :                 f.get_mask(mask);
    1558          17 :                 for(int idx(0); idx < 16; ++idx)
    1559             :                 {
    1560          16 :                     CATCH_REQUIRE(mask[idx] == 255);
    1561             :                 }
    1562           1 :             }
    1563             : 
    1564             :             // 10.11.12.99:77
    1565             :             {
    1566           1 :                 addr::addr_range const & r(ips[2]);
    1567           1 :                 CATCH_REQUIRE(r.has_from());
    1568           1 :                 CATCH_REQUIRE_FALSE(r.has_to());
    1569           1 :                 CATCH_REQUIRE_FALSE(r.is_range());
    1570           1 :                 CATCH_REQUIRE_FALSE(r.is_empty());
    1571           1 :                 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           1 :                 CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "10.11.12.99");
    1576           1 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "10.11.12.99");
    1577           1 :                 CATCH_REQUIRE(f.get_port() == 77);
    1578           1 :                 CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
    1579           1 :                 CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
    1580           1 :                 CATCH_REQUIRE(f.is_lan());
    1581           1 :                 CATCH_REQUIRE(f.is_lan(true));
    1582           1 :                 CATCH_REQUIRE(f.is_lan(false));
    1583           1 :                 CATCH_REQUIRE_FALSE(f.is_wan());
    1584           1 :                 CATCH_REQUIRE_FALSE(f.is_wan(true));
    1585           1 :                 CATCH_REQUIRE_FALSE(f.is_wan(false));
    1586           1 :                 f.get_mask(mask);
    1587          17 :                 for(int idx(0); idx < 16; ++idx)
    1588             :                 {
    1589          16 :                     CATCH_REQUIRE(mask[idx] == 255);
    1590             :                 }
    1591           1 :             }
    1592           1 :         }
    1593           6 :         CATCH_END_SECTION()
    1594          21 :     }
    1595             : 
    1596          21 :     CATCH_GIVEN("addr_parser() with numeric only IPv4 addresses")
    1597             :     {
    1598           3 :         CATCH_START_SECTION("addr: simple numeric IPv4")
    1599             :         {
    1600           1 :             addr::addr_parser p;
    1601           1 :             p.set_protocol(IPPROTO_TCP);
    1602           1 :             p.set_allow(addr::allow_t::ALLOW_ADDRESS_LOOKUP, false);
    1603           3 :             addr::addr_range::vector_t ips(p.parse("4.3.1.2:3003"));
    1604           1 :             CATCH_REQUIRE_FALSE(p.has_errors());
    1605           1 :             CATCH_REQUIRE(ips.size() == 1);
    1606             : 
    1607           1 :             addr::addr_range const & r(ips[0]);
    1608           1 :             CATCH_REQUIRE(r.has_from());
    1609           1 :             CATCH_REQUIRE_FALSE(r.has_to());
    1610           1 :             CATCH_REQUIRE_FALSE(r.is_range());
    1611           1 :             CATCH_REQUIRE_FALSE(r.is_empty());
    1612           1 :             addr::addr f(r.get_from());
    1613           1 :             CATCH_REQUIRE(f.is_ipv4());
    1614           1 :             CATCH_REQUIRE(f.get_family() == AF_INET);
    1615           1 :             CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
    1616           1 :             CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "4.3.1.2");
    1617           1 :             CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "4.3.1.2");
    1618           1 :             CATCH_REQUIRE(f.get_port() == 3003);
    1619           1 :             CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
    1620           1 :             CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
    1621           1 :             CATCH_REQUIRE_FALSE(f.is_lan());
    1622           1 :             CATCH_REQUIRE_FALSE(f.is_lan(true));
    1623           1 :             CATCH_REQUIRE_FALSE(f.is_lan(false));
    1624           1 :             CATCH_REQUIRE(f.is_wan());
    1625           1 :             CATCH_REQUIRE(f.is_wan(true));
    1626           1 :             CATCH_REQUIRE(f.is_wan(false));
    1627           1 :             uint8_t mask[16] = {};
    1628           1 :             f.get_mask(mask);
    1629          17 :             for(int idx(0); idx < 16; ++idx)
    1630             :             {
    1631          16 :                 CATCH_REQUIRE(mask[idx] == 255);
    1632             :             }
    1633           1 :         }
    1634           3 :         CATCH_END_SECTION()
    1635             : 
    1636           3 :         CATCH_START_SECTION("addr: invalid domain name address when we only accept numeric IPs")
    1637             :         {
    1638           1 :             addr::addr_parser p;
    1639           1 :             p.set_protocol(IPPROTO_TCP);
    1640           1 :             p.set_allow(addr::allow_t::ALLOW_ADDRESS_LOOKUP, false);
    1641           3 :             addr::addr_range::vector_t ips(p.parse("www.example.com:4471"));
    1642           1 :             CATCH_REQUIRE(p.has_errors());
    1643           1 :             CATCH_REQUIRE(p.error_count() == 1);
    1644           1 :             CATCH_REQUIRE(p.error_messages() == "Unknown address in \"www.example.com\" (no DNS lookup was allowed).\n");
    1645           1 :             CATCH_REQUIRE(ips.size() == 0);
    1646           1 :         }
    1647           3 :         CATCH_END_SECTION()
    1648             : 
    1649           3 :         CATCH_START_SECTION("addr: invalid port: service name not allowed")
    1650             :         {
    1651           1 :             addr::addr_parser p;
    1652           1 :             p.set_protocol(IPPROTO_TCP);
    1653           1 :             p.set_allow(addr::allow_t::ALLOW_ADDRESS_LOOKUP, false);
    1654           3 :             addr::addr_range::vector_t ips(p.parse("192.168.255.32:https"));
    1655           1 :             CATCH_REQUIRE(p.has_errors());
    1656           1 :             CATCH_REQUIRE(p.error_count() == 1);
    1657           1 :             CATCH_REQUIRE(p.error_messages() == "Invalid port in \"https\" (no service name lookup allowed).\n");
    1658           1 :             CATCH_REQUIRE(ips.size() == 0);
    1659           1 :         }
    1660           3 :         CATCH_END_SECTION()
    1661          21 :     }
    1662             : 
    1663          21 :     CATCH_START_SECTION("addr: IP as hostname")
    1664             :     {
    1665          11 :         for(int idx(0); idx < 10; ++idx)
    1666             :         {
    1667          10 :             struct sockaddr_in in = sockaddr_in();
    1668          10 :             in.sin_family = AF_INET;
    1669          10 :             in.sin_port = htons(rand());
    1670          10 :             in.sin_addr.s_addr = htonl(rand() ^ (rand() << 16));
    1671          10 :             addr::addr a(in);
    1672          10 :             struct sockaddr_in out;
    1673          10 :             a.get_ipv4(out);
    1674          10 :             CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
    1675          10 :             CATCH_REQUIRE(a.get_hostname().empty());
    1676          10 :             std::string const ip(a.to_ipv4or6_string(addr::STRING_IP_ADDRESS));
    1677          10 :             a.set_hostname(ip);
    1678          10 :             CATCH_REQUIRE(a.get_hostname() == ip);
    1679          10 :             CATCH_REQUIRE(a.is_hostname_an_ip());
    1680          10 :             a.set_hostname("no.an.ip");
    1681          10 :             CATCH_REQUIRE(a.get_hostname() == "no.an.ip");
    1682          10 :             CATCH_REQUIRE_FALSE(a.is_hostname_an_ip());
    1683          10 :         }
    1684             :     }
    1685          21 :     CATCH_END_SECTION()
    1686             : 
    1687          21 :     CATCH_START_SECTION("addr: set interface")
    1688             :     {
    1689           1 :         addr::addr a;
    1690           1 :         CATCH_REQUIRE(a.get_interface().empty());
    1691           1 :         a.set_interface("eth0");
    1692           1 :         CATCH_REQUIRE(a.get_interface() == "eth0");
    1693           1 :         a.set_interface("epn3");
    1694           1 :         CATCH_REQUIRE(a.get_interface() == "epn3");
    1695           1 :         a.set_interface(std::string());
    1696           1 :         CATCH_REQUIRE(a.get_interface().empty());
    1697           1 :     }
    1698          21 :     CATCH_END_SECTION()
    1699          21 : }
    1700             : 
    1701             : 
    1702           3 : CATCH_TEST_CASE("ipv4::ports", "[ipv4]")
    1703             : {
    1704           3 :     CATCH_GIVEN("addr_parser() with IPv4 addresses and port")
    1705             :     {
    1706           3 :         CATCH_START_SECTION("addr: verify port")
    1707             :         {
    1708       65537 :             for(int port(0); port < 65536; ++port)
    1709             :             {
    1710       65536 :                 int proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
    1711       65536 :                 addr::addr_parser p;
    1712       65536 :                 p.set_protocol(proto);
    1713      196608 :                 addr::addr_range::vector_t ips(p.parse("192.168.12.199:" + std::to_string(port)));
    1714       65536 :                 CATCH_REQUIRE_FALSE(p.has_errors());
    1715       65536 :                 CATCH_REQUIRE(ips.size() == 1);
    1716       65536 :                 addr::addr_range const & r(ips[0]);
    1717       65536 :                 addr::addr f(r.get_from());
    1718       65536 :                 CATCH_REQUIRE(f.is_ipv4());
    1719       65536 :                 CATCH_REQUIRE(f.get_family() == AF_INET);
    1720       65536 :                 CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
    1721       65536 :                 CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "192.168.12.199");
    1722       65536 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "192.168.12.199");
    1723       65536 :                 CATCH_REQUIRE(f.get_port() == port);
    1724       65536 :                 CATCH_REQUIRE(f.get_protocol() == proto);
    1725       65536 :                 CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
    1726       65536 :                 CATCH_REQUIRE(f.is_lan());
    1727       65536 :                 CATCH_REQUIRE(f.is_lan(true));
    1728       65536 :                 CATCH_REQUIRE(f.is_lan(false));
    1729       65536 :                 CATCH_REQUIRE_FALSE(f.is_wan());
    1730       65536 :                 CATCH_REQUIRE_FALSE(f.is_wan(true));
    1731       65536 :                 CATCH_REQUIRE_FALSE(f.is_wan(false));
    1732       65536 :             }
    1733             :         }
    1734           3 :         CATCH_END_SECTION()
    1735             : 
    1736           3 :         CATCH_START_SECTION("addr: default address with various port")
    1737             :         {
    1738         101 :             for(int idx(0); idx < 100; ++idx)
    1739             :             {
    1740         100 :                 uint16_t const port(rand());
    1741         100 :                 addr::addr_parser p;
    1742         100 :                 p.set_protocol(IPPROTO_TCP);
    1743         100 :                 p.set_default_address("5.5.5.5");
    1744         100 :                 CATCH_REQUIRE(p.get_default_address4() == "5.5.5.5");
    1745         100 :                 CATCH_REQUIRE(p.get_default_address6() == "");
    1746         300 :                 addr::addr_range::vector_t ips(p.parse(":" + std::to_string(static_cast<int>(port))));
    1747         100 :                 CATCH_REQUIRE_FALSE(p.has_errors());
    1748         100 :                 CATCH_REQUIRE(ips.size() == 1);
    1749         100 :                 addr::addr_range const & r(ips[0]);
    1750         100 :                 CATCH_REQUIRE(r.has_from());
    1751         100 :                 CATCH_REQUIRE_FALSE(r.has_to());
    1752         100 :                 CATCH_REQUIRE_FALSE(r.is_range());
    1753         100 :                 CATCH_REQUIRE_FALSE(r.is_empty());
    1754         100 :                 addr::addr f(r.get_from());
    1755         100 :                 CATCH_REQUIRE(f.is_ipv4());
    1756         100 :                 CATCH_REQUIRE(f.get_family() == AF_INET);
    1757         100 :                 CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
    1758         100 :                 CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
    1759         100 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
    1760         100 :                 CATCH_REQUIRE(f.get_port() == port);
    1761         100 :                 CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
    1762         100 :                 CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
    1763         100 :                 CATCH_REQUIRE_FALSE(f.is_lan());
    1764         100 :                 CATCH_REQUIRE_FALSE(f.is_lan(true));
    1765         100 :                 CATCH_REQUIRE_FALSE(f.is_lan(false));
    1766         100 :                 CATCH_REQUIRE(f.is_wan());
    1767         100 :                 CATCH_REQUIRE(f.is_wan(true));
    1768         100 :                 CATCH_REQUIRE(f.is_wan(false));
    1769         100 :             }
    1770             :         }
    1771           3 :         CATCH_END_SECTION()
    1772             : 
    1773           3 :         CATCH_START_SECTION("addr: address with default port")
    1774             :         {
    1775          26 :             for(int idx(0); idx < 25; ++idx)
    1776             :             {
    1777          25 :                 std::uint16_t const port(rand());
    1778          25 :                 addr::addr_parser p;
    1779          25 :                 p.set_protocol(IPPROTO_TCP);
    1780          25 :                 if((rand() & 1) == 0)
    1781             :                 {
    1782          13 :                     p.set_default_port(port);
    1783             :                 }
    1784             :                 else
    1785             :                 {
    1786          12 :                     std::string const port_str(std::to_string(static_cast<int>(port)));
    1787          12 :                     p.set_default_port(port_str);
    1788          12 :                 }
    1789          25 :                 CATCH_REQUIRE(p.get_default_port() == port);
    1790          75 :                 addr::addr_range::vector_t ips(p.parse("5.5.5.5"));
    1791          25 :                 CATCH_REQUIRE_FALSE(p.has_errors());
    1792          25 :                 CATCH_REQUIRE(ips.size() == 1);
    1793          25 :                 addr::addr_range const & r(ips[0]);
    1794          25 :                 CATCH_REQUIRE(r.has_from());
    1795          25 :                 CATCH_REQUIRE_FALSE(r.has_to());
    1796          25 :                 CATCH_REQUIRE_FALSE(r.is_range());
    1797          25 :                 CATCH_REQUIRE_FALSE(r.is_empty());
    1798          25 :                 addr::addr f(r.get_from());
    1799          25 :                 CATCH_REQUIRE(f.is_ipv4());
    1800          25 :                 CATCH_REQUIRE(f.get_family() == AF_INET);
    1801          25 :                 CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
    1802          25 :                 CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
    1803          25 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
    1804          25 :                 CATCH_REQUIRE(f.get_port() == port);
    1805          25 :                 CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
    1806          25 :                 CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
    1807          25 :                 CATCH_REQUIRE_FALSE(f.is_lan());
    1808          25 :                 CATCH_REQUIRE_FALSE(f.is_lan(true));
    1809          25 :                 CATCH_REQUIRE_FALSE(f.is_lan(false));
    1810          25 :                 CATCH_REQUIRE(f.is_wan());
    1811          25 :                 CATCH_REQUIRE(f.is_wan(true));
    1812          25 :                 CATCH_REQUIRE(f.is_wan(false));
    1813          25 :             }
    1814             : 
    1815          26 :             for(int idx(0); idx < 25; ++idx)
    1816             :             {
    1817          25 :                 std::uint16_t const port(rand());
    1818          25 :                 addr::addr_parser p;
    1819          25 :                 p.set_protocol(IPPROTO_TCP);
    1820          25 :                 if((rand() & 1) == 0)
    1821             :                 {
    1822          12 :                     p.set_default_port(port);
    1823             :                 }
    1824             :                 else
    1825             :                 {
    1826          13 :                     std::string const port_str(std::to_string(static_cast<int>(port)));
    1827          13 :                     p.set_default_port(port_str);
    1828          13 :                 }
    1829          25 :                 CATCH_REQUIRE(p.get_default_port() == port);
    1830          75 :                 addr::addr_range::vector_t ips(p.parse("5.5.5.5:"));
    1831          25 :                 CATCH_REQUIRE_FALSE(p.has_errors());
    1832          25 :                 CATCH_REQUIRE(ips.size() == 1);
    1833          25 :                 addr::addr_range const & r(ips[0]);
    1834          25 :                 CATCH_REQUIRE(r.has_from());
    1835          25 :                 CATCH_REQUIRE_FALSE(r.has_to());
    1836          25 :                 CATCH_REQUIRE_FALSE(r.is_range());
    1837          25 :                 CATCH_REQUIRE_FALSE(r.is_empty());
    1838          25 :                 addr::addr f(r.get_from());
    1839          25 :                 CATCH_REQUIRE(f.is_ipv4());
    1840          25 :                 CATCH_REQUIRE(f.get_family() == AF_INET);
    1841          25 :                 CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
    1842          25 :                 CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
    1843          25 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_BRACKET_ADDRESS | addr::STRING_IP_PORT) == "5.5.5.5:" + std::to_string(static_cast<int>(port)));
    1844          25 :                 CATCH_REQUIRE(f.get_port() == port);
    1845          25 :                 CATCH_REQUIRE(f.get_protocol() == IPPROTO_TCP);
    1846          25 :                 CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PUBLIC);
    1847          25 :                 CATCH_REQUIRE_FALSE(f.is_lan());
    1848          25 :                 CATCH_REQUIRE_FALSE(f.is_lan(true));
    1849          25 :                 CATCH_REQUIRE_FALSE(f.is_lan(false));
    1850          25 :                 CATCH_REQUIRE(f.is_wan());
    1851          25 :                 CATCH_REQUIRE(f.is_wan(true));
    1852          25 :                 CATCH_REQUIRE(f.is_wan(false));
    1853          25 :             }
    1854             :         }
    1855           3 :         CATCH_END_SECTION()
    1856           3 :     }
    1857           3 : }
    1858             : 
    1859             : 
    1860           9 : CATCH_TEST_CASE("ipv4::masks", "[ipv4]")
    1861             : {
    1862           9 :     CATCH_GIVEN("addr_parser() of address:port/mask")
    1863             :     {
    1864           9 :         CATCH_START_SECTION("addr: mask allowed, but no mask")
    1865             :         {
    1866           1 :             int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
    1867           1 :             int const port(rand() & 0xFFFF);
    1868           1 :             addr::addr_parser p;
    1869           1 :             p.set_protocol(proto);
    1870           1 :             p.set_allow(addr::allow_t::ALLOW_MASK, true);
    1871           3 :             addr::addr_range::vector_t ips(p.parse("172.19.6.91:" + std::to_string(port)));
    1872           1 :             CATCH_REQUIRE_FALSE(p.has_errors());
    1873           1 :             CATCH_REQUIRE(ips.size() == 1);
    1874           1 :             addr::addr_range const & r(ips[0]);
    1875           1 :             addr::addr f(r.get_from());
    1876           1 :             CATCH_REQUIRE(f.is_ipv4());
    1877           1 :             CATCH_REQUIRE(f.get_family() == AF_INET);
    1878           1 :             CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
    1879           3 :             std::string result("172.19.6.91:" + std::to_string(port) + "/32");
    1880           1 :             CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ALL) == result);
    1881           1 :             CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ALL) == result);
    1882           1 :             CATCH_REQUIRE(f.get_port() == port);
    1883           1 :             CATCH_REQUIRE(f.get_protocol() == proto);
    1884           1 :             CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
    1885           1 :             CATCH_REQUIRE(f.is_lan());
    1886           1 :             CATCH_REQUIRE(f.is_lan(true));
    1887           1 :             CATCH_REQUIRE(f.is_lan(false));
    1888           1 :             CATCH_REQUIRE_FALSE(f.is_wan());
    1889           1 :             CATCH_REQUIRE_FALSE(f.is_wan(true));
    1890           1 :             CATCH_REQUIRE_FALSE(f.is_wan(false));
    1891           1 :             CATCH_REQUIRE(f.get_mask_size() == 128);
    1892           1 :         }
    1893           9 :         CATCH_END_SECTION()
    1894             : 
    1895           9 :         CATCH_START_SECTION("addr: empty mask")
    1896             :         {
    1897           1 :             int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
    1898           1 :             int const port(rand() & 0xFFFF);
    1899           1 :             addr::addr_parser p;
    1900           1 :             p.set_protocol(proto);
    1901           1 :             p.set_allow(addr::allow_t::ALLOW_MASK, true);
    1902           4 :             addr::addr_range::vector_t ips(p.parse("172.18.5.91:" + std::to_string(port) + "/"));
    1903           1 :             CATCH_REQUIRE_FALSE(p.has_errors());
    1904           1 :             CATCH_REQUIRE(ips.size() == 1);
    1905           1 :             addr::addr_range const & r(ips[0]);
    1906           1 :             addr::addr f(r.get_from());
    1907           1 :             CATCH_REQUIRE(f.is_ipv4());
    1908           1 :             CATCH_REQUIRE(f.get_family() == AF_INET);
    1909           1 :             CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
    1910           3 :             std::string result("172.18.5.91:" + std::to_string(port) + "/32");
    1911           1 :             CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ALL) == result);
    1912           1 :             CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ALL) == result);
    1913           1 :             CATCH_REQUIRE(f.get_port() == port);
    1914           1 :             CATCH_REQUIRE(f.get_protocol() == proto);
    1915           1 :             CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
    1916           1 :             CATCH_REQUIRE(f.is_lan());
    1917           1 :             CATCH_REQUIRE(f.is_lan(true));
    1918           1 :             CATCH_REQUIRE(f.is_lan(false));
    1919           1 :             CATCH_REQUIRE_FALSE(f.is_wan());
    1920           1 :             CATCH_REQUIRE_FALSE(f.is_wan(true));
    1921           1 :             CATCH_REQUIRE_FALSE(f.is_wan(false));
    1922           1 :             CATCH_REQUIRE(f.get_mask_size() == 128);
    1923           1 :         }
    1924           9 :         CATCH_END_SECTION()
    1925             : 
    1926           9 :         CATCH_START_SECTION("addr: one number masks")
    1927             :         {
    1928          34 :             for(int idx(0); idx <= 32; ++idx)
    1929             :             {
    1930          33 :                 int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
    1931          33 :                 int const port(rand() & 0xFFFF);
    1932          33 :                 addr::addr_parser p;
    1933          33 :                 p.set_protocol(proto);
    1934          33 :                 p.set_allow(addr::allow_t::ALLOW_MASK, true);
    1935         198 :                 addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port) + "/" + std::to_string(idx)));
    1936          33 :                 CATCH_REQUIRE_FALSE(p.has_errors());
    1937          33 :                 CATCH_REQUIRE(ips.size() == 1);
    1938          33 :                 addr::addr_range const & r(ips[0]);
    1939          33 :                 addr::addr f(r.get_from());
    1940          33 :                 CATCH_REQUIRE(f.is_ipv4());
    1941          33 :                 CATCH_REQUIRE(f.get_family() == AF_INET);
    1942          33 :                 CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
    1943             :                 //uint64_t const mask(std::numeric_limits<uint64_t>::max() << (32 - idx));
    1944             :                 //std::string mask_str(
    1945             :                 //          std::to_string((mask >> 24) & 255)
    1946             :                 //        + "."
    1947             :                 //        + std::to_string((mask >> 16) & 255)
    1948             :                 //        + "."
    1949             :                 //        + std::to_string((mask >>  8) & 255)
    1950             :                 //        + "."
    1951             :                 //        + std::to_string((mask >>  0) & 255));
    1952         165 :                 std::string result("172.17.3.91:" + std::to_string(port) + "/" + std::to_string(idx));
    1953          33 :                 CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ALL) == result);
    1954          33 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ALL) == result);
    1955          33 :                 CATCH_REQUIRE(f.get_port() == port);
    1956          33 :                 CATCH_REQUIRE(f.get_protocol() == proto);
    1957          33 :                 CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
    1958          33 :                 CATCH_REQUIRE(f.is_lan());
    1959          33 :                 CATCH_REQUIRE(f.is_lan(true));
    1960          33 :                 CATCH_REQUIRE(f.is_lan(false));
    1961          33 :                 CATCH_REQUIRE_FALSE(f.is_wan());
    1962          33 :                 CATCH_REQUIRE_FALSE(f.is_wan(true));
    1963          33 :                 CATCH_REQUIRE_FALSE(f.is_wan(false));
    1964          33 :                 CATCH_REQUIRE(f.get_mask_size() == 96 + idx);
    1965          33 :             }
    1966             :         }
    1967           9 :         CATCH_END_SECTION()
    1968             : 
    1969           9 :         CATCH_START_SECTION("addr: address like mask")
    1970             :         {
    1971          26 :             for(int idx(0); idx < 25; ++idx)
    1972             :             {
    1973          25 :                 int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
    1974          25 :                 int const port(rand() & 0xFFFF);
    1975          25 :                 addr::addr_parser p;
    1976          25 :                 p.set_protocol(proto);
    1977          25 :                 p.set_allow(addr::allow_t::ALLOW_MASK, true);
    1978          25 :                 p.set_allow(addr::allow_t::ALLOW_ADDRESS_MASK, true);
    1979             :                 // when specified as an IP, the mask can be absolutely anything
    1980          25 :                 uint8_t mask[4];
    1981             :                 do
    1982             :                 {
    1983         125 :                     for(int j(0); j < 4; ++j)
    1984             :                     {
    1985         100 :                         mask[j] = rand();
    1986             :                     }
    1987             :                 }
    1988          25 :                 while(mask[0] == 0      // make sure the mask is no just a number
    1989           0 :                    && mask[1] == 0
    1990           0 :                    && mask[2] == 0
    1991          25 :                    && mask[3] == 0);
    1992          25 :                 switch(mask[0])
    1993             :                 {
    1994           0 :                 case 0xFF:
    1995           0 :                     mask[0] &= ~(1 << (rand() & 7));
    1996           0 :                     break;
    1997             : 
    1998           0 :                 case 0xFE:
    1999             :                 case 0xFC:
    2000             :                 case 0xF8:
    2001             :                 case 0xF0:
    2002             :                 case 0xE0:
    2003             :                 case 0xC0:
    2004           0 :                     mask[0] &= 0x7F;
    2005           0 :                     break;
    2006             : 
    2007           0 :                 case 0x80:
    2008           0 :                     mask[0] |= 1 << (rand() % 6);
    2009           0 :                     break;
    2010             : 
    2011             :                 }
    2012          25 :                 std::string const mask_str(
    2013          50 :                               std::to_string(static_cast<int>(mask[0]))
    2014          75 :                             + "."
    2015         100 :                             + std::to_string(static_cast<int>(mask[1]))
    2016          75 :                             + "."
    2017         100 :                             + std::to_string(static_cast<int>(mask[2]))
    2018          75 :                             + "."
    2019         100 :                             + std::to_string(static_cast<int>(mask[3])));
    2020         150 :                 addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port) + "/" + mask_str));
    2021          25 :                 CATCH_REQUIRE_FALSE(p.has_errors());
    2022          25 :                 CATCH_REQUIRE(ips.size() == 1);
    2023          25 :                 addr::addr_range const & r(ips[0]);
    2024          50 :                 addr::addr f(r.get_from());
    2025          25 :                 CATCH_REQUIRE(f.is_ipv4());
    2026          25 :                 CATCH_REQUIRE(f.get_family() == AF_INET);
    2027          25 :                 CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
    2028         125 :                 std::string result("172.17.3.91:" + std::to_string(port) + "/" + mask_str);
    2029          25 :                 CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ALL) == result);
    2030          25 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ALL) == result);
    2031          25 :                 CATCH_REQUIRE(f.get_port() == port);
    2032          25 :                 CATCH_REQUIRE(f.get_protocol() == proto);
    2033          25 :                 CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
    2034          25 :                 CATCH_REQUIRE(f.is_lan());
    2035          25 :                 CATCH_REQUIRE(f.is_lan(true));
    2036          25 :                 CATCH_REQUIRE(f.is_lan(false));
    2037          25 :                 CATCH_REQUIRE_FALSE(f.is_wan());
    2038          25 :                 CATCH_REQUIRE_FALSE(f.is_wan(true));
    2039          25 :                 CATCH_REQUIRE_FALSE(f.is_wan(false));
    2040             : 
    2041             :                 // above we made sure that the mask was not just a number so
    2042             :                 // here we should always get -1
    2043             :                 //
    2044          25 :                 CATCH_REQUIRE(f.get_mask_size() == -1);
    2045          25 :             }
    2046             :         }
    2047           9 :         CATCH_END_SECTION()
    2048             : 
    2049           9 :         CATCH_START_SECTION("addr: address like mask when not allowed")
    2050             :         {
    2051          26 :             for(int idx(0); idx < 25; ++idx)
    2052             :             {
    2053          25 :                 int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
    2054          25 :                 int const port(rand() & 0xFFFF);
    2055          25 :                 addr::addr_parser p;
    2056          25 :                 p.set_protocol(proto);
    2057          25 :                 p.set_allow(addr::allow_t::ALLOW_MASK, true);
    2058          25 :                 p.set_allow(addr::allow_t::ALLOW_ADDRESS_MASK, false);
    2059             :                 // when specified as an IP, the mask can be absolutely anything
    2060          25 :                 uint8_t mask[4];
    2061             :                 do
    2062             :                 {
    2063         125 :                     for(int j(0); j < 4; ++j)
    2064             :                     {
    2065         100 :                         mask[j] = rand();
    2066             :                     }
    2067             :                 }
    2068          25 :                 while(mask[0] == 0      // make sure the mask is no just a number
    2069           0 :                    && mask[1] == 0
    2070           0 :                    && mask[2] == 0
    2071          25 :                    && mask[3] == 0);
    2072          25 :                 switch(mask[0])
    2073             :                 {
    2074           0 :                 case 0xFF:
    2075           0 :                     mask[0] &= ~(1 << (rand() & 7));
    2076           0 :                     break;
    2077             : 
    2078           1 :                 case 0xFE:
    2079             :                 case 0xFC:
    2080             :                 case 0xF8:
    2081             :                 case 0xF0:
    2082             :                 case 0xE0:
    2083             :                 case 0xC0:
    2084           1 :                     mask[0] &= 0x7F;
    2085           1 :                     break;
    2086             : 
    2087           0 :                 case 0x80:
    2088           0 :                     mask[0] |= 1 << (rand() % 6);
    2089           0 :                     break;
    2090             : 
    2091             :                 }
    2092          25 :                 std::string const mask_str(
    2093          50 :                               std::to_string(static_cast<int>(mask[0]))
    2094          75 :                             + "."
    2095         100 :                             + std::to_string(static_cast<int>(mask[1]))
    2096          75 :                             + "."
    2097         100 :                             + std::to_string(static_cast<int>(mask[2]))
    2098          75 :                             + "."
    2099         100 :                             + std::to_string(static_cast<int>(mask[3])));
    2100         150 :                 addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port) + "/" + mask_str));
    2101          25 :                 CATCH_REQUIRE(p.has_errors());
    2102          25 :                 CATCH_REQUIRE(ips.size() == 0);
    2103          25 :             }
    2104             :         }
    2105           9 :         CATCH_END_SECTION()
    2106             : 
    2107           9 :         CATCH_START_SECTION("addr: address like default mask")
    2108             :         {
    2109          26 :             for(int idx(0); idx < 25; ++idx)
    2110             :             {
    2111          25 :                 int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
    2112          25 :                 int const port(rand() & 0xFFFF);
    2113          25 :                 addr::addr_parser p;
    2114          25 :                 p.set_protocol(proto);
    2115          25 :                 p.set_allow(addr::allow_t::ALLOW_MASK, true);
    2116          25 :                 p.set_allow(addr::allow_t::ALLOW_ADDRESS_MASK, true);
    2117             :                 // when specified as an IP, the mask can be absolutely anything
    2118             :                 // (here the mask is a string an it will be parsed by the
    2119             :                 // parser if required)
    2120             :                 //
    2121          25 :                 uint8_t mask[4];
    2122         125 :                 for(int j(0); j < 4; ++j)
    2123             :                 {
    2124         100 :                     mask[j] = rand();
    2125             :                 }
    2126          25 :                 std::string const mask_str(
    2127          50 :                               std::to_string(static_cast<int>(mask[0]))
    2128          75 :                             + "."
    2129         100 :                             + std::to_string(static_cast<int>(mask[1]))
    2130          75 :                             + "."
    2131         100 :                             + std::to_string(static_cast<int>(mask[2]))
    2132          75 :                             + "."
    2133          75 :                             + std::to_string(static_cast<int>(mask[3])));
    2134          25 :                 p.set_default_mask(mask_str);
    2135          75 :                 addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port)));
    2136          25 :                 CATCH_REQUIRE_FALSE(p.has_errors());
    2137          25 :                 CATCH_REQUIRE(ips.size() == 1);
    2138          25 :                 addr::addr_range const & r(ips[0]);
    2139          25 :                 addr::addr f(r.get_from());
    2140          25 :                 CATCH_REQUIRE(f.is_ipv4());
    2141          25 :                 CATCH_REQUIRE(f.get_family() == AF_INET);
    2142          25 :                 CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
    2143         100 :                 std::string result("172.17.3.91:" + std::to_string(port) + "/" + mask_str);
    2144          25 :                 CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ALL) == result);
    2145          25 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ALL) == result);
    2146          25 :                 CATCH_REQUIRE(f.get_port() == port);
    2147          25 :                 CATCH_REQUIRE(f.get_protocol() == proto);
    2148          25 :                 CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
    2149          25 :                 CATCH_REQUIRE(f.is_lan());
    2150          25 :                 CATCH_REQUIRE(f.is_lan(true));
    2151          25 :                 CATCH_REQUIRE(f.is_lan(false));
    2152          25 :                 CATCH_REQUIRE_FALSE(f.is_wan());
    2153          25 :                 CATCH_REQUIRE_FALSE(f.is_wan(true));
    2154          25 :                 CATCH_REQUIRE_FALSE(f.is_wan(false));
    2155          25 :                 uint8_t verify_mask[16];
    2156          25 :                 f.get_mask(verify_mask);
    2157         325 :                 for(int j(0); j < 16 - 4; ++j)
    2158             :                 {
    2159         300 :                     CATCH_REQUIRE(verify_mask[j] == 255);
    2160             :                 }
    2161         125 :                 for(int j(12); j < 16; ++j)
    2162             :                 {
    2163         100 :                     CATCH_REQUIRE(verify_mask[j] == mask[j - 12]);
    2164             :                 }
    2165          25 :             }
    2166             :         }
    2167           9 :         CATCH_END_SECTION()
    2168             : 
    2169           9 :         CATCH_START_SECTION("addr: address like mask with a default")
    2170             :         {
    2171          26 :             for(int idx(0); idx < 25; ++idx)
    2172             :             {
    2173          25 :                 int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
    2174          25 :                 int const port(rand() & 0xFFFF);
    2175          25 :                 addr::addr_parser p;
    2176          25 :                 p.set_protocol(proto);
    2177          25 :                 p.set_allow(addr::allow_t::ALLOW_MASK, true);
    2178          25 :                 p.set_allow(addr::allow_t::ALLOW_ADDRESS_MASK, true);
    2179             : 
    2180             :                 // here we want a default and an IP with a specific mask
    2181             :                 // to make sure that the specific mask has priority
    2182             :                 //
    2183          25 :                 uint8_t mask[4];
    2184         125 :                 for(int j(0); j < 4; ++j)
    2185             :                 {
    2186         100 :                     mask[j] = rand();
    2187             :                 }
    2188          25 :                 std::string const mask_str(
    2189          50 :                               std::to_string(static_cast<int>(mask[0]))
    2190          75 :                             + "."
    2191         100 :                             + std::to_string(static_cast<int>(mask[1]))
    2192          75 :                             + "."
    2193         100 :                             + std::to_string(static_cast<int>(mask[2]))
    2194          75 :                             + "."
    2195          75 :                             + std::to_string(static_cast<int>(mask[3])));
    2196             : 
    2197          25 :                 uint8_t default_mask[4];
    2198         125 :                 for(int j(0); j < 4; ++j)
    2199             :                 {
    2200         100 :                     default_mask[j] = rand();
    2201             :                 }
    2202          25 :                 std::string const default_mask_str(
    2203          50 :                               std::to_string(static_cast<int>(default_mask[0]))
    2204          75 :                             + "."
    2205         100 :                             + std::to_string(static_cast<int>(default_mask[1]))
    2206          75 :                             + "."
    2207         100 :                             + std::to_string(static_cast<int>(default_mask[2]))
    2208          75 :                             + "."
    2209          75 :                             + std::to_string(static_cast<int>(default_mask[3])));
    2210          25 :                 p.set_default_mask(default_mask_str);
    2211             : 
    2212         125 :                 addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port) + "/" + mask_str));
    2213          25 :                 CATCH_REQUIRE_FALSE(p.has_errors());
    2214          25 :                 CATCH_REQUIRE(ips.size() == 1);
    2215          25 :                 addr::addr_range const & r(ips[0]);
    2216          25 :                 addr::addr f(r.get_from());
    2217          25 :                 CATCH_REQUIRE(f.is_ipv4());
    2218          25 :                 CATCH_REQUIRE(f.get_family() == AF_INET);
    2219          25 :                 CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
    2220         100 :                 std::string result("172.17.3.91:" + std::to_string(port) + "/" + mask_str);
    2221          25 :                 CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ALL) == result);
    2222          25 :                 CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ALL) == result);
    2223          25 :                 CATCH_REQUIRE(f.get_port() == port);
    2224          25 :                 CATCH_REQUIRE(f.get_protocol() == proto);
    2225          25 :                 CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
    2226          25 :                 CATCH_REQUIRE(f.is_lan());
    2227          25 :                 CATCH_REQUIRE(f.is_lan(true));
    2228          25 :                 CATCH_REQUIRE(f.is_lan(false));
    2229          25 :                 CATCH_REQUIRE_FALSE(f.is_wan());
    2230          25 :                 CATCH_REQUIRE_FALSE(f.is_wan(true));
    2231          25 :                 CATCH_REQUIRE_FALSE(f.is_wan(false));
    2232          25 :                 uint8_t verify_mask[16];
    2233          25 :                 f.get_mask(verify_mask);
    2234         325 :                 for(int j(0); j < 16 - 4; ++j)
    2235             :                 {
    2236         300 :                     CATCH_REQUIRE(verify_mask[j] == 255);
    2237             :                 }
    2238         125 :                 for(int j(12); j < 16; ++j)
    2239             :                 {
    2240         100 :                     CATCH_REQUIRE(verify_mask[j] == mask[j - 12]);
    2241             :                 }
    2242          25 :             }
    2243             :         }
    2244           9 :         CATCH_END_SECTION()
    2245             : 
    2246           9 :         CATCH_START_SECTION("addr: address like default mask")
    2247             :         {
    2248          26 :             for(int idx(0); idx < 25; ++idx)
    2249             :             {
    2250          25 :                 int const proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
    2251          25 :                 int const port(rand() & 0xFFFF);
    2252          25 :                 addr::addr_parser p;
    2253          25 :                 p.set_protocol(proto);
    2254          25 :                 p.set_allow(addr::allow_t::ALLOW_MASK, true);
    2255             : 
    2256             :                 //p.set_allow(addr::allow_t::ALLOW_ADDRESS_MASK, true); -- if we forget this one, the parsing fails with an error
    2257             : 
    2258             :                 // when specified as an IP, the mask can be absolutely anything
    2259             :                 // (here the mask is a string an it will be parsed by the
    2260             :                 // parser if required)
    2261             :                 //
    2262          25 :                 uint8_t mask[4];
    2263         125 :                 for(int j(0); j < 4; ++j)
    2264             :                 {
    2265         100 :                     mask[j] = rand();
    2266             :                 }
    2267          25 :                 std::string const mask_str(
    2268          50 :                               std::to_string(static_cast<int>(mask[0]))
    2269          75 :                             + "."
    2270         100 :                             + std::to_string(static_cast<int>(mask[1]))
    2271          75 :                             + "."
    2272         100 :                             + std::to_string(static_cast<int>(mask[2]))
    2273          75 :                             + "."
    2274          75 :                             + std::to_string(static_cast<int>(mask[3])));
    2275          25 :                 p.set_default_mask(mask_str);
    2276          75 :                 addr::addr_range::vector_t ips(p.parse("172.17.3.91:" + std::to_string(port)));
    2277          25 :                 CATCH_REQUIRE(p.has_errors());
    2278          25 :                 CATCH_REQUIRE(ips.size() == 0);
    2279          25 :             }
    2280             :         }
    2281           9 :         CATCH_END_SECTION()
    2282             : 
    2283           9 :         CATCH_START_SECTION("addr: two addresses and a mask for a match / no match")
    2284             :         {
    2285           1 :             int const port1(rand() & 0xFFFF);
    2286           1 :             addr::addr_parser p;
    2287           1 :             p.set_allow(addr::allow_t::ALLOW_MASK, true);
    2288             : 
    2289             :             // parse the IP with a mask
    2290             :             //
    2291           1 :             int proto(rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP);
    2292           1 :             p.set_protocol(proto);
    2293           4 :             addr::addr_range::vector_t ips1(p.parse("192.168.0.0:" + std::to_string(port1) + "/16"));
    2294           1 :             CATCH_REQUIRE_FALSE(p.has_errors());
    2295           1 :             CATCH_REQUIRE(ips1.size() == 1);
    2296           1 :             addr::addr_range const & r1(ips1[0]);
    2297           1 :             addr::addr f1(r1.get_from());
    2298           1 :             CATCH_REQUIRE(f1.is_ipv4());
    2299           1 :             CATCH_REQUIRE(f1.get_family() == AF_INET);
    2300           1 :             CATCH_REQUIRE_FALSE(f1.get_family() == AF_INET6);
    2301           1 :             CATCH_REQUIRE(f1.to_ipv4_string(addr::STRING_IP_ALL) == "192.168.0.0:" + std::to_string(port1) + "/16");
    2302           1 :             CATCH_REQUIRE(f1.to_ipv4or6_string(addr::STRING_IP_ALL) == "192.168.0.0:" + std::to_string(port1) + "/16");
    2303           1 :             CATCH_REQUIRE(f1.get_port() == port1);
    2304           1 :             CATCH_REQUIRE(f1.get_protocol() == proto);
    2305           1 :             CATCH_REQUIRE(f1.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
    2306           1 :             CATCH_REQUIRE(f1.is_lan());
    2307           1 :             CATCH_REQUIRE(f1.is_lan(true));
    2308           1 :             CATCH_REQUIRE(f1.is_lan(false));
    2309           1 :             CATCH_REQUIRE_FALSE(f1.is_wan());
    2310           1 :             CATCH_REQUIRE_FALSE(f1.is_wan(true));
    2311           1 :             CATCH_REQUIRE_FALSE(f1.is_wan(false));
    2312             : 
    2313             :             // reuse parser
    2314             :             //
    2315           1 :             proto = rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP;
    2316           1 :             p.set_protocol(proto);
    2317           1 :             int const port2(rand() & 0xFFFF);
    2318           3 :             addr::addr_range::vector_t ips2(p.parse("192.168.5.36:" + std::to_string(port2)));
    2319           1 :             CATCH_REQUIRE_FALSE(p.has_errors());
    2320           1 :             CATCH_REQUIRE(ips2.size() == 1);
    2321           1 :             addr::addr_range const & r2(ips2[0]);
    2322           1 :             addr::addr f2(r2.get_from());
    2323           1 :             CATCH_REQUIRE(f2.is_ipv4());
    2324           1 :             CATCH_REQUIRE(f2.get_family() == AF_INET);
    2325           1 :             CATCH_REQUIRE_FALSE(f2.get_family() == AF_INET6);
    2326           1 :             CATCH_REQUIRE(f2.to_ipv4_string(addr::STRING_IP_ALL) == "192.168.5.36:" + std::to_string(port2) + "/32");
    2327           1 :             CATCH_REQUIRE(f2.to_ipv4or6_string(addr::STRING_IP_ALL) == "192.168.5.36:" + std::to_string(port2) + "/32");
    2328           1 :             CATCH_REQUIRE(f2.get_port() == port2);
    2329           1 :             CATCH_REQUIRE(f2.get_protocol() == proto);
    2330           1 :             CATCH_REQUIRE(f2.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
    2331           1 :             CATCH_REQUIRE(f2.is_lan());
    2332           1 :             CATCH_REQUIRE(f2.is_lan(true));
    2333           1 :             CATCH_REQUIRE(f2.is_lan(false));
    2334           1 :             CATCH_REQUIRE_FALSE(f2.is_wan());
    2335           1 :             CATCH_REQUIRE_FALSE(f2.is_wan(true));
    2336           1 :             CATCH_REQUIRE_FALSE(f2.is_wan(false));
    2337             : 
    2338             :             // 3rd with a mask along the full IP
    2339             :             //
    2340           1 :             proto = rand() & 1 ? IPPROTO_TCP : IPPROTO_UDP;
    2341           1 :             p.set_protocol(proto);
    2342           1 :             int const port3(rand() & 0xFFFF);
    2343           4 :             addr::addr_range::vector_t ips3(p.parse("192.168.5.36:" + std::to_string(port3) + "/16"));
    2344           1 :             CATCH_REQUIRE_FALSE(p.has_errors());
    2345           1 :             CATCH_REQUIRE(ips3.size() == 1);
    2346           1 :             addr::addr_range const & r3(ips3[0]);
    2347           1 :             addr::addr f3(r3.get_from());
    2348           1 :             CATCH_REQUIRE(f3.is_ipv4());
    2349           1 :             CATCH_REQUIRE(f3.get_family() == AF_INET);
    2350           1 :             CATCH_REQUIRE_FALSE(f3.get_family() == AF_INET6);
    2351           1 :             CATCH_REQUIRE(f3.to_ipv4_string(addr::STRING_IP_ALL) == "192.168.5.36:" + std::to_string(port3) + "/16");
    2352           1 :             CATCH_REQUIRE(f3.to_ipv4or6_string(addr::STRING_IP_ALL) == "192.168.5.36:" + std::to_string(port3) + "/16");
    2353           1 :             CATCH_REQUIRE(f3.get_port() == port3);
    2354           1 :             CATCH_REQUIRE(f3.get_protocol() == proto);
    2355           1 :             CATCH_REQUIRE(f3.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
    2356           1 :             CATCH_REQUIRE(f3.is_lan());
    2357           1 :             CATCH_REQUIRE(f3.is_lan(true));
    2358           1 :             CATCH_REQUIRE(f3.is_lan(false));
    2359           1 :             CATCH_REQUIRE_FALSE(f3.is_wan());
    2360           1 :             CATCH_REQUIRE_FALSE(f3.is_wan(true));
    2361           1 :             CATCH_REQUIRE_FALSE(f3.is_wan(false));
    2362             : 
    2363             :             // just a side test
    2364             :             //
    2365           1 :             CATCH_REQUIRE(f1 != f2);
    2366           1 :             CATCH_REQUIRE(f1 != f3);
    2367           1 :             CATCH_REQUIRE(f2 == f3);
    2368             : 
    2369             :             // check whether p1 matches p2 and vice versa
    2370             :             //
    2371           1 :             CATCH_REQUIRE(f1.match(f2));          // f2 & mask1 == f1 & mask1
    2372           1 :             CATCH_REQUIRE(f1.match(f3));          // f3 & mask1 == f1 & mask1
    2373             : 
    2374           1 :             CATCH_REQUIRE_FALSE(f2.match(f1));    // f1 & mask2 != f2 & mask2
    2375           1 :             CATCH_REQUIRE(f2.match(f3));          // f3 & mask2 == f2 & mask2  (because f2 == f3 anyway)
    2376             : 
    2377           1 :             CATCH_REQUIRE(f3.match(f1));          // f1 & mask3 == f3 & mask3
    2378           1 :             CATCH_REQUIRE(f3.match(f2));          // f2 & mask3 == f3 & mask3
    2379             : 
    2380           1 :             f3.apply_mask();
    2381             : 
    2382           1 :             CATCH_REQUIRE(f1 != f2);
    2383           1 :             CATCH_REQUIRE(f1 == f3);
    2384           1 :             CATCH_REQUIRE(f2 != f3);
    2385             : 
    2386             :             // re-run the match() calls with f3 since it changed...
    2387             :             //
    2388           1 :             CATCH_REQUIRE(f1.match(f3));          // f3 & mask1 == f1 & mask1
    2389             : 
    2390           1 :             CATCH_REQUIRE_FALSE(f2.match(f3));    // f3 & mask2 == f2 & mask2  (because f2 != f3 anymore)
    2391             : 
    2392           1 :             CATCH_REQUIRE(f3.match(f1));          // f1 & mask3 == f3 & mask3
    2393           1 :             CATCH_REQUIRE(f3.match(f2));          // f2 & mask3 == f3 & mask3
    2394             : 
    2395           1 :             addr::addr fa; // by default an address is ANY and it matches everything
    2396           1 :             CATCH_REQUIRE(fa.match(f1, true));
    2397           1 :             CATCH_REQUIRE(fa.match(f2, true));
    2398           1 :             CATCH_REQUIRE(fa.match(f3, true));
    2399           1 :             std::uint8_t const verify_match[16] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 };
    2400           1 :             std::uint8_t any_mask[16] = {};
    2401           1 :             fa.get_mask(any_mask);
    2402           1 :             CATCH_REQUIRE(memcmp(verify_match, any_mask, 16) == 0);
    2403           1 :         }
    2404           9 :         CATCH_END_SECTION()
    2405           9 :     }
    2406           9 : }
    2407             : 
    2408             : 
    2409           6 : CATCH_TEST_CASE("ipv4::protocol", "[ipv4]")
    2410             : {
    2411           6 :     CATCH_GIVEN("addr()")
    2412             :     {
    2413           2 :         addr::addr a;
    2414             : 
    2415           2 :         CATCH_START_SECTION("addr: default protocol")
    2416             :         {
    2417           1 :             CATCH_REQUIRE(a.get_protocol() == IPPROTO_TCP);
    2418             :         }
    2419           2 :         CATCH_END_SECTION()
    2420             : 
    2421           2 :         CATCH_START_SECTION("addr: set_protocol()")
    2422             :         {
    2423             :             // setup a random protocol
    2424             :             //
    2425           1 :             int const start_protocol([]()
    2426             :                 {
    2427           1 :                     switch(rand() % 3)
    2428             :                     {
    2429           0 :                     case 0:
    2430           0 :                         return IPPROTO_IP;
    2431             : 
    2432           0 :                     case 1:
    2433           0 :                         return IPPROTO_TCP;
    2434             : 
    2435             :                     //case 2:
    2436           1 :                     default:
    2437           1 :                         return IPPROTO_UDP;
    2438             : 
    2439             :                     }
    2440           1 :                 }());
    2441           1 :             a.set_protocol(start_protocol);
    2442             : 
    2443             :             // test 100 invalid protocols
    2444             :             //
    2445         101 :             for(int idx(0); idx < 100; ++idx)
    2446             :             {
    2447             :                 int invalid_protocol;
    2448             :                 do
    2449             :                 {
    2450         100 :                     invalid_protocol = rand();
    2451             :                 }
    2452             :                 while(invalid_protocol == IPPROTO_IP
    2453         100 :                    || invalid_protocol == IPPROTO_TCP
    2454         200 :                    || invalid_protocol == IPPROTO_UDP);
    2455         100 :                 CATCH_REQUIRE_THROWS_AS(a.set_protocol(invalid_protocol), addr::addr_invalid_argument);
    2456             : 
    2457             :                 // make sure the protocol does not change on errors
    2458         100 :                 CATCH_REQUIRE(a.get_protocol() == start_protocol);
    2459             :             }
    2460             : 
    2461             :             // null string is not allowed
    2462             :             //
    2463           1 :             CATCH_REQUIRE_THROWS_AS(a.set_protocol(nullptr), addr::addr_invalid_argument);
    2464             : 
    2465             :             // other "invalid" (unsupported, really) string protocols
    2466             :             //
    2467           1 :             CATCH_REQUIRE_THROWS_AS(a.set_protocol("unknown"), addr::addr_invalid_argument);
    2468           1 :             CATCH_REQUIRE_THROWS_AS(a.set_protocol("invalid"), addr::addr_invalid_argument);
    2469           1 :             CATCH_REQUIRE_THROWS_AS(a.set_protocol("other"), addr::addr_invalid_argument);
    2470             : 
    2471             :             // test all valid protocols (numeric)
    2472             :             //
    2473           1 :             a.set_protocol(IPPROTO_IP);
    2474           1 :             CATCH_REQUIRE(a.get_protocol() == IPPROTO_IP);
    2475           1 :             a.set_protocol(IPPROTO_TCP);
    2476           1 :             CATCH_REQUIRE(a.get_protocol() == IPPROTO_TCP);
    2477           1 :             a.set_protocol(IPPROTO_UDP);
    2478           1 :             CATCH_REQUIRE(a.get_protocol() == IPPROTO_UDP);
    2479             : 
    2480             :             // test all valid protocols (ascii)
    2481             :             //
    2482           1 :             a.set_protocol("ip");
    2483           1 :             CATCH_REQUIRE(a.get_protocol() == IPPROTO_IP);
    2484           1 :             a.set_protocol("tcp");
    2485           1 :             CATCH_REQUIRE(a.get_protocol() == IPPROTO_TCP);
    2486           1 :             a.set_protocol("udp");
    2487           1 :             CATCH_REQUIRE(a.get_protocol() == IPPROTO_UDP);
    2488             :         }
    2489           2 :         CATCH_END_SECTION()
    2490           8 :     }
    2491             : 
    2492           6 :     CATCH_GIVEN("addr_parser()")
    2493             :     {
    2494           3 :         addr::addr_parser p;
    2495             : 
    2496           3 :         CATCH_START_SECTION("addr: verify default")
    2497             :         {
    2498           1 :             CATCH_REQUIRE(p.get_protocol() == -1);
    2499             :         }
    2500           3 :         CATCH_END_SECTION()
    2501             : 
    2502           3 :         CATCH_START_SECTION("addr: test 3 allowed protocols")
    2503             :         {
    2504             :             // by string
    2505             :             //
    2506           1 :             p.set_protocol("ip");
    2507           1 :             CATCH_REQUIRE(p.get_protocol() == IPPROTO_IP);
    2508           1 :             p.set_protocol("tcp");
    2509           1 :             CATCH_REQUIRE(p.get_protocol() == IPPROTO_TCP);
    2510           1 :             p.set_protocol("udp");
    2511           1 :             CATCH_REQUIRE(p.get_protocol() == IPPROTO_UDP);
    2512             : 
    2513             :             // numerically
    2514             :             //
    2515           1 :             p.set_protocol(IPPROTO_IP);
    2516           1 :             CATCH_REQUIRE(p.get_protocol() == IPPROTO_IP);
    2517           1 :             p.set_protocol(IPPROTO_TCP);
    2518           1 :             CATCH_REQUIRE(p.get_protocol() == IPPROTO_TCP);
    2519           1 :             p.set_protocol(IPPROTO_UDP);
    2520           1 :             CATCH_REQUIRE(p.get_protocol() == IPPROTO_UDP);
    2521             :         }
    2522           3 :         CATCH_END_SECTION()
    2523             : 
    2524           3 :         CATCH_START_SECTION("addr: verify clearing works")
    2525             :         {
    2526           1 :             p.set_protocol("ip");
    2527           1 :             CATCH_REQUIRE(p.get_protocol() == IPPROTO_IP);
    2528           1 :             p.clear_protocol();
    2529           1 :             CATCH_REQUIRE(p.get_protocol() == -1);
    2530             : 
    2531           1 :             p.set_protocol("tcp");
    2532           1 :             CATCH_REQUIRE(p.get_protocol() == IPPROTO_TCP);
    2533           1 :             p.clear_protocol();
    2534           1 :             CATCH_REQUIRE(p.get_protocol() == -1);
    2535             : 
    2536           1 :             p.set_protocol("udp");
    2537           1 :             CATCH_REQUIRE(p.get_protocol() == IPPROTO_UDP);
    2538           1 :             p.clear_protocol();
    2539           1 :             CATCH_REQUIRE(p.get_protocol() == -1);
    2540             :         }
    2541           3 :         CATCH_END_SECTION()
    2542           9 :     }
    2543             : 
    2544           6 :     CATCH_GIVEN("addr_parser with any protocol")
    2545             :     {
    2546           1 :         addr::addr a;
    2547             : 
    2548           1 :         CATCH_START_SECTION("addr: get address with all protocols")
    2549             :         {
    2550           1 :             addr::addr_parser p;
    2551             :             //p.set_protocol(...); -- by default we'll get all the protocols supported
    2552           3 :             addr::addr_range::vector_t ips(p.parse("127.0.0.1"));
    2553           1 :             CATCH_REQUIRE_FALSE(p.has_errors());
    2554           1 :             CATCH_REQUIRE(!ips.empty());
    2555           4 :             for(size_t idx(0); idx < ips.size(); ++idx)
    2556             :             {
    2557           3 :                 addr::addr_range const & r(ips[idx]);
    2558           3 :                 CATCH_REQUIRE(r.has_from());
    2559           3 :                 CATCH_REQUIRE_FALSE(r.has_to());
    2560           3 :                 CATCH_REQUIRE_FALSE(r.is_range());
    2561           3 :                 CATCH_REQUIRE_FALSE(r.is_empty());
    2562           3 :                 addr::addr f(r.get_from());
    2563           3 :                 if(f.is_ipv4())
    2564             :                 {
    2565           3 :                     CATCH_REQUIRE(f.get_family() == AF_INET);
    2566           3 :                     CATCH_REQUIRE_FALSE(f.get_family() == AF_INET6);
    2567           3 :                     CATCH_REQUIRE(f.to_ipv4_string(addr::STRING_IP_ADDRESS) == "127.0.0.1");
    2568           3 :                     CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "127.0.0.1");
    2569           3 :                     CATCH_REQUIRE(f.get_port() == 0);
    2570             :                     //CATCH_REQUIRE(f.get_protocol() == ...); -- may be TCP, UDP, IP
    2571           3 :                     CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_LOOPBACK);
    2572           3 :                     CATCH_REQUIRE(f.is_lan());
    2573           3 :                     CATCH_REQUIRE(f.is_lan(true));
    2574           3 :                     CATCH_REQUIRE(f.is_lan(false));
    2575           3 :                     CATCH_REQUIRE_FALSE(f.is_wan());
    2576           3 :                     CATCH_REQUIRE_FALSE(f.is_wan(true));
    2577           3 :                     CATCH_REQUIRE_FALSE(f.is_wan(false));
    2578             :                 }
    2579             :                 else
    2580             :                 {
    2581           0 :                     CATCH_REQUIRE_FALSE(f.get_family() == AF_INET);
    2582           0 :                     CATCH_REQUIRE(f.get_family() == AF_INET6);
    2583           0 :                     CATCH_REQUIRE(f.to_ipv6_string(addr::STRING_IP_ADDRESS) == "::1");
    2584           0 :                     CATCH_REQUIRE(f.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "::1");
    2585           0 :                     CATCH_REQUIRE(f.get_port() == 0);
    2586             :                     //CATCH_REQUIRE(f.get_protocol() == ...); -- may be TCP, UDP, IP
    2587           0 :                     CATCH_REQUIRE(f.get_network_type() == addr::network_type_t::NETWORK_TYPE_LOOPBACK);
    2588           0 :                     CATCH_REQUIRE(f.is_lan());
    2589           0 :                     CATCH_REQUIRE(f.is_lan(true));
    2590           0 :                     CATCH_REQUIRE(f.is_lan(false));
    2591           0 :                     CATCH_REQUIRE_FALSE(f.is_wan());
    2592           0 :                     CATCH_REQUIRE_FALSE(f.is_wan(true));
    2593           0 :                     CATCH_REQUIRE_FALSE(f.is_wan(false));
    2594             :                 }
    2595           3 :             }
    2596           1 :         }
    2597           1 :         CATCH_END_SECTION()
    2598           7 :     }
    2599           6 : }
    2600             : 
    2601             : 
    2602           8 : CATCH_TEST_CASE("ipv4::network_type", "[ipv4]")
    2603             : {
    2604           8 :     CATCH_GIVEN("addr()")
    2605             :     {
    2606           8 :         addr::addr a;
    2607             : 
    2608           8 :         CATCH_START_SECTION("addr: any (0.0.0.0)")
    2609             :         {
    2610           1 :             struct sockaddr_in in = sockaddr_in();
    2611           1 :             in.sin_family = AF_INET;
    2612           1 :             in.sin_port = htons(rand());
    2613           1 :             in.sin_addr.s_addr = 0;
    2614             : 
    2615             :             // verify network type
    2616             :             //
    2617           1 :             a.set_ipv4(in);
    2618             : 
    2619           1 :             CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_ANY);
    2620           1 :             CATCH_REQUIRE(a.get_network_type_string() == "Any");
    2621           1 :             CATCH_REQUIRE_FALSE(a.is_lan());
    2622           1 :             CATCH_REQUIRE_FALSE(a.is_lan(true));
    2623           1 :             CATCH_REQUIRE_FALSE(a.is_lan(false));
    2624           1 :             CATCH_REQUIRE(a.is_wan());
    2625           1 :             CATCH_REQUIRE(a.is_wan(true));
    2626           1 :             CATCH_REQUIRE_FALSE(a.is_wan(false));
    2627             :         }
    2628           8 :         CATCH_END_SECTION()
    2629             : 
    2630           8 :         CATCH_START_SECTION("addr: private address 10.x.x.x/8")
    2631             :         {
    2632          11 :             for(int idx(0); idx < 10; ++idx)
    2633             :             {
    2634          10 :                 struct sockaddr_in in = sockaddr_in();
    2635          10 :                 in.sin_family = AF_INET;
    2636          10 :                 in.sin_port = htons(rand());
    2637             :                 uint32_t address((10 << 24)
    2638          10 :                               | ((rand() & 255) << 16)
    2639          10 :                               | ((rand() & 255) << 8)
    2640          10 :                               | ((rand() & 255) << 0));
    2641          10 :                 in.sin_addr.s_addr = htonl(address);
    2642             : 
    2643             :                 // verify network type
    2644             :                 //
    2645          10 :                 a.set_ipv4(in);
    2646          10 :                 CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
    2647          10 :                 CATCH_REQUIRE(a.get_network_type_string() == "Private");
    2648          10 :                 CATCH_REQUIRE(a.is_lan());
    2649          10 :                 CATCH_REQUIRE(a.is_lan(true));
    2650          10 :                 CATCH_REQUIRE(a.is_lan(false));
    2651          10 :                 CATCH_REQUIRE_FALSE(a.is_wan());
    2652          10 :                 CATCH_REQUIRE_FALSE(a.is_wan(true));
    2653          10 :                 CATCH_REQUIRE_FALSE(a.is_wan(false));
    2654             :             }
    2655             :         }
    2656           8 :         CATCH_END_SECTION()
    2657             : 
    2658           8 :         CATCH_START_SECTION("addr: private address 172.16.x.x/12")
    2659             :         {
    2660          11 :             for(int idx(0); idx < 10; ++idx)
    2661             :             {
    2662          10 :                 struct sockaddr_in in = sockaddr_in();
    2663          10 :                 in.sin_family = AF_INET;
    2664          10 :                 in.sin_port = htons(rand());
    2665             :                 uint32_t address((172 << 24)
    2666          10 :                               | (((rand() & 15) | 16) << 16)
    2667          10 :                               | ((rand() & 255) << 8)
    2668          10 :                               | ((rand() & 255) << 0));
    2669          10 :                 in.sin_addr.s_addr = htonl(address);
    2670             : 
    2671             :                 // verify network type
    2672             :                 //
    2673          10 :                 a.set_ipv4(in);
    2674          10 :                 CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
    2675          10 :                 CATCH_REQUIRE(a.get_network_type_string() == "Private");
    2676          10 :                 CATCH_REQUIRE(a.is_lan());
    2677          10 :                 CATCH_REQUIRE(a.is_lan(true));
    2678          10 :                 CATCH_REQUIRE(a.is_lan(false));
    2679          10 :                 CATCH_REQUIRE_FALSE(a.is_wan());
    2680          10 :                 CATCH_REQUIRE_FALSE(a.is_wan(true));
    2681          10 :                 CATCH_REQUIRE_FALSE(a.is_wan(false));
    2682             :             }
    2683             :         }
    2684           8 :         CATCH_END_SECTION()
    2685             : 
    2686           8 :         CATCH_START_SECTION("addr: private address 192.168.x.x/16")
    2687             :         {
    2688          11 :             for(int idx(0); idx < 10; ++idx)
    2689             :             {
    2690          10 :                 struct sockaddr_in in = sockaddr_in();
    2691          10 :                 in.sin_family = AF_INET;
    2692          10 :                 in.sin_port = htons(rand());
    2693             :                 uint32_t address((192 << 24)
    2694             :                               |  (168 << 16)
    2695          10 :                               | ((rand() & 255) << 8)
    2696          10 :                               | ((rand() & 255) << 0));
    2697          10 :                 in.sin_addr.s_addr = htonl(address);
    2698             : 
    2699             :                 // verify network type
    2700             :                 //
    2701          10 :                 a.set_ipv4(in);
    2702          10 :                 CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_PRIVATE);
    2703          10 :                 CATCH_REQUIRE(a.get_network_type_string() == "Private");
    2704          10 :                 CATCH_REQUIRE(a.is_lan());
    2705          10 :                 CATCH_REQUIRE(a.is_lan(true));
    2706          10 :                 CATCH_REQUIRE(a.is_lan(false));
    2707          10 :                 CATCH_REQUIRE_FALSE(a.is_wan());
    2708          10 :                 CATCH_REQUIRE_FALSE(a.is_wan(true));
    2709          10 :                 CATCH_REQUIRE_FALSE(a.is_wan(false));
    2710             :             }
    2711             :         }
    2712           8 :         CATCH_END_SECTION()
    2713             : 
    2714           8 :         CATCH_START_SECTION("addr: private address 100.66.x.x/10")
    2715             :         {
    2716          11 :             for(int idx(0); idx < 10; ++idx)
    2717             :             {
    2718          10 :                 struct sockaddr_in in = sockaddr_in();
    2719          10 :                 in.sin_family = AF_INET;
    2720          10 :                 in.sin_port = htons(rand());
    2721             :                 uint32_t address((100 << 24)
    2722          10 :                               | (((rand() & 63) | 64) << 16)
    2723          10 :                               | ((rand() & 255) << 8)
    2724          10 :                               | ((rand() & 255) << 0));
    2725          10 :                 in.sin_addr.s_addr = htonl(address);
    2726             : 
    2727             :                 // verify network type
    2728             :                 //
    2729          10 :                 a.set_ipv4(in);
    2730          10 :                 CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_CARRIER);
    2731          10 :                 CATCH_REQUIRE(a.get_network_type_string() == "Carrier");
    2732          10 :                 CATCH_REQUIRE_FALSE(a.is_lan());
    2733          10 :                 CATCH_REQUIRE(a.is_lan(true));
    2734          10 :                 CATCH_REQUIRE_FALSE(a.is_lan(false));
    2735          10 :                 CATCH_REQUIRE_FALSE(a.is_wan());
    2736          10 :                 CATCH_REQUIRE_FALSE(a.is_wan(true));
    2737          10 :                 CATCH_REQUIRE_FALSE(a.is_wan(false));
    2738             :             }
    2739             :         }
    2740           8 :         CATCH_END_SECTION()
    2741             : 
    2742           8 :         CATCH_START_SECTION("addr: private address 169.254.x.x/16")
    2743             :         {
    2744          11 :             for(int idx(0); idx < 10; ++idx)
    2745             :             {
    2746          10 :                 struct sockaddr_in in = sockaddr_in();
    2747          10 :                 in.sin_family = AF_INET;
    2748          10 :                 in.sin_port = htons(rand());
    2749             :                 uint32_t address((169 << 24)
    2750             :                               |  (254 << 16)
    2751          10 :                               | ((rand() & 255) << 8)
    2752          10 :                               | ((rand() & 255) << 0));
    2753          10 :                 in.sin_addr.s_addr = htonl(address);
    2754             : 
    2755             :                 // verify network type
    2756             :                 //
    2757          10 :                 a.set_ipv4(in);
    2758          10 :                 CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_LINK_LOCAL);
    2759          10 :                 CATCH_REQUIRE(a.get_network_type_string() == "Local Link");
    2760          10 :                 CATCH_REQUIRE_FALSE(a.is_lan());
    2761          10 :                 CATCH_REQUIRE(a.is_lan(true));
    2762          10 :                 CATCH_REQUIRE_FALSE(a.is_lan(false));
    2763          10 :                 CATCH_REQUIRE_FALSE(a.is_wan());
    2764          10 :                 CATCH_REQUIRE_FALSE(a.is_wan(true));
    2765          10 :                 CATCH_REQUIRE_FALSE(a.is_wan(false));
    2766             :             }
    2767             :         }
    2768           8 :         CATCH_END_SECTION()
    2769             : 
    2770           8 :         CATCH_START_SECTION("addr: private address 224.x.x.x/4")
    2771             :         {
    2772          11 :             for(int idx(0); idx < 10; ++idx)
    2773             :             {
    2774          10 :                 struct sockaddr_in in = sockaddr_in();
    2775          10 :                 in.sin_family = AF_INET;
    2776          10 :                 in.sin_port = htons(rand());
    2777          10 :                 uint32_t address((((rand() & 15) | 224) << 24)
    2778          10 :                               | ((rand() & 255) << 16)
    2779          10 :                               | ((rand() & 255) << 8)
    2780          10 :                               | ((rand() & 255) << 0));
    2781          10 :                 in.sin_addr.s_addr = htonl(address);
    2782             : 
    2783             :                 // verify network type
    2784             :                 //
    2785          10 :                 a.set_ipv4(in);
    2786          10 :                 CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_MULTICAST);
    2787          10 :                 CATCH_REQUIRE(a.get_network_type_string() == "Multicast");
    2788          10 :                 CATCH_REQUIRE_FALSE(a.is_lan());
    2789          10 :                 CATCH_REQUIRE(a.is_lan(true));
    2790          10 :                 CATCH_REQUIRE_FALSE(a.is_lan(false));
    2791          10 :                 CATCH_REQUIRE_FALSE(a.is_wan());
    2792          10 :                 CATCH_REQUIRE_FALSE(a.is_wan(true));
    2793          10 :                 CATCH_REQUIRE_FALSE(a.is_wan(false));
    2794             : 
    2795             :                 // make sure no interface uses that IP
    2796             :                 //
    2797          10 :                 CATCH_REQUIRE(addr::find_addr_interface(a, false) == nullptr);
    2798             :             }
    2799             :         }
    2800           8 :         CATCH_END_SECTION()
    2801             : 
    2802           8 :         CATCH_START_SECTION("addr: private address 127.x.x.x/8")
    2803             :         {
    2804          11 :             for(int idx(0); idx < 10; ++idx)
    2805             :             {
    2806          10 :                 struct sockaddr_in in = sockaddr_in();
    2807          10 :                 in.sin_family = AF_INET;
    2808          10 :                 in.sin_port = htons(rand());
    2809             :                 uint32_t address((127 << 24)
    2810          10 :                               | ((rand() & 255) << 16)
    2811          10 :                               | ((rand() & 255) << 8)
    2812          10 :                               | ((rand() & 255) << 0));
    2813          10 :                 in.sin_addr.s_addr = htonl(address);
    2814             : 
    2815             :                 // verify network type
    2816             :                 //
    2817          10 :                 a.set_ipv4(in);
    2818          10 :                 CATCH_REQUIRE(a.get_network_type() == addr::network_type_t::NETWORK_TYPE_LOOPBACK);
    2819          10 :                 CATCH_REQUIRE(a.get_network_type_string() == "Loopback");
    2820          10 :                 CATCH_REQUIRE(a.is_lan());
    2821          10 :                 CATCH_REQUIRE(a.is_lan(true));
    2822          10 :                 CATCH_REQUIRE(a.is_lan(false));
    2823          10 :                 CATCH_REQUIRE_FALSE(a.is_wan());
    2824          10 :                 CATCH_REQUIRE_FALSE(a.is_wan(true));
    2825          10 :                 CATCH_REQUIRE_FALSE(a.is_wan(false));
    2826             :             }
    2827             :         }
    2828           8 :         CATCH_END_SECTION()
    2829          16 :     }
    2830           8 : }
    2831             : 
    2832             : 
    2833           7 : CATCH_TEST_CASE("ipv4::network", "[ipv4]")
    2834             : {
    2835           7 :     CATCH_GIVEN("set_from_socket()")
    2836             :     {
    2837           7 :         CATCH_START_SECTION("addr: invalid socket")
    2838             :         {
    2839           1 :             addr::addr a;
    2840           1 :             CATCH_REQUIRE_THROWS_AS(a.set_from_socket(-1, true),  addr::addr_invalid_argument);
    2841           1 :             CATCH_REQUIRE_THROWS_AS(a.set_from_socket(-1, false), addr::addr_invalid_argument);
    2842           1 :         }
    2843           7 :         CATCH_END_SECTION()
    2844             : 
    2845           7 :         CATCH_START_SECTION("addr: non-opened file descriptor")
    2846             :         {
    2847           1 :             addr::addr a;
    2848             : 
    2849             :             // unless we have a bug, there should not be any file descriptor
    2850             :             // currently open with an ID of 1,000
    2851             :             //
    2852           1 :             CATCH_REQUIRE_THROWS_AS(a.set_from_socket(1000, true),  addr::addr_io_error);
    2853           1 :             CATCH_REQUIRE_THROWS_AS(a.set_from_socket(1000, false), addr::addr_io_error);
    2854           1 :         }
    2855           7 :         CATCH_END_SECTION()
    2856             : 
    2857           7 :         CATCH_START_SECTION("addr: unknown socket type")
    2858             :         {
    2859           1 :             addr::addr a;
    2860             : 
    2861           1 :             int s(socket(AF_UNIX, SOCK_STREAM, 0));
    2862           1 :             CATCH_REQUIRE(s >= 0);
    2863           1 :             std::shared_ptr<int> auto_free(&s, socket_deleter);
    2864             : 
    2865             :             // unless we have a bug, there should not be any file descriptor
    2866             :             // currently open with an ID of 1,000
    2867             :             //
    2868           1 :             CATCH_REQUIRE_THROWS_AS(a.set_from_socket(s, true),  addr::addr_io_error);
    2869           1 :             CATCH_REQUIRE_THROWS_AS(a.set_from_socket(s, false), addr::addr_invalid_state);
    2870           1 :         }
    2871           7 :         CATCH_END_SECTION()
    2872             : 
    2873           7 :         CATCH_START_SECTION("addr/addr_parser: create a server (bind), but do not test it (yet)...")
    2874             :         {
    2875           1 :             addr::addr_parser p;
    2876           3 :             addr::addr_range::vector_t ips(p.parse("127.0.0.1:49999"));
    2877           1 :             CATCH_REQUIRE(ips.size() >= 1);
    2878             : 
    2879           1 :             addr::addr & a(ips[0].get_from());
    2880           1 :             int s(a.create_socket(addr::addr::SOCKET_FLAG_NONBLOCK | addr::addr::SOCKET_FLAG_CLOEXEC | addr::addr::SOCKET_FLAG_REUSE));
    2881           1 :             CATCH_REQUIRE(s >= 0);
    2882           1 :             std::shared_ptr<int> auto_free(&s, socket_deleter);
    2883             : 
    2884           1 :             CATCH_REQUIRE(a.bind(s) == 0);
    2885           1 :         }
    2886           7 :         CATCH_END_SECTION()
    2887             : 
    2888           7 :         CATCH_START_SECTION("addr/addr_parser: connect() with TCP to 127.0.0.1")
    2889             :         {
    2890           1 :             if(SNAP_CATCH2_NAMESPACE::g_tcp_port != -1)
    2891             :             {
    2892           1 :                 addr::addr_parser p;
    2893           3 :                 addr::addr_range::vector_t ips(p.parse("127.0.0.1:" + std::to_string(SNAP_CATCH2_NAMESPACE::g_tcp_port)));
    2894           1 :                 CATCH_REQUIRE(ips.size() >= 1);
    2895             : 
    2896           1 :                 addr::addr & a(ips[0].get_from());
    2897           1 :                 int s(a.create_socket(addr::addr::SOCKET_FLAG_CLOEXEC));// | addr::addr::SOCKET_FLAG_REUSE));
    2898           1 :                 CATCH_REQUIRE(s >= 0);
    2899           1 :                 std::shared_ptr<int> auto_free(&s, socket_deleter);
    2900             : 
    2901           1 :                 CATCH_REQUIRE(a.connect(s) == 0);
    2902             : 
    2903             :                 // get socket info from the other side (peer == true)
    2904             :                 //
    2905           1 :                 addr::addr b;
    2906           1 :                 b.set_from_socket(s, true);
    2907           1 :                 CATCH_REQUIRE(b.is_ipv4());
    2908           1 :                 CATCH_REQUIRE(b.get_family() == AF_INET);
    2909           1 :                 CATCH_REQUIRE_FALSE(b.get_family() == AF_INET6);
    2910           1 :                 CATCH_REQUIRE(b.to_ipv4_string(addr::STRING_IP_ADDRESS)    == "127.0.0.1");
    2911           1 :                 CATCH_REQUIRE(b.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "127.0.0.1");
    2912             : 
    2913             :                 // in this case we know what the port is since we specified
    2914             :                 // that when connecting
    2915             :                 //
    2916           1 :                 CATCH_REQUIRE(b.get_port() == SNAP_CATCH2_NAMESPACE::g_tcp_port);
    2917             : 
    2918             :                 // now try this side (peer == false)
    2919             :                 //
    2920           1 :                 addr::addr c;
    2921           1 :                 c.set_from_socket(s, false);
    2922           1 :                 CATCH_REQUIRE(c.is_ipv4());
    2923           1 :                 CATCH_REQUIRE(c.get_family() == AF_INET);
    2924           1 :                 CATCH_REQUIRE_FALSE(c.get_family() == AF_INET6);
    2925           1 :                 CATCH_REQUIRE(c.to_ipv4_string(addr::STRING_IP_ADDRESS)    == "127.0.0.1");
    2926           1 :                 CATCH_REQUIRE(c.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "127.0.0.1");
    2927             : 
    2928             :                 // we cannot be sure of the port, there is a range we could
    2929             :                 // test better (more constraining) but for this test is
    2930             :                 // certainly does not matter much; it has to be more than
    2931             :                 // 1023, though
    2932             :                 //
    2933           1 :                 CATCH_REQUIRE(c.get_port() > 1023);
    2934           1 :             }
    2935             :             else
    2936             :             {
    2937             :                 // avoid issue of no assertions
    2938             :                 //
    2939           0 :                 CATCH_REQUIRE(SNAP_CATCH2_NAMESPACE::g_tcp_port == -1);
    2940           0 :                 std::cout << "connect to 127.0.0.1 test skipped as no TCP port was specified on the command line." << std::endl;
    2941             :             }
    2942             :         }
    2943           7 :         CATCH_END_SECTION()
    2944             : 
    2945           7 :         CATCH_START_SECTION("addr/addr_parser: connect() with UDP to 127.0.0.1:53 which fails")
    2946             :         {
    2947           1 :             addr::addr_parser p;
    2948           1 :             p.set_protocol("udp");
    2949           3 :             addr::addr_range::vector_t ips(p.parse("127.0.0.1:53"));
    2950           1 :             CATCH_REQUIRE(ips.size() >= 1);
    2951             : 
    2952           1 :             addr::addr & a(ips[0].get_from());
    2953           1 :             int s(a.create_socket(addr::addr::SOCKET_FLAG_CLOEXEC));// | addr::addr::SOCKET_FLAG_REUSE));
    2954           1 :             CATCH_REQUIRE(s >= 0);
    2955           1 :             std::shared_ptr<int> auto_free(&s, socket_deleter);
    2956             : 
    2957             :             // addr::connect() does not support UDP
    2958             :             //
    2959           1 :             CATCH_REQUIRE(a.connect(s) == -1);
    2960             : 
    2961           1 :             addr::addr b;
    2962           1 :             CATCH_REQUIRE_THROWS_AS(b.set_from_socket(s, true), addr::addr_io_error);
    2963           1 :             CATCH_REQUIRE_FALSE(b.is_ipv4());
    2964           1 :             CATCH_REQUIRE_FALSE(b.get_family() == AF_INET);
    2965           1 :             CATCH_REQUIRE(b.get_family() == AF_INET6);
    2966           1 :             CATCH_REQUIRE(b.to_ipv6_string(addr::STRING_IP_ADDRESS)    == "::");
    2967           1 :             CATCH_REQUIRE(b.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "::");
    2968           1 :             CATCH_REQUIRE(b.get_port() == 0);
    2969             : 
    2970           1 :             addr::addr c;
    2971           1 :             c.set_from_socket(s, false);
    2972           1 :             CATCH_REQUIRE(c.is_ipv4());
    2973           1 :             CATCH_REQUIRE(c.get_family() == AF_INET);
    2974           1 :             CATCH_REQUIRE_FALSE(c.get_family() == AF_INET6);
    2975           1 :             CATCH_REQUIRE(c.to_ipv4_string(addr::STRING_IP_ADDRESS)    == "0.0.0.0");
    2976           1 :             CATCH_REQUIRE(c.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "0.0.0.0");
    2977           1 :             CATCH_REQUIRE(c.get_port() == 0);
    2978           1 :         }
    2979           7 :         CATCH_END_SECTION()
    2980             : 
    2981           7 :         CATCH_START_SECTION("addr/addr_parser: bind() with UDP to 127.0.0.1:<auto> (as a \"client\") which works")
    2982             :         {
    2983           1 :             addr::addr_parser p;
    2984           1 :             p.set_protocol("udp");
    2985           3 :             addr::addr_range::vector_t ips(p.parse("127.0.0.1"));
    2986           1 :             CATCH_REQUIRE(ips.size() >= 1);
    2987             : 
    2988           1 :             addr::addr & a(ips[0].get_from());
    2989           1 :             int s(a.create_socket(addr::addr::SOCKET_FLAG_CLOEXEC));// | addr::addr::SOCKET_FLAG_REUSE));
    2990           1 :             CATCH_REQUIRE(s >= 0);
    2991           1 :             std::shared_ptr<int> auto_free(&s, socket_deleter);
    2992             : 
    2993             :             // succeeds, but the port is not known
    2994             :             //
    2995           1 :             CATCH_REQUIRE(a.bind(s) == 0);
    2996             : 
    2997             :             // this is a UDP socket, there is no other side so we get ANY
    2998             :             //
    2999           1 :             addr::addr b;
    3000           1 :             CATCH_REQUIRE_THROWS_AS(b.set_from_socket(s, true), addr::addr_io_error);
    3001           1 :             CATCH_REQUIRE_FALSE(b.is_ipv4());
    3002           1 :             CATCH_REQUIRE_FALSE(b.get_family() == AF_INET);
    3003           1 :             CATCH_REQUIRE(b.get_family() == AF_INET6);
    3004           1 :             CATCH_REQUIRE(b.to_ipv6_string(addr::STRING_IP_ADDRESS)    == "::");
    3005           1 :             CATCH_REQUIRE(b.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "::");
    3006           1 :             CATCH_REQUIRE(b.get_port() == 0);
    3007             : 
    3008             :             // now try this side (peer == false) and again it is "any"
    3009             :             // since it failed connecting
    3010             :             //
    3011           1 :             addr::addr c;
    3012           1 :             c.set_from_socket(s, false);
    3013           1 :             CATCH_REQUIRE(c.is_ipv4());
    3014           1 :             CATCH_REQUIRE(c.get_family() == AF_INET);
    3015           1 :             CATCH_REQUIRE_FALSE(c.get_family() == AF_INET6);
    3016           1 :             CATCH_REQUIRE(c.to_ipv4_string(addr::STRING_IP_ADDRESS)    == "127.0.0.1");
    3017           1 :             CATCH_REQUIRE(c.to_ipv4or6_string(addr::STRING_IP_ADDRESS) == "127.0.0.1");
    3018             : 
    3019             :             // if this worked, the port is > 1023 (it was auto-allocated)
    3020             :             //
    3021           1 :             CATCH_REQUIRE(c.get_port() > 1023);
    3022             : 
    3023             :             // since the a.bind() is expected to read that port, it should
    3024             :             // equal the one in `a`
    3025             :             //
    3026           1 :             CATCH_REQUIRE(a.get_port() == c.get_port());
    3027           1 :         }
    3028           7 :         CATCH_END_SECTION()
    3029           7 :     }
    3030           7 : }
    3031             : 
    3032             : 
    3033          14 : CATCH_TEST_CASE("ipv4::string_to_addr", "[ipv4]")
    3034             : {
    3035          14 :     CATCH_GIVEN("string_to_addr() ipv4")
    3036             :     {
    3037          14 :         CATCH_START_SECTION("string_to_addr: empty address without defaults")
    3038             :         {
    3039           4 :             addr::addr a(addr::string_to_addr(std::string()));
    3040             : 
    3041           1 :             CATCH_REQUIRE(a.is_ipv4());
    3042           1 :             CATCH_REQUIRE(a.get_family() == AF_INET);
    3043           1 :             CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
    3044             : 
    3045           1 :             struct sockaddr_in in = sockaddr_in();
    3046           1 :             in.sin_family = AF_INET;
    3047           1 :             in.sin_port = 0;
    3048           1 :             in.sin_addr.s_addr = htonl((0 << 24) | (0 << 16) | (0 << 8) | (0 << 0));
    3049             : 
    3050             :             // test string_to_addr accuracy
    3051             :             //
    3052           1 :             struct sockaddr_in out;
    3053           1 :             a.get_ipv4(out);
    3054           1 :             CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
    3055             : 
    3056           1 :             uint8_t mask[16];
    3057           1 :             a.get_mask(mask);
    3058           1 :             CATCH_REQUIRE(mask[ 0] == 0xFF);
    3059           1 :             CATCH_REQUIRE(mask[ 1] == 0xFF);
    3060           1 :             CATCH_REQUIRE(mask[ 2] == 0xFF);
    3061           1 :             CATCH_REQUIRE(mask[ 3] == 0xFF);
    3062           1 :             CATCH_REQUIRE(mask[ 4] == 0xFF);
    3063           1 :             CATCH_REQUIRE(mask[ 5] == 0xFF);
    3064           1 :             CATCH_REQUIRE(mask[ 6] == 0xFF);
    3065           1 :             CATCH_REQUIRE(mask[ 7] == 0xFF);
    3066           1 :             CATCH_REQUIRE(mask[ 8] == 0xFF);
    3067           1 :             CATCH_REQUIRE(mask[ 9] == 0xFF);
    3068           1 :             CATCH_REQUIRE(mask[10] == 0xFF);
    3069           1 :             CATCH_REQUIRE(mask[11] == 0xFF);
    3070           1 :             CATCH_REQUIRE(mask[12] == 0xFF);
    3071           1 :             CATCH_REQUIRE(mask[13] == 0xFF);
    3072           1 :             CATCH_REQUIRE(mask[14] == 0xFF);
    3073           1 :             CATCH_REQUIRE(mask[15] == 0xFF);
    3074           1 :         }
    3075          14 :         CATCH_END_SECTION()
    3076             : 
    3077          14 :         CATCH_START_SECTION("string_to_addr: explicit defaults")
    3078             :         {
    3079           5 :             addr::addr a(addr::string_to_addr("5.14.34.111", std::string(), -1, std::string(), false));
    3080             : 
    3081           1 :             CATCH_REQUIRE(a.is_ipv4());
    3082           1 :             CATCH_REQUIRE(a.get_family() == AF_INET);
    3083           1 :             CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
    3084             : 
    3085           1 :             struct sockaddr_in in = sockaddr_in();
    3086           1 :             in.sin_family = AF_INET;
    3087           1 :             in.sin_port = 0;
    3088           1 :             in.sin_addr.s_addr = htonl((5 << 24) | (14 << 16) | (34 << 8) | (111 << 0));
    3089             : 
    3090             :             // test string_to_addr accuracy
    3091             :             //
    3092           1 :             struct sockaddr_in out;
    3093           1 :             a.get_ipv4(out);
    3094           1 :             CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
    3095             : 
    3096           1 :             uint8_t mask[16];
    3097           1 :             a.get_mask(mask);
    3098           1 :             CATCH_REQUIRE(mask[ 0] == 0xFF);
    3099           1 :             CATCH_REQUIRE(mask[ 1] == 0xFF);
    3100           1 :             CATCH_REQUIRE(mask[ 2] == 0xFF);
    3101           1 :             CATCH_REQUIRE(mask[ 3] == 0xFF);
    3102           1 :             CATCH_REQUIRE(mask[ 4] == 0xFF);
    3103           1 :             CATCH_REQUIRE(mask[ 5] == 0xFF);
    3104           1 :             CATCH_REQUIRE(mask[ 6] == 0xFF);
    3105           1 :             CATCH_REQUIRE(mask[ 7] == 0xFF);
    3106           1 :             CATCH_REQUIRE(mask[ 8] == 0xFF);
    3107           1 :             CATCH_REQUIRE(mask[ 9] == 0xFF);
    3108           1 :             CATCH_REQUIRE(mask[10] == 0xFF);
    3109           1 :             CATCH_REQUIRE(mask[11] == 0xFF);
    3110           1 :             CATCH_REQUIRE(mask[12] == 0xFF);
    3111           1 :             CATCH_REQUIRE(mask[13] == 0xFF);
    3112           1 :             CATCH_REQUIRE(mask[14] == 0xFF);
    3113           1 :             CATCH_REQUIRE(mask[15] == 0xFF);
    3114           1 :         }
    3115          14 :         CATCH_END_SECTION()
    3116             : 
    3117          14 :         CATCH_START_SECTION("string_to_addr: defaults")
    3118             :         {
    3119           5 :             addr::addr a(addr::string_to_addr("7.149.104.211"));
    3120             : 
    3121           1 :             CATCH_REQUIRE(a.is_ipv4());
    3122           1 :             CATCH_REQUIRE(a.get_family() == AF_INET);
    3123           1 :             CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
    3124             : 
    3125           1 :             struct sockaddr_in in = sockaddr_in();
    3126           1 :             in.sin_family = AF_INET;
    3127           1 :             in.sin_port = 0;
    3128           1 :             in.sin_addr.s_addr = htonl((7 << 24) | (149 << 16) | (104 << 8) | (211 << 0));
    3129             : 
    3130             :             // test string_to_addr accuracy
    3131             :             //
    3132           1 :             struct sockaddr_in out;
    3133           1 :             a.get_ipv4(out);
    3134           1 :             CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
    3135             : 
    3136           1 :             uint8_t mask[16];
    3137           1 :             a.get_mask(mask);
    3138           1 :             CATCH_REQUIRE(mask[ 0] == 0xFF);
    3139           1 :             CATCH_REQUIRE(mask[ 1] == 0xFF);
    3140           1 :             CATCH_REQUIRE(mask[ 2] == 0xFF);
    3141           1 :             CATCH_REQUIRE(mask[ 3] == 0xFF);
    3142           1 :             CATCH_REQUIRE(mask[ 4] == 0xFF);
    3143           1 :             CATCH_REQUIRE(mask[ 5] == 0xFF);
    3144           1 :             CATCH_REQUIRE(mask[ 6] == 0xFF);
    3145           1 :             CATCH_REQUIRE(mask[ 7] == 0xFF);
    3146           1 :             CATCH_REQUIRE(mask[ 8] == 0xFF);
    3147           1 :             CATCH_REQUIRE(mask[ 9] == 0xFF);
    3148           1 :             CATCH_REQUIRE(mask[10] == 0xFF);
    3149           1 :             CATCH_REQUIRE(mask[11] == 0xFF);
    3150           1 :             CATCH_REQUIRE(mask[12] == 0xFF);
    3151           1 :             CATCH_REQUIRE(mask[13] == 0xFF);
    3152           1 :             CATCH_REQUIRE(mask[14] == 0xFF);
    3153           1 :             CATCH_REQUIRE(mask[15] == 0xFF);
    3154           1 :         }
    3155          14 :         CATCH_END_SECTION()
    3156             : 
    3157          14 :         CATCH_START_SECTION("string_to_addr: addr & default addr")
    3158             :         {
    3159           6 :             addr::addr a(addr::string_to_addr("37.149.174.11", "1.205.32.11"));
    3160             : 
    3161           1 :             CATCH_REQUIRE(a.is_ipv4());
    3162           1 :             CATCH_REQUIRE(a.get_family() == AF_INET);
    3163           1 :             CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
    3164             : 
    3165           1 :             struct sockaddr_in in = sockaddr_in();
    3166           1 :             in.sin_family = AF_INET;
    3167           1 :             in.sin_port = 0;
    3168           1 :             in.sin_addr.s_addr = htonl((37 << 24) | (149 << 16) | (174 << 8) | (11 << 0));
    3169             : 
    3170             :             // test string_to_addr accuracy
    3171             :             //
    3172           1 :             struct sockaddr_in out;
    3173           1 :             a.get_ipv4(out);
    3174           1 :             CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
    3175             : 
    3176           1 :             uint8_t mask[16];
    3177           1 :             a.get_mask(mask);
    3178           1 :             CATCH_REQUIRE(mask[ 0] == 0xFF);
    3179           1 :             CATCH_REQUIRE(mask[ 1] == 0xFF);
    3180           1 :             CATCH_REQUIRE(mask[ 2] == 0xFF);
    3181           1 :             CATCH_REQUIRE(mask[ 3] == 0xFF);
    3182           1 :             CATCH_REQUIRE(mask[ 4] == 0xFF);
    3183           1 :             CATCH_REQUIRE(mask[ 5] == 0xFF);
    3184           1 :             CATCH_REQUIRE(mask[ 6] == 0xFF);
    3185           1 :             CATCH_REQUIRE(mask[ 7] == 0xFF);
    3186           1 :             CATCH_REQUIRE(mask[ 8] == 0xFF);
    3187           1 :             CATCH_REQUIRE(mask[ 9] == 0xFF);
    3188           1 :             CATCH_REQUIRE(mask[10] == 0xFF);
    3189           1 :             CATCH_REQUIRE(mask[11] == 0xFF);
    3190           1 :             CATCH_REQUIRE(mask[12] == 0xFF);
    3191           1 :             CATCH_REQUIRE(mask[13] == 0xFF);
    3192           1 :             CATCH_REQUIRE(mask[14] == 0xFF);
    3193           1 :             CATCH_REQUIRE(mask[15] == 0xFF);
    3194           1 :         }
    3195          14 :         CATCH_END_SECTION()
    3196             : 
    3197          14 :         CATCH_START_SECTION("string_to_addr: no addr, expect default addr")
    3198             :         {
    3199           6 :             addr::addr a(addr::string_to_addr("", "1.205.32.11"));
    3200             : 
    3201           1 :             CATCH_REQUIRE(a.is_ipv4());
    3202           1 :             CATCH_REQUIRE(a.get_family() == AF_INET);
    3203           1 :             CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
    3204             : 
    3205           1 :             struct sockaddr_in in = sockaddr_in();
    3206           1 :             in.sin_family = AF_INET;
    3207           1 :             in.sin_port = 0;
    3208           1 :             in.sin_addr.s_addr = htonl((1 << 24) | (205 << 16) | (32 << 8) | (11 << 0));
    3209             : 
    3210             :             // test string_to_addr accuracy
    3211             :             //
    3212           1 :             struct sockaddr_in out;
    3213           1 :             a.get_ipv4(out);
    3214           1 :             CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
    3215             : 
    3216           1 :             uint8_t mask[16];
    3217           1 :             a.get_mask(mask);
    3218           1 :             CATCH_REQUIRE(mask[ 0] == 0xFF);
    3219           1 :             CATCH_REQUIRE(mask[ 1] == 0xFF);
    3220           1 :             CATCH_REQUIRE(mask[ 2] == 0xFF);
    3221           1 :             CATCH_REQUIRE(mask[ 3] == 0xFF);
    3222           1 :             CATCH_REQUIRE(mask[ 4] == 0xFF);
    3223           1 :             CATCH_REQUIRE(mask[ 5] == 0xFF);
    3224           1 :             CATCH_REQUIRE(mask[ 6] == 0xFF);
    3225           1 :             CATCH_REQUIRE(mask[ 7] == 0xFF);
    3226           1 :             CATCH_REQUIRE(mask[ 8] == 0xFF);
    3227           1 :             CATCH_REQUIRE(mask[ 9] == 0xFF);
    3228           1 :             CATCH_REQUIRE(mask[10] == 0xFF);
    3229           1 :             CATCH_REQUIRE(mask[11] == 0xFF);
    3230           1 :             CATCH_REQUIRE(mask[12] == 0xFF);
    3231           1 :             CATCH_REQUIRE(mask[13] == 0xFF);
    3232           1 :             CATCH_REQUIRE(mask[14] == 0xFF);
    3233           1 :             CATCH_REQUIRE(mask[15] == 0xFF);
    3234           1 :         }
    3235          14 :         CATCH_END_SECTION()
    3236             : 
    3237          14 :         CATCH_START_SECTION("string_to_addr: addr and port, with a default port")
    3238             :         {
    3239           6 :             addr::addr a(addr::string_to_addr("69.109.223.17:697", "1.205.32.11", 123));
    3240             : 
    3241           1 :             CATCH_REQUIRE(a.is_ipv4());
    3242           1 :             CATCH_REQUIRE(a.get_family() == AF_INET);
    3243           1 :             CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
    3244             : 
    3245           1 :             struct sockaddr_in in = sockaddr_in();
    3246           1 :             in.sin_family = AF_INET;
    3247           1 :             in.sin_port = htons(697);
    3248           1 :             in.sin_addr.s_addr = htonl((69 << 24) | (109 << 16) | (223 << 8) | (17 << 0));
    3249             : 
    3250             :             // test string_to_addr accuracy
    3251             :             //
    3252           1 :             struct sockaddr_in out;
    3253           1 :             a.get_ipv4(out);
    3254           1 :             CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
    3255             : 
    3256           1 :             uint8_t mask[16];
    3257           1 :             a.get_mask(mask);
    3258           1 :             CATCH_REQUIRE(mask[ 0] == 0xFF);
    3259           1 :             CATCH_REQUIRE(mask[ 1] == 0xFF);
    3260           1 :             CATCH_REQUIRE(mask[ 2] == 0xFF);
    3261           1 :             CATCH_REQUIRE(mask[ 3] == 0xFF);
    3262           1 :             CATCH_REQUIRE(mask[ 4] == 0xFF);
    3263           1 :             CATCH_REQUIRE(mask[ 5] == 0xFF);
    3264           1 :             CATCH_REQUIRE(mask[ 6] == 0xFF);
    3265           1 :             CATCH_REQUIRE(mask[ 7] == 0xFF);
    3266           1 :             CATCH_REQUIRE(mask[ 8] == 0xFF);
    3267           1 :             CATCH_REQUIRE(mask[ 9] == 0xFF);
    3268           1 :             CATCH_REQUIRE(mask[10] == 0xFF);
    3269           1 :             CATCH_REQUIRE(mask[11] == 0xFF);
    3270           1 :             CATCH_REQUIRE(mask[12] == 0xFF);
    3271           1 :             CATCH_REQUIRE(mask[13] == 0xFF);
    3272           1 :             CATCH_REQUIRE(mask[14] == 0xFF);
    3273           1 :             CATCH_REQUIRE(mask[15] == 0xFF);
    3274           1 :         }
    3275          14 :         CATCH_END_SECTION()
    3276             : 
    3277          14 :         CATCH_START_SECTION("string_to_addr: addr without port, with a default port")
    3278             :         {
    3279           6 :             addr::addr a(addr::string_to_addr("169.209.23.217", "1.205.32.11", 123));
    3280             : 
    3281           1 :             CATCH_REQUIRE(a.is_ipv4());
    3282           1 :             CATCH_REQUIRE(a.get_family() == AF_INET);
    3283           1 :             CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
    3284             : 
    3285           1 :             struct sockaddr_in in = sockaddr_in();
    3286           1 :             in.sin_family = AF_INET;
    3287           1 :             in.sin_port = htons(123);
    3288           1 :             in.sin_addr.s_addr = htonl((169 << 24) | (209 << 16) | (23 << 8) | (217 << 0));
    3289             : 
    3290             :             // test string_to_addr accuracy
    3291             :             //
    3292           1 :             struct sockaddr_in out;
    3293           1 :             a.get_ipv4(out);
    3294           1 :             CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
    3295             : 
    3296           1 :             uint8_t mask[16];
    3297           1 :             a.get_mask(mask);
    3298           1 :             CATCH_REQUIRE(mask[ 0] == 0xFF);
    3299           1 :             CATCH_REQUIRE(mask[ 1] == 0xFF);
    3300           1 :             CATCH_REQUIRE(mask[ 2] == 0xFF);
    3301           1 :             CATCH_REQUIRE(mask[ 3] == 0xFF);
    3302           1 :             CATCH_REQUIRE(mask[ 4] == 0xFF);
    3303           1 :             CATCH_REQUIRE(mask[ 5] == 0xFF);
    3304           1 :             CATCH_REQUIRE(mask[ 6] == 0xFF);
    3305           1 :             CATCH_REQUIRE(mask[ 7] == 0xFF);
    3306           1 :             CATCH_REQUIRE(mask[ 8] == 0xFF);
    3307           1 :             CATCH_REQUIRE(mask[ 9] == 0xFF);
    3308           1 :             CATCH_REQUIRE(mask[10] == 0xFF);
    3309           1 :             CATCH_REQUIRE(mask[11] == 0xFF);
    3310           1 :             CATCH_REQUIRE(mask[12] == 0xFF);
    3311           1 :             CATCH_REQUIRE(mask[13] == 0xFF);
    3312           1 :             CATCH_REQUIRE(mask[14] == 0xFF);
    3313           1 :             CATCH_REQUIRE(mask[15] == 0xFF);
    3314           1 :         }
    3315          14 :         CATCH_END_SECTION()
    3316             : 
    3317          14 :         CATCH_START_SECTION("string_to_addr: addr without port but protocol")
    3318             :         {
    3319           7 :             addr::addr a(addr::string_to_addr("4.5.123.7", "1.205.32.11", 60000, "tcp"));
    3320             : 
    3321           1 :             CATCH_REQUIRE(a.is_ipv4());
    3322           1 :             CATCH_REQUIRE(a.get_family() == AF_INET);
    3323           1 :             CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
    3324             : 
    3325           1 :             struct sockaddr_in in = sockaddr_in();
    3326           1 :             in.sin_family = AF_INET;
    3327           1 :             in.sin_port = htons(60000);
    3328           1 :             in.sin_addr.s_addr = htonl((4 << 24) | (5 << 16) | (123 << 8) | (7 << 0));
    3329             : 
    3330             :             // test string_to_addr accuracy
    3331             :             //
    3332           1 :             struct sockaddr_in out;
    3333           1 :             a.get_ipv4(out);
    3334           1 :             CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
    3335             : 
    3336           1 :             uint8_t mask[16];
    3337           1 :             a.get_mask(mask);
    3338           1 :             CATCH_REQUIRE(mask[ 0] == 0xFF);
    3339           1 :             CATCH_REQUIRE(mask[ 1] == 0xFF);
    3340           1 :             CATCH_REQUIRE(mask[ 2] == 0xFF);
    3341           1 :             CATCH_REQUIRE(mask[ 3] == 0xFF);
    3342           1 :             CATCH_REQUIRE(mask[ 4] == 0xFF);
    3343           1 :             CATCH_REQUIRE(mask[ 5] == 0xFF);
    3344           1 :             CATCH_REQUIRE(mask[ 6] == 0xFF);
    3345           1 :             CATCH_REQUIRE(mask[ 7] == 0xFF);
    3346           1 :             CATCH_REQUIRE(mask[ 8] == 0xFF);
    3347           1 :             CATCH_REQUIRE(mask[ 9] == 0xFF);
    3348           1 :             CATCH_REQUIRE(mask[10] == 0xFF);
    3349           1 :             CATCH_REQUIRE(mask[11] == 0xFF);
    3350           1 :             CATCH_REQUIRE(mask[12] == 0xFF);
    3351           1 :             CATCH_REQUIRE(mask[13] == 0xFF);
    3352           1 :             CATCH_REQUIRE(mask[14] == 0xFF);
    3353           1 :             CATCH_REQUIRE(mask[15] == 0xFF);
    3354           1 :         }
    3355          14 :         CATCH_END_SECTION()
    3356             : 
    3357          14 :         CATCH_START_SECTION("string_to_addr: addr with port and protocol")
    3358             :         {
    3359           7 :             addr::addr a(addr::string_to_addr("204.105.13.9:65", "1.205.32.11", 60000, "tcp"));
    3360             : 
    3361           1 :             CATCH_REQUIRE(a.is_ipv4());
    3362           1 :             CATCH_REQUIRE(a.get_family() == AF_INET);
    3363           1 :             CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
    3364             : 
    3365           1 :             struct sockaddr_in in = sockaddr_in();
    3366           1 :             in.sin_family = AF_INET;
    3367           1 :             in.sin_port = htons(65);
    3368           1 :             in.sin_addr.s_addr = htonl((204 << 24) | (105 << 16) | (13 << 8) | (9 << 0));
    3369             : 
    3370             :             // test string_to_addr accuracy
    3371             :             //
    3372           1 :             struct sockaddr_in out;
    3373           1 :             a.get_ipv4(out);
    3374           1 :             CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
    3375             : 
    3376           1 :             uint8_t mask[16];
    3377           1 :             a.get_mask(mask);
    3378           1 :             CATCH_REQUIRE(mask[ 0] == 0xFF);
    3379           1 :             CATCH_REQUIRE(mask[ 1] == 0xFF);
    3380           1 :             CATCH_REQUIRE(mask[ 2] == 0xFF);
    3381           1 :             CATCH_REQUIRE(mask[ 3] == 0xFF);
    3382           1 :             CATCH_REQUIRE(mask[ 4] == 0xFF);
    3383           1 :             CATCH_REQUIRE(mask[ 5] == 0xFF);
    3384           1 :             CATCH_REQUIRE(mask[ 6] == 0xFF);
    3385           1 :             CATCH_REQUIRE(mask[ 7] == 0xFF);
    3386           1 :             CATCH_REQUIRE(mask[ 8] == 0xFF);
    3387           1 :             CATCH_REQUIRE(mask[ 9] == 0xFF);
    3388           1 :             CATCH_REQUIRE(mask[10] == 0xFF);
    3389           1 :             CATCH_REQUIRE(mask[11] == 0xFF);
    3390           1 :             CATCH_REQUIRE(mask[12] == 0xFF);
    3391           1 :             CATCH_REQUIRE(mask[13] == 0xFF);
    3392           1 :             CATCH_REQUIRE(mask[14] == 0xFF);
    3393           1 :             CATCH_REQUIRE(mask[15] == 0xFF);
    3394           1 :         }
    3395          14 :         CATCH_END_SECTION()
    3396             : 
    3397          14 :         CATCH_START_SECTION("string_to_addr: addr with port and protocol but no mask, albeit allowed")
    3398             :         {
    3399           7 :             addr::addr a(addr::string_to_addr("94.95.131.18:765", "11.205.32.21", 54003, "tcp", true));
    3400             : 
    3401           1 :             CATCH_REQUIRE(a.is_ipv4());
    3402           1 :             CATCH_REQUIRE(a.get_family() == AF_INET);
    3403           1 :             CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
    3404             : 
    3405           1 :             struct sockaddr_in in = sockaddr_in();
    3406           1 :             in.sin_family = AF_INET;
    3407           1 :             in.sin_port = htons(765);
    3408           1 :             in.sin_addr.s_addr = htonl((94 << 24) | (95 << 16) | (131 << 8) | (18 << 0));
    3409             : 
    3410             :             // test string_to_addr accuracy
    3411             :             //
    3412           1 :             struct sockaddr_in out;
    3413           1 :             a.get_ipv4(out);
    3414           1 :             CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
    3415             : 
    3416           1 :             uint8_t mask[16];
    3417           1 :             a.get_mask(mask);
    3418           1 :             CATCH_REQUIRE(mask[ 0] == 0xFF);
    3419           1 :             CATCH_REQUIRE(mask[ 1] == 0xFF);
    3420           1 :             CATCH_REQUIRE(mask[ 2] == 0xFF);
    3421           1 :             CATCH_REQUIRE(mask[ 3] == 0xFF);
    3422           1 :             CATCH_REQUIRE(mask[ 4] == 0xFF);
    3423           1 :             CATCH_REQUIRE(mask[ 5] == 0xFF);
    3424           1 :             CATCH_REQUIRE(mask[ 6] == 0xFF);
    3425           1 :             CATCH_REQUIRE(mask[ 7] == 0xFF);
    3426           1 :             CATCH_REQUIRE(mask[ 8] == 0xFF);
    3427           1 :             CATCH_REQUIRE(mask[ 9] == 0xFF);
    3428           1 :             CATCH_REQUIRE(mask[10] == 0xFF);
    3429           1 :             CATCH_REQUIRE(mask[11] == 0xFF);
    3430           1 :             CATCH_REQUIRE(mask[12] == 0xFF);
    3431           1 :             CATCH_REQUIRE(mask[13] == 0xFF);
    3432           1 :             CATCH_REQUIRE(mask[14] == 0xFF);
    3433           1 :             CATCH_REQUIRE(mask[15] == 0xFF);
    3434           1 :         }
    3435          14 :         CATCH_END_SECTION()
    3436             : 
    3437          14 :         CATCH_START_SECTION("string_to_addr: addr with port and protocol and mask, albeit allowed")
    3438             :         {
    3439           7 :             addr::addr a(addr::string_to_addr("44.45.141.48:765/30", "11.205.32.21", 54003, "tcp", true));
    3440             : 
    3441           1 :             CATCH_REQUIRE(a.is_ipv4());
    3442           1 :             CATCH_REQUIRE(a.get_family() == AF_INET);
    3443           1 :             CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
    3444             : 
    3445           1 :             struct sockaddr_in in = sockaddr_in();
    3446           1 :             in.sin_family = AF_INET;
    3447           1 :             in.sin_port = htons(765);
    3448           1 :             in.sin_addr.s_addr = htonl((44 << 24) | (45 << 16) | (141 << 8) | (48 << 0));
    3449             : 
    3450             :             // test string_to_addr accuracy
    3451             :             //
    3452           1 :             struct sockaddr_in out;
    3453           1 :             a.get_ipv4(out);
    3454           1 :             CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
    3455             : 
    3456           1 :             uint8_t mask[16];
    3457           1 :             a.get_mask(mask);
    3458           1 :             CATCH_REQUIRE(mask[ 0] == 0xFF);
    3459           1 :             CATCH_REQUIRE(mask[ 1] == 0xFF);
    3460           1 :             CATCH_REQUIRE(mask[ 2] == 0xFF);
    3461           1 :             CATCH_REQUIRE(mask[ 3] == 0xFF);
    3462           1 :             CATCH_REQUIRE(mask[ 4] == 0xFF);
    3463           1 :             CATCH_REQUIRE(mask[ 5] == 0xFF);
    3464           1 :             CATCH_REQUIRE(mask[ 6] == 0xFF);
    3465           1 :             CATCH_REQUIRE(mask[ 7] == 0xFF);
    3466           1 :             CATCH_REQUIRE(mask[ 8] == 0xFF);
    3467           1 :             CATCH_REQUIRE(mask[ 9] == 0xFF);
    3468           1 :             CATCH_REQUIRE(mask[10] == 0xFF);
    3469           1 :             CATCH_REQUIRE(mask[11] == 0xFF);
    3470           1 :             CATCH_REQUIRE(mask[12] == 0xFF);
    3471           1 :             CATCH_REQUIRE(mask[13] == 0xFF);
    3472           1 :             CATCH_REQUIRE(mask[14] == 0xFF);
    3473           1 :             CATCH_REQUIRE(mask[15] == 0xFC);
    3474           1 :         }
    3475          14 :         CATCH_END_SECTION()
    3476             : 
    3477          14 :         CATCH_START_SECTION("string_to_addr: addr with port and protocol and mask, albeit allowed")
    3478             :         {
    3479           7 :             addr::addr a(addr::string_to_addr("160.0.0.0:1675/4", "11.205.32.21", 14003, "udp", true));
    3480             : 
    3481           1 :             CATCH_REQUIRE(a.is_ipv4());
    3482           1 :             CATCH_REQUIRE(a.get_family() == AF_INET);
    3483           1 :             CATCH_REQUIRE_FALSE(a.get_family() == AF_INET6);
    3484             : 
    3485           1 :             struct sockaddr_in in = sockaddr_in();
    3486           1 :             in.sin_family = AF_INET;
    3487           1 :             in.sin_port = htons(1675);
    3488           1 :             in.sin_addr.s_addr = htonl((160 << 24) | (0 << 16) | (0 << 8) | (0 << 0));
    3489             : 
    3490             :             // test string_to_addr accuracy
    3491             :             //
    3492           1 :             struct sockaddr_in out;
    3493           1 :             a.get_ipv4(out);
    3494           1 :             CATCH_REQUIRE(memcmp(&out, &in, sizeof(struct sockaddr_in)) == 0);
    3495             : 
    3496           1 :             uint8_t mask[16];
    3497           1 :             a.get_mask(mask);
    3498           1 :             CATCH_REQUIRE(mask[ 0] == 0xFF);
    3499           1 :             CATCH_REQUIRE(mask[ 1] == 0xFF);
    3500           1 :             CATCH_REQUIRE(mask[ 2] == 0xFF);
    3501           1 :             CATCH_REQUIRE(mask[ 3] == 0xFF);
    3502           1 :             CATCH_REQUIRE(mask[ 4] == 0xFF);
    3503           1 :             CATCH_REQUIRE(mask[ 5] == 0xFF);
    3504           1 :             CATCH_REQUIRE(mask[ 6] == 0xFF);
    3505           1 :             CATCH_REQUIRE(mask[ 7] == 0xFF);
    3506           1 :             CATCH_REQUIRE(mask[ 8] == 0xFF);
    3507           1 :             CATCH_REQUIRE(mask[ 9] == 0xFF);
    3508           1 :             CATCH_REQUIRE(mask[10] == 0xFF);
    3509           1 :             CATCH_REQUIRE(mask[11] == 0xFF);
    3510           1 :             CATCH_REQUIRE(mask[12] == 0xF0);
    3511           1 :             CATCH_REQUIRE(mask[13] == 0x00);
    3512           1 :             CATCH_REQUIRE(mask[14] == 0x00);
    3513           1 :             CATCH_REQUIRE(mask[15] == 0x00);
    3514           1 :         }
    3515          14 :         CATCH_END_SECTION()
    3516             : 
    3517          14 :         CATCH_START_SECTION("string_to_addr: addr with port and invalid protocol so we get an exception")
    3518             :         {
    3519          11 :             CATCH_REQUIRE_THROWS_AS(addr::string_to_addr("169.60.33.0:9322/24", std::string(), -1, "icmp", true),
    3520             :                                                                         addr::addr_invalid_argument);
    3521             :         }
    3522          14 :         CATCH_END_SECTION()
    3523             : 
    3524          14 :         CATCH_START_SECTION("string_to_addr: definitely not a valid address")
    3525             :         {
    3526           9 :             CATCH_REQUIRE_THROWS_MATCHES(
    3527             :                   addr::string_to_addr("not an address")
    3528             :                 , addr::addr_invalid_argument
    3529             :                 , Catch::Matchers::ExceptionMessage("addr_error: the address \"not an address\" could not be converted to a single address in string_to_addr(), found 0 entries instead."));
    3530             :         }
    3531          14 :         CATCH_END_SECTION()
    3532          14 :     }
    3533          14 : }
    3534             : 
    3535             : 
    3536             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.14

Snap C++ | List of projects | List of versions