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

Generated by: LCOV version 1.12