mirror of
https://github.com/MrUnknownDE/utools.git
synced 2026-04-17 05:13:44 +02:00
471 lines
19 KiB
HTML
471 lines
19 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="de">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>ASN / AS Lookup - uTools</title>
|
|
<meta name="description"
|
|
content="Look up any Autonomous System Number (ASN) to see peering connections, network graph, prefixes and IXP information.">
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<!-- D3.js v7 for network graph -->
|
|
<script src="https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js"></script>
|
|
<style>
|
|
.loader {
|
|
border: 4px solid rgba(168, 85, 247, 0.1);
|
|
border-left-color: #d8b4fe;
|
|
border-radius: 50%;
|
|
width: 24px;
|
|
height: 24px;
|
|
animation: spin 1s linear infinite;
|
|
}
|
|
|
|
@keyframes spin {
|
|
to {
|
|
transform: rotate(360deg);
|
|
}
|
|
}
|
|
|
|
.glass-panel {
|
|
background: rgba(17, 24, 39, 0.7);
|
|
backdrop-filter: blur(12px);
|
|
-webkit-backdrop-filter: blur(12px);
|
|
border: 1px solid rgba(255, 255, 255, 0.05);
|
|
}
|
|
|
|
.glass-card {
|
|
background: rgba(31, 41, 55, 0.6);
|
|
backdrop-filter: blur(8px);
|
|
-webkit-backdrop-filter: blur(8px);
|
|
border: 1px solid rgba(255, 255, 255, 0.05);
|
|
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
|
}
|
|
|
|
.glass-card:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 10px 30px -10px rgba(0, 0, 0, 0.5);
|
|
}
|
|
|
|
@keyframes fadeIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(10px);
|
|
}
|
|
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
.fade-in {
|
|
animation: fadeIn 0.5s ease-out forwards;
|
|
}
|
|
|
|
.text-gradient {
|
|
background: linear-gradient(to right, #c084fc, #e879f9);
|
|
-webkit-background-clip: text;
|
|
background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
}
|
|
|
|
.hidden {
|
|
display: none !important;
|
|
}
|
|
|
|
nav ul {
|
|
list-style: none;
|
|
padding: 0;
|
|
margin: 0;
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 0.5rem;
|
|
}
|
|
|
|
nav a {
|
|
color: #d1d5db;
|
|
text-decoration: none;
|
|
padding: 0.5rem 1rem;
|
|
border-radius: 0.5rem;
|
|
transition: all 0.2s ease;
|
|
background: rgba(255, 255, 255, 0.03);
|
|
border: 1px solid rgba(255, 255, 255, 0.05);
|
|
}
|
|
|
|
nav a:hover {
|
|
color: #fff;
|
|
background: rgba(168, 85, 247, 0.2);
|
|
border-color: rgba(168, 85, 247, 0.4);
|
|
}
|
|
|
|
nav a.active-link {
|
|
background: rgba(168, 85, 247, 0.3);
|
|
color: #fff;
|
|
border-color: #a855f7;
|
|
}
|
|
|
|
header {
|
|
background: rgba(31, 41, 55, 0.4);
|
|
backdrop-filter: blur(10px);
|
|
padding: 1.5rem;
|
|
margin-bottom: 2rem;
|
|
border-radius: 1rem;
|
|
border: 1px solid rgba(255, 255, 255, 0.05);
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 1rem;
|
|
}
|
|
|
|
@media (min-width: 768px) {
|
|
header {
|
|
flex-direction: row;
|
|
justify-content: space-between;
|
|
}
|
|
}
|
|
|
|
/* ── Network Graph ─────────────────────────────────────── */
|
|
#graph-container {
|
|
width: 100%;
|
|
height: 600px;
|
|
background: rgba(0, 0, 0, 0.3);
|
|
border-radius: 0.75rem;
|
|
border: 1px solid rgba(255, 255, 255, 0.06);
|
|
overflow: hidden;
|
|
position: relative;
|
|
}
|
|
|
|
#graph-svg {
|
|
width: 100%;
|
|
height: 100%;
|
|
cursor: grab;
|
|
}
|
|
|
|
#graph-svg:active {
|
|
cursor: grabbing;
|
|
}
|
|
|
|
.node-center circle {
|
|
fill: #a855f7;
|
|
stroke: #d8b4fe;
|
|
stroke-width: 2.5;
|
|
}
|
|
|
|
.node-upstream circle {
|
|
fill: #3b82f6;
|
|
stroke: #93c5fd;
|
|
stroke-width: 1.5;
|
|
}
|
|
|
|
.node-downstream circle {
|
|
fill: #10b981;
|
|
stroke: #6ee7b7;
|
|
stroke-width: 1.5;
|
|
}
|
|
|
|
.node-tier1 circle {
|
|
fill: #6b7280;
|
|
stroke: #9ca3af;
|
|
stroke-width: 1.5;
|
|
}
|
|
|
|
.node text {
|
|
fill: #e5e7eb;
|
|
font-size: 11px;
|
|
font-family: 'Courier New', monospace;
|
|
pointer-events: none;
|
|
text-anchor: middle;
|
|
}
|
|
|
|
.node:hover circle {
|
|
filter: brightness(1.4);
|
|
cursor: pointer;
|
|
}
|
|
|
|
.link {
|
|
stroke: rgba(255, 255, 255, 0.12);
|
|
stroke-linecap: round;
|
|
}
|
|
|
|
.link-upstream {
|
|
stroke: rgba(59, 130, 246, 0.35);
|
|
}
|
|
|
|
.link-tier1 {
|
|
stroke: rgba(107, 114, 128, 0.3);
|
|
stroke-dasharray: 4 3;
|
|
}
|
|
|
|
.link-downstream {
|
|
stroke: rgba(16, 185, 129, 0.35);
|
|
}
|
|
|
|
/* Tooltip */
|
|
#graph-tooltip {
|
|
position: absolute;
|
|
pointer-events: none;
|
|
background: rgba(17, 24, 39, 0.95);
|
|
backdrop-filter: blur(8px);
|
|
border: 1px solid rgba(168, 85, 247, 0.4);
|
|
border-radius: 0.5rem;
|
|
padding: 0.6rem 0.9rem;
|
|
font-size: 12px;
|
|
color: #e5e7eb;
|
|
max-width: 220px;
|
|
z-index: 50;
|
|
opacity: 0;
|
|
transition: opacity 0.15s;
|
|
}
|
|
|
|
/* Prefix list */
|
|
.prefix-tag {
|
|
display: inline-block;
|
|
font-family: monospace;
|
|
font-size: 11px;
|
|
background: rgba(168, 85, 247, 0.15);
|
|
color: #c084fc;
|
|
border: 1px solid rgba(168, 85, 247, 0.3);
|
|
border-radius: 4px;
|
|
padding: 2px 6px;
|
|
margin: 2px;
|
|
}
|
|
|
|
/* IXP table */
|
|
.ixp-row {
|
|
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
|
}
|
|
|
|
.ixp-row:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
::-webkit-scrollbar {
|
|
width: 8px;
|
|
height: 8px;
|
|
}
|
|
|
|
::-webkit-scrollbar-track {
|
|
background: rgba(31, 41, 55, 0.5);
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb {
|
|
background: #4b5563;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb:hover {
|
|
background: #6b7280;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body
|
|
class="bg-gray-950 text-gray-100 font-sans p-4 md:p-8 min-h-screen bg-[url('https://tailwindcss.com/_next/static/media/hero-dark.939eb757.png')] bg-cover bg-center bg-fixed selection:bg-purple-500 selection:text-white">
|
|
|
|
<header class="glass-panel">
|
|
<h1>uTools <span class="text-sm font-normal text-gray-400 opacity-75 tracking-wider uppercase ml-2">Network
|
|
Suite</span></h1>
|
|
<nav>
|
|
<ul>
|
|
<li><a href="/">IP Info & Tools</a></li>
|
|
<li><a href="/subnet">Subnetz Rechner</a></li>
|
|
<li><a href="/dns">DNS Lookup</a></li>
|
|
<li><a href="/whois">WHOIS Lookup</a></li>
|
|
<li><a href="/mac">MAC Lookup</a></li>
|
|
<li><a href="/asn" class="active-link">ASN Lookup</a></li>
|
|
</ul>
|
|
</nav>
|
|
</header>
|
|
|
|
<div
|
|
class="container mx-auto max-w-6xl glass-panel rounded-xl shadow-2xl p-6 md:p-8 backdrop-blur-xl border border-gray-800/50">
|
|
|
|
<h1 class="text-3xl font-bold mb-2 text-center text-gradient">AS / ASN Lookup</h1>
|
|
<p class="text-center text-gray-400 text-sm mb-8">Peering graph, prefixes & IXP connections for any
|
|
Autonomous System</p>
|
|
|
|
<!-- Search -->
|
|
<div class="flex flex-col sm:flex-row gap-3 mb-6 max-w-2xl mx-auto">
|
|
<input type="text" id="asn-input" placeholder="Enter ASN (e.g. 15169 or AS3320)"
|
|
class="flex-grow px-4 py-3 bg-gray-900/50 border border-gray-700/50 rounded-lg text-gray-200 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent font-mono transition-all placeholder-gray-600">
|
|
<button id="lookup-button"
|
|
class="bg-gradient-to-r from-purple-600 to-pink-600 hover:from-purple-500 hover:to-pink-500 text-white font-bold py-3 px-6 rounded-lg shadow-lg hover:shadow-purple-500/25 transition-all duration-200 ease-in-out transform hover:-translate-y-0.5">
|
|
Lookup
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Error -->
|
|
<div id="error-box"
|
|
class="hidden max-w-2xl mx-auto mb-6 p-4 bg-red-900/30 border border-red-500/40 text-red-300 rounded-lg text-sm">
|
|
</div>
|
|
|
|
<!-- Loading -->
|
|
<div id="loading-section" class="hidden flex flex-col items-center gap-4 py-16">
|
|
<div class="loader" style="width:40px;height:40px;border-width:5px;"></div>
|
|
<p class="text-gray-400 text-sm" id="loading-msg">Querying RIPE Stat & PeeringDB…</p>
|
|
<!-- Shown after 3s for slow lookups -->
|
|
<div id="loading-hint" class="hidden mt-2 max-w-sm text-center">
|
|
<p class="text-xs text-amber-400/80 bg-amber-400/10 border border-amber-400/20 rounded-lg px-4 py-2">
|
|
⏳ Large ASes (like Cloudflare, Google, Tier-1 carriers) can take up to 15 seconds on the first
|
|
lookup — subsequent lookups are cached for 7 days.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Results -->
|
|
<div id="results-section" class="hidden fade-in">
|
|
|
|
<!-- AS Info Header -->
|
|
<div class="glass-card rounded-xl p-6 mb-6">
|
|
<div class="flex flex-col md:flex-row md:items-center gap-4">
|
|
<div class="flex-1">
|
|
<div class="flex items-center gap-3 mb-1">
|
|
<span id="res-asn" class="font-mono text-2xl font-bold text-purple-400"></span>
|
|
<span id="res-announced-badge"
|
|
class="hidden text-xs px-2 py-0.5 bg-green-500/20 border border-green-500/40 text-green-400 rounded-full">Announced</span>
|
|
<span id="res-type-badge"
|
|
class="text-xs px-2 py-0.5 bg-blue-500/20 border border-blue-500/40 text-blue-300 rounded-full"></span>
|
|
</div>
|
|
<h2 id="res-name" class="text-xl font-semibold text-white mb-1"></h2>
|
|
<div class="flex flex-wrap items-center gap-x-4 gap-y-1 text-sm text-gray-400 mb-2">
|
|
<span id="res-policy-container" class="hidden">Peering Policy: <span id="res-policy"
|
|
class="text-gray-200"></span></span>
|
|
<span id="res-website-container" class="hidden">Website: <a id="res-website" href="#"
|
|
target="_blank"
|
|
class="text-purple-400 hover:text-purple-300 transition-colors"></a></span>
|
|
</div>
|
|
|
|
<!-- Rich Info Grid -->
|
|
<div id="res-rich-info"
|
|
class="grid grid-cols-2 sm:grid-cols-4 gap-3 mt-4 pt-4 border-t border-gray-700/50 hidden">
|
|
<div id="res-info-type-container" class="hidden">
|
|
<div class="text-xs text-gray-500 uppercase tracking-widest">Type</div>
|
|
<div id="res-info-type" class="text-sm text-gray-200 capitalize mt-0.5"></div>
|
|
</div>
|
|
<div id="res-info-scope-container" class="hidden">
|
|
<div class="text-xs text-gray-500 uppercase tracking-widest">Scope</div>
|
|
<div id="res-info-scope" class="text-sm text-gray-200 capitalize mt-0.5"></div>
|
|
</div>
|
|
<div id="res-info-traffic-container" class="hidden">
|
|
<div class="text-xs text-gray-500 uppercase tracking-widest">Traffic</div>
|
|
<div id="res-info-traffic" class="text-sm text-gray-200 capitalize mt-0.5"></div>
|
|
</div>
|
|
<div id="res-info-ratio-container" class="hidden">
|
|
<div class="text-xs text-gray-500 uppercase tracking-widest">Ratio</div>
|
|
<div id="res-info-ratio" class="text-sm text-gray-200 capitalize mt-0.5"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="grid grid-cols-2 sm:grid-cols-3 gap-3 text-center">
|
|
<div class="bg-blue-500/10 border border-blue-500/20 rounded-lg p-3">
|
|
<div id="res-upstream-count" class="text-xl font-bold text-blue-400">—</div>
|
|
<div class="text-xs text-gray-400 mt-0.5">Upstreams</div>
|
|
</div>
|
|
<div class="bg-green-500/10 border border-green-500/20 rounded-lg p-3">
|
|
<div id="res-downstream-count" class="text-xl font-bold text-green-400">—</div>
|
|
<div class="text-xs text-gray-400 mt-0.5">Downstreams</div>
|
|
</div>
|
|
<div
|
|
class="bg-purple-500/10 border border-purple-500/20 rounded-lg p-3 col-span-2 sm:col-span-1">
|
|
<div id="res-prefix-count" class="text-xl font-bold text-purple-400">—</div>
|
|
<div class="text-xs text-gray-400 mt-0.5">Prefixes</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Network Map -->
|
|
<div class="glass-card rounded-xl p-6 mb-6">
|
|
<div class="flex items-center gap-3 mb-4">
|
|
<h3 class="text-lg font-bold text-purple-300">Network Map</h3>
|
|
<div class="flex gap-3 text-xs text-gray-400">
|
|
<span class="flex items-center gap-1"><span
|
|
class="inline-block w-3 h-3 rounded-full bg-gray-500"></span>Tier-1 / Transit</span>
|
|
<span class="flex items-center gap-1"><span
|
|
class="inline-block w-3 h-3 rounded-full bg-blue-500"></span>Upstream</span>
|
|
<span class="flex items-center gap-1"><span
|
|
class="inline-block w-3 h-3 rounded-full bg-purple-500"></span>This AS</span>
|
|
<span class="flex items-center gap-1"><span
|
|
class="inline-block w-3 h-3 rounded-full bg-green-500"></span>Downstream</span>
|
|
</div>
|
|
<span class="ml-auto text-xs text-gray-500">Scroll to zoom · Drag to pan · Click node to open</span>
|
|
</div>
|
|
<div id="graph-container">
|
|
<svg id="graph-svg"></svg>
|
|
<div id="graph-tooltip"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Prefixes + IXPs side by side -->
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
|
|
|
|
<!-- Prefixes -->
|
|
<div class="glass-card rounded-xl p-5">
|
|
<div class="flex items-center justify-between mb-3">
|
|
<h3 class="text-sm font-bold text-gray-400 uppercase tracking-widest">Announced Prefixes</h3>
|
|
<button id="prefix-toggle"
|
|
class="text-xs text-purple-400 hover:text-purple-300 transition-colors">Show all</button>
|
|
</div>
|
|
<div id="prefix-list" class="max-h-48 overflow-y-auto"></div>
|
|
<p id="prefix-empty" class="hidden text-sm text-gray-500 italic">No prefix data available.</p>
|
|
</div>
|
|
|
|
<!-- IXPs -->
|
|
<div class="glass-card rounded-xl p-5">
|
|
<h3 class="text-sm font-bold text-gray-400 uppercase tracking-widest mb-3">IXP Presence <span
|
|
class="text-xs font-normal text-gray-500">(via PeeringDB)</span></h3>
|
|
<div id="ixp-list" class="space-y-1 text-sm max-h-48 overflow-y-auto">
|
|
<p id="ixp-empty" class="text-gray-500 italic text-sm">Not listed on PeeringDB.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Direct Peers Table -->
|
|
<div class="glass-card rounded-xl p-5">
|
|
<h3 class="text-sm font-bold text-gray-400 uppercase tracking-widest mb-3">Direct Neighbours <span
|
|
class="text-xs font-normal text-gray-500">(Level 2 · via RIPE Stat)</span></h3>
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<!-- Upstreams -->
|
|
<div>
|
|
<h4 class="text-xs font-semibold text-blue-400 mb-2 flex items-center gap-1">
|
|
<svg class="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
|
|
<path fill-rule="evenodd"
|
|
d="M10 17a.75.75 0 01-.75-.75V5.56l-2.47 2.47a.75.75 0 01-1.06-1.06l3.75-3.75a.75.75 0 011.06 0l3.75 3.75a.75.75 0 11-1.06 1.06L10.75 5.56v10.69A.75.75 0 0110 17z"
|
|
clip-rule="evenodd" />
|
|
</svg>
|
|
Upstreams (Transit Providers)
|
|
</h4>
|
|
<div id="upstream-table" class="space-y-1 text-xs font-mono max-h-52 overflow-y-auto"></div>
|
|
</div>
|
|
<!-- Downstreams -->
|
|
<div>
|
|
<h4 class="text-xs font-semibold text-green-400 mb-2 flex items-center gap-1">
|
|
<svg class="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
|
|
<path fill-rule="evenodd"
|
|
d="M10 3a.75.75 0 01.75.75v10.69l2.47-2.47a.75.75 0 111.06 1.06l-3.75 3.75a.75.75 0 01-1.06 0l-3.75-3.75a.75.75 0 111.06-1.06L9.25 14.44V3.75A.75.75 0 0110 3z"
|
|
clip-rule="evenodd" />
|
|
</svg>
|
|
Downstreams (Customers)
|
|
</h4>
|
|
<div id="downstream-table" class="space-y-1 text-xs font-mono max-h-52 overflow-y-auto"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div><!-- /results -->
|
|
|
|
<footer class="mt-12 pt-6 border-t border-gray-700/30 text-center text-xs text-gray-500">
|
|
<p>Data: <a href="https://stat.ripe.net" target="_blank"
|
|
class="text-purple-400 hover:text-purple-300 transition-colors">RIPE Stat</a> & <a
|
|
href="https://www.peeringdb.com" target="_blank"
|
|
class="text-purple-400 hover:text-purple-300 transition-colors">PeeringDB</a> · Cache: 7 days</p>
|
|
<p class="mt-1">© 2025 <a href="https://mrunk.de"
|
|
class="text-purple-400 hover:text-purple-300 transition-colors">MrUnknownDE</a></p>
|
|
</footer>
|
|
|
|
</div>
|
|
|
|
<script src="asn-lookup.js"></script>
|
|
</body>
|
|
|
|
</html> |