Đang tải dữ liệu...
18:12

[PHP] ip addresses and ip prefixes



<?php /**
* input $limits array or yii object of IP addresses sorted by SQL server
* returns array of aggregated prefixes and netmask lengths (aka masklen)
*/ function _viewAggregate($limits) { // input addresses must be sorted ascending
$input = $output = array();
$index = 0;
foreach( $limits as $l ) { // fix pure IPs without prefix, prepare array of prefixes
$n = explode ("/",$l->address, 1);
if (empty($n[1])) // optionally fix host mask = /32
$n[1] = 32;
$net['prefix'] = $n[0];
$net['masklen'] = $n[1];
$net['version'] = (8*strlen($net['prefix']) == 128 ) ? 6 : 4; // detect IP prefix version (6 or 4)
$net['index'] = $index;
$input[$index++] = $net; // pure array of prefixes with extra info
}
$reductions = 1; $iteration = 0;
while($reductions > 0) {
$iteration++;
$reductions = $skipNext = 0;
$output = array();
foreach( array_keys($input) as $key ) {
if ($skipNext) {
$skipNext = false;
continue;
}
$i = $input[$key];
$prefixWithoutMask = ($i['version']==4) ? ip2long($i['prefix']) >> (32-$i['masklen']) : ip2long6($i['prefix']) >> (128-$i['masklen']);
if (!empty($input[1+$key])) {
$next = $input[1+$key];
} else continue; // skip the last element
$nextPrefixWithoutMask = ($next['version']==4) ? ip2long($next['prefix']) >> (32-$next['masklen']) : ip2long6($next['prefix']) >> (128-$next['masklen']);
if ( ($i['masklen'] == $next['masklen']) // neighbouring prefixes are of the same length
AND ($nextPrefixWithoutMask - $prefixWithoutMask === 1) // prefixes differ by 1 in the last digit
AND (($prefixWithoutMask >> 1) === ($nextPrefixWithoutMask >> 1)) ) { // higher bits are equal
$i['masklen']--; // aggregate with the next record
$skipNext = true;
$reductions++;
}
$output[] = $i;
}
$input = array_merge(array(), $output); // renumber the array index/key
}
return $input;
}

function _viewMaskLengthToMask($len) { // ipv4 only
if ($len <= 32)
return long2ip(((1 << (32-$len)) - 1));
}

function ip2long6($ipv6) {
$ip_n = inet_pton($ipv6);
$bits = 15; // 16 x 8 bit = 128bit
while ($bits >= 0) {
$bin = sprintf("%08b",(ord($ip_n[$bits])));
$ipv6long = $bin.$ipv6long;
$bits--;
}
return gmp_strval(gmp_init($ipv6long,2),10);
}

function long2ip6($ipv6long) {

$bin = gmp_strval(gmp_init($ipv6long,10),2);
if (strlen($bin) < 128) {
$pad = 128 - strlen($bin);
for ($i = 1; $i <= $pad; $i++) {
$bin = "0".$bin;
}
}
$bits = 0;
while ($bits <= 7) {
$bin_part = substr($bin,($bits*16),16);
$ipv6 .= dechex(bindec($bin_part)).":";
$bits++;
}
// compress

return inet_ntop(inet_pton(substr($ipv6,0,-1)));
}



0 nhận xét

Leave a reply

Like Me On Facebook

Bài Đăng Mới

Quảng Cáo