Last active
September 24, 2021 03:40
-
-
Save Byteflux/df76b827085ad97af64f2c352d83d243 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// ip2asn.php?ip=IP_OR_HOSTNAME : Returns a comma-separated list of matching ASNs | |
// ip2asn.php?asn=AS_NUMBER : Returns the organization name | |
// ip2asn.php?update=1&token=SECRET_TOKEN : Updates the local database (setup cron to run once a day) | |
$SECRET_TOKEN = 'ChangeMe'; | |
$TMP_DIR = '/tmp/ip2asn'; | |
$DATA_DIR = '/var/lib/ip2asn'; | |
function remove_recursive($dir, $remove_dir = false) { | |
$files = new RecursiveIteratorIterator( | |
new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS), | |
RecursiveIteratorIterator::CHILD_FIRST | |
); | |
foreach ($files as $file) { | |
$delete = ($file->isDir() ? 'rmdir' : 'unlink'); | |
$delete($file->getRealPath()); | |
} | |
if ($remove_dir) { | |
rmdir($dir); | |
} | |
} | |
function ip_in_range($ip, $range) { | |
if (strpos($range, '/') === false) { | |
$range .= '/32'; | |
} | |
list($range, $netmask) = explode('/', $range, 2); | |
$range_decimal = ip2long($range); | |
$ip_decimal = ip2long($ip); | |
$wildcard_decimal = pow(2, (32 - $netmask)) - 1; | |
$netmask_decimal = ~ $wildcard_decimal; | |
return (($ip_decimal & $netmask_decimal) == ($range_decimal & $netmask_decimal)); | |
} | |
if (!empty($_GET['update']) && isset($_GET['token']) && $_GET['token'] == $SECRET_TOKEN) { | |
set_time_limit(0); | |
if (!file_exists($TMP_DIR)) { | |
mkdir($TMP_DIR, 0770, true); | |
} else { | |
remove_recursive($TMP_DIR); | |
} | |
if (!file_exists($DATA_DIR)) { | |
mkdir($DATA_DIR, 0770, true); | |
} | |
$dumps = ['data-used-autnums', 'data-raw-table']; | |
foreach ($dumps as $dump) { | |
$fp = fopen("$TMP_DIR/$dump", 'w+'); | |
$ch = curl_init("http://thyme.apnic.net/current/$dump"); | |
curl_setopt($ch, CURLOPT_TIMEOUT, 50); | |
curl_setopt($ch, CURLOPT_FILE, $fp); | |
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); | |
curl_exec($ch); | |
try { | |
$error = curl_error($ch); | |
if (!empty($error)) { | |
echo "$error\n"; | |
exit(1); | |
} | |
} finally { | |
curl_close($ch); | |
fclose($fp); | |
} | |
} | |
$index_dirs = ['index', 'index/asn', 'index/prefix']; | |
foreach ($index_dirs as $index_dir) { | |
$dir = "$TMP_DIR/$index_dir"; | |
if (!file_exists($dir)) { | |
mkdir($dir); | |
} | |
} | |
$fp = fopen("$TMP_DIR/data-used-autnums", 'r'); | |
while (($line = fgets($fp)) != null) { | |
list ($asn, $org) = preg_split('/\s+/', trim($line), 2); | |
$dir = "$TMP_DIR/index/asn/$asn[0]"; | |
if (!file_exists($dir)) { | |
mkdir($dir, 0770); | |
} | |
file_put_contents("$dir/$asn", $org); | |
} | |
fclose($fp); | |
$fp = fopen("$TMP_DIR/data-raw-table", 'r'); | |
$prefixes = []; | |
while (($line = fgets($fp)) != null) { | |
list ($prefix, $asn) = preg_split('/\s+/', trim($line), 2); | |
$key = explode('.', $prefix)[0]; | |
$prefixes[$key][$prefix] = $asn; | |
} | |
fclose($fp); | |
foreach ($prefixes as $key => $prefix) { | |
$fp = fopen("$TMP_DIR/index/prefix/$key", 'w+'); | |
foreach ($prefix as $cidr => $asn) { | |
fwrite($fp, "$cidr $asn\n"); | |
} | |
fclose($fp); | |
} | |
if (file_exists("$DATA_DIR/index")) { | |
rename("$DATA_DIR/index", "$DATA_DIR/index.old"); | |
} | |
rename("$TMP_DIR/index", "$DATA_DIR/index"); | |
$remove_dirs = ['index.old', 'cache']; | |
foreach ($remove_dirs as $remove_dir) { | |
if (file_exists("$DATA_DIR/$remove_dir")) { | |
remove_recursive("$DATA_DIR/$remove_dir", true); | |
} | |
} | |
exit; | |
} | |
if (isset($_GET['ip'])) { | |
$ip = gethostbyname($_GET['ip']); | |
if (preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $ip)) { | |
$cache_file = "$DATA_DIR/cache/" . str_replace('.', '/', $ip); | |
if (file_exists($cache_file)) { | |
readfile($cache_file); | |
} else { | |
$key = explode('.', $ip)[0]; | |
$prefix_file = "$DATA_DIR/index/prefix/$key"; | |
if (file_exists($prefix_file)) { | |
$results = []; | |
$fp = fopen($prefix_file, 'r'); | |
while (($line = fgets($fp)) != null) { | |
list ($prefix, $asn) = explode(' ', trim($line), 2); | |
if (ip_in_range($ip, $prefix)) { | |
$results[] = $asn; | |
} | |
} | |
fclose($fp); | |
$cache_dir = dirname($cache_file); | |
if (!file_exists($cache_dir)) { | |
mkdir($cache_dir, 0770, true); | |
} | |
$output = implode(',', array_unique($results)); | |
file_put_contents($cache_file, $output); | |
echo $output; | |
} | |
} | |
} | |
exit; | |
} | |
if (isset($_GET['asn']) && ctype_digit($_GET['asn'])) { | |
$file = "$DATA_DIR/index/asn/{$_GET['asn'][0]}/$_GET[asn]"; | |
if (file_exists($file)) { | |
readfile($file); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment