<?php
require_once __DIR__ . '/../config.php';
require_once __DIR__ . '/../includes/functions.php';

$page_title   = 'ASN Lookup – Networks, Upstreams and Prefixes';
$page_desc    = 'Free ASN Lookup: networks, upstreams, peers, IPv4/IPv6 prefixes and more for any autonomous system – on ipcheck.tools.';
$page_current = 'asn';

$query  = trim(strip_tags($_GET['asn'] ?? ''));
$result = [];
$error  = '';

function api_get_en(string $url): ?array {
    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL            => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 8,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_USERAGENT      => 'ipcheck.tools/1.0',
        CURLOPT_HTTPHEADER     => ['Accept: application/json'],
    ]);
    $json = curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    if (!$json || $code >= 400) return null;
    return json_decode($json, true);
}

if ($query) {
    $asn_num = preg_replace('/^AS/i', '', $query);
    $asn_num = preg_replace('/[^0-9]/', '', $asn_num);
    $asn     = 'AS' . $asn_num;

    if (!$asn_num) {
        $error = 'Invalid ASN. Please use format AS3320 or 3320.';
    } else {
        $rdap          = api_get_en("https://rdap.db.ripe.net/autnum/{$asn_num}");
        if (!$rdap) $rdap = api_get_en("https://rdap.arin.net/registry/autnum/{$asn_num}");
        $ripe_prefixes  = api_get_en("https://stat.ripe.net/data/announced-prefixes/data.json?resource=AS{$asn_num}");
        $ripe_upstreams = api_get_en("https://stat.ripe.net/data/asn-neighbours/data.json?resource=AS{$asn_num}");

        if (!$rdap) {
            $error = 'ASN <strong>' . h($asn) . '</strong> not found.';
        } else {
            $name = $rdap['name'] ?? $asn;
            $org = $rir = $abuse_email = '';
            foreach ($rdap['entities'] ?? [] as $entity) {
                $roles = $entity['roles'] ?? [];
                $fn = '';
                foreach ($entity['vcardArray'][1] ?? [] as $vcard) {
                    if (($vcard[0] ?? '') === 'fn') $fn = $vcard[3] ?? '';
                }
                if (in_array('registrant', $roles) && !$org) $org = $fn;
                if (in_array('abuse', $roles)) {
                    foreach ($entity['vcardArray'][1] ?? [] as $v) {
                        if (($v[0] ?? '') === 'email') $abuse_email = $v[3] ?? '';
                    }
                }
            }
            foreach ($rdap['links'] ?? [] as $link) {
                $href = $link['href'] ?? '';
                if (str_contains($href, 'ripe.net'))    $rir = 'RIPE NCC';
                if (str_contains($href, 'arin.net'))    $rir = 'ARIN';
                if (str_contains($href, 'apnic.net'))   $rir = 'APNIC';
                if (str_contains($href, 'lacnic.net'))  $rir = 'LACNIC';
                if (str_contains($href, 'afrinic.net')) $rir = 'AFRINIC';
            }
            $created = $updated = '';
            foreach ($rdap['events'] ?? [] as $event) {
                $date = isset($event['eventDate']) ? date('d.m.Y', strtotime($event['eventDate'])) : '';
                if ($event['eventAction'] === 'registration') $created = $date;
                if ($event['eventAction'] === 'last changed')  $updated = $date;
            }
            $ipv4_prefixes = $ipv6_prefixes = [];
            foreach ($ripe_prefixes['data']['prefixes'] ?? [] as $p) {
                $prefix = $p['prefix'] ?? '';
                if (str_contains($prefix, ':')) $ipv6_prefixes[] = ['prefix' => $prefix];
                else $ipv4_prefixes[] = ['prefix' => $prefix];
            }
            $upstreams_v4 = $peers_v4 = [];
            foreach ($ripe_upstreams['data']['neighbours'] ?? [] as $n) {
                $entry = ['asn' => $n['asn'], 'name' => 'AS' . $n['asn']];
                if (($n['type'] ?? '') === 'left') $upstreams_v4[] = $entry;
                else $peers_v4[] = $entry;
            }
            foreach ($upstreams_v4 as $idx => $up) {
                if ($idx >= 10) break;
                $r = api_get_en("https://rdap.db.ripe.net/autnum/{$up['asn']}");
                if (!$r) $r = api_get_en("https://rdap.arin.net/registry/autnum/{$up['asn']}");
                if ($r && isset($r['name'])) $upstreams_v4[$idx]['name'] = $r['name'];
            }
            $result = [
                'asn' => $asn, 'asn_num' => $asn_num, 'name' => $name,
                'description' => $org, 'country_code' => $rdap['country'] ?? '',
                'abuse_email' => $abuse_email, 'rir' => $rir,
                'allocated' => $created, 'updated' => $updated,
                'ipv4_prefixes' => array_slice($ipv4_prefixes, 0, 20),
                'ipv6_prefixes' => array_slice($ipv6_prefixes, 0, 10),
                'ipv4_count' => count($ipv4_prefixes),
                'ipv6_count' => count($ipv6_prefixes),
                'upstreams_v4' => array_slice($upstreams_v4, 0, 10),
                'peers_v4' => array_slice($peers_v4, 0, 20),
                'peers_v4_count' => count($peers_v4),
            ];
        }
    }
}

