| Server IP : 202.61.199.114 / Your IP : 216.73.217.139 Web Server : nginx/1.22.1 System : Linux de.arni-solutions.de 6.1.0-49-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64 User : web20 ( 1018) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /var/www/clients/client2/web21/web/api/lib/ |
Upload File : |
<?php
/**
* RIPEstat-Datenanbindung (RIPE NCC, Amsterdam / EU) – DSGVO-freundlich, ohne Key.
* Dokumentation: https://stat.ripe.net/docs/data_api
*
* @package SafeMyIdent\Api
*/
declare(strict_types=1);
require_once __DIR__ . '/net.php';
/**
* Roh-Aufruf einer RIPEstat-Data-API mit Cache.
*
* @param string $call z. B. 'network-info'.
* @param string $resource IP/ASN/Prefix.
* @param int $ttl Cache-Sekunden.
* @return array<string,mixed>|null 'data'-Teil oder null.
*/
function smi_ripe(string $call, string $resource, int $ttl = 900): ?array
{
$key = 'ripe|' . $call . '|' . $resource;
$hit = smi_cache_get($key);
if ($hit !== null) {
return $hit ?: null;
}
$url = 'https://stat.ripe.net/data/' . rawurlencode($call) . '/data.json?sourceapp=safemyident&resource=' . rawurlencode($resource);
$body = smi_provider_get($url, 6);
$data = null;
if ($body !== '') {
$dec = json_decode($body, true);
if (is_array($dec) && ($dec['status'] ?? '') === 'ok' && isset($dec['data'])) {
$data = $dec['data'];
}
}
smi_cache_set($key, $data ?? [], $ttl);
return $data;
}
/**
* Netz-Info (ASN + Prefix) zu einer IP.
*
* @param string $ip IP.
* @return array{asns:string[],prefix:string}
*/
function smi_ripe_network_info(string $ip): array
{
$d = smi_ripe('network-info', $ip) ?? [];
return [
'asns' => array_values(array_map('strval', (array) ($d['asns'] ?? []))),
'prefix' => (string) ($d['prefix'] ?? ''),
];
}
/**
* AS-Übersicht (Holder/Name).
*
* @param string $asn ASN (Zahl oder "AS123").
* @return array{holder:string,announced:?bool}
*/
function smi_ripe_as_overview(string $asn): array
{
$asn = 'AS' . preg_replace('/\D/', '', $asn);
$d = smi_ripe('as-overview', $asn) ?? [];
return [
'holder' => (string) ($d['holder'] ?? ''),
'announced' => isset($d['announced']) ? (bool) $d['announced'] : null,
];
}
/**
* Geolokalisierung (MaxMind GeoLite über RIPEstat, EU-gehostet).
*
* @param string $ip IP.
* @return array<string,mixed>
*/
function smi_ripe_geoloc(string $ip): array
{
$d = smi_ripe('maxmind-geo-lite', $ip) ?? [];
$loc = (is_array($d['located_resources'] ?? null) && isset($d['located_resources'][0]['locations'][0]))
? $d['located_resources'][0]['locations'][0] : [];
return [
'country' => (string) ($loc['country'] ?? ''),
'city' => (string) ($loc['city'] ?? ''),
'latitude' => isset($loc['latitude']) ? (float) $loc['latitude'] : null,
'longitude' => isset($loc['longitude']) ? (float) $loc['longitude'] : null,
'covered' => isset($loc['covered_percentage']) ? (float) $loc['covered_percentage'] : null,
];
}
/**
* Abuse-Kontakt zu einer IP/Prefix (RIPEstat abuse-contact-finder).
*
* @param string $ip IP.
* @return string E-Mail oder ''.
*/
function smi_ripe_abuse(string $ip): string
{
$d = smi_ripe('abuse-contact-finder', $ip) ?? [];
$c = (array) ($d['abuse_contacts'] ?? []);
return isset($c[0]) ? (string) $c[0] : '';
}
/**
* RPKI-Validierung (Route Origin Authorization) für ASN + Prefix.
*
* @param string $asn ASN (Zahl).
* @param string $prefix Prefix (CIDR).
* @return string valid|invalid|unknown|''
*/
function smi_ripe_rpki(string $asn, string $prefix): string
{
$asn = preg_replace('/\D/', '', $asn);
if ($asn === '' || $prefix === '') {
return '';
}
$d = smi_ripe('rpki-validation', 'AS' . $asn . ',' . $prefix, 3600) ?? [];
return strtolower((string) ($d['status'] ?? ''));
}
/**
* Routing-Status einer IP/Prefix (Sichtbarkeit im globalen BGP).
*
* @param string $resource IP/Prefix.
* @return array{announced:?bool,visibility:?int,first_seen:string,last_seen:string}
*/
function smi_ripe_routing(string $resource): array
{
$d = smi_ripe('routing-status', $resource) ?? [];
$vis = $d['visibility']['v4']['ris_peers_seeing'] ?? ($d['visibility']['v6']['ris_peers_seeing'] ?? null);
return [
'announced' => isset($d['announced']) ? (bool) $d['announced'] : null,
'visibility' => $vis !== null ? (int) $vis : null,
'first_seen' => (string) ($d['first_seen']['time'] ?? ''),
'last_seen' => (string) ($d['last_seen']['time'] ?? ''),
];
}
/**
* WHOIS-Detailfelder (Netname, descr, Kontakte, Daten) aus RIPEstat extrahieren.
*
* @param string $resource IP/Prefix.
* @return array<string,string>
*/
function smi_ripe_whois_detail(string $resource): array
{
$flat = smi_ripe_whois($resource);
$want = ['netname' => '', 'descr' => '', 'country' => '', 'org' => '', 'admin-c' => '', 'tech-c' => '', 'mnt-by' => '', 'created' => '', 'last-modified' => '', 'status' => '', 'inetnum' => '', 'route' => '', 'origin' => ''];
foreach ($flat as $pair) {
$k = strtolower($pair['key']);
if (array_key_exists($k, $want) && $want[$k] === '') {
$want[$k] = $pair['value'];
}
}
return $want;
}
/**
* WHOIS-Objekte (RIPE/ARIN/… über RIPEstat) – liefert flache Key/Value-Paare.
*
* @param string $resource IP/Prefix/ASN.
* @return array<int,array{key:string,value:string}>
*/
function smi_ripe_whois(string $resource): array
{
$d = smi_ripe('whois', $resource) ?? [];
$out = [];
foreach ((array) ($d['records'] ?? []) as $rec) {
foreach ((array) $rec as $attr) {
$k = (string) ($attr['key'] ?? '');
$v = (string) ($attr['value'] ?? '');
if ($k !== '' && $v !== '') {
$out[] = ['key' => $k, 'value' => $v];
}
}
}
return $out;
}