download this file: mkmerge-from-geoip.php view text/plain: mkmerge-from-geoip.php file encoding: UTF-8 [goback]
<?php
##
## san2@2015.07.29: add inet_cidrtonetmask()
## san2@2013.07.xx : new build
##
function inet_aton($ipaddr)
{
return sprintf('%u',ip2long($ipaddr));
}
function inet_ntoa($base)
{
return long2ip($base);
}
function inet_ntocidr($netmask)
{
$netmask = trim($netmask);
$bits = decbin(abs(sprintf('%u',ip2long($netmask))));
$cidr = strpos($bits,'0') + 0;
return ($cidr > 0) ? $cidr : 32;
}
function inet_cidrtonetmask($cidr)
{
$cidr = (int)preg_replace('/[^\d]+/','',$cidr);
if($cidr > 32) return FALSE;
$n = floor($cidr/8);
$p = $cidr % 8;
$m = '';
for($i=1; $i<=$n; $i++) $m .= '255.';
if($p > 0) { $m .= (256-pow(2,8-$p)).'.'; $n++; }
for($i=$n; $i<4; $i++) $m .= '0.';
$m = preg_replace('/\.$/','',$m);
return $m;
}
## network to pow of bit
##
function inet_ntopow($start, $end, $nn=0)
{
static $_class_b = 2147483648; // inet_aton('128.0.0.0') == start of B class
static $_class_c = 3221225472; // inet_aton('192.0.0.0') == start of C class
static $_all_bit = 4294967295; // inet_aton('255.255.255.255')
if($start < $_class_b) $pow = 1; // is an A class
else if($start < $_class_c) $pow = 8; // is a B class
else
{
if(!$nn)
{
$nn = $start + $_all_bit - $end; // network to int
//$ln = strlen(preg_replace('/^([1]+).*$/','\1',decbin($nn)));
}
$pow = strpos(decbin($nn),"0");
}
return $pow; // integer, pow of bit
}
function _find_subnet($start, $end, $np=0, $nn=0)
{
if(!$np) $np = inet_ntopow($start,$end,$nn);
for($l=$np; $l<=32; $l++)
{
$hbit = 32 - $l;
$host = pow(2,$hbit);
$tbit = str_repeat(1,$l).str_repeat(0,$hbit);
$tnet = bindec($tbit);
$tend = $start + $host - 1;
//echo $l."\n";
if($tend > $end) continue;
$tand = bindec($tbit & sprintf('%032b',$tend));
if($start == $tand)
{
//$nstart = $tend + 1; // change
break;
}
}
return array($tend,$tnet);
}
function mksubnet($start, $end)
{
$r = array();
$np = inet_ntopow($start,$end);
while($start <= $end)
{
list($tend,$mask) = _find_subnet($start,$end,$np);
$ps = inet_ntoa($start);
$pe = inet_ntoa($tend);
$netmask = inet_ntoa($mask);
$cidr = inet_ntocidr($netmask);
$r[] = array($ps,$pe,$netmask,$cidr);
$start = $tend + 1; // change
}
return $r; // array
}
## GeoIP-103_20130618-KR.txt
## file format
## 1.11.0.0 1.11.255.255 16 17498112 17563647 KR Korea Republic of
## 1.16.0.0 1.19.255.255 14 17825792 18087935 KR Korea Republic of
$file = $_SERVER['argv'][1];
if(!file_exists($file)) exit(1);
$f = file($file);
$size = sizeof($f);
$netblock = array();
for($i=0; $i<$size; $i++)
{
$tmp = preg_split('/\s+/',$f[$i]);
$netblock[] = array_slice($tmp,0,5);
}
## merge and mksubnet
##
$size = sizeof($netblock);
$start = NULL;
for($i=0; $i<$size; $i++)
{
list(,$endip,,$s,$end) = $netblock[$i];
$start = $start ? $start : $s;
if(($end + 1) == $netblock[$i+1][3])
{
continue; // not next skip
}
$nn = $start + inet_aton('255.255.255.255') - $end;
$nu = $end - $start + 1; // number of host
$nnbit = decbin($nn);
if(preg_match('/^[1]+[0]*$/',$nnbit)) // is subnet
{
$startip = inet_ntoa($start);
$endip = inet_ntoa($end);
$netmask = inet_ntoa($nn);
$cidr = inet_ntocidr($netmask);
echo "$startip\t$endip\t$netmask\t$cidr\n";
} else
{
$np = inet_ntopow($start,$end,$nn);
$tmp = mksubnet($start,$end,$np,$nn);
foreach($tmp AS $arr)
{
list($startip,$endip,$netmask,$cidr) = $arr;
echo "$startip\t$endip\t$netmask\t$cidr\n";
}
}
flush();
unset($start);
}
exit(0);
?>