|
|
@ -1067,15 +1067,24 @@ CSubNet::CSubNet(const CNetAddr& addr, const CNetAddr& mask) : CSubNet() |
|
|
|
|
|
|
|
CSubNet::CSubNet(const CNetAddr& addr) : CSubNet() |
|
|
|
{ |
|
|
|
valid = addr.IsIPv4() || addr.IsIPv6(); |
|
|
|
if (!valid) { |
|
|
|
switch (addr.m_net) { |
|
|
|
case NET_IPV4: |
|
|
|
case NET_IPV6: |
|
|
|
valid = true; |
|
|
|
assert(addr.m_addr.size() <= sizeof(netmask)); |
|
|
|
memset(netmask, 0xFF, addr.m_addr.size()); |
|
|
|
break; |
|
|
|
case NET_ONION: |
|
|
|
case NET_I2P: |
|
|
|
case NET_CJDNS: |
|
|
|
valid = true; |
|
|
|
break; |
|
|
|
case NET_INTERNAL: |
|
|
|
case NET_UNROUTABLE: |
|
|
|
case NET_MAX: |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
assert(addr.m_addr.size() <= sizeof(netmask)); |
|
|
|
|
|
|
|
memset(netmask, 0xFF, addr.m_addr.size()); |
|
|
|
|
|
|
|
network = addr; |
|
|
|
} |
|
|
|
|
|
|
@ -1087,6 +1096,21 @@ bool CSubNet::Match(const CNetAddr &addr) const |
|
|
|
{ |
|
|
|
if (!valid || !addr.IsValid() || network.m_net != addr.m_net) |
|
|
|
return false; |
|
|
|
|
|
|
|
switch (network.m_net) { |
|
|
|
case NET_IPV4: |
|
|
|
case NET_IPV6: |
|
|
|
break; |
|
|
|
case NET_ONION: |
|
|
|
case NET_I2P: |
|
|
|
case NET_CJDNS: |
|
|
|
case NET_INTERNAL: |
|
|
|
return addr == network; |
|
|
|
case NET_UNROUTABLE: |
|
|
|
case NET_MAX: |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
assert(network.m_addr.size() == addr.m_addr.size()); |
|
|
|
for (size_t x = 0; x < addr.m_addr.size(); ++x) { |
|
|
|
if ((addr.m_addr[x] & netmask[x]) != network.m_addr[x]) { |
|
|
@ -1098,18 +1122,35 @@ bool CSubNet::Match(const CNetAddr &addr) const |
|
|
|
|
|
|
|
std::string CSubNet::ToString() const |
|
|
|
{ |
|
|
|
assert(network.m_addr.size() <= sizeof(netmask)); |
|
|
|
std::string suffix; |
|
|
|
|
|
|
|
uint8_t cidr = 0; |
|
|
|
switch (network.m_net) { |
|
|
|
case NET_IPV4: |
|
|
|
case NET_IPV6: { |
|
|
|
assert(network.m_addr.size() <= sizeof(netmask)); |
|
|
|
|
|
|
|
for (size_t i = 0; i < network.m_addr.size(); ++i) { |
|
|
|
if (netmask[i] == 0x00) { |
|
|
|
break; |
|
|
|
uint8_t cidr = 0; |
|
|
|
|
|
|
|
for (size_t i = 0; i < network.m_addr.size(); ++i) { |
|
|
|
if (netmask[i] == 0x00) { |
|
|
|
break; |
|
|
|
} |
|
|
|
cidr += NetmaskBits(netmask[i]); |
|
|
|
} |
|
|
|
cidr += NetmaskBits(netmask[i]); |
|
|
|
|
|
|
|
suffix = strprintf("/%u", cidr); |
|
|
|
break; |
|
|
|
} |
|
|
|
case NET_ONION: |
|
|
|
case NET_I2P: |
|
|
|
case NET_CJDNS: |
|
|
|
case NET_INTERNAL: |
|
|
|
case NET_UNROUTABLE: |
|
|
|
case NET_MAX: |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
return network.ToString() + strprintf("/%u", cidr); |
|
|
|
return network.ToString() + suffix; |
|
|
|
} |
|
|
|
|
|
|
|
bool CSubNet::IsValid() const |
|
|
@ -1119,7 +1160,19 @@ bool CSubNet::IsValid() const |
|
|
|
|
|
|
|
bool CSubNet::SanityCheck() const |
|
|
|
{ |
|
|
|
if (!(network.IsIPv4() || network.IsIPv6())) return false; |
|
|
|
switch (network.m_net) { |
|
|
|
case NET_IPV4: |
|
|
|
case NET_IPV6: |
|
|
|
break; |
|
|
|
case NET_ONION: |
|
|
|
case NET_I2P: |
|
|
|
case NET_CJDNS: |
|
|
|
return true; |
|
|
|
case NET_INTERNAL: |
|
|
|
case NET_UNROUTABLE: |
|
|
|
case NET_MAX: |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
for (size_t x = 0; x < network.m_addr.size(); ++x) { |
|
|
|
if (network.m_addr[x] & ~netmask[x]) return false; |
|
|
|