Added whois client, renamed parsers to providers & more
This commit is contained in:
parent
1b45a5b6c9
commit
c186760831
10 changed files with 192 additions and 40 deletions
|
@ -5,7 +5,7 @@
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"CodeSpace\\WhoisParser\\": "src/",
|
"CodeSpace\\WhoisParser\\": "src/",
|
||||||
"CodeSpace\\WhoisParser\\Parser\\": "src/parser/"
|
"CodeSpace\\WhoisParser\\Provider\\": "src/provider/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
<?php namespace CodeSpace\WhoisParser;
|
|
||||||
|
|
||||||
interface ParserInterface {
|
|
||||||
|
|
||||||
public function parseAsn(WhoisParser $whois): ?array;
|
|
||||||
|
|
||||||
public function parseAbuse(WhoisParser $whois): ?array;
|
|
||||||
|
|
||||||
public function parseOrg(WhoisParser $whois): ?array;
|
|
||||||
|
|
||||||
public function parseRoute(WhoisParser $whois): ?array;
|
|
||||||
|
|
||||||
public function parseInet(WhoisParser $whois): ?array;
|
|
||||||
|
|
||||||
public function findAsn(WhoisParser $whois): ?string;
|
|
||||||
|
|
||||||
public function findAbuseContact(WhoisParser $whois): ?string;
|
|
||||||
|
|
||||||
}
|
|
11
src/Provider.php
Normal file
11
src/Provider.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php namespace CodeSpace\WhoisParser;
|
||||||
|
|
||||||
|
enum Provider: string {
|
||||||
|
|
||||||
|
const APNIC_WHOIS = "whois.apnic.net";
|
||||||
|
const RIPE_WHOIS = "whois.ripe.net";
|
||||||
|
|
||||||
|
case APNIC = self::APNIC_WHOIS;
|
||||||
|
case RIPE = self::RIPE_WHOIS;
|
||||||
|
|
||||||
|
}
|
19
src/ProviderInterface.php
Normal file
19
src/ProviderInterface.php
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?php namespace CodeSpace\WhoisParser;
|
||||||
|
|
||||||
|
interface ProviderInterface {
|
||||||
|
|
||||||
|
public function parseAsn(): ?array;
|
||||||
|
|
||||||
|
public function parseAbuse(): ?array;
|
||||||
|
|
||||||
|
public function parseOrg(): ?array;
|
||||||
|
|
||||||
|
public function parseRoute(): ?array;
|
||||||
|
|
||||||
|
public function parseInet(): ?array;
|
||||||
|
|
||||||
|
public function findAsn(): ?string;
|
||||||
|
|
||||||
|
public function findAbuseContact(): ?string;
|
||||||
|
|
||||||
|
}
|
33
src/Whois.php
Normal file
33
src/Whois.php
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
<?php namespace CodeSpace\WhoisParser;
|
||||||
|
|
||||||
|
class Whois {
|
||||||
|
|
||||||
|
public function getIpAddress(string $ip): array {
|
||||||
|
$whois = WhoisClient::query($ip);
|
||||||
|
$list = new WhoisList($whois);
|
||||||
|
$this->addAsn($list);
|
||||||
|
$this->addAbuse($list);
|
||||||
|
return [
|
||||||
|
"network" => $list->parseInet(),
|
||||||
|
"route" => $list->parseRoute(),
|
||||||
|
"asn" => $list->parseAsn(),
|
||||||
|
"org" => $list->parseOrg(),
|
||||||
|
"abuse" => $list->parseAbuse()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function addAsn(WhoisList $list) {
|
||||||
|
$asn = $list->findAsn();
|
||||||
|
if (!$asn) return;
|
||||||
|
$asn_whois = WhoisClient::query($asn);
|
||||||
|
$list->addResponse($asn_whois);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function addAbuse(WhoisList $list) {
|
||||||
|
$abuse_c = $list->findAbuseContact();
|
||||||
|
if (!$abuse_c) return;
|
||||||
|
$abuse_whois = WhoisClient::query($abuse_c);
|
||||||
|
$list->addResponse($abuse_whois);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
26
src/WhoisClient.php
Normal file
26
src/WhoisClient.php
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<?php namespace CodeSpace\WhoisParser;
|
||||||
|
|
||||||
|
use MallardDuck\Whois\Client;
|
||||||
|
|
||||||
|
class WhoisClient {
|
||||||
|
|
||||||
|
public static function query(string $q): ?WhoisParser {
|
||||||
|
$server = self::getServer($q);
|
||||||
|
if (!$server) return null;
|
||||||
|
return self::queryServer("$q -B", $server);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function queryServer(string $q, string $server): WhoisParser {
|
||||||
|
$client = new Client($server);
|
||||||
|
$response = $client->makeRequest($q);
|
||||||
|
return WhoisParser::fromString($response, Provider::tryFrom($server));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getServer(string $q): ?string {
|
||||||
|
if (str_ends_with($q, "-RIPE")) return Provider::RIPE_WHOIS;
|
||||||
|
if (str_ends_with($q, "-AP")) return Provider::APNIC_WHOIS;
|
||||||
|
$res = self::queryServer($q, "whois.iana.org");
|
||||||
|
return $res->getKeysValue(["refer", "whois"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
57
src/WhoisList.php
Normal file
57
src/WhoisList.php
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
<?php namespace CodeSpace\WhoisParser;
|
||||||
|
|
||||||
|
class WhoisList implements ProviderInterface {
|
||||||
|
|
||||||
|
private array $responses = [];
|
||||||
|
|
||||||
|
private array $providers = [];
|
||||||
|
|
||||||
|
public function __construct(?WhoisParser $response = null) {
|
||||||
|
$this->addResponse($response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addResponse(?WhoisParser $response) {
|
||||||
|
if (!$response) return;
|
||||||
|
$provider = $response->getProvider();
|
||||||
|
if (!$provider) return;
|
||||||
|
$this->responses[] = $response;
|
||||||
|
$this->providers[] = $provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function providerIter(string $fn) {
|
||||||
|
foreach ($this->providers as $provider) {
|
||||||
|
$res = $provider->$fn();
|
||||||
|
if ($res) return $res;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parseAsn(): ?array {
|
||||||
|
return $this->providerIter("parseAsn");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parseAbuse(): ?array {
|
||||||
|
return $this->providerIter("parseAbuse");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parseOrg(): ?array {
|
||||||
|
return $this->providerIter("parseOrg");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parseRoute(): ?array {
|
||||||
|
return $this->providerIter("parseRoute");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parseInet(): ?array {
|
||||||
|
return $this->providerIter("parseInet");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findAsn(): ?string {
|
||||||
|
return $this->providerIter("findAsn");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findAbuseContact(): ?string {
|
||||||
|
return $this->providerIter("findAbuseContact");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,21 +1,32 @@
|
||||||
<?php namespace CodeSpace\WhoisParser;
|
<?php namespace CodeSpace\WhoisParser;
|
||||||
|
|
||||||
|
use CodeSpace\WhoisParser\Provider\ApNicProvider;
|
||||||
|
use CodeSpace\WhoisParser\Provider\RipeProvider;
|
||||||
|
|
||||||
class WhoisParser {
|
class WhoisParser {
|
||||||
|
|
||||||
public array $lines = [];
|
public array $lines = [];
|
||||||
public string $provider;
|
public ?Provider $provider;
|
||||||
|
|
||||||
public static function fromArray(array $lines, string $provider) {
|
public static function fromArray(array $lines, ?Provider $provider = null) {
|
||||||
$parser = new self();
|
$parser = new self();
|
||||||
$parser->lines = $lines;
|
$parser->lines = $lines;
|
||||||
$parser->provider = $provider;
|
$parser->provider = $provider;
|
||||||
return $parser;
|
return $parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function fromString(string $whois, string $provider) {
|
public static function fromString(string $whois, ?Provider $provider = null) {
|
||||||
return self::fromArray(explode("\n", $whois), $provider);
|
return self::fromArray(explode("\n", $whois), $provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getProvider(): ?ProviderInterface {
|
||||||
|
if (!$this->provider) return null;
|
||||||
|
return match ($this->provider) {
|
||||||
|
Provider::RIPE => new RipeProvider($this),
|
||||||
|
Provider::APNIC => new ApNicProvider($this)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private function getOffset(array $arr, int $index): mixed {
|
private function getOffset(array $arr, int $index): mixed {
|
||||||
return count($arr) > $index ? $arr[$index] : null;
|
return count($arr) > $index ? $arr[$index] : null;
|
||||||
}
|
}
|
||||||
|
|
3
src/provider/ApNicProvider.php
Normal file
3
src/provider/ApNicProvider.php
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<?php namespace CodeSpace\WhoisParser\Provider;
|
||||||
|
|
||||||
|
class ApNicProvider extends RipeProvider {}
|
|
@ -1,12 +1,19 @@
|
||||||
<?php namespace CodeSpace\WhoisParser\Parser;
|
<?php namespace CodeSpace\WhoisParser\Provider;
|
||||||
|
|
||||||
use CodeSpace\WhoisParser\ParserInterface;
|
use CodeSpace\WhoisParser\ProviderInterface;
|
||||||
use CodeSpace\WhoisParser\WhoisParser;
|
use CodeSpace\WhoisParser\WhoisParser;
|
||||||
|
|
||||||
class RipeParser implements ParserInterface {
|
class RipeProvider implements ProviderInterface {
|
||||||
|
|
||||||
public function parseAsn(WhoisParser $whois): ?array {
|
private $whois;
|
||||||
$as = $whois->getSectionWithKey("aut-num");
|
|
||||||
|
public function __construct(WhoisParser $whois) {
|
||||||
|
$this->whois = $whois;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parseAsn(): ?array {
|
||||||
|
$as = $this->whois->getSectionWithKey("aut-num");
|
||||||
|
if (!$as) return null;
|
||||||
return [
|
return [
|
||||||
"asn" => $as->getKeyValue("aut-num"),
|
"asn" => $as->getKeyValue("aut-num"),
|
||||||
"name" => $as->getKeyValue("as-name"),
|
"name" => $as->getKeyValue("as-name"),
|
||||||
|
@ -14,8 +21,9 @@ class RipeParser implements ParserInterface {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function parseAbuse(WhoisParser $whois): ?array {
|
public function parseAbuse(): ?array {
|
||||||
$abuse = $whois->getSectionWithKey("abuse-mailbox");
|
$abuse = $this->whois->getSectionWithKey("abuse-mailbox");
|
||||||
|
if (!$abuse) return null;
|
||||||
return [
|
return [
|
||||||
"role" => $abuse->getKeyValue("role"),
|
"role" => $abuse->getKeyValue("role"),
|
||||||
"address" => $abuse->getKeyValues("address"),
|
"address" => $abuse->getKeyValues("address"),
|
||||||
|
@ -25,8 +33,9 @@ class RipeParser implements ParserInterface {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function parseOrg(WhoisParser $whois): ?array {
|
public function parseOrg(): ?array {
|
||||||
$org = $whois->getSectionWithKey("organisation");
|
$org = $this->whois->getSectionWithKey("organisation");
|
||||||
|
if (!$org) return null;
|
||||||
return [
|
return [
|
||||||
"id" => $org->getKeyValue("organisation"),
|
"id" => $org->getKeyValue("organisation"),
|
||||||
"name" => $org->getKeyValue("org-name"),
|
"name" => $org->getKeyValue("org-name"),
|
||||||
|
@ -37,8 +46,9 @@ class RipeParser implements ParserInterface {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function parseRoute(WhoisParser $whois): ?array {
|
public function parseRoute(): ?array {
|
||||||
$section = $whois->getSectionWithKeys(["route", "route6"]);
|
$section = $this->whois->getSectionWithKeys(["route", "route6"]);
|
||||||
|
if (!$section) return null;
|
||||||
$range = $section->getKeysValue(["route", "route6"]);
|
$range = $section->getKeysValue(["route", "route6"]);
|
||||||
return [
|
return [
|
||||||
"range" => $range,
|
"range" => $range,
|
||||||
|
@ -47,8 +57,9 @@ class RipeParser implements ParserInterface {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function parseInet(WhoisParser $whois): ?array {
|
public function parseInet(): ?array {
|
||||||
$section = $whois->getSectionWithKeys(["inetnum", "inet6num"]);
|
$section = $this->whois->getSectionWithKeys(["inetnum", "inet6num"]);
|
||||||
|
if (!$section) return null;
|
||||||
$range = $section->getKeysValue(["inetnum", "inet6num"]);
|
$range = $section->getKeysValue(["inetnum", "inet6num"]);
|
||||||
return [
|
return [
|
||||||
"range" => $range,
|
"range" => $range,
|
||||||
|
@ -58,12 +69,12 @@ class RipeParser implements ParserInterface {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function findAsn(WhoisParser $whois): ?string {
|
public function findAsn(): ?string {
|
||||||
return $whois->getKeyValue("origin");
|
return $this->whois->getKeyValue("origin");
|
||||||
}
|
}
|
||||||
|
|
||||||
public function findAbuseContact(WhoisParser $whois): ?string {
|
public function findAbuseContact(): ?string {
|
||||||
return $whois->getKeyValue("abuse-c");
|
return $this->whois->getKeyValue("abuse-c");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue