LCOV - code coverage report
Current view: top level - tests - catch_ipv4.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 2042 2079 98.2 %
Date: 2022-06-26 14:27:46 Functions: 13 13 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13