08 2024
This commit is contained in:
parent
04d677d37a
commit
bfa3bb1df4
1191 changed files with 637397 additions and 10619 deletions
94
app/Services/dbip/MyDBIP.php
Normal file
94
app/Services/dbip/MyDBIP.php
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* DB-IP.com database query and management class
|
||||
*
|
||||
* Copyright (C) 2022 db-ip.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
namespace App\Services\dbip;
|
||||
|
||||
use PDO;
|
||||
use Exception;
|
||||
use PDOException;
|
||||
use App\Models\DbipLookup;
|
||||
use App\Models\DbipLookup2;
|
||||
use App\Models\DbipLookup3;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
|
||||
class DBIPException extends Exception {
|
||||
|
||||
}
|
||||
|
||||
class MyDBIP {
|
||||
|
||||
const VERSION = 4;
|
||||
|
||||
|
||||
static public function lookup($addr) {
|
||||
if ($ret = self::doLookup(self::addrType($addr), inet_pton($addr))) {
|
||||
return $ret;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static public function doLookup($addrType, $addrStart) {
|
||||
|
||||
$res = DbipLookup::where('addr_type', $addrType)->where('ip_start', '<=', $addrStart)->orderBy('ip_start', 'desc')->first();
|
||||
$c1 = isset($res->country) ? $res->country : null;
|
||||
|
||||
$res = DbipLookup2::where('addr_type', $addrType)->where('ip_start', '<=', $addrStart)->orderBy('ip_start', 'desc')->first();
|
||||
$c2 = isset($res->country) ? $res->country : null;
|
||||
|
||||
if($c1 == $c2){
|
||||
return $c1;
|
||||
}
|
||||
|
||||
$res = DbipLookup3::where('addr_type', $addrType)->where('ip_start', '<=', $addrStart)->orderBy('ip_start', 'desc')->first();
|
||||
if(isset($res->country)){
|
||||
return $res->country;
|
||||
}
|
||||
|
||||
//look in api
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static private function addrType($addr) {
|
||||
if (ip2long($addr) !== false) {
|
||||
return "ipv4";
|
||||
} else if (preg_match('/^[0-9a-fA-F:]+$/', $addr) && @inet_pton($addr)) {
|
||||
return "ipv6";
|
||||
}
|
||||
throw new DBIPException("unknown address type for {$addr}");
|
||||
}
|
||||
|
||||
static public function insert($addr, $country) {
|
||||
|
||||
$lookup = new DbipLookup3();
|
||||
$lookup->addr_type = self::addrType($addr);
|
||||
$lookup->ip_start = inet_pton($addr);
|
||||
$lookup->ip_end = inet_pton($addr);
|
||||
$lookup->country = strtoupper($country);
|
||||
$lookup->save();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
211
app/Services/dbip/dbip-convert.php
Executable file
211
app/Services/dbip/dbip-convert.php
Executable file
|
|
@ -0,0 +1,211 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* DB-IP.com CSV database format conversion tool
|
||||
*
|
||||
* Copyright (C) 2020 db-ip.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
$outputFormats = [
|
||||
"range" => function(array $csvData, $of, string $firstIpBin, string $lastIpBin): void {
|
||||
writeCSV($of, $csvData);
|
||||
},
|
||||
"cidr" => function(array $csvData, $of, string $firstIpBin, string $lastIpBin): void {
|
||||
array_shift($csvData);
|
||||
foreach (rangeToCIDR($firstIpBin, $lastIpBin) as $cidrNet) {
|
||||
$csvData[0] = $cidrNet;
|
||||
writeCSV($of, $csvData);
|
||||
}
|
||||
},
|
||||
"long" => function(array $csvData, $of, string $firstIpBin, string $lastIpBin): void {
|
||||
if (($firstIpLong = ip2long($csvData[0])) === false) {
|
||||
throw new Exception("invalid IP address for long conversion : {$csvData[0]}");
|
||||
} else if (($lastIpLong = ip2long($csvData[1])) === false) {
|
||||
throw new Exception("invalid IP address for long conversion : {$csvData[1]}");
|
||||
}
|
||||
$csvData[0] = $firstIpLong;
|
||||
$csvData[1] = $lastIpLong;
|
||||
writeCSV($of, $csvData);
|
||||
},
|
||||
];
|
||||
|
||||
function writeCSV($of, $csvData) {
|
||||
fputcsv($of, $csvData);
|
||||
}
|
||||
|
||||
function vEcho(string $s): void {
|
||||
if (!$GLOBALS["verbose"]) {
|
||||
return;
|
||||
}
|
||||
echo $s;
|
||||
}
|
||||
|
||||
function findLargestNetwork(string $ipStartBin): int {
|
||||
for ($i = strlen($ipStartBin); $i--; $i >= 0) {
|
||||
$byte = ord($ipStartBin[$i]);
|
||||
for ($j = 7; $j >= 0; $j--) {
|
||||
if ($byte & (0xff >> $j)) {
|
||||
return ($i << 3) + $j + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function getLastAddress(string $ipStartBin, int $cidrBits): string {
|
||||
$ret = $ipStartBin;
|
||||
for ($i = strlen($ipStartBin); $i--; $i >= 0) {
|
||||
$firstBit = ($i << 3) + 1;
|
||||
$lastBit = ($i + 1) << 3;
|
||||
if ($cidrBits > $lastBit) {
|
||||
continue;
|
||||
} else if ($cidrBits < $firstBit) {
|
||||
$ret[$i] = "\xff";
|
||||
} else {
|
||||
$ret[$i] = chr(ord($ret[$i]) | (0xff >> ($cidrBits - $firstBit + 1)));
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function getNextAddress(string $ipStartBin): string {
|
||||
$ret = $ipStartBin;
|
||||
for ($i = strlen($ipStartBin); $i--; $i >= 0) {
|
||||
for ($j = 7; $j >= 0; $j--) {
|
||||
$byte = ord($ret[$i]);
|
||||
$mask = 1 << (7 - $j);
|
||||
if ($byte & $mask) {
|
||||
$ret[$i] = chr($byte & ~$mask);
|
||||
} else {
|
||||
$ret[$i] = chr($byte | $mask);
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Exception("no next address for " . inet_ntop($ipStartBin));
|
||||
}
|
||||
|
||||
function rangeToCIDR(string $ipStartBin, string $ipEndBin): array {
|
||||
if (strcmp($ipStartBin, $ipEndBin) > 0) {
|
||||
throw new Exception("wrong ip address order");
|
||||
}
|
||||
$cidrNets = [];
|
||||
$cidrBits = findLargestNetwork($ipStartBin);
|
||||
do {
|
||||
$lastAddrBin = getLastAddress($ipStartBin, $cidrBits);
|
||||
if (($cmp = strcmp($lastAddrBin, $ipEndBin)) <= 0) {
|
||||
$cidrNets[] = inet_ntop($ipStartBin) . "/" . $cidrBits;
|
||||
if ($cmp === 0) {
|
||||
return $cidrNets;
|
||||
}
|
||||
$ipStartBin = getNextAddress($lastAddrBin);
|
||||
$cidrBits = findLargestNetwork($ipStartBin);
|
||||
} else {
|
||||
$cidrBits++;
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
$exitCode = 0;
|
||||
$opts = getopt("i:o:f:qhw46");
|
||||
$verbose = !isset($opts["q"]);
|
||||
|
||||
if (!$opts || isset($opts["h"]) || !isset($opts["i"]) || !isset($opts["o"]) || !isset($opts["f"]) || (isset($opts["4"]) && isset($opts["6"]))) {
|
||||
echo "usage: {$argv[0]} -i <inputFileName.csv> -o <outputFileName.csv> -f <outputFormat> [-4|-6] [-w] [-q]\n";
|
||||
echo " -i input CSV file\n";
|
||||
echo " -o output file name\n";
|
||||
echo " -f output format (" . implode("|", array_keys($outputFormats)) . ")\n";
|
||||
echo " -4 output ipv4 networks only\n";
|
||||
echo " -6 output ipv6 networks only\n";
|
||||
echo " -w overwrite output file if it already exists\n";
|
||||
echo " -q be quiet\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$inputFile = $opts["i"];
|
||||
if (!file_exists($inputFile)) {
|
||||
throw new Exception("cannot find input file: {$inputFile}");
|
||||
} else if (!is_readable($inputFile)) {
|
||||
throw new Exception("cannot read input file: {$inputFile}");
|
||||
}
|
||||
if (substr($inputFile, -3) === ".gz") {
|
||||
$inputFile = "compress.zlib://" . $inputFile;
|
||||
}
|
||||
if (!$if = fopen($inputFile, "r")) {
|
||||
throw new Exception("cannot open input file: {$inputFile}");
|
||||
}
|
||||
|
||||
$outputFile = $opts["o"];
|
||||
if (file_exists($outputFile) && !isset($opts["w"])) {
|
||||
throw new Exception("output file {$outputFile} already exists, use -w to force overwrite");
|
||||
}
|
||||
if (substr($outputFile, -3) === ".gz") {
|
||||
$outputFile = "compress.zlib://" . $outputFile;
|
||||
}
|
||||
if (!$of = fopen($outputFile, "w")) {
|
||||
throw new Exception("cannot open output file: {$outPutFile}");
|
||||
}
|
||||
|
||||
if (!isset($outputFormats[$opts["f"]])) {
|
||||
throw new Exception("invalid output format {$opts['f']}");
|
||||
}
|
||||
$outputFormatter = $outputFormats[$opts["f"]];
|
||||
|
||||
$i = 0;
|
||||
while ($r = fgetcsv($if, 8192)) {
|
||||
$i++;
|
||||
[ $firstIp, $lastIp ] = $r;
|
||||
try {
|
||||
if (!$firstIpBin = inet_pton($firstIp)) {
|
||||
throw new Exception("invalid first IP '{$firstIp}' in CSV record");
|
||||
} else if (!$lastIpBin = inet_pton($lastIp)) {
|
||||
throw new Exception("invalid last IP '{$lastIp}' in CSV record");
|
||||
} else if (($addrLen = strlen($firstIpBin)) !== strlen($lastIpBin)) {
|
||||
throw new Exception("first and last IP address family mismatch ({$firstIp} / {$lastIp})");
|
||||
}
|
||||
if (isset($opts["4"]) && ($addrLen !== 4)) {
|
||||
continue;
|
||||
} else if (isset($opts["6"]) && ($addrLen !== 16)) {
|
||||
continue;
|
||||
}
|
||||
$outputFormatter($r, $of, $firstIpBin, $lastIpBin);
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("line {$i}: {$e->getMessage()}");
|
||||
}
|
||||
}
|
||||
fclose($if);
|
||||
fclose($of);
|
||||
|
||||
vEcho("Wrote {$outputFile}\n");
|
||||
|
||||
} catch (Exception $e) {
|
||||
if ($stdErr = @fopen("php://stderr", "w")) {
|
||||
fwrite($stdErr, "ERROR: {$e->getMessage()}\n");
|
||||
fclose($stdErr);
|
||||
} else {
|
||||
echo "ERROR: {$e->getMessage()}\n";
|
||||
}
|
||||
$exitCode = 1;
|
||||
}
|
||||
if ($exitCode) {
|
||||
exit($exitCode);
|
||||
}
|
||||
12
app/Services/dbip/dbip-country-ipinfo-2024-test.csv
Normal file
12
app/Services/dbip/dbip-country-ipinfo-2024-test.csv
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
1.0.0.0,1.0.0.254,AU,Australia,OC,Oceania
|
||||
1.0.0.255,1.0.0.255,ID,Indonesia,AS,Asia
|
||||
1.0.1.0,1.0.3.255,CN,China,AS,Asia
|
||||
1.0.4.0,1.0.7.255,AU,Australia,OC,Oceania
|
||||
1.0.8.0,1.0.15.255,CN,China,AS,Asia
|
||||
1.0.16.0,1.0.31.255,JP,Japan,AS,Asia
|
||||
1.0.32.0,1.0.63.255,CN,China,AS,Asia
|
||||
1.0.64.0,1.0.127.255,JP,Japan,AS,Asia
|
||||
1.0.128.0,1.0.218.40,TH,Thailand,AS,Asia
|
||||
1.0.218.41,1.0.218.41,MY,Malaysia,AS,Asia
|
||||
1.0.218.42,1.0.255.255,TH,Thailand,AS,Asia
|
||||
1.1.0.0,1.1.0.255,CN,China,AS,Asia
|
||||
|
1980348
app/Services/dbip/dbip-country-ipinfo-2024.csv
Normal file
1980348
app/Services/dbip/dbip-country-ipinfo-2024.csv
Normal file
File diff suppressed because it is too large
Load diff
586697
app/Services/dbip/dbip-country-lite-2024-07.csv
Normal file
586697
app/Services/dbip/dbip-country-lite-2024-07.csv
Normal file
File diff suppressed because it is too large
Load diff
10
app/Services/dbip/dbip-update.ini.sample
Normal file
10
app/Services/dbip/dbip-update.ini.sample
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
[account]
|
||||
; Your account key is available in your customer section at https://db-ip.com/account/
|
||||
accountKey = INSERT_YOUR_ACCOUNT_KEY_HERE
|
||||
|
||||
[database]
|
||||
; This is the PDO Data Source Name for your database instance, see http://php.net/manual/pdo.construct.php
|
||||
dataSourceName = "mysql:host=localhost;dbname=myapp"
|
||||
; dbUser and dbPassword are the database account credentials
|
||||
dbUser = myapp
|
||||
dbPassword = myapp123
|
||||
327
app/Services/dbip/dbip-update.php
Executable file
327
app/Services/dbip/dbip-update.php
Executable file
|
|
@ -0,0 +1,327 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* DB-IP.com database update tool
|
||||
*
|
||||
* Copyright (C) 2021 db-ip.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
require "dbip.class.php";
|
||||
|
||||
const API_BASE = "https://db-ip.com/account";
|
||||
const DEFAULT_CONF = "dbip-update.ini";
|
||||
|
||||
function apiRequest($path, $key) {
|
||||
$url = API_BASE . "/" . $key . "/db" . $path;
|
||||
if (($jsonData = file_get_contents($url)) === false) {
|
||||
throw new Exception("cannot fetch API result from {$url}");
|
||||
} else if (!isset($jsonData) || !$jsonData || (($resp = json_decode($jsonData)) === false)) {
|
||||
throw new Exception("cannot decode API result from {$url}");
|
||||
} else if (isset($resp->error)) {
|
||||
throw new Exception("API error: {$resp->error}");
|
||||
}
|
||||
return $resp;
|
||||
}
|
||||
|
||||
function vEcho($s) {
|
||||
if (!$GLOBALS["verbose"]) {
|
||||
return false;
|
||||
}
|
||||
echo $s;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
$exitCode = 0;
|
||||
$opts = getopt("k:d:f:o:zZqlnwb:u:p:t:c:D");
|
||||
$verbose = !isset($opts["q"]);
|
||||
|
||||
if (isset($opts["c"])) {
|
||||
if (!file_exists($opts["c"]) || !is_readable($opts["c"])) {
|
||||
throw new Exception("cannot read configuration file {$opts['c']}");
|
||||
}
|
||||
$confName = $opts["c"];
|
||||
} else if (file_exists(__DIR__ . DIRECTORY_SEPARATOR . DEFAULT_CONF) && is_readable(__DIR__ . DIRECTORY_SEPARATOR . DEFAULT_CONF)) {
|
||||
$confName = __DIR__ . DIRECTORY_SEPARATOR . DEFAULT_CONF;
|
||||
}
|
||||
|
||||
if (isset($confName)) {
|
||||
if (($conf = parse_ini_file($confName)) === false) {
|
||||
throw new Exception("cannot parse configuration file {$confName}");
|
||||
}
|
||||
$confMap = [
|
||||
"accountKey" => "k",
|
||||
"dbType" => "d",
|
||||
"format" => "f",
|
||||
"outputDir" => "o",
|
||||
"outputFileName" => "o",
|
||||
"dataSourceName" => "b",
|
||||
"dbUser" => "u",
|
||||
"dbPassword" => "p",
|
||||
"dbTableName" => "t",
|
||||
];
|
||||
foreach ($conf as $name => $value) {
|
||||
if (!isset($confMap[$name])) {
|
||||
throw new Exception("invalid configuration parameter {$name}");
|
||||
} else if (!isset($opts[$confMap[$name]])) {
|
||||
$opts[$confMap[$name]] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($opts["k"]) || !$opts["k"]) {
|
||||
echo "usage: {$argv[0]} -k <accountKey> [-l] [-d <dbType>] [-f <format>] [-o <outputDir|outputFileName>] [-b <dataSourceName> [-u <dbUser>] [-p <dbPassword] [-t <dbTableName>] [-D]] [-c <configFile>] [-n] [-z|-Z] [-w] [-q]\n";
|
||||
echo " -l list available items and exit\n";
|
||||
echo " -n request new items only\n";
|
||||
echo " -z fetch uncompressed file (default for mmdb format)\n";
|
||||
echo " -Z fetch compressed file (default for csv format)\n";
|
||||
echo " -w overwrite destination file if it already exists\n";
|
||||
echo " -b PDO DSN for database update (ie. \"mysql:host=localhost;dbname=dbip\")\n";
|
||||
echo " -u database username (default 'root')\n";
|
||||
echo " -p database password (default '')\n";
|
||||
echo " -t name of database table (default 'dbip_lookup')\n";
|
||||
echo " -D do not use a temporary table (table specified by -t must be empty)\n";
|
||||
echo " -q be quiet\n";
|
||||
exit(1);
|
||||
}
|
||||
$apiKey = $opts["k"];
|
||||
|
||||
if (!isset($opts["d"])) {
|
||||
$dbList = apiRequest("/", $apiKey);
|
||||
if (count((array)$dbList) > 1) {
|
||||
vEcho("Use -d to select a database type :\n");
|
||||
foreach ($dbList as $dbType => $dbInfo) {
|
||||
echo $dbType . "\n";
|
||||
}
|
||||
exit();
|
||||
} else {
|
||||
foreach ($dbList as $dbType => $dbInfo) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$dbType = $opts["d"];
|
||||
}
|
||||
|
||||
if (isset($opts["b"])) {
|
||||
if (isset($opts["o"])) {
|
||||
throw new Exception("Arguments -b and -o cannot be used in the same command line");
|
||||
}
|
||||
$dbUser = isset($opts["u"]) ? $opts["u"] : "root";
|
||||
$dbPassword = isset($opts["p"]) ? $opts["p"] : "";
|
||||
$dbTable = isset($opts["t"]) ? $opts["t"] : "dbip_lookup";
|
||||
$format = "csv";
|
||||
try {
|
||||
$dsn = $opts["b"];
|
||||
if (preg_match('/^mysql:/', $dsn)) {
|
||||
if (!preg_match('/charset=/', $dsn)) {
|
||||
$dsn .= ";charset=utf8mb4";
|
||||
}
|
||||
$dbQuoteChar = '`'; // backquote for MySQL
|
||||
} else {
|
||||
$dbQuoteChar = '"'; // double quote for ANSI SQL
|
||||
}
|
||||
$db = new PDO($dsn, $dbUser, $dbPassword);
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
|
||||
$dbUseTempTable = !isset($opts["D"]);
|
||||
} catch (PDOException $e) {
|
||||
throw new Exception("Cannot connect to database: {$e->getMessage()}");
|
||||
}
|
||||
} else {
|
||||
if (!isset($opts["f"])) {
|
||||
$filesList = apiRequest("/{$dbType}", $apiKey);
|
||||
vEcho("Use -f to specify a format for your {$dbType} subscription :\n");
|
||||
foreach ($filesList as $format => $fileInfo) {
|
||||
echo $format . "\n";
|
||||
}
|
||||
exit();
|
||||
}
|
||||
$format = $opts["f"];
|
||||
}
|
||||
$onlyNew = isset($opts["n"]);
|
||||
|
||||
try {
|
||||
$queryString = $onlyNew ? "?new=1" : "";
|
||||
$fileInfo = apiRequest("/{$dbType}/{$format}{$queryString}", $apiKey);
|
||||
if ($onlyNew && !$fileInfo) {
|
||||
vEcho("there are no new downloads available\n");
|
||||
exit(0);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("cannot access download info : {$e->getMessage()}");
|
||||
}
|
||||
|
||||
if (isset($opts["l"])) {
|
||||
if (!isset($fileInfo)) {
|
||||
vEcho("no download file match\n");
|
||||
exit();
|
||||
}
|
||||
foreach ($fileInfo as $name => $value) {
|
||||
echo "{$name}: {$value}\n";
|
||||
}
|
||||
exit();
|
||||
}
|
||||
|
||||
if (isset($opts["z"])) {
|
||||
$uncompress = true;
|
||||
} else if (isset($opts["Z"]) || ($format === "csv")) {
|
||||
$uncompress = false;
|
||||
} else {
|
||||
$uncompress = true;
|
||||
}
|
||||
|
||||
$outputFile = "." . DIRECTORY_SEPARATOR . $fileInfo->name;
|
||||
if (isset($opts["o"])) {
|
||||
if (is_dir($opts["o"])) {
|
||||
$outputFile = $opts["o"] . DIRECTORY_SEPARATOR . $fileInfo->name;
|
||||
} else {
|
||||
$outputFile = $opts["o"];
|
||||
}
|
||||
}
|
||||
$sourcePrefix = $uncompress ? "compress.zlib://" : "";
|
||||
if ($uncompress && preg_match('/\.gz$/i', $outputFile)) {
|
||||
$outputFile = preg_replace('/\.gz$/i', '', $outputFile);
|
||||
}
|
||||
$outputTempFile = $outputFile . ".update-tmp";
|
||||
|
||||
if (file_exists($outputTempFile) && !unlink($outputTempFile)) {
|
||||
throw new Exception("cannot delete temporary file {$outputTempFile}");
|
||||
} else if (!isset($db) && file_exists($outputFile) && !isset($opts["w"])) {
|
||||
throw new Exception("destination file {$outputFile} already exists, use -w to force overwrite");
|
||||
}
|
||||
|
||||
vEcho("Starting update for {$dbType} ({$fileInfo->date})\n");
|
||||
if (!copy($sourcePrefix . $fileInfo->url, $outputTempFile, stream_context_create([], [ "notification" => function($notificationCode, $severity, $message, $messageCode, $bytesTransferred, $bytesMax) {
|
||||
static $totBytes, $prevPct = false;
|
||||
if ($bytesMax) {
|
||||
$totBytes = $bytesMax;
|
||||
}
|
||||
if ($bytesTransferred) {
|
||||
if (isset($totBytes) && $totBytes) {
|
||||
$pct = number_format(($bytesTransferred / $totBytes) * 100, 1);
|
||||
}
|
||||
if ($pct !== $prevPct) {
|
||||
vEcho("\rDownloading: " . number_format($bytesTransferred / 1024) . " KB" . (isset($pct) ? " ({$pct}%)" : ""));
|
||||
$prevPct = $pct;
|
||||
}
|
||||
}
|
||||
}]))) {
|
||||
throw new Exception("unable to download file to {$outputTempFile}");
|
||||
}
|
||||
vEcho("\rDownload completed: " . number_format(filesize($outputTempFile) / 1024, 1) . " KB\n");
|
||||
|
||||
$checkPrefix = $uncompress ? "" : "compress.zlib://";
|
||||
if (isset($fileInfo->md5sum) || isset($fileInfo->sha1sum)) {
|
||||
vEcho("Verify signature: ");
|
||||
if (isset($fileInfo->md5sum)) {
|
||||
$md5sum = md5_file($checkPrefix . $outputTempFile);
|
||||
if ($md5sum !== $fileInfo->md5sum) {
|
||||
vEcho("MISMATCH {$md5sum} != {$fileInfo->md5sum}\n");
|
||||
throw new Exception("MD5 signature verification failed, file is probably corrupt or altered");
|
||||
}
|
||||
vEcho("[MD5] ");
|
||||
}
|
||||
if (isset($fileInfo->sha1sum)) {
|
||||
$sha1sum = sha1_file($checkPrefix . $outputTempFile);
|
||||
if ($sha1sum !== $fileInfo->sha1sum) {
|
||||
vEcho("MISMATCH {$sha1sum} != {$fileInfo->sha1sum}\n");
|
||||
throw new Exception("SHA1 signature verification failed, file is probably corrupt or altered");
|
||||
}
|
||||
vEcho("[SHA1] ");
|
||||
}
|
||||
vEcho("passed\n");
|
||||
}
|
||||
|
||||
if (isset($db)) {
|
||||
$dbip = new DBIP($db, $dbQuoteChar);
|
||||
$relId = $dbType;
|
||||
if ($fileInfo->version) {
|
||||
$relId .= "-v{$fileInfo->version}";
|
||||
}
|
||||
switch ($relId) {
|
||||
case "ip-to-country-lite": $importType = DBIP::TYPE_COUNTRY_LITE; break;
|
||||
case "ip-to-city-lite": $importType = DBIP::TYPE_CITY_LITE; break;
|
||||
case "ip-to-country-v4": $importType = DBIP::TYPE_COUNTRY_V4; break;
|
||||
case "ip-to-location-v4": $importType = DBIP::TYPE_LOCATION_V4; break;
|
||||
case "ip-to-isp-v4": $importType = DBIP::TYPE_ISP_V4; break;
|
||||
case "ip-to-location-isp-v4":
|
||||
case "ip-to-full-v4": $importType = DBIP::TYPE_FULL_V4; break;
|
||||
case "ip-to-country-v3": $importType = DBIP::TYPE_COUNTRY_V3; break;
|
||||
case "ip-to-location-v3": $importType = DBIP::TYPE_LOCATION_V3; break;
|
||||
case "ip-to-isp-v3": $importType = DBIP::TYPE_ISP_V3; break;
|
||||
case "ip-to-location-isp-v3":
|
||||
case "ip-to-full-v3": $importType = DBIP::TYPE_FULL_V3; break;
|
||||
case "ip-to-location-v2": $importType = DBIP::TYPE_LOCATION_V2; break;
|
||||
case "ip-to-isp-v2": $importType = DBIP::TYPE_ISP_V2; break;
|
||||
case "ip-to-location-isp-v2":
|
||||
case "ip-to-full-v2": $importType = DBIP::TYPE_FULL_V2; break;
|
||||
default: throw new Exception("unsupported database type");
|
||||
}
|
||||
if ($dbUseTempTable) {
|
||||
$tempTable = "dbip_update_" . time();
|
||||
$db->exec("drop table if exists {$dbQuoteChar}{$tempTable}{$dbQuoteChar}");
|
||||
$db->exec("create table {$dbQuoteChar}{$tempTable}{$dbQuoteChar} like {$dbQuoteChar}{$dbTable}{$dbQuoteChar}");
|
||||
} else {
|
||||
$tempTable = $dbTable;
|
||||
}
|
||||
$dbip->importFromCsv($outputTempFile, $importType, $tempTable, function($numRows) use ($fileInfo) {
|
||||
if ($numRows % 1000) {
|
||||
return false;
|
||||
}
|
||||
if (isset($fileInfo->rows) && $fileInfo->rows) {
|
||||
$pct = number_format(($numRows / $fileInfo->rows) * 100, 1);
|
||||
}
|
||||
vEcho("\rImporting: " . number_format($numRows) . " rows" . (isset($pct) ? " ({$pct}%)" : ""));
|
||||
});
|
||||
$numRows = (int)$db->query("select count(1) cnt from {$dbQuoteChar}{$tempTable}{$dbQuoteChar}")->fetchObject()->cnt;
|
||||
if ($dbUseTempTable) {
|
||||
$db->exec("drop table if exists {$dbQuoteChar}{$tempTable}_old{$dbQuoteChar}");
|
||||
$db->exec("rename table {$dbQuoteChar}{$dbTable}{$dbQuoteChar} to {$dbQuoteChar}{$tempTable}_old{$dbQuoteChar}, {$dbQuoteChar}{$tempTable}{$dbQuoteChar} to {$dbQuoteChar}{$dbTable}{$dbQuoteChar}");
|
||||
$db->exec("drop table {$dbQuoteChar}{$tempTable}_old{$dbQuoteChar}");
|
||||
}
|
||||
vEcho("\rDatabase updated: " . number_format($numRows) . " rows imported\n");
|
||||
} else {
|
||||
if (!rename($outputTempFile, $outputFile)) {
|
||||
throw new Exception("cannot rename temporary file {$outputTempFile} to {$outputFile}");
|
||||
}
|
||||
vEcho("Wrote {$outputFile}\n");
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
if ($stdErr = @fopen("php://stderr", "w")) {
|
||||
fwrite($stdErr, "ERROR: {$e->getMessage()}\n");
|
||||
fclose($stdErr);
|
||||
} else {
|
||||
echo "ERROR: {$e->getMessage()}\n";
|
||||
}
|
||||
$exitCode = 1;
|
||||
} finally {
|
||||
if (isset($outputTempFile) && file_exists($outputTempFile)) {
|
||||
unlink($outputTempFile);
|
||||
}
|
||||
if (isset($db) && isset($tempTable) && $dbUseTempTable) {
|
||||
$db->exec("drop table if exists {$dbQuoteChar}{$tempTable}{$dbQuoteChar}");
|
||||
$db->exec("drop table if exists {$dbQuoteChar}{$tempTable}_old{$dbQuoteChar}");
|
||||
}
|
||||
}
|
||||
if ($exitCode) {
|
||||
exit($exitCode);
|
||||
}
|
||||
346
app/Services/dbip/dbip.class.php
Executable file
346
app/Services/dbip/dbip.class.php
Executable file
|
|
@ -0,0 +1,346 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* DB-IP.com database query and management class
|
||||
*
|
||||
* Copyright (C) 2022 db-ip.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
use PDO;
|
||||
use Exception;
|
||||
use PDOException;
|
||||
|
||||
|
||||
class DBIPException extends Exception {
|
||||
|
||||
}
|
||||
|
||||
class DBIP {
|
||||
|
||||
const VERSION = 4;
|
||||
|
||||
const TYPE_COUNTRY_LITE = 1;
|
||||
const TYPE_CITY_LITE = 2;
|
||||
const TYPE_COUNTRY_V4 = 3;
|
||||
const TYPE_LOCATION_V4 = 4;
|
||||
const TYPE_ISP_V4 = 5;
|
||||
const TYPE_FULL_V4 = 6;
|
||||
|
||||
const TYPE_COUNTRY_V3 = 7;
|
||||
const TYPE_LOCATION_V3 = 8;
|
||||
const TYPE_ISP_V3 = 9;
|
||||
const TYPE_FULL_V3 = 10;
|
||||
|
||||
const TYPE_LOCATION_V2 = 11;
|
||||
const TYPE_ISP_V2 = 12;
|
||||
const TYPE_FULL_V2 = 13;
|
||||
|
||||
const TYPE_COUNTRY_IPINFO = 15;
|
||||
|
||||
const TYPE_COUNTRY = self::TYPE_COUNTRY_V4;
|
||||
const TYPE_LOCATION = self::TYPE_LOCATION_V4;
|
||||
const TYPE_ISP = self::TYPE_ISP_V4;
|
||||
const TYPE_FULL = self::TYPE_FULL_V4;
|
||||
|
||||
private $db;
|
||||
protected $dbQuoteChar = "";
|
||||
|
||||
public function __construct(PDO $db, $dbQuoteChar = "") {
|
||||
$this->db = $db;
|
||||
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$this->dbQuoteChar = $dbQuoteChar;
|
||||
}
|
||||
|
||||
public function importFromCsv($fileName, $type, $tableName = "dbip_lookup", $progressCallback = null) {
|
||||
switch ($type) {
|
||||
case self::TYPE_COUNTRY_LITE:
|
||||
$fields = array("ip_start", "ip_end", "country");
|
||||
$fieldsprepare = $fields;
|
||||
break;
|
||||
case self::TYPE_COUNTRY_IPINFO:
|
||||
$fields = array("ip_start", "ip_end", "country", "d1", "d2", "d3");
|
||||
$fieldsprepare = array("ip_start", "ip_end", "country");
|
||||
break;
|
||||
case self::TYPE_CITY_LITE:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country", "stateprov", "city", "latitude", "longitude");
|
||||
break;
|
||||
case self::TYPE_COUNTRY_V4:
|
||||
case self::TYPE_COUNTRY_V3:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country");
|
||||
break;
|
||||
case self::TYPE_LOCATION_V4:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country", "stateprov_code", "stateprov", "district", "city", "zipcode", "latitude", "longitude", "geoname_id", "timezone_offset", "timezone_name", "weather_code");
|
||||
break;
|
||||
case self::TYPE_ISP_V4:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country", "isp_name", "as_number", "usage_type", "connection_type", "organization_name");
|
||||
break;
|
||||
case self::TYPE_FULL_V4:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country", "stateprov_code", "stateprov", "district", "city", "zipcode", "latitude", "longitude", "geoname_id", "timezone_offset", "timezone_name", "weather_code", "isp_name", "as_number", "usage_type", "connection_type", "organization_name");
|
||||
break;
|
||||
case self::TYPE_LOCATION_V3:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country", "stateprov", "district", "city", "zipcode", "latitude", "longitude", "geoname_id", "timezone_offset", "timezone_name", "weather_code");
|
||||
break;
|
||||
case self::TYPE_ISP_V3:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country", "isp_name", "as_number", "connection_type", "organization_name");
|
||||
break;
|
||||
case self::TYPE_FULL_V3:
|
||||
$fields = array("ip_start", "ip_end", "continent", "country", "stateprov", "district", "city", "zipcode", "latitude", "longitude", "geoname_id", "timezone_offset", "timezone_name", "weather_code", "isp_name", "as_number", "connection_type", "organization_name");
|
||||
break;
|
||||
case self::TYPE_LOCATION_V2:
|
||||
$fields = array("ip_start", "ip_end", "country", "stateprov", "district", "city", "zipcode", "latitude", "longitude", "geoname_id", "timezone_offset", "timezone_name");
|
||||
break;
|
||||
case self::TYPE_ISP_V2:
|
||||
$fields = array("ip_start", "ip_end", "country", "isp_name", "connection_type", "organization_name");
|
||||
break;
|
||||
case self::TYPE_FULL_V2:
|
||||
$fields = array("ip_start", "ip_end", "country", "stateprov", "district", "city", "zipcode", "latitude", "longitude", "geoname_id", "timezone_offset", "timezone_name", "isp_name", "connection_type", "organization_name");
|
||||
break;
|
||||
default:
|
||||
throw new DBIPException("invalid database type");
|
||||
}
|
||||
if (!file_exists($fileName)) {
|
||||
throw new DBIPException("file {$fileName} does not exists");
|
||||
}
|
||||
$q = $this->prepareImport($tableName, $fieldsprepare);
|
||||
if (preg_match('/\.gz(\..+)?$/', $fileName)) {
|
||||
$openName = "compress.zlib://" . $fileName;
|
||||
} else {
|
||||
$openName = $fileName;
|
||||
}
|
||||
$f = @fopen($openName, "r");
|
||||
if (!is_resource($f)) {
|
||||
throw new DBIPException("cannot open {$fileName} for reading");
|
||||
}
|
||||
$nrecs = 0;
|
||||
while ($r = fgetcsv($f, 1024, ",", '"', "\0")) {
|
||||
foreach ($r as $k => $v) {
|
||||
if (!isset($fields[$k])) {
|
||||
throw new DBIPException("invalid CSV record for {$r[0]}");
|
||||
}
|
||||
switch ($fields[$k]) {
|
||||
case "latitude":
|
||||
case "longitude":
|
||||
case "timezone_offset":
|
||||
$r[$k] = (float)$v;
|
||||
break;
|
||||
case "d1":
|
||||
case "d2":
|
||||
case "d3":
|
||||
unset($r[$k]);
|
||||
break;
|
||||
case "isp_name":
|
||||
case "organization_name":
|
||||
$r[$k] = mb_substr($v, 0, 128);
|
||||
break;
|
||||
case "city":
|
||||
case "district":
|
||||
case "stateprov":
|
||||
$r[$k] = mb_substr($v, 0, 80);
|
||||
break;
|
||||
case "zipcode":
|
||||
$r[$k] = mb_substr($v, 0, 20);
|
||||
break;
|
||||
case "timezone_name":
|
||||
$r[$k] = mb_substr($v, 0, 64);
|
||||
break;
|
||||
case "connection_type":
|
||||
case "stateprov_code":
|
||||
case "usage_type":
|
||||
case "geoname_id":
|
||||
case "as_number":
|
||||
if (!$r[$k]) $r[$k] = null;
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
/*$r[] = self::addrType($r[0]);
|
||||
$r[0] = inet_pton($r[0]);
|
||||
$r[1] = inet_pton($r[1]);*/
|
||||
|
||||
$set = [
|
||||
0 => inet_pton($r[0]),
|
||||
1 => inet_pton($r[1]),
|
||||
2 => $r[2],
|
||||
3 => self::addrType($r[0])
|
||||
];
|
||||
$this->importRow($q, $set);
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("cannot import record #{$nrecs}: {$e->getMessage()}");
|
||||
}
|
||||
if ((($nrecs % 100) === 0) && is_callable($progressCallback)) {
|
||||
call_user_func($progressCallback, $nrecs);
|
||||
}
|
||||
$nrecs++;
|
||||
}
|
||||
fclose($f);
|
||||
$this->finalizeImport();
|
||||
return $nrecs;
|
||||
}
|
||||
|
||||
public function lookup($addr, $tableName = "dbip_lookup") {
|
||||
if ($ret = $this->doLookup($tableName, self::addrType($addr), inet_pton($addr))) {
|
||||
$ret->ip_start = inet_ntop($ret->ip_start);
|
||||
$ret->ip_end = inet_ntop($ret->ip_end);
|
||||
return $ret;
|
||||
} else {
|
||||
throw new DBIPException("address not found");
|
||||
}
|
||||
}
|
||||
|
||||
protected function prepareImport($tableName, array $fields) {
|
||||
try {
|
||||
if ($this->db->query("select count(*) as cnt from {$this->dbQuoteChar}{$tableName}{$this->dbQuoteChar}")->fetchObject()->cnt) {
|
||||
throw new DBIPException("table {$tableName} is not empty");
|
||||
}
|
||||
$this->db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
|
||||
$this->db->beginTransaction();
|
||||
$q = $this->db->prepare("insert into {$this->dbQuoteChar}{$tableName}{$this->dbQuoteChar} (" . implode(",", $fields) . ",addr_type) values (" . implode(",", array_fill(0, count($fields), "?")) . ",?)");
|
||||
return $q;
|
||||
} catch (PDOException $e) {
|
||||
throw new DBIPException("database error: {$e->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
protected function finalizeImport() {
|
||||
try{
|
||||
$this->db->commit();
|
||||
}catch (Exception $e) {
|
||||
throw new Exception("commit import record: {$e->getMessage()}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected function importRow($res, $row) {
|
||||
return $res->execute($row);
|
||||
}
|
||||
|
||||
protected function doLookup($tableName, $addrType, $addrStart) {
|
||||
$q = $this->db->prepare("select * from {$this->dbQuoteChar}{$tableName}{$this->dbQuoteChar} where addr_type = ? and ip_start <= ? order by ip_start desc limit 1");
|
||||
$q->execute(array($addrType, $addrStart));
|
||||
return $q->fetchObject();
|
||||
}
|
||||
|
||||
static private function addrType($addr) {
|
||||
if (ip2long($addr) !== false) {
|
||||
return "ipv4";
|
||||
} else if (preg_match('/^[0-9a-fA-F:]+$/', $addr) && @inet_pton($addr)) {
|
||||
return "ipv6";
|
||||
}
|
||||
throw new DBIPException("unknown address type for {$addr}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* DBIP MySQL class
|
||||
*
|
||||
* If you are using a MySQL database backend, please prefer the DBIP base class which uses the PDO mysql driver.
|
||||
* This is only meant to be used on PHP installations where PDO is disabled and the old mysql_* interface is available.
|
||||
*/
|
||||
class DBIPMySQL extends DBIP {
|
||||
|
||||
private $db;
|
||||
|
||||
public function __construct($db) {
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
protected function prepareImport($tableName, array $fields) {
|
||||
$q = mysql_query("select count(*) as cnt from {$this->dbQuoteChar}{$tableName}{$this->dbQuoteChar}", $this->db);
|
||||
$r = mysql_fetch_object($q);
|
||||
mysql_free_result($q);
|
||||
if ($r->cnt) {
|
||||
throw new DBIPException("table {$tableName} is not empty");
|
||||
}
|
||||
return array($tableName, $fields);
|
||||
}
|
||||
|
||||
protected function finalizeImport() {
|
||||
}
|
||||
|
||||
protected function importRow($res, $row) {
|
||||
$vals = array();
|
||||
foreach ($row as $val) {
|
||||
$vals[] = "'" . mysql_real_escape_string($val) . "'";
|
||||
}
|
||||
if (!mysql_query("insert into {$this->dbQuoteChar}{$res[0]}{$this->dbQuoteChar} (" . implode(",", $res[1]) . ",addr_type) values (" . implode(",", $vals) . ")", $this->db)) {
|
||||
throw new DBIPException("database error: cannot insert row");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function doLookup($tableName, $addrType, $addrStart) {
|
||||
$q = mysql_query("select * from {$this->dbQuoteChar}{$tableName}{$this->dbQuoteChar} where addr_type = '{$addrType}' and ip_start <= '" . mysql_real_escape_string($addrStart) . "' order by ip_start desc limit 1", $this->db);
|
||||
$r = mysql_fetch_object($q);
|
||||
mysql_free_result($q);
|
||||
return $r;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* DBIP MySQLI class
|
||||
*
|
||||
* If you are using a MySQL database backend, please prefer the DBIP base class which uses the PDO mysql driver.
|
||||
* This is only meant to be used on PHP installations where PDO is disabled and the old mysqli_* interface is available.
|
||||
*/
|
||||
class DBIPMySQLI extends DBIP {
|
||||
|
||||
private $db;
|
||||
|
||||
public function __construct($db) {
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
protected function prepareImport($tableName, array $fields) {
|
||||
$q = mysqli_query($this->db, "select count(*) as cnt from {$this->dbQuoteChar}{$tableName}{$this->dbQuoteChar}");
|
||||
$r = mysqli_fetch_object($q);
|
||||
mysqli_free_result($q);
|
||||
if ($r->cnt) {
|
||||
throw new DBIPException("table {$tableName} is not empty");
|
||||
}
|
||||
return array($tableName, $fields);
|
||||
}
|
||||
|
||||
protected function finalizeImport() {
|
||||
}
|
||||
|
||||
protected function importRow($res, $row) {
|
||||
$vals = array();
|
||||
foreach ($row as $val) {
|
||||
$vals[] = "'" . mysqli_real_escape_string($this->db, $val) . "'";
|
||||
}
|
||||
if (!mysqli_query($this->db, "insert into {$this->dbQuoteChar}{$res[0]}{$this->dbQuoteChar} (" . implode(",", $res[1]) . ",addr_type) values (" . implode(",", $vals) . ")")) {
|
||||
throw new DBIPException("database error: cannot insert row");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function doLookup($tableName, $addrType, $addrStart) {
|
||||
$q = mysqli_query($this->db, "select * from {$this->dbQuoteChar}{$tableName}{$this->dbQuoteChar} where addr_type = '{$addrType}' and ip_start <= '" . mysqli_real_escape_string($this->db, $addrStart) . "' order by ip_start desc limit 1");
|
||||
$r = mysqli_fetch_object($q);
|
||||
mysqli_free_result($q);
|
||||
return $r;
|
||||
}
|
||||
|
||||
}
|
||||
96
app/Services/dbip/import.php
Executable file
96
app/Services/dbip/import.php
Executable file
|
|
@ -0,0 +1,96 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* DB-IP.com database import script
|
||||
*
|
||||
* Copyright (C) 2018 db-ip.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
require "dbip.class.php";
|
||||
|
||||
$opts = getopt("f:d:t:b:u:p:");
|
||||
|
||||
$filename = @$opts["f"];
|
||||
$type = @$opts["d"];
|
||||
|
||||
$dbname = @$opts["b"]
|
||||
or $dbname = "mivita";
|
||||
|
||||
$table = @$opts["t"]
|
||||
or $table = "dbip_lookup_2"; //
|
||||
|
||||
$username = @$opts["u"]
|
||||
or $username = "kadmin";
|
||||
|
||||
$password = @$opts["p"]
|
||||
or $password = "KT32vQ7ix";
|
||||
|
||||
$host = "192.168.1.8";
|
||||
|
||||
//https://db-ip.com/db/download/ip-to-country-lite
|
||||
$filename = "dbip-country-lite-2024-07.csv";
|
||||
$table = "dbip_lookup";
|
||||
|
||||
//https://ipinfo.io/account/data-downloads
|
||||
$filename = "dbip-country-ipinfo-2024.csv";
|
||||
$table = "dbip_lookup_2";
|
||||
|
||||
if (!isset($type) && preg_match('/dbip-(country-lite|country-ipinfo|city-lite|country|location|isp|full)/i', $filename, $res)) {
|
||||
$type = $res[1];
|
||||
}
|
||||
|
||||
if (!isset($filename) || !isset($type)) {
|
||||
die("usage: {$argv[0]} -f <filename.csv[.gz]> [-d <country-lite|city-lite|country|location|isp|full>] [-b <database_name>] [-t <table_name>] [-u <username>] [-p <password>]\n");
|
||||
}
|
||||
|
||||
switch (strtolower($type)) {
|
||||
case "country-lite": $dbtype = DBIP::TYPE_COUNTRY_LITE; break;
|
||||
case "country-ipinfo": $dbtype = DBIP::TYPE_COUNTRY_IPINFO; break;
|
||||
case "city-lite": $dbtype = DBIP::TYPE_CITY_LITE; break;
|
||||
case "country": $dbtype = DBIP::TYPE_COUNTRY; break;
|
||||
case "location": $dbtype = DBIP::TYPE_LOCATION; break;
|
||||
case "isp": $dbtype = DBIP::TYPE_ISP; break;
|
||||
case "full": $dbtype = DBIP::TYPE_FULL; break;
|
||||
default: echo "invalid database type\n"; exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
// Connect to the database
|
||||
$db = new PDO("mysql:{$host}=localhost;dbname={$dbname};charset=utf8mb4", $username, $password);
|
||||
// Alternatively connect to MySQL using the old interface
|
||||
// Comment the PDO statement above and uncomment the mysql_ calls
|
||||
// below if your PHP installation doesn't support PDO :
|
||||
// $db = mysql_connect("localhost", $username, $password);
|
||||
// mysql_select_db($dbname, $db);
|
||||
|
||||
// Instanciate a new DBIP object with the database connection
|
||||
$dbip = new DBIP($db); //DBIPMySQLI
|
||||
// Alternatively instanciate a DBIP_MySQL object
|
||||
// Comment the new statement above and uncomment below if your PHP
|
||||
// installation doesn't support PDO :
|
||||
// $dbip = new DBIPMySQL($db);
|
||||
|
||||
$nrecs = $dbip->importFromCsv($filename, $dbtype, $table, function($progress) {
|
||||
echo "\r{$progress} ...";
|
||||
});
|
||||
echo "\rfinished importing " . number_format($nrecs) . " records\n";
|
||||
} catch (DBIPException $e) {
|
||||
echo "error: {$e->getMessage()}\n";
|
||||
}
|
||||
73
app/Services/dbip/lookup-example.php
Executable file
73
app/Services/dbip/lookup-example.php
Executable file
|
|
@ -0,0 +1,73 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* DB-IP.com database sample query code
|
||||
*
|
||||
* Copyright (C) 2018 db-ip.com
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
// Include the DB-IP class
|
||||
require "dbip.class.php";
|
||||
|
||||
$host = "192.168.1.8";
|
||||
$dbname = "mivita";
|
||||
$username = "kadmin";
|
||||
$password = "KT32vQ7ix";
|
||||
|
||||
$table = "dbip_lookup";
|
||||
$table_2 = "dbip_lookup_2";
|
||||
|
||||
try {
|
||||
|
||||
// Check if we have a command line parameter
|
||||
if ($argc < 2) {
|
||||
die("usage: {$argv[0]} <ip_address>\n");
|
||||
}
|
||||
|
||||
// Connect to the database
|
||||
$db = new PDO("mysql:{$host}=localhost;dbname={$dbname};charset=utf8mb4", $username, $password);
|
||||
|
||||
// Alternatively connect to MySQL using the old interface
|
||||
// Comment the PDO statement above and uncomment the mysql_ calls
|
||||
// below if your PHP installation doesn't support PDO :
|
||||
// $db = mysql_connect("localhost", "root", "");
|
||||
// mysql_select_db("test", $db);
|
||||
|
||||
// Instanciate a new DBIP object with the database connection
|
||||
$dbip = new DBIP($db);
|
||||
|
||||
// Alternatively instanciate a DBIP_MySQL object
|
||||
// Comment the new statement above and uncomment below if your PHP
|
||||
// installation doesn't support PDO :
|
||||
// $dbip = new DBIPMySQL($db);
|
||||
|
||||
// Lookup an IP address
|
||||
$inf = $dbip->lookup($argv[1], $table);
|
||||
// Show the associated country
|
||||
echo "t:".$table." country = " . $inf->country . "\n";
|
||||
|
||||
$inf = $dbip->lookup($argv[1], $table_2);
|
||||
// Show the associated country
|
||||
echo "t:".$table_2." country = " . $inf->country . "\n";
|
||||
|
||||
} catch (DBIPException $e) {
|
||||
echo "error: {$e->getMessage()}\n";
|
||||
exit(1);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue