Get IP range by CIDR notation
🔗 Permalink
I wanted to get the IPv4 range of a WHOIS record provided by LACNIC, because unlike other RIRs they don't supply you with the range, but with just a CIDR notation.
To make matters worse, they give 'incomplete' net numbers. The only working "CIDR to IP range" function I could find didn't accept it, so I had to sprinkle some magic.
<?php
$ipdata = explode('/', ltrim($incomplete_cidr_notation, '0'));
$dotcount = substr_count($ipdata[0], '.');
if ($dotcount != 3) {
$ipdata[0] .= str_repeat('.0', (3-$dotcount));
}
$finalip = sprintf('%s/%s', $ipdata[0], $ipdata[1]);
$range = cidr_conv($finalip);
?>
The final cidr_conv()
is written by someone unknown in 2003 and can be
found in the PHP.net comments of the Network functions page.
<?php
function cidr_conv($cidr_address) {
$first = substr($cidr_address, 0, strpos($cidr_address, "/"));
$netmask = substr(strstr($cidr_address, "/"), 1);
$first_bin = str_pad(decbin(ip2long($first)), 32, "0", STR_PAD_LEFT);
$netmask_bin = str_pad(str_repeat("1", (integer)$netmask), 32, "0", STR_PAD_RIGHT);
for ($i = 0; $i < 32; $i++) {
if ($netmask_bin[$i] == "1")
$last_bin .= $first_bin[$i];
else
$last_bin .= "1";
}
$last = long2ip(bindec($last_bin));
return array($first, $last);
}
?>
So you can enter 190.151.192/18
as $incomplete_cidr_notation
and get
<?php
(
[0] => 190.151.192.0
[1] => 190.151.255.255
)
?>
But even if you enter 17/8
(or with a leading zero, straight out of IANAs IP allocation file) it will work, and you'll get in this case Apple's IP range
<?php
(
[0] => 17.0.0.0
[1] => 17.255.255.255
)
?>
Update: Since this article is getting quite a few hits and when I read this back it seemed kinda confusing, I've recreated this a bit better as a Gist.