This commit is contained in:
Halbe Bruno
2025-12-05 19:40:39 -03:00
commit f37bc712e6
4312 changed files with 359196 additions and 0 deletions

View File

@@ -0,0 +1,85 @@
<?php
namespace App\Services;
class ASNService
{
public static function validateIP($ip, $asn)
{
// Remove 'AS' prefix if present for comparison
$targetAsn = ltrim(strtoupper($asn), 'AS');
// Use whois command
// This command queries Cymru's whois server which is reliable for IP to ASN mapping
// Format: whois -h whois.cymru.com " -v [IP]"
$command = sprintf('whois -h whois.cymru.com " -v %s"', escapeshellarg($ip));
// Use proc_open to capture output and potential errors
$descriptorspec = [
0 => ["pipe", "r"], // stdin
1 => ["pipe", "w"], // stdout
2 => ["pipe", "w"] // stderr
];
$process = proc_open($command, $descriptorspec, $pipes);
if (is_resource($process)) {
$output = stream_get_contents($pipes[1]);
$errors = stream_get_contents($pipes[2]);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
$return_value = proc_close($process);
if ($return_value !== 0 || empty($output)) {
// Whois command failed, try HTTP API fallback
// Using ip-api.com (free, no key required for limited use)
// Format: http://ip-api.com/json/{ip}?fields=status,message,as
$apiUrl = "http://ip-api.com/json/" . $ip . "?fields=status,message,as";
$context = stream_context_create(['http' => ['timeout' => 3]]);
$apiResponse = @file_get_contents($apiUrl, false, $context);
if ($apiResponse !== FALSE) {
$data = json_decode($apiResponse, true);
if (isset($data['status']) && $data['status'] === 'success' && isset($data['as'])) {
// Format example: "AS15169 Google LLC"
// Extract AS number
if (preg_match('/AS(\d+)/', $data['as'], $matches)) {
$foundAsn = $matches[1];
return $foundAsn === $targetAsn;
}
}
}
// If both fail, strictly return false as requested to prevent invalid registrations
return false;
}
} else {
return false;
}
// Parse output
// Output example:
// AS | IP | BGP Prefix | CC | Registry | Allocated | AS Name
// 15169 | 8.8.8.8 | 8.8.8.0/24 | US | arin | 2000-03-30 | GOOGLE, US
$lines = explode("\n", trim($output));
foreach ($lines as $line) {
if (strpos($line, 'AS') !== false && strpos($line, 'IP') !== false) {
continue;
}
$parts = explode('|', $line);
if (count($parts) >= 1) {
$foundAsn = trim($parts[0]);
if ($foundAsn === $targetAsn) {
return true;
}
}
}
return false;
}
}