<?php
function cngeoip4array($ip, $dbfile='') {
$info = cngeoip4text($ip, $dbfile);
if ( is_array($info) )
return $info;
$result = explode('!', $info);
for($i=1,$s=sizeof($result); $i<$s; $i++) {
$result[$i] = explode('|', $result[$i]);
}
return $result;
}
function cngeoip4array1251($ip, $dbfile='') {
$info = cngeoip4unUTF(cngeoip4text($ip, $dbfile));
$result = explode('!', $info);
for($i=1,$s=sizeof($result); $i<$s; $i++) {
$result[$i] = explode('|', $result[$i]);
}
return $result;
}
function cngeoip_lookup_ip($ip, $dbfile='') {
$result = cngeoip4array($ip, $dbfile);
if ( sizeof($result) < 2 )
return array('','','','','','','','','');
$old = array(
'',
'',
$result[sizeof($result)-1][6],
$result[1][4],
$result[1][5],
$result[sizeof($result)-1][3],
$result[sizeof($result)-1][2],
'',
'');
reset ($result);
foreach ($result as $r) {
if ( !is_array($r) )
continue;
if ( @$r[0] == 't' ) {
$old[0] = $r[3];
$old[1] = $r[2];
}
}
reset ($result);
foreach ($result as $r) {
if ( !is_array($r) )
continue;
if ( @$r[0] == 'r' ) {
$old[7] = $r[3];
$old[8] = $r[2];
}
}
return $old;
}
function cngeoip_lookup_ip_cp1251($ip, $dbfile='') {
$result = cngeoip4array1251($ip, $dbfile);
if ( sizeof($result) < 2 )
return array('','','','','','','','','');
$old = array(
'',
'',
$result[sizeof($result)-1][6],
$result[1][4],
$result[1][5],
$result[sizeof($result)-1][3],
$result[sizeof($result)-1][2],
'',
'');
foreach ($result as $r) {
if ( !is_array($r) )
continue;
if ( @$r[0] == 't' ) {
$old[0] = $r[3];
$old[1] = $r[2];
}
}
reset ($result);
foreach ($result as $r) {
if ( !is_array($r) )
continue;
if ( @$r[0] == 'r' ) {
$old[7] = $r[3];
$old[8] = $r[2];
}
}
return $old;
}
function cngeoip4text($ip, $dbfile='') {
if ( ereg("^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$", $ip, $res) ) {
if ( $res[1] > 255 || $res[2] > 255 || $res[3] > 255 || $res[4] > 255) return array('error'=>'invalid ip');
} else
return array('error'=>'invalid ip');
$ipint = ($res[1]<<24) + ($res[2]<<16) + ($res[3]<<8) + $res[4];
if ( $dbfile == '' )
$FP = fopen(dirname(__FILE__)."/cngeoip.dat", "r");
else
$FP = fopen($dbfile, "r");
if ( !$FP )
return array('error'=>'datafile not found');
$data = fread($FP, 4);
$unp = unpack('Ndata', $data);
if ( (($unp['data'] >> 8) & 0xffffff) != 0xcd301b )
return array('error'=>'invalid datafile signature', 'signature'=>(($unp['data'] >> 8) & 0xffffff));
if ( (($unp['data']) & 0xff) != 0x01 )
return array('error'=>'incompatible datafile version', 'version'=>(($unp['data']) & 0xff));
$LEVEL_SIZE = array();
for(;;) {
$data = fread($FP, 1);
$unp = unpack('Cdata', $data);
$hi = ($unp['data']>>4) & 0x0f;
$lo = $unp['data'] & 0x0f;
$LEVEL_SIZE[] = $hi;
if ( $hi == 0 )
break;
$LEVEL_SIZE[] = $lo;
if ( $lo == 0 )
break;
}
$first_xor_code = 1;
for($i=0,$left=32;$i<sizeof($LEVEL_SIZE);$i++) {
if ( $LEVEL_SIZE[$i] == 0 )
break;
$first_xor_code <<= $LEVEL_SIZE[$i];
$first_xor_code += $left;
$first_xor_code = (($first_xor_code >> 11) & 0x001fffff) + ( $first_xor_code << 11);
$left -= $LEVEL_SIZE[$i];
}
$shift = 32;
$offset = ftell($FP);
for($l=0; $l<sizeof($LEVEL_SIZE); $l++) {
$shift -= $LEVEL_SIZE[$l];
$index = (($ipint>>$shift)) & ((1<<$LEVEL_SIZE[$l])-1);
$tell = $offset+$index*4;
fseek($FP, $tell, 0);
$data = fread($FP, 4);
$unp = unpack('Ndata',$data);
$offset = $unp['data'] ^ $first_xor_code ^ $tell;
$offset &= 0xffffffff;
if ( $offset & 0x80000000 ) {
$tell = $offset & 0x7fffffff;
fseek($FP, $tell, 0);
$data = fread($FP, 2);
$unp = unpack('nlen', $data);
$length = ( $unp['len'] ^ $first_xor_code ^ $tell ) &0xffff;
$tell += 2;
$xor = $tell ^ $first_xor_code;
for($i=0,$info=""; $i<$length; $i++) {
$char = fread($FP, 1);
$info .= chr((ord($char) ^ $xor) & 0xff );
$xor = ( ($xor >> 3) &0x1fffffff) ^ ( ($xor & 0x1fffffff) << 3);
}
break;
}
}
fclose($FP);
return $info;
}
function cngeoip4unUTF($s) {
$out='';
$byte2='';
for ($c=0;$c<strlen($s);$c++) {
$i=ord($s[$c]);
if ($i<=127) $out.=$s[$c];
if ($byte2) {
$new_c2=($c1&3)*64+($i&63);
$new_c1=($c1>>2)&5;
$new_i=$new_c1*256+$new_c2;
if ($new_i==1025) {
$out_i=168;
} else {
if ($new_i==1105) {
$out_i=184;
} else {
$out_i=$new_i-848;
}
}
$out.=chr($out_i);
$byte2=false;
}
if (($i>>5)==6) {
$c1=$i;
$byte2=true;
}
}
return $out;
}
?>