kebabs
asked on
How do I summarise CIDR addresses in PHP?
I have a list of CIDR addresses that can be summarised/aggregated and I wish to do this in PHP but cannot find a PEAR package or class through the likes of http://phpclasses.org to do this task.
There is a Perl extension Net::CIDR::Lite and a Ruby class but I'm having a hard time trying to convert this to PHP nor do I want to spend much time on that.
Here is an excerpt of a possible output.
There is a Perl extension Net::CIDR::Lite and a Ruby class but I'm having a hard time trying to convert this to PHP nor do I want to spend much time on that.
Here is an excerpt of a possible output.
58.6.0.0/15
58.65.248.0/21
58.84.64.0/18
58.84.128.0/18
58.84.192.0/19
58.84.240.0/20
58.87.0.0/20
58.96.0.0/16
58.97.128.0/17
58.104.0.0/13
58.145.128.0/19
58.160.0.0/12
58.178.0.0/15
58.181.64.0/19
58.181.112.0/20
59.86.160.0/19
59.100.0.0/15
59.102.0.0/16
59.151.128.0/18
59.152.224.0/19
59.154.0.0/18
59.154.64.0/19
59.154.96.0/23
59.154.98.0/24
59.154.99.0/25
59.154.99.128/27
59.154.99.160/28
59.154.99.176/29
59.154.99.184/30
59.154.99.192/26
59.154.100.0/22
59.154.104.0/21
59.154.112.0/20
59.154.128.0/17
59.167.0.0/16
59.191.192.0/19
59.191.224.0/20
ASKER
Bitwise operators give me too much of a head ache, possibly the worst aspect of writing code. Otherwise, I could simply transcode the Perl/Ruby variants. I was hoping for a ready solution.
Sorry for that! I searched Google and it didn't come up with anything useful. I want to make a real code that works but this weekend I don't have the time. Maybe tonight when I come home. I'm a nightowl! One question though... are the IP-addresses you submitted already summarized? (I think they are) If so, can you please send some example IP-addresses that should be summarized.
For example: Any IPs that summarize into 58.84.240.0/20.
For example: Any IPs that summarize into 58.84.240.0/20.
ASKER
The example was not a good one... below is one that summarises better. If you do take the time to write one, make sure to leave a point of contact as I doubt some points here are enough reward :)
# Summarised (9 CIDR addresses)
58.147.128.0/19
117.55.192.0/20
121.100.48.0/21
125.213.192.0/19
202.56.176.0/20
202.86.16.0/20
203.215.32.0/20
210.80.0.0/19
210.80.32.0/19
# Unsummarised (72 CIDR addresses)
58.147.128.0/19
62.142.210.32/27
63.243.149.0/27
63.243.150.8/29
63.243.150.16/28
64.86.63.64/27
80.247.139.0/24
82.205.190.0/23
82.205.192.0/21
82.205.202.0/23
82.205.204.0/22
82.205.246.0/25
84.11.26.128/26
84.11.33.0/24
84.11.79.0/24
87.249.84.0/24
117.55.192.0/20
117.104.224.0/21
121.100.48.0/21
121.127.32.0/19
125.213.192.0/19
202.56.176.0/20
202.86.16.0/20
202.133.9.240/28
202.133.13.8/29
202.133.13.16/28
202.133.13.40/29
202.133.13.56/29
202.133.13.96/28
202.174.133.8/29
202.174.133.32/28
202.174.133.144/29
202.174.134.0/29
202.174.144.0/29
202.174.144.216/29
202.174.148.48/29
202.174.148.128/29
202.174.153.184/29
202.174.154.0/29
202.174.154.24/29
202.174.154.96/28
202.174.154.128/29
202.174.154.160/29
202.174.154.180/30
202.174.154.184/30
202.174.154.212/30
202.174.155.128/29
202.174.155.144/29
202.174.155.216/29
202.174.155.240/29
202.174.156.64/26
202.174.156.192/28
202.174.156.208/29
202.174.156.248/29
202.174.157.192/27
202.174.157.232/29
203.88.66.64/29
203.88.66.160/29
203.88.82.240/29
203.88.88.24/29
203.88.88.32/29
203.88.88.40/30
203.88.88.160/29
203.88.88.224/29
203.208.205.192/26
203.215.32.0/20
208.35.53.176/28
210.5.226.0/24
212.116.232.208/28
217.10.167.0/24
217.195.144.24/29
217.195.144.32/30
ASKER
BTW, this was data from 2 different sources covering Afghanistan's IP ranges (the country was only for example's sake). I think the unsummarised list is an older/newer list as there seems to be some ranges that are not represented in the summarised one.
Hmm, it was more difficult than I thought it should be. I'm too tired I have to much to do in school so I don't have the time. I have a problem with my code-logic, but I'm posting my code so far and some pseudo-code for you to try. I need to point out that I'm studying for the CCNA exam and so my CIDR knowledge is a bit bad, but I think I know how to calculate it (taking common bits and return network_address/bits). See pseudo for more details.
I am sorry for this but I hope you get a solution soon. You can e-mail me on waschman at gmail dot com when you find a solution. Good luck!
I am sorry for this but I hope you get a solution soon. You can e-mail me on waschman at gmail dot com when you find a solution. Good luck!
/**
* Get single IP-address class
*
* @param string $ip
*/
function get_ip_class($ip)
{
$class = false;
$octet = explode('.', $ip);
if ($octet[0] <= 126) $class = 'A';
elseif ($octet[0] == 127) $class = 'Loopback';
elseif ($octet[0] <= 191) $class = 'B';
elseif ($octet[0] <= 223) $class = 'C';
elseif ($octet[0] <= 239) $class = 'Multicast';
else $class = 'Reserved';
return $class;
}
/**
* Enter description here...
*
* @param array $ip
*/
function summarize($ips)
{
$count = count($ips);
$octet_diff = 0;
// Save all octets into an array
for ($pos=0; $pos<4; $pos++) {
for ($i=0; $i<$count; $i++) {
$octets[$i] = explode('.', $ips[$i], 4);
// Save first octet so we can check which octet differs from
// the others. Crucial when we want to know where to begin checking
// of binary digits.
if ($i==0) $first = $octets[$i][$pos];
// Find different octets
if ($first != $octets[$i][$pos]) {
$debug = $i .':'. $pos;//save which IP and octet
$octet_diff = $pos;
break;
}
}
}
echo 'Debug: Position of octet that differs is '. $debug .'<br>';
// Logic problem here -- too tired and too much in to do in school instead
// Some kind of main-loop.
// Check the diffing octet in IP x and x+1.
// Convert them both to binary (or leave as int).
// Loop through binary positions, starting from the left.
// Is ANDing y bit of octet in IP x y bit of octet in IP x+1 equal to 1?
// If 1 goto next loop.
// Now compare y bit of octet in IP x+1 and x+2.
// Is ANDing equal to 1?
// And so on...
//
// Loop through y bit of all IP:s passed to summarize().
// If every ANDing did get 1 move on to y+1 bit.
// And repeat above until you encounter an ANDing equal to 0.
// If 0 then we have all the bits needed to summarize the IP-addresses.
// We only have to keep track of the number of bits tested from left
// to right to have the number of bits used for the subnetmask.
}
// Should summarize into 192.168.16.0/20
$ip[] = '192.168.1.0';
$ip[] = '192.168.2.0';
$ip[] = '192.168.3.0';
$ip[] = '192.168.4.0';
$ip[] = '192.168.5.0';
$ip[] = '192.168.6.0';
$ip[] = '192.168.7.0';
$ip[] = '192.168.8.0';
$ip[] = '192.168.9.0';
$ip[] = '192.168.10.0';
$cidr_ip = summarize($ip);
echo '<p>'. $cidr_ip .'</p>';
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Then you can use the convert-to-binary functions to convert between int and bin.
I assume you know how to calculate summaries with CIDR addressing.
Open in new window