|
|
|
@ -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
|
|
|
|
|