diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2015-06-25 10:47:34 +0200 |
---|---|---|
committer | Jonas Schnelli <jonas.schnelli@include7.ch> | 2015-09-16 16:50:19 +0200 |
commit | e2b8028e4c60708a8d49b17d9d49dda10aaecc51 (patch) | |
tree | 2b8bcb0c6f61d3fef5f957306be35672dfbb3946 /src/netbase.cpp | |
parent | 9e521c173586257f57764b479beb5923c33ed0eb (diff) |
net: Fix CIDR notation in ToString()
Only use CIDR notation if the netmask can be represented as such.
Diffstat (limited to 'src/netbase.cpp')
-rw-r--r-- | src/netbase.cpp | 58 |
1 files changed, 48 insertions, 10 deletions
diff --git a/src/netbase.cpp b/src/netbase.cpp index 4163b18086..c3d56d9184 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -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; } - return network.ToString() + strprintf("/%u", cidr); + 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() + "/" + strNetmask; } bool CSubNet::IsValid() const |