Skip to content

Commit b45c50c

Browse files
committed
Fix two problems in CSubNet parsing
Fix two CSubNet constructor problems: - The use of `/x` where 8 does not divide x was broken, due to a bit-order issue - The use of e.g. `1.2.3.4/24` where the netmasked bits in the network are not 0 was broken. Fix this by explicitly normalizing the netwok according to the bitmask. Also add tests for these cases. Fixes #6179. Thanks to @jonasschnelli for reporting and initial fix.
1 parent 19e8d7b commit b45c50c

File tree

2 files changed

+10
-1
lines changed

2 files changed

+10
-1
lines changed

src/netbase.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1260,7 +1260,7 @@ CSubNet::CSubNet(const std::string &strSubnet, bool fAllowLookup)
12601260
n += astartofs*8;
12611261
// Clear bits [n..127]
12621262
for (; n < 128; ++n)
1263-
netmask[n>>3] &= ~(1<<(n&7));
1263+
netmask[n>>3] &= ~(1<<(7-(n&7)));
12641264
}
12651265
else
12661266
{
@@ -1287,6 +1287,10 @@ CSubNet::CSubNet(const std::string &strSubnet, bool fAllowLookup)
12871287
{
12881288
valid = false;
12891289
}
1290+
1291+
// Normalize network according to netmask
1292+
for(int x=0; x<16; ++x)
1293+
network.ip[x] &= netmask[x];
12901294
}
12911295

12921296
bool CSubNet::Match(const CNetAddr &addr) const

src/test/netbase_tests.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ BOOST_AUTO_TEST_CASE(subnet_test)
117117
BOOST_CHECK(CSubNet("1:2:3:4:5:6:7:8").Match(CNetAddr("1:2:3:4:5:6:7:8")));
118118
BOOST_CHECK(!CSubNet("1:2:3:4:5:6:7:8").Match(CNetAddr("1:2:3:4:5:6:7:9")));
119119
BOOST_CHECK(CSubNet("1:2:3:4:5:6:7:0/112").Match(CNetAddr("1:2:3:4:5:6:7:1234")));
120+
BOOST_CHECK(CSubNet("192.168.0.1/24").Match(CNetAddr("192.168.0.2")));
121+
BOOST_CHECK(CSubNet("192.168.0.20/29").Match(CNetAddr("192.168.0.18")));
122+
BOOST_CHECK(CSubNet("1.2.2.1/24").Match(CNetAddr("1.2.2.4")));
123+
BOOST_CHECK(CSubNet("1.2.2.110/31").Match(CNetAddr("1.2.2.111")));
124+
BOOST_CHECK(CSubNet("1.2.2.20/26").Match(CNetAddr("1.2.2.63")));
120125
// All-Matching IPv6 Matches arbitrary IPv4 and IPv6
121126
BOOST_CHECK(CSubNet("::/0").Match(CNetAddr("1:2:3:4:5:6:7:1234")));
122127
BOOST_CHECK(CSubNet("::/0").Match(CNetAddr("1.2.3.4")));

0 commit comments

Comments
 (0)