Skip to content

Commit eb997f5

Browse files
authored
fix incorrect IP address range calculation when using /0 prefix (#484) (#486)
According to the C/C++ Standard, for shift operations, the behavior is undefined if the right operand is equal to the width of the promoted left operand. On a 64-bit Windows machine, this causes IP addresses 0.0.0.0 and 255.255.255.255 to have the same internal representation, leading to various issues when using a /0 prefix.
1 parent 18cbab4 commit eb997f5

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

src/ip_address.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ const AddressRange<IPv4Address> loopback_range = IPv4Address("127.0.0.0") / 8;
6262
const AddressRange<IPv4Address> multicast_range = IPv4Address("224.0.0.0") / 4;
6363

6464
IPv4Address IPv4Address::from_prefix_length(uint32_t prefix_length) {
65-
return IPv4Address(Endian::host_to_be(0xffffffff << (32 - prefix_length)));
65+
return IPv4Address(prefix_length ? Endian::host_to_be(0xffffffff << (32 - prefix_length)) : 0u);
6666
}
6767

6868
IPv4Address::IPv4Address(uint32_t ip)

tests/src/address_range_test.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,19 @@ using namespace Tins;
1212

1313
class AddressRangeTest : public testing::Test {
1414
public:
15+
void contain_tests0(const IPv4Range& range);
16+
void contain_tests0(const IPv6Range& range);
1517
void contain_tests24(const IPv4Range& range);
1618
void contain_tests24(const IPv6Range& range);
1719
void contain_tests26(const IPv4Range& range);
1820
};
1921

22+
void AddressRangeTest::contain_tests0(const IPv4Range& range) {
23+
EXPECT_TRUE(range.contains("0.0.0.0"));
24+
EXPECT_TRUE(range.contains("192.168.1.1"));
25+
EXPECT_TRUE(range.contains("255.255.255.255"));
26+
}
27+
2028
void AddressRangeTest::contain_tests24(const IPv4Range& range) {
2129
EXPECT_TRUE(range.contains("192.168.0.0"));
2230
EXPECT_TRUE(range.contains("192.168.0.1"));
@@ -33,6 +41,12 @@ void AddressRangeTest::contain_tests26(const IPv4Range& range) {
3341
EXPECT_FALSE(range.contains("192.168.254.191"));
3442
}
3543

44+
void AddressRangeTest::contain_tests0(const IPv6Range& range) {
45+
EXPECT_TRUE(range.contains("::"));
46+
EXPECT_TRUE(range.contains("dead::1:1"));
47+
EXPECT_TRUE(range.contains("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
48+
}
49+
3650
void AddressRangeTest::contain_tests24(const IPv6Range& range) {
3751
EXPECT_TRUE(range.contains("dead::1"));
3852
EXPECT_TRUE(range.contains("dead::1fee"));
@@ -42,13 +56,22 @@ void AddressRangeTest::contain_tests24(const IPv6Range& range) {
4256
}
4357

4458
TEST_F(AddressRangeTest, Contains) {
59+
contain_tests0(IPv4Range("0.0.0.0", "255.255.255.255"));
60+
contain_tests0(IPv4Range::from_mask("0.0.0.0", "0.0.0.0"));
61+
contain_tests0(IPv4Range::from_mask("0.0.0.0", IPv4Address::from_prefix_length(0)));
4562
contain_tests24(IPv4Range("192.168.0.0", "192.168.0.255"));
4663
contain_tests24(IPv4Range::from_mask("192.168.0.0", "255.255.255.0"));
64+
contain_tests24(IPv4Range::from_mask("192.168.0.0", IPv4Address::from_prefix_length(24)));
4765
contain_tests26(IPv4Range("192.168.254.192", "192.168.254.255"));
4866
contain_tests26(IPv4Range::from_mask("192.168.254.192", "255.255.255.192"));
67+
contain_tests26(IPv4Range::from_mask("192.168.254.192", IPv4Address::from_prefix_length(26)));
4968

69+
contain_tests0(IPv6Range("::0", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
70+
contain_tests0(IPv6Range::from_mask("::", "::"));
71+
contain_tests0(IPv6Range::from_mask("::", IPv6Address::from_prefix_length(0)));
5072
contain_tests24(IPv6Range("dead::0", "dead::ffff"));
5173
contain_tests24(IPv6Range::from_mask("dead::0", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:0"));
74+
contain_tests24(IPv6Range::from_mask("dead::0", IPv6Address::from_prefix_length(112)));
5275

5376
{
5477
AddressRange<HWAddress<6> > range("00:00:00:00:00:00", "00:00:00:00:00:ff");

0 commit comments

Comments
 (0)