mfontanini / libtins

High-level, multiplatform C++ network packet sniffing and crafting library.
http://libtins.github.io/
BSD 2-Clause "Simplified" License
1.91k stars 377 forks source link

Incorrect IP Address range calculation when using /0 prefix #484

Closed mbcdev closed 1 year ago

mbcdev commented 2 years ago

It looks like IP address range calculations are not working correctly when using a /0 prefix.

Test Results (using 64-Bit Windows):

auto host_ip = Tins::IPv4Address("10.2.34.10");
auto zero_ip = Tins::IPv4Address("0.0.0.0");
auto zero_mask = Tins::IPv4Address("0.0.0.0");

auto range1 = Tins::IPv4Range::from_mask(zero_ip, zero_mask);
auto is_in_range1 = range1.contains(host_ip); // true (correct!)

auto range2 = Tins::IPv4Address(zero_ip) / 0;
auto is_in_range2 = range2.contains(host_ip); // false (wrong, should be true!)

auto range3 = Tins::IPv4Range::from_mask(zero_ip, Tins::IPv4Address::from_prefix_length(0));
auto is_in_range3 = range3.contains(host_ip); // false (wrong, should be true as well!)

auto mask0 = Tins::IPv4Address::from_prefix_length(0);
auto mask32 = Tins::IPv4Address::from_prefix_length(32);
auto is_equal = (mask0 == mask32); // true (wrong, should be false!)
mbcdev commented 2 years ago

Reason: 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 e.g. 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.

see #486 for fix proposal

mbcdev commented 1 year ago

merged, closing issue