Browse Source

Merge pull request #6186

b45c50c Fix two problems in CSubNet parsing (Wladimir J. van der Laan)
19e8d7b Simplify code for CSubnet (Wladimir J. van der Laan)
0.13
Wladimir J. van der Laan 10 years ago
parent
commit
182686cdbd
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 20
      src/netbase.cpp
  2. 2
      src/netbase.h
  3. 5
      src/test/netbase_tests.cpp

20
src/netbase.cpp

@ -1252,15 +1252,15 @@ CSubNet::CSubNet(const std::string &strSubnet, bool fAllowLookup) @@ -1252,15 +1252,15 @@ CSubNet::CSubNet(const std::string &strSubnet, bool fAllowLookup)
std::string strNetmask = strSubnet.substr(slash + 1);
int32_t n;
// IPv4 addresses start at offset 12, and first 12 bytes must match, so just offset n
int noffset = network.IsIPv4() ? (12 * 8) : 0;
const int astartofs = network.IsIPv4() ? 12 : 0;
if (ParseInt32(strNetmask, &n)) // If valid number, assume /24 symtex
{
if(n >= 0 && n <= (128 - noffset)) // Only valid if in range of bits of address
if(n >= 0 && n <= (128 - astartofs*8)) // Only valid if in range of bits of address
{
n += noffset;
n += astartofs*8;
// Clear bits [n..127]
for (; n < 128; ++n)
netmask[n>>3] &= ~(1<<(n&7));
netmask[n>>3] &= ~(1<<(7-(n&7)));
}
else
{
@ -1271,12 +1271,10 @@ CSubNet::CSubNet(const std::string &strSubnet, bool fAllowLookup) @@ -1271,12 +1271,10 @@ CSubNet::CSubNet(const std::string &strSubnet, bool fAllowLookup)
{
if (LookupHost(strNetmask.c_str(), vIP, 1, false)) // Never allow lookup for netmask
{
// Remember: GetByte returns bytes in reversed order
// Copy only the *last* four bytes in case of IPv4, the rest of the mask should stay 1's as
// we don't want pchIPv4 to be part of the mask.
int asize = network.IsIPv4() ? 4 : 16;
for(int x=0; x<asize; ++x)
netmask[15-x] = vIP[0].GetByte(x);
for(int x=astartofs; x<16; ++x)
netmask[x] = vIP[0].ip[x];
}
else
{
@ -1289,6 +1287,10 @@ CSubNet::CSubNet(const std::string &strSubnet, bool fAllowLookup) @@ -1289,6 +1287,10 @@ CSubNet::CSubNet(const std::string &strSubnet, bool fAllowLookup)
{
valid = false;
}
// Normalize network according to netmask
for(int x=0; x<16; ++x)
network.ip[x] &= netmask[x];
}
bool CSubNet::Match(const CNetAddr &addr) const
@ -1296,7 +1298,7 @@ bool CSubNet::Match(const CNetAddr &addr) const @@ -1296,7 +1298,7 @@ bool CSubNet::Match(const CNetAddr &addr) const
if (!valid || !addr.IsValid())
return false;
for(int x=0; x<16; ++x)
if ((addr.GetByte(x) & netmask[15-x]) != network.GetByte(x))
if ((addr.ip[x] & netmask[x]) != network.ip[x])
return false;
return true;
}

2
src/netbase.h

@ -100,6 +100,8 @@ class CNetAddr @@ -100,6 +100,8 @@ class CNetAddr
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(FLATDATA(ip));
}
friend class CSubNet;
};
class CSubNet

5
src/test/netbase_tests.cpp

@ -117,6 +117,11 @@ BOOST_AUTO_TEST_CASE(subnet_test) @@ -117,6 +117,11 @@ BOOST_AUTO_TEST_CASE(subnet_test)
BOOST_CHECK(CSubNet("1:2:3:4:5:6:7:8").Match(CNetAddr("1:2:3:4:5:6:7:8")));
BOOST_CHECK(!CSubNet("1:2:3:4:5:6:7:8").Match(CNetAddr("1:2:3:4:5:6:7:9")));
BOOST_CHECK(CSubNet("1:2:3:4:5:6:7:0/112").Match(CNetAddr("1:2:3:4:5:6:7:1234")));
BOOST_CHECK(CSubNet("192.168.0.1/24").Match(CNetAddr("192.168.0.2")));
BOOST_CHECK(CSubNet("192.168.0.20/29").Match(CNetAddr("192.168.0.18")));
BOOST_CHECK(CSubNet("1.2.2.1/24").Match(CNetAddr("1.2.2.4")));
BOOST_CHECK(CSubNet("1.2.2.110/31").Match(CNetAddr("1.2.2.111")));
BOOST_CHECK(CSubNet("1.2.2.20/26").Match(CNetAddr("1.2.2.63")));
// All-Matching IPv6 Matches arbitrary IPv4 and IPv6
BOOST_CHECK(CSubNet("::/0").Match(CNetAddr("1:2:3:4:5:6:7:1234")));
BOOST_CHECK(CSubNet("::/0").Match(CNetAddr("1.2.3.4")));

Loading…
Cancel
Save