LCOV - code coverage report
Current view: top level - tests - test_addr_ipv4.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1116 1129 98.8 %
Date: 2017-01-21 19:00:32 Functions: 10 10 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.12