Browse Source

net: Fix CIDR notation in ToString()

Only use CIDR notation if the netmask can be represented as such.
0.13
Wladimir J. van der Laan 10 years ago committed by Jonas Schnelli
parent
commit
e2b8028e4c
  1. 56
      src/netbase.cpp
  2. 6
      src/test/netbase_tests.cpp

56
src/netbase.cpp

@ -1311,20 +1311,58 @@ bool CSubNet::Match(const CNetAddr &addr) const @@ -1311,20 +1311,58 @@ bool CSubNet::Match(const CNetAddr &addr) const
return true;
}
static inline int NetmaskBits(uint8_t x)
{
switch(x) {
case 0x00: return 0; break;
case 0x80: return 1; break;
case 0xc0: return 2; break;
case 0xe0: return 3; break;
case 0xf0: return 4; break;
case 0xf8: return 5; break;
case 0xfc: return 6; break;
case 0xfe: return 7; break;
case 0xff: return 8; break;
default: return -1; break;
}
}
std::string CSubNet::ToString() const
{
std::string strNetmask;
/* Parse binary 1{n}0{N-n} to see if mask can be represented as /n */
int cidr = 0;
for (int n = network.IsIPv4() ? 12 : 0 ; n < 16; ++n)
{
uint8_t netmaskpart = netmask[n];
while (netmaskpart)
{
cidr += ( netmaskpart & 0x01 );
netmaskpart >>= 1;
bool valid_cidr = true;
int n = network.IsIPv4() ? 12 : 0;
for (; n < 16 && netmask[n] == 0xff; ++n)
cidr += 8;
if (n < 16) {
int bits = NetmaskBits(netmask[n]);
if (bits < 0)
valid_cidr = false;
else
cidr += bits;
++n;
}
for (; n < 16 && valid_cidr; ++n)
if (netmask[n] != 0x00)
valid_cidr = false;
/* Format output */
std::string strNetmask;
if (valid_cidr) {
strNetmask = strprintf("%u", cidr);
} else {
if (network.IsIPv4())
strNetmask = strprintf("%u.%u.%u.%u", netmask[12], netmask[13], netmask[14], netmask[15]);
else
strNetmask = strprintf("%x:%x:%x:%x:%x:%x:%x:%x",
netmask[0] << 8 | netmask[1], netmask[2] << 8 | netmask[3],
netmask[4] << 8 | netmask[5], netmask[6] << 8 | netmask[7],
netmask[8] << 8 | netmask[9], netmask[10] << 8 | netmask[11],
netmask[12] << 8 | netmask[13], netmask[14] << 8 | netmask[15]);
}
return network.ToString() + strprintf("/%u", cidr);
return network.ToString() + "/" + strNetmask;
}
bool CSubNet::IsValid() const

6
src/test/netbase_tests.cpp

@ -229,6 +229,12 @@ BOOST_AUTO_TEST_CASE(subnet_test) @@ -229,6 +229,12 @@ BOOST_AUTO_TEST_CASE(subnet_test)
BOOST_CHECK_EQUAL(subnet.ToString(), "1::/16");
subnet = CSubNet("1:2:3:4:5:6:7:8/0000:0000:0000:0000:0000:0000:0000:0000");
BOOST_CHECK_EQUAL(subnet.ToString(), "::/0");
subnet = CSubNet("1.2.3.4/255.255.232.0");
BOOST_CHECK_EQUAL(subnet.ToString(), "1.2.0.0/255.255.232.0");
subnet = CSubNet("1:2:3:4:5:6:7:8/ffff:ffff:ffff:fffe:ffff:ffff:ffff:ff0f");
BOOST_CHECK_EQUAL(subnet.ToString(), "1:2:3:4:5:6:7:8/ffff:ffff:ffff:fffe:ffff:ffff:ffff:ff0f");
subnet = CSubNet("1:2:3:4:5:6:7:8/fff:ffff:ffff:ffff:ffff:ffff:ffff:fff0");
BOOST_CHECK_EQUAL(subnet.ToString(), "1:2:3:4:5:6:7:0/fff:ffff:ffff:ffff:ffff:ffff:ffff:fff0");
}
BOOST_AUTO_TEST_CASE(netbase_getgroup)

Loading…
Cancel
Save