@ -1068,15 +1068,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 ;
}
@ -1088,6 +1097,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 ] ) {
@ -1099,18 +1123,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 ( ) + s uffix ;
}
bool CSubNet : : IsValid ( ) const
@ -1120,7 +1161,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 ;