require_once __DIR__ . '/header.php';
?>

<div class="hero">
  <div class="hero-label">Tool</div>
  <div class="hero-title">ASN Lookup</div>
  <div class="hero-sub">Networks, upstreams, peers and prefixes of an autonomous system</div>
  <form method="GET" action="/en/asn.php">
    <div class="input-group">
      <input class="input-text" type="text" name="asn"
             value="<?= h($query) ?>"
             placeholder="e.g. AS3320 or 3320"
             required />
      <button type="submit" class="btn btn-primary">
        <i class="ti ti-search"></i> Query ASN
      </button>
    </div>
  </form>
</div>

<div class="wrap">

  <div class="ad-slot"><ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-8287576653347400" data-ad-slot="2715725452" data-ad-format="auto" data-full-width-responsive="true"></ins><script>(adsbygoogle = window.adsbygoogle || []).push({});</script></div>

  <?php if ($error): ?>
    <div class="alert alert-warn"><i class="ti ti-alert-triangle"></i><span><?= $error ?></span></div>

  <?php elseif ($result): ?>

    <div class="stat-grid">
      <div class="stat"><div class="stat-val" style="color:var(--blue-dim);"><?= h($result['asn']) ?></div><div class="stat-key">ASN</div></div>
      <div class="stat"><div class="stat-val" style="font-size:12px;"><?= h($result['rir'] ?: '–') ?></div><div class="stat-key">RIR</div></div>
      <div class="stat"><div class="stat-val"><?= $result['ipv4_count'] ?></div><div class="stat-key">IPv4 Prefixes</div></div>
      <div class="stat"><div class="stat-val"><?= $result['ipv6_count'] ?></div><div class="stat-key">IPv6 Prefixes</div></div>
    </div>

    <div class="grid2">
      <div class="card card-blue">
        <div class="card-title"><i class="ti ti-building"></i> AS Information</div>
        <div class="data-row"><span class="dk">ASN</span><span class="dv mono blue"><?= h($result['asn']) ?></span></div>
        <div class="data-row"><span class="dk">Name</span><span class="dv"><?= h($result['name']) ?></span></div>
        <?php if ($result['description']): ?>
        <div class="data-row"><span class="dk">Organisation</span><span class="dv" style="font-size:12px;"><?= h($result['description']) ?></span></div>
        <?php endif; ?>
        <div class="data-row"><span class="dk">Country</span><span class="dv">
          <?php if ($result['country_code']): ?><?= country_flag($result['country_code']) ?> <?= h($result['country_code']) ?><?php else: ?>–<?php endif; ?>
        </span></div>
        <div class="data-row"><span class="dk">RIR</span><span class="dv"><?= h($result['rir'] ?: '–') ?></span></div>
        <?php if ($result['allocated']): ?>
        <div class="data-row"><span class="dk">Allocated</span><span class="dv mono"><?= h($result['allocated']) ?></span></div>
        <?php endif; ?>
        <?php if ($result['abuse_email']): ?>
        <div class="data-row"><span class="dk">Abuse contact</span><span class="dv mono" style="font-size:11px;"><?= h($result['abuse_email']) ?></span></div>
        <?php endif; ?>
      </div>
      <div class="card">
        <div class="card-title"><i class="ti ti-chart-bar"></i> Network Overview</div>
        <div class="data-row"><span class="dk">IPv4 Prefixes</span><span class="dv" style="color:var(--blue-dim);"><?= $result['ipv4_count'] ?></span></div>
        <div class="data-row"><span class="dk">IPv6 Prefixes</span><span class="dv" style="color:var(--purple-dim);"><?= $result['ipv6_count'] ?></span></div>
        <div class="data-row"><span class="dk">Upstreams IPv4</span><span class="dv"><?= count($result['upstreams_v4']) ?></span></div>
        <div class="data-row"><span class="dk">BGP Peers IPv4</span><span class="dv"><?= $result['peers_v4_count'] ?></span></div>
      </div>
    </div>

    <?php if ($result['upstreams_v4']): ?>
    <div class="card">
      <div class="card-title"><i class="ti ti-arrow-up"></i> Upstreams (Transit Providers)</div>
      <div style="font-size:10px; color:var(--text4); letter-spacing:1px; text-transform:uppercase; margin-bottom:8px;">IPv4</div>
      <?php foreach ($result['upstreams_v4'] as $up): ?>
      <div style="display:flex; justify-content:space-between; align-items:center; padding:7px 0; border-bottom:1px solid var(--border2);">
        <a href="/en/asn.php?asn=AS<?= h($up['asn']) ?>" style="font-family:var(--font-mono); font-size:12px; font-weight:600; color:var(--blue-dim); flex-shrink:0;">AS<?= h($up['asn']) ?></a>
        <span style="font-size:12px; color:var(--text2); text-align:right; margin-left:12px;"><?= h($up['name']) ?></span>
      </div>
      <?php endforeach; ?>
    </div>
    <?php endif; ?>

    <?php if ($result['ipv4_prefixes']): ?>
    <div class="card">
      <div class="card-title"><i class="ti ti-network"></i> IPv4 Prefixes (<?= $result['ipv4_count'] ?> total<?= $result['ipv4_count'] > 20 ? ', showing 20' : '' ?>)</div>
      <div style="display:grid; grid-template-columns:repeat(2,1fr); gap:4px 16px;">
        <?php foreach ($result['ipv4_prefixes'] as $p): ?>
        <div style="font-family:var(--font-mono); font-size:12px; color:var(--blue-dim); padding:4px 0; border-bottom:1px solid var(--border2);"><?= h($p['prefix']) ?></div>
        <?php endforeach; ?>
      </div>
    </div>
    <?php endif; ?>

    <?php if ($result['ipv6_prefixes']): ?>
    <div class="card">
      <div class="card-title"><i class="ti ti-network"></i> IPv6 Prefixes (<?= $result['ipv6_count'] ?> total<?= $result['ipv6_count'] > 10 ? ', showing 10' : '' ?>)</div>
      <div style="display:grid; grid-template-columns:repeat(2,1fr); gap:4px 16px;">
        <?php foreach ($result['ipv6_prefixes'] as $p): ?>
        <div style="font-family:var(--font-mono); font-size:11px; color:var(--purple-dim); padding:4px 0; border-bottom:1px solid var(--border2);"><?= h($p['prefix']) ?></div>
        <?php endforeach; ?>
      </div>
    </div>
    <?php endif; ?>

    <?php if ($result['peers_v4']): ?>
    <div class="card">
      <div class="card-title"><i class="ti ti-arrows-exchange"></i> BGP Peers IPv4 (<?= $result['peers_v4_count'] ?> total<?= $result['peers_v4_count'] > 20 ? ', showing 20' : '' ?>)</div>
      <div style="display:grid; grid-template-columns:repeat(3,1fr); gap:4px 16px;">
        <?php foreach ($result['peers_v4'] as $p): ?>
        <div style="padding:4px 0; border-bottom:1px solid var(--border2);">
          <a href="/en/asn.php?asn=AS<?= h($p['asn']) ?>" style="font-family:var(--font-mono); font-size:11px; color:var(--blue-dim);">AS<?= h($p['asn']) ?></a>
        </div>
        <?php endforeach; ?>
      </div>
    </div>
    <?php endif; ?>

  <?php else: ?>
    <div class="alert alert-info">
      <i class="ti ti-info-circle"></i>
      <span>Enter an ASN to retrieve networks, upstreams, peers and prefixes. Format: <strong>AS3320</strong> or <strong>3320</strong>.</span>
    </div>
    <div class="card">
      <div class="card-title"><i class="ti ti-bookmark"></i> Known ASNs</div>
      <?php foreach ([['AS3320','Deutsche Telekom'],['AS3209','Vodafone Germany'],['AS15169','Google'],['AS13335','Cloudflare'],['AS16509','Amazon AWS'],['AS8075','Microsoft'],['AS32934','Meta (Facebook)'],['AS8560','IONOS']] as [$asn,$name]): ?>
      <div class="data-row">
        <span class="dk"><a href="/en/asn.php?asn=<?= urlencode($asn) ?>" style="font-family:var(--font-mono); font-size:12px;"><?= $asn ?></a></span>
        <span class="dv"><?= $name ?></span>
      </div>
      <?php endforeach; ?>
    </div>
  <?php endif; ?>

  <div class="ad-slot"><ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-8287576653347400" data-ad-slot="2715725452" data-ad-format="auto" data-full-width-responsive="true"></ins><script>(adsbygoogle = window.adsbygoogle || []).push({});</script></div>

  <div class="tools-row">
    <a href="/en/"              class="tool-btn"><i class="ti ti-home"></i><span>My IP</span></a>
    <a href="/en/asn.php"       class="tool-btn current"><i class="ti ti-building"></i><span>ASN Lookup</span></a>
    <a href="/en/ip-lookup.php" class="tool-btn"><i class="ti ti-world-search"></i><span>IP Lookup</span></a>
    <a href="/en/whois.php"     class="tool-btn"><i class="ti ti-id"></i><span>WHOIS</span></a>
    <a href="/en/dns-lookup.php" class="tool-btn"><i class="ti ti-search"></i><span>DNS Lookup</span></a>
  </div>

  <div class="seo-box">
    <h2>What is an ASN?</h2>
    <p>An <strong>Autonomous System Number (ASN)</strong> is a unique number assigned to a network on the internet. <strong>Upstreams</strong> are the transit providers through which the AS reaches the internet. <strong>Peers</strong> are networks with which direct traffic exchange takes place. <strong>Prefixes</strong> are the IP address ranges that the AS announces to the internet. Data via RIPE NCC RDAP and RIPEstat API.</p>
  </div>

<?php require_once __DIR__ . '/footer.php'; ?>
