Changeset View
Changeset View
Standalone View
Standalone View
src/app/Console/Commands/DataIP4Nets.php
- This file was added.
<?php | |||||
namespace App\Console\Commands; | |||||
use Carbon\Carbon; | |||||
use Illuminate\Console\Command; | |||||
class DataIP4Nets extends Command | |||||
{ | |||||
/** | |||||
* The name and signature of the console command. | |||||
* | |||||
* @var string | |||||
*/ | |||||
protected $signature = 'data:ip4nets'; | |||||
/** | |||||
* The console command description. | |||||
* | |||||
* @var string | |||||
*/ | |||||
protected $description = 'Update IP4 Networks'; | |||||
/** | |||||
* Create a new command instance. | |||||
* | |||||
* @return void | |||||
*/ | |||||
public function __construct() | |||||
{ | |||||
parent::__construct(); | |||||
} | |||||
/** | |||||
* Execute the console command. | |||||
* | |||||
* @return int | |||||
*/ | |||||
public function handle() | |||||
{ | |||||
$rirs = [ | |||||
'afrinic' => 'ftp://ftp.afrinic.net/stats/afrinic/delegated-afrinic-latest', | |||||
'apnic' => 'ftp://ftp.apnic.net/pub/apnic/stats/apnic/delegated-apnic-latest', | |||||
'arin' => 'ftp://ftp.arin.net/pub/stats/arin/delegated-arin-extended-latest', | |||||
'lacnic' => 'ftp://ftp.lacnic.net/pub/stats/lacnic/delegated-lacnic-latest', | |||||
'ripencc' => 'ftp://ftp.ripe.net/ripe/stats/delegated-ripencc-latest' | |||||
]; | |||||
$today = Carbon::now()->toDateString(); | |||||
foreach ($rirs as $rir => $url) { | |||||
$file = storage_path("{$rir}-{$today}"); | |||||
if (!is_file($file)) { | |||||
$fp = fopen(storage_path("{$rir}-{$today}"), 'w'); | |||||
$curl = curl_init(); | |||||
curl_setopt($curl, CURLOPT_URL, $url); | |||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); | |||||
curl_setopt($curl, CURLOPT_FILE, $fp); | |||||
curl_exec($curl); | |||||
curl_close($curl); | |||||
fclose($fp); | |||||
if (curl_errno($curl)) { | |||||
\Log::error("Request error on {$url}: " . curl_error($curl)); | |||||
unlink($file); | |||||
continue; | |||||
} | |||||
} | |||||
$serial = $this->serialFromStatsFile($file); | |||||
if (!$serial) { | |||||
\Log::error("Can not derive serial from {$file}"); | |||||
continue; | |||||
} | |||||
$numLines = $this->countLines($file); | |||||
if (!$numLines) { | |||||
\Log::error("No relevant lines could be found in {$file}"); | |||||
continue; | |||||
} | |||||
$bar = \App\Utils::createProgressBar( | |||||
$this->output, | |||||
$numLines, | |||||
"Importing IPv4 Networks from {$file}" | |||||
); | |||||
$fp = fopen($file, 'r'); | |||||
$nets = []; | |||||
while (!feof($fp)) { | |||||
$line = trim(fgets($fp)); | |||||
if ($line == "") { | |||||
continue; | |||||
} | |||||
if ((int)$line) { | |||||
continue; | |||||
} | |||||
if ($line[0] == "#") { | |||||
continue; | |||||
} | |||||
$items = explode('|', $line); | |||||
if (sizeof($items) < 7) { | |||||
continue; | |||||
} | |||||
if ($items[1] == "*") { | |||||
continue; | |||||
} | |||||
if ($items[2] != "ipv4") { | |||||
continue; | |||||
} | |||||
if ($items[5] == "00000000") { | |||||
$items[5] = "19700102"; | |||||
} | |||||
if ($items[1] == "" || $items[1] == "ZZ") { | |||||
continue; | |||||
} | |||||
$bar->advance(); | |||||
$mask = 32 - log($items[4], 2); | |||||
$net = \App\IP4Net::where( | |||||
[ | |||||
'net_number' => $items[3], | |||||
'net_mask' => $mask, | |||||
'net_broadcast' => long2ip((ip2long($items[3]) + 2 ** (32 - $mask)) - 1) | |||||
] | |||||
)->first(); | |||||
if ($net) { | |||||
$net->update( | |||||
[ | |||||
'country' => $items[1], | |||||
'serial' => $serial | |||||
] | |||||
); | |||||
continue; | |||||
} | |||||
$nets[] = [ | |||||
'net_number' => $items[3], | |||||
'net_mask' => $mask, | |||||
'net_broadcast' => long2ip((ip2long($items[3]) + 2 ** (32 - $mask)) - 1), | |||||
'country' => $items[1], | |||||
'serial' => $serial | |||||
]; | |||||
if (sizeof($nets) >= 100) { | |||||
\App\IP4Net::insert($nets); | |||||
$nets = []; | |||||
} | |||||
} | |||||
if (sizeof($nets) > 0) { | |||||
\App\IP4Net::insert($nets); | |||||
} | |||||
$bar->finish(); | |||||
$this->info("DONE"); | |||||
} | |||||
} | |||||
private function countLines($file) | |||||
{ | |||||
$numLines = 0; | |||||
$fh = fopen($file, 'r'); | |||||
while (!feof($fh)) { | |||||
$line = trim(fgets($fh)); | |||||
$items = explode('|', $line); | |||||
if (sizeof($items) < 3) { | |||||
continue; | |||||
} | |||||
if ($items[2] == "ipv4") { | |||||
$numLines++; | |||||
} | |||||
} | |||||
fclose($fh); | |||||
return $numLines; | |||||
} | |||||
private function serialFromStatsFile($file) | |||||
{ | |||||
$serial = null; | |||||
$fh = fopen($file, 'r'); | |||||
while (!feof($fh)) { | |||||
$line = trim(fgets($fh)); | |||||
$items = explode('|', $line); | |||||
if (sizeof($items) < 2) { | |||||
continue; | |||||
} | |||||
if ((int)$items[2]) { | |||||
$serial = (int)$items[2]; | |||||
break; | |||||
} | |||||
} | |||||
fclose($fh); | |||||
return $serial; | |||||
} | |||||
} |