Getting List Ips from Cidr Notation in PHP

Getting list IPs from CIDR notation in PHP

I'll edit the aforementioned class to contain a method for that. Here is the code I came up with that might help you until then.

function cidrToRange($cidr) {
$range = array();
$cidr = explode('/', $cidr);
$range[0] = long2ip((ip2long($cidr[0])) & ((-1 << (32 - (int)$cidr[1]))));
$range[1] = long2ip((ip2long($range[0])) + pow(2, (32 - (int)$cidr[1])) - 1);
return $range;
}
var_dump(cidrToRange("73.35.143.32/27"));

//////////////////OUTPUT////////////////////////
// array(2) {
// [0]=>
// string(12) "73.35.143.32"
// [1]=>
// string(12) "73.35.143.63"
// }
/////////////////////////////////////////////////

Returns the low end of the ip range as the first entry in the array, then returns the high end as the second entry.

calculate IP range using PHP and CIDR

As you've already noted, all IPv4 addresses can be converted to numbers using ip2long(), and converted back using long2ip(). The critical extra bit I'm not sure you've noticed is that sequential IPs correspond with sequential numbers, so you can manipulate these numbers!

Given a CIDR prefix (e.g, $prefix = 30 for your range), you can calculate the number of IPs in that range using a bit shift operator:

$ip_count = 1 << (32 - $prefix);

And then loop through all the IPs in that range using:

$start = ip2long($start_ip);
for ($i = 0; $i < $ip_count; $i++) {
$ip = long2ip($start + $i);
// do stuff with $ip...
}

PHP How to run list of IP ranges through a CIDR function?

Just loop through the list of ranges, and use array_merge() to append the results to the collection of all results.

$ranges = [
["start" => "8.8.8.0", "end" => "8.8.8.16"],
["start" => "192.168.10.5", "end" => "192.168.32.255"],
["start" => "10.1.2.32", "end" => "10.1.3.0"]
];
$allCidrs = [];
foreach ($ranges as $range) {
$cidr = iprange2cidr($range["start"], $range["end"]);
$allCidrs = array_merge($allCidrs, $cidr);
}

convert ip short notation into CIDR notation

Note, that I did this as a fun experiment. Your question was a little vague, and you showed no attempt to actually to this yourself. That being said, this function should accomplish what you are wanting. Let me explain what it does:

First thing, checks if last character in the ip is a dot and removes it.

Second, count the number of ranges your IP has.

Third use a switch/case statement (cleaner than if elseif IMHO) to determine what to do with the string, based on IP range.

Lastly define the starting range and the ending range and concatenate them.

Finally return result.

<?php

$ips = array();

$ips[0] = '125.45.';
$ips[1] = '201.35.1.';
$ips[2] = '101.135.2';
$ips[3] = '222.122';
$ips[4] = '78.56.21.146';

foreach($ips as $ip){

echo "\n\nNEW IP RANGE: " . convert_ip($ip) . "\n\n";

}

function convert_ip($ip){

$ip = rtrim($ip, '.');

$ip_count = count( explode('.', $ip) );

switch ($ip_count) {

case 1:

$starting_ip = $ip . '.0.0.0';

$ending_ip = $ip . '.255.255.255';

$return_ip = "$starting_ip-$ending_ip";

break;
case 2:

$starting_ip = $ip . '.0.0';

$ending_ip = $ip . '.255.255';

$return_ip = "$starting_ip-$ending_ip";

break;
case 3:

$starting_ip = $ip . '.0';

$ending_ip = $ip . '.255';

$return_ip = "$starting_ip-$ending_ip";

break;
case 4:

$return_ip = $ip;

break;

default:
$return_ip = 'Unknown';
}

return $return_ip;

}

?>

NEW IP RANGE: 125.45.0.0-125.45.255.255

NEW IP RANGE: 201.35.1.0-201.35.1.255

NEW IP RANGE: 101.135.2.0-101.135.2.255

NEW IP RANGE: 222.122.0.0-222.122.255.255

NEW IP RANGE: 78.56.21.146

Check whether or not a CIDR subnet contains an IP address

If only using IPv4:

  • use ip2long() to convert the IPs and the subnet range into long integers
  • convert the /xx into a subnet mask
  • do a bitwise 'and' (i.e. ip & mask)' and check that that 'result = subnet'

something like this should work:

function cidr_match($ip, $range)
{
list ($subnet, $bits) = explode('/', $range);
if ($bits === null) {
$bits = 32;
}
$ip = ip2long($ip);
$subnet = ip2long($subnet);
$mask = -1 << (32 - $bits);
$subnet &= $mask; # nb: in case the supplied subnet wasn't correctly aligned
return ($ip & $mask) == $subnet;
}

Convert Array From IP CIDR

Just put the result of the function call into a variable and then print the parts you want

<?php
function cidrToRange($cidr) {
$range = array();
$cidr = explode('/', $cidr);
$range[0] = long2ip((ip2long($cidr[0])) & ((-1 << (32 - (int)$cidr[1]))));
$range[1] = long2ip((ip2long($range[0])) + pow(2, (32 - (int)$cidr[1])) - 1);
return $range;
}
$range = cidrToRange("104.176.0.0/12");
echo 'Staring at ' . $range[0] .'<br>'
echo 'Ending at ' . $range[1] .'<br>'

How to load a list of ip ranges to use it with $allowedIps script?

/*
You need the proper fopen wrapper server settings for reading
URLs using file_get_contents, see the notes at the PHP manual
*/
$allowedIps = explode('\n', file_get_contents('http://my/url/file.txt'));
$userIp = $_SERVER['REMOTE_ADDR'];

if (!in_array($userIp, $allowedIps)) {
exit('Unauthorized');
}

PHP manual for file_get_contents

What is the best way to get /24 blocks from IP address ranges?

Here is the example off of https://www.php.net/manual/en/ref.network.php#74656

A simple and very fast function to check against CIDR.

This example takes into account your range parameter

Here it is (only with arithmetic operators and call only to ip2long () and split() ):

<?php

function ipCIDRCheck ($IP, $CIDR) {
list ($net, $mask) = explode("/", $CIDR);

$ip_net = ip2long ($net);
$ip_mask = ~((1 << (32 - $mask)) - 1);

$ip_ip = ip2long ($IP);

$ip_ip_net = $ip_ip & $ip_mask;

return long2ip($ip_ip_net);
}

$range = "86.111.160.0 - 86.111.175.255";
list($lower,$upper) = explode('-',$range);
$lowerIp = ip2long(trim($lower));
$upperIp = ip2long(trim($upper));

while($lowerIp <= $upperIp){
echo ipCIDRCheck(long2ip($lowerIp),long2ip($lowerIp) .'/24') . "\n\r";
$lowerIp += 255;
}



Related Topics



Leave a reply



Submit