IP range contains maybe wrong
regnerisch opened this issue ยท 4 comments
Here a example of the bug(?):
$ipRange = \IPLib\Factory::rangeFromBoundaries('46.222.1.1', '46.223.25.255');
var_dump($ipRange->contains(\IPLib\Factory::addressFromString('46.223.26.1')), (string) $ipRange, (string) $ipRange->getEndAddress());
This shows something like:
true, 46.222.0.0/15, 46.223.255.255
But shouldn't be 46.223.25.255 be the last ip address in the range? I need to check if the given IP is between the range, and currently it is, but i think it should not. Is there a possibility to check whether the given ip is inside of the other two?
The problem is that IPLib\Factory::rangeFromBoundaries()
builds a CIDR/pattern range.
In your case, you have these two bounadry IPs
Decimal notation | Binary notation |
---|---|
46.222.1.1 |
โญ00101110 11011110 00000001 00000001 |
46.223.25.255 |
00101110 11011111โฌ 00011001 11111111 |
As you can see from the binary representation, the first 15 bits are in common, so the library builds the range 46.222.0.0/15
, whose boundaries are actually 46.222.0.0
and 46.223.255.255
(so, 46.223.26.1
is included in that range).
So, since your boundaries don't match the final range, I'd simply do something like this:
$start = \IPLib\Factory::addressFromString('46.222.1.1');
$end = \IPLib\Factory::addressFromString('46.223.25.255');
$ip = \IPLib\Factory::addressFromString('46.223.26.1');
$ipInRange = $ip->getComparableString() >= $start->getComparableString() && $ip->getComparableString() <= $end->getComparableString();
Thank you ๐
I think you can close this issue
@regnerisch FYI I just published a new version (1.14.0) that provides a way to retrieve the ranges that exactly describe all the addresses between two boundaries (see IPLibFactory::rangesFromBoundaries()
, which differs from IPLibFactory::rangeFromBoundaries()
).
For example:
$ip = \IPLib\Factory::addressFromString('46.223.26.1');
$ipRange = \IPLib\Factory::rangeFromBoundaries('46.222.1.1', '46.223.25.255');
// This will print true
var_dump($ipRange->contains($ip));
with this new method:
$ip = \IPLib\Factory::addressFromString('46.223.26.1');
$ipRanges = \IPLib\Factory::rangesFromBoundaries('46.222.1.1', '46.223.25.255');
$contains = false;
foreach ($ipRanges as $ipRange) {
if ($ipRange->contains($ip)) {
$contains = true;
break;
}
}
// This will print false
var_dump($contains);