- MANRS: replace broken Observatory API with public participants page scraping (www.manrs.org/netops/participants/), 24h cache, returns pass/fail with member count - /api/validate: add 'relationships' field (upstreams/downstreams/top_peers) sourced from RIPE Stat asn-neighbours, no extra API calls needed - /api/relationships?asn=X: new dedicated endpoint with resolved AS names, full upstream/downstream/peer lists sorted by power score, 10min cache - editorial: rebrand 'The ASN Newspaper' → 'The ASN News' across index-editorial.html
1130 lines
37 KiB
HTML
1130 lines
37 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>PeerCortex — Craft Editorial Draft</title>
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,700;0,800;0,900;1,700;1,800&family=Source+Serif+4:ital,wght@0,300;0,400;0,600;1,300;1,400&family=IBM+Plex+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
|
<style>
|
|
/* ── Tokens ───────────────────────────────────────────── */
|
|
:root {
|
|
--bg: #F5F2EC;
|
|
--bg-alt: #EDE9E1;
|
|
--bg-inv: #1C1917;
|
|
--text: #1C1917;
|
|
--muted: #57534E;
|
|
--dim: #A8A29E;
|
|
--rule: #C9C3B6;
|
|
--rule-h: #78716C;
|
|
--accent: #B83A1B; /* deep editorial red */
|
|
--blue: #1D4ED8;
|
|
--green: #15803D;
|
|
--amber: #B45309;
|
|
--red: #B91C1C;
|
|
--serif: 'Playfair Display', Georgia, serif;
|
|
--body: 'Source Serif 4', Georgia, serif;
|
|
--mono: 'IBM Plex Mono', 'Courier New', monospace;
|
|
}
|
|
|
|
/* ── Reset ────────────────────────────────────────────── */
|
|
*{margin:0;padding:0;box-sizing:border-box}
|
|
html{font-size:16px}
|
|
body{
|
|
font-family: var(--body);
|
|
background: var(--bg);
|
|
color: var(--text);
|
|
line-height: 1.65;
|
|
-webkit-font-smoothing: antialiased;
|
|
}
|
|
a{color:var(--accent);text-decoration:none}
|
|
a:hover{text-decoration:underline}
|
|
|
|
/* ── Thin rule utility ────────────────────────────────── */
|
|
.rule { border:none; border-top:1px solid var(--rule); margin:0 }
|
|
.rule-h { border:none; border-top:2px solid var(--text); margin:0 }
|
|
.rule-acc { border:none; border-top:3px solid var(--accent); margin:0 }
|
|
|
|
/* ══════════════════════════════════════════════════════
|
|
MASTHEAD
|
|
══════════════════════════════════════════════════════ */
|
|
.masthead {
|
|
max-width: 1080px;
|
|
margin: 0 auto;
|
|
padding: 1.25rem 2rem 0;
|
|
}
|
|
.masthead-top {
|
|
display: flex;
|
|
align-items: baseline;
|
|
justify-content: space-between;
|
|
gap: 1rem;
|
|
flex-wrap: wrap;
|
|
padding-bottom: .75rem;
|
|
}
|
|
.masthead-name {
|
|
font-family: var(--serif);
|
|
font-size: 2.4rem;
|
|
font-weight: 900;
|
|
letter-spacing: -.03em;
|
|
color: var(--text);
|
|
line-height: 1;
|
|
}
|
|
.masthead-name sup {
|
|
font-size: .85rem;
|
|
font-weight: 700;
|
|
color: var(--accent);
|
|
vertical-align: super;
|
|
letter-spacing: .04em;
|
|
font-family: var(--mono);
|
|
}
|
|
.masthead-meta {
|
|
font-family: var(--mono);
|
|
font-size: .68rem;
|
|
color: var(--muted);
|
|
text-align: right;
|
|
line-height: 1.6;
|
|
}
|
|
.masthead-nav {
|
|
display: flex;
|
|
gap: 1.75rem;
|
|
padding: .6rem 0;
|
|
flex-wrap: wrap;
|
|
}
|
|
.masthead-nav a {
|
|
font-family: var(--body);
|
|
font-size: .78rem;
|
|
font-weight: 600;
|
|
color: var(--muted);
|
|
letter-spacing: .04em;
|
|
text-transform: uppercase;
|
|
text-decoration: none;
|
|
transition: color .15s;
|
|
}
|
|
.masthead-nav a:hover { color: var(--accent) }
|
|
|
|
/* ══════════════════════════════════════════════════════
|
|
SEARCH BAR
|
|
══════════════════════════════════════════════════════ */
|
|
.search-band {
|
|
background: var(--bg-inv);
|
|
padding: 1.5rem 0;
|
|
margin: .75rem 0 2rem;
|
|
}
|
|
.search-inner {
|
|
max-width: 1080px;
|
|
margin: 0 auto;
|
|
padding: 0 2rem;
|
|
display: flex;
|
|
gap: .75rem;
|
|
align-items: stretch;
|
|
}
|
|
.search-label {
|
|
font-family: var(--mono);
|
|
font-size: .65rem;
|
|
font-weight: 600;
|
|
color: #D6D0C4;
|
|
letter-spacing: .1em;
|
|
text-transform: uppercase;
|
|
white-space: nowrap;
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
.search-input {
|
|
flex: 1;
|
|
background: transparent;
|
|
border: none;
|
|
border-bottom: 2px solid #57534E;
|
|
padding: .4rem .5rem;
|
|
font-family: var(--mono);
|
|
font-size: 1.1rem;
|
|
color: #F5F2EC;
|
|
outline: none;
|
|
transition: border-color .2s;
|
|
letter-spacing: .02em;
|
|
}
|
|
.search-input:focus { border-color: var(--accent) }
|
|
.search-input::placeholder { color: #57534E; font-size: .9rem }
|
|
.search-btn {
|
|
background: var(--accent);
|
|
border: none;
|
|
padding: .5rem 1.75rem;
|
|
font-family: var(--mono);
|
|
font-size: .75rem;
|
|
font-weight: 600;
|
|
letter-spacing: .08em;
|
|
text-transform: uppercase;
|
|
color: #fff;
|
|
cursor: pointer;
|
|
transition: background .15s;
|
|
}
|
|
.search-btn:hover { background: #9A2F14 }
|
|
|
|
/* ══════════════════════════════════════════════════════
|
|
LAYOUT
|
|
══════════════════════════════════════════════════════ */
|
|
.page {
|
|
max-width: 1080px;
|
|
margin: 0 auto;
|
|
padding: 0 2rem 4rem;
|
|
display: grid;
|
|
grid-template-columns: 1fr 300px;
|
|
gap: 3rem;
|
|
}
|
|
@media(max-width:800px){
|
|
.page{grid-template-columns:1fr;gap:2rem}
|
|
.sidebar{display:none}
|
|
}
|
|
.main{}
|
|
|
|
/* ══════════════════════════════════════════════════════
|
|
AS HEADER — the "front page article" block
|
|
══════════════════════════════════════════════════════ */
|
|
.as-header {
|
|
padding-bottom: 1.5rem;
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
.as-dateline {
|
|
font-family: var(--mono);
|
|
font-size: .68rem;
|
|
font-weight: 600;
|
|
letter-spacing: .1em;
|
|
text-transform: uppercase;
|
|
color: var(--accent);
|
|
margin-bottom: .6rem;
|
|
}
|
|
.as-headline {
|
|
font-family: var(--serif);
|
|
font-size: 3.2rem;
|
|
font-weight: 900;
|
|
line-height: 1.05;
|
|
letter-spacing: -.02em;
|
|
color: var(--text);
|
|
margin-bottom: .4rem;
|
|
}
|
|
.as-byline {
|
|
font-family: var(--body);
|
|
font-size: .85rem;
|
|
color: var(--muted);
|
|
font-style: italic;
|
|
margin-bottom: 1rem;
|
|
}
|
|
.as-byline strong {
|
|
font-style: normal;
|
|
font-weight: 600;
|
|
color: var(--text);
|
|
}
|
|
.as-lead {
|
|
font-family: var(--body);
|
|
font-size: 1.05rem;
|
|
font-weight: 300;
|
|
color: var(--muted);
|
|
line-height: 1.7;
|
|
max-width: 64ch;
|
|
}
|
|
|
|
/* AS number pill */
|
|
.as-number-pill {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: .5rem;
|
|
font-family: var(--mono);
|
|
font-size: .75rem;
|
|
background: var(--bg-inv);
|
|
color: #D6D0C4;
|
|
padding: .25rem .75rem;
|
|
margin-bottom: 1rem;
|
|
letter-spacing: .04em;
|
|
}
|
|
.as-number-pill .asn { color: #F5F2EC; font-weight: 600; }
|
|
|
|
/* ══════════════════════════════════════════════════════
|
|
SECTION DIVIDER
|
|
══════════════════════════════════════════════════════ */
|
|
.section {
|
|
margin-top: 2rem;
|
|
}
|
|
.section-head {
|
|
display: grid;
|
|
grid-template-columns: 1fr auto;
|
|
align-items: baseline;
|
|
gap: 1rem;
|
|
margin-bottom: .75rem;
|
|
}
|
|
.section-title {
|
|
font-family: var(--body);
|
|
font-size: .72rem;
|
|
font-weight: 600;
|
|
letter-spacing: .1em;
|
|
text-transform: uppercase;
|
|
color: var(--muted);
|
|
}
|
|
.section-count {
|
|
font-family: var(--mono);
|
|
font-size: .65rem;
|
|
color: var(--dim);
|
|
}
|
|
|
|
/* ══════════════════════════════════════════════════════
|
|
PULL QUOTE (large editorial stat)
|
|
══════════════════════════════════════════════════════ */
|
|
.pull-stats {
|
|
display: grid;
|
|
grid-template-columns: repeat(4, 1fr);
|
|
gap: 0;
|
|
border-top: 3px solid var(--text);
|
|
border-bottom: 1px solid var(--rule);
|
|
padding: 1.25rem 0;
|
|
margin: 1.5rem 0;
|
|
}
|
|
.pull-stat {
|
|
padding: 0 1.5rem 0 0;
|
|
border-right: 1px solid var(--rule);
|
|
}
|
|
.pull-stat:first-child { padding-left: 0 }
|
|
.pull-stat:last-child { border-right: none }
|
|
.pull-val {
|
|
font-family: var(--serif);
|
|
font-size: 2.6rem;
|
|
font-weight: 800;
|
|
line-height: 1;
|
|
letter-spacing: -.02em;
|
|
color: var(--text);
|
|
}
|
|
.pull-val.good { color: var(--green) }
|
|
.pull-val.warn { color: var(--amber) }
|
|
.pull-val.bad { color: var(--red) }
|
|
.pull-val.neutral { color: var(--text) }
|
|
.pull-label {
|
|
font-family: var(--body);
|
|
font-size: .7rem;
|
|
color: var(--muted);
|
|
margin-top: .2rem;
|
|
line-height: 1.4;
|
|
}
|
|
.pull-note {
|
|
font-family: var(--mono);
|
|
font-size: .6rem;
|
|
color: var(--dim);
|
|
margin-top: .25rem;
|
|
}
|
|
|
|
/* ══════════════════════════════════════════════════════
|
|
VERDICT BLOCK (RPKI / ASPA status)
|
|
══════════════════════════════════════════════════════ */
|
|
.verdict-row {
|
|
display: flex;
|
|
gap: 1rem;
|
|
flex-wrap: wrap;
|
|
margin: 1.25rem 0;
|
|
}
|
|
.verdict {
|
|
display: flex;
|
|
align-items: stretch;
|
|
gap: 0;
|
|
border: 1px solid var(--rule);
|
|
}
|
|
.verdict-bar {
|
|
width: 4px;
|
|
}
|
|
.verdict-bar.valid { background: var(--green) }
|
|
.verdict-bar.invalid { background: var(--red) }
|
|
.verdict-bar.unknown { background: var(--dim) }
|
|
.verdict-bar.warn { background: var(--amber) }
|
|
.verdict-body {
|
|
padding: .65rem .9rem;
|
|
}
|
|
.verdict-label {
|
|
font-family: var(--mono);
|
|
font-size: .6rem;
|
|
letter-spacing: .08em;
|
|
text-transform: uppercase;
|
|
color: var(--dim);
|
|
margin-bottom: .2rem;
|
|
}
|
|
.verdict-value {
|
|
font-family: var(--serif);
|
|
font-size: 1rem;
|
|
font-weight: 700;
|
|
line-height: 1.2;
|
|
}
|
|
.verdict-value.valid { color: var(--green) }
|
|
.verdict-value.invalid { color: var(--red) }
|
|
.verdict-value.unknown { color: var(--muted) }
|
|
.verdict-value.warn { color: var(--amber) }
|
|
.verdict-sub {
|
|
font-family: var(--body);
|
|
font-size: .7rem;
|
|
color: var(--muted);
|
|
margin-top: .15rem;
|
|
}
|
|
|
|
/* ══════════════════════════════════════════════════════
|
|
DATA TABLE — newspaper style
|
|
══════════════════════════════════════════════════════ */
|
|
.data-table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
font-family: var(--mono);
|
|
font-size: .75rem;
|
|
}
|
|
.data-table thead tr {
|
|
border-top: 2px solid var(--text);
|
|
border-bottom: 1px solid var(--rule);
|
|
}
|
|
.data-table th {
|
|
text-align: left;
|
|
padding: .45rem .5rem;
|
|
font-size: .6rem;
|
|
font-weight: 600;
|
|
letter-spacing: .08em;
|
|
text-transform: uppercase;
|
|
color: var(--muted);
|
|
font-family: var(--body);
|
|
}
|
|
.data-table td {
|
|
padding: .45rem .5rem;
|
|
color: var(--text);
|
|
border-bottom: 1px solid var(--rule);
|
|
vertical-align: middle;
|
|
}
|
|
.data-table tbody tr:last-child td { border-bottom: none }
|
|
.data-table tbody tr:hover td { background: var(--bg-alt) }
|
|
.td-prefix { font-weight: 500; letter-spacing: .02em }
|
|
.td-muted { color: var(--muted) }
|
|
.td-valid { color: var(--green); font-weight: 500 }
|
|
.td-invalid { color: var(--red); font-weight: 500 }
|
|
.td-unknown { color: var(--dim) }
|
|
.td-link { color: var(--accent); cursor: pointer }
|
|
.td-link:hover { text-decoration: underline }
|
|
.td-num { text-align: right; tabular-nums; font-variant-numeric: tabular-nums }
|
|
|
|
/* ══════════════════════════════════════════════════════
|
|
HEALTH REPORT (13-check checklist)
|
|
══════════════════════════════════════════════════════ */
|
|
.health-grid {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 0;
|
|
border-top: 1px solid var(--rule);
|
|
}
|
|
.health-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: .75rem;
|
|
padding: .6rem 0;
|
|
border-bottom: 1px solid var(--rule);
|
|
font-size: .78rem;
|
|
}
|
|
.health-item:nth-child(odd) { padding-right: 1.5rem }
|
|
.health-item:nth-child(even) { padding-left: 1.5rem; border-left: 1px solid var(--rule) }
|
|
.health-mark {
|
|
font-family: var(--mono);
|
|
font-size: .7rem;
|
|
font-weight: 600;
|
|
width: 1.4rem;
|
|
height: 1.4rem;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-shrink: 0;
|
|
}
|
|
.health-mark.pass { color: var(--green) }
|
|
.health-mark.fail { color: var(--red) }
|
|
.health-mark.warn { color: var(--amber) }
|
|
.health-text { color: var(--text); font-family: var(--body); font-size: .78rem }
|
|
.health-sub { color: var(--dim); font-family: var(--mono); font-size: .65rem; margin-top: .1rem }
|
|
|
|
/* ══════════════════════════════════════════════════════
|
|
SIDEBAR
|
|
══════════════════════════════════════════════════════ */
|
|
.sidebar {
|
|
padding-top: 0;
|
|
}
|
|
.sidebar-block {
|
|
padding: 1.25rem 0;
|
|
border-top: 2px solid var(--text);
|
|
border-bottom: 1px solid var(--rule);
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
.sidebar-block-title {
|
|
font-family: var(--body);
|
|
font-size: .68rem;
|
|
font-weight: 600;
|
|
letter-spacing: .1em;
|
|
text-transform: uppercase;
|
|
color: var(--muted);
|
|
margin-bottom: .9rem;
|
|
}
|
|
.sidebar-stat {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: baseline;
|
|
padding: .35rem 0;
|
|
border-bottom: 1px solid var(--rule);
|
|
font-size: .78rem;
|
|
}
|
|
.sidebar-stat:last-child { border-bottom: none }
|
|
.sidebar-stat-label { color: var(--muted); font-family: var(--body) }
|
|
.sidebar-stat-val { font-family: var(--mono); font-weight: 500; color: var(--text); font-size: .72rem }
|
|
|
|
.tag-cloud {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: .4rem;
|
|
margin-top: .5rem;
|
|
}
|
|
.tag {
|
|
font-family: var(--mono);
|
|
font-size: .62rem;
|
|
padding: .2rem .55rem;
|
|
border: 1px solid var(--rule);
|
|
color: var(--muted);
|
|
letter-spacing: .03em;
|
|
}
|
|
.tag:hover { border-color: var(--accent); color: var(--accent); cursor: pointer }
|
|
|
|
.ext-links {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: .5rem;
|
|
margin-top: .25rem;
|
|
}
|
|
.ext-link {
|
|
font-family: var(--body);
|
|
font-size: .78rem;
|
|
color: var(--accent);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: .4rem;
|
|
}
|
|
.ext-link::before { content: '→'; font-family: var(--mono); font-size: .7rem }
|
|
.ext-link:hover { text-decoration: underline }
|
|
|
|
/* data quality score meter */
|
|
.score-meter {
|
|
margin: .75rem 0;
|
|
}
|
|
.score-track {
|
|
height: 6px;
|
|
background: var(--rule);
|
|
position: relative;
|
|
margin: .5rem 0;
|
|
}
|
|
.score-fill {
|
|
height: 100%;
|
|
background: var(--green);
|
|
transition: width .6s ease;
|
|
}
|
|
.score-label {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
font-family: var(--mono);
|
|
font-size: .62rem;
|
|
color: var(--dim);
|
|
}
|
|
|
|
/* ══════════════════════════════════════════════════════
|
|
COMPARE SECTION
|
|
══════════════════════════════════════════════════════ */
|
|
.compare-banner {
|
|
background: var(--bg-inv);
|
|
padding: 1.25rem 2rem;
|
|
margin: 2rem -2rem;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 1.5rem;
|
|
flex-wrap: wrap;
|
|
}
|
|
.compare-label {
|
|
font-family: var(--mono);
|
|
font-size: .65rem;
|
|
letter-spacing: .1em;
|
|
text-transform: uppercase;
|
|
color: #A8A29E;
|
|
white-space: nowrap;
|
|
}
|
|
.compare-input {
|
|
background: transparent;
|
|
border: none;
|
|
border-bottom: 1px solid #57534E;
|
|
padding: .3rem .4rem;
|
|
font-family: var(--mono);
|
|
font-size: .85rem;
|
|
color: #F5F2EC;
|
|
outline: none;
|
|
width: 130px;
|
|
transition: border-color .2s;
|
|
}
|
|
.compare-input:focus { border-color: var(--accent) }
|
|
.compare-input::placeholder { color: #57534E }
|
|
.compare-btn {
|
|
background: transparent;
|
|
border: 1px solid #57534E;
|
|
padding: .35rem 1rem;
|
|
font-family: var(--mono);
|
|
font-size: .68rem;
|
|
font-weight: 600;
|
|
letter-spacing: .07em;
|
|
text-transform: uppercase;
|
|
color: #D6D0C4;
|
|
cursor: pointer;
|
|
transition: all .15s;
|
|
}
|
|
.compare-btn:hover { border-color: var(--accent); color: var(--accent) }
|
|
|
|
/* ══════════════════════════════════════════════════════
|
|
FOOTER
|
|
══════════════════════════════════════════════════════ */
|
|
.footer {
|
|
max-width: 1080px;
|
|
margin: 3rem auto 0;
|
|
padding: 1.25rem 2rem 2.5rem;
|
|
border-top: 2px solid var(--text);
|
|
display: flex;
|
|
align-items: baseline;
|
|
justify-content: space-between;
|
|
gap: 1rem;
|
|
flex-wrap: wrap;
|
|
}
|
|
.footer-name {
|
|
font-family: var(--serif);
|
|
font-size: 1.1rem;
|
|
font-weight: 800;
|
|
color: var(--text);
|
|
}
|
|
.footer-links {
|
|
display: flex;
|
|
gap: 1.5rem;
|
|
font-family: var(--body);
|
|
font-size: .72rem;
|
|
color: var(--muted);
|
|
}
|
|
.footer-links a { color: var(--muted); text-decoration: none }
|
|
.footer-links a:hover { color: var(--accent) }
|
|
.footer-copy {
|
|
font-family: var(--mono);
|
|
font-size: .62rem;
|
|
color: var(--dim);
|
|
width: 100%;
|
|
}
|
|
|
|
/* ── utility ─────────────────────────────────────────── */
|
|
.mt0{margin-top:0}.mt1{margin-top:.5rem}.mt2{margin-top:1rem}.mt3{margin-top:1.5rem}
|
|
.italic{font-style:italic}
|
|
.mono{font-family:var(--mono)}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<!-- ══════════════════════════════════════════════════════
|
|
MASTHEAD
|
|
══════════════════════════════════════════════════════ -->
|
|
<div class="masthead">
|
|
<div class="masthead-top">
|
|
<div>
|
|
<div class="masthead-name">PeerCortex<sup>β</sup></div>
|
|
</div>
|
|
<div class="masthead-meta">
|
|
Network Intelligence<br>
|
|
<span class="mono" style="font-size:.62rem;color:var(--dim)">peercortex.org</span>
|
|
</div>
|
|
</div>
|
|
<hr class="rule-h">
|
|
<nav class="masthead-nav">
|
|
<a href="#">ASN Lookup</a>
|
|
<a href="#">RPKI Validator</a>
|
|
<a href="#">ASPA Check</a>
|
|
<a href="#">Health Report</a>
|
|
<a href="#">BGP Routes</a>
|
|
<a href="#">Compare</a>
|
|
<a href="#">API</a>
|
|
</nav>
|
|
<hr class="rule">
|
|
</div>
|
|
|
|
<!-- ══════════════════════════════════════════════════════
|
|
SEARCH BAND
|
|
══════════════════════════════════════════════════════ -->
|
|
<div class="search-band">
|
|
<div class="search-inner">
|
|
<span class="search-label">ASN / Prefix / Org</span>
|
|
<input class="search-input" type="text" value="AS15169" placeholder="e.g. AS15169 · 8.8.0.0/24 · Google">
|
|
<button class="search-btn">Analyse</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ══════════════════════════════════════════════════════
|
|
MAIN + SIDEBAR
|
|
══════════════════════════════════════════════════════ -->
|
|
<div class="page">
|
|
|
|
<!-- ── MAIN ─────────────────────────────────────────── -->
|
|
<main class="main">
|
|
|
|
<!-- AS Header -->
|
|
<div class="as-header">
|
|
<div class="as-dateline">Autonomous System Report · Updated 4 minutes ago</div>
|
|
<div class="as-number-pill">
|
|
<span>ASN</span><span class="asn">AS15169</span>
|
|
<span style="color:var(--dim)">·</span>
|
|
<span>ARIN</span>
|
|
<span style="color:var(--dim)">·</span>
|
|
<span>US</span>
|
|
</div>
|
|
<h1 class="as-headline">Google LLC</h1>
|
|
<p class="as-byline">
|
|
<strong>GOOGLE-AS, US</strong> · Mountain View, California
|
|
· Internet Services Provider
|
|
</p>
|
|
<hr class="rule-acc" style="margin-bottom:1rem">
|
|
<p class="as-lead">
|
|
Google LLC operates one of the largest and most interconnected autonomous
|
|
systems on the internet, maintaining a global PoP footprint across six
|
|
continents. Its routing policy is broadly open, with full RPKI coverage
|
|
and a mature ASPA deployment. The network scores in the top 2% of all
|
|
tracked ASNs by data quality.
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Pull stats -->
|
|
<div class="pull-stats">
|
|
<div class="pull-stat">
|
|
<div class="pull-val good">97</div>
|
|
<div class="pull-label">Health Score</div>
|
|
<div class="pull-note">13/13 checks pass</div>
|
|
</div>
|
|
<div class="pull-stat">
|
|
<div class="pull-val neutral">4,682</div>
|
|
<div class="pull-label">IPv4 Prefixes</div>
|
|
<div class="pull-note">announced routes</div>
|
|
</div>
|
|
<div class="pull-stat">
|
|
<div class="pull-val neutral">1,104</div>
|
|
<div class="pull-label">IPv6 Prefixes</div>
|
|
<div class="pull-note">announced routes</div>
|
|
</div>
|
|
<div class="pull-stat">
|
|
<div class="pull-val neutral">426</div>
|
|
<div class="pull-label">Peers</div>
|
|
<div class="pull-note">direct sessions</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Verdict row -->
|
|
<div class="section">
|
|
<div class="section-head">
|
|
<span class="section-title">Security & Policy</span>
|
|
</div>
|
|
<hr class="rule" style="margin-bottom:1rem">
|
|
<div class="verdict-row">
|
|
|
|
<div class="verdict">
|
|
<div class="verdict-bar valid"></div>
|
|
<div class="verdict-body">
|
|
<div class="verdict-label">RPKI Origin Validation</div>
|
|
<div class="verdict-value valid">VALID</div>
|
|
<div class="verdict-sub">4,682 of 4,682 prefixes signed</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="verdict">
|
|
<div class="verdict-bar valid"></div>
|
|
<div class="verdict-body">
|
|
<div class="verdict-label">ASPA</div>
|
|
<div class="verdict-value valid">DEPLOYED</div>
|
|
<div class="verdict-sub">RFC 9582 — provider set complete</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="verdict">
|
|
<div class="verdict-bar valid"></div>
|
|
<div class="verdict-body">
|
|
<div class="verdict-label">IRR Consistency</div>
|
|
<div class="verdict-value valid">CONSISTENT</div>
|
|
<div class="verdict-sub">ARIN DB matches announced routes</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="verdict">
|
|
<div class="verdict-bar warn"></div>
|
|
<div class="verdict-body">
|
|
<div class="verdict-label">Route Leak Guard</div>
|
|
<div class="verdict-value warn">PARTIAL</div>
|
|
<div class="verdict-sub">2 peers without max-prefix</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Compare banner -->
|
|
<div class="compare-banner">
|
|
<span class="compare-label">Compare with</span>
|
|
<input class="compare-input" type="text" placeholder="AS13335">
|
|
<input class="compare-input" type="text" placeholder="AS16509">
|
|
<button class="compare-btn">Compare</button>
|
|
</div>
|
|
|
|
<!-- Route prefixes table -->
|
|
<div class="section">
|
|
<div class="section-head">
|
|
<span class="section-title">IPv4 Announced Prefixes</span>
|
|
<span class="section-count">showing 8 of 4,682</span>
|
|
</div>
|
|
<hr class="rule" style="margin-bottom:.5rem">
|
|
<table class="data-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Prefix</th>
|
|
<th>Description</th>
|
|
<th>RPKI</th>
|
|
<th>IRR</th>
|
|
<th style="text-align:right">Routes</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td class="td-prefix">8.8.8.0/24</td>
|
|
<td class="td-muted">Google DNS Anycast</td>
|
|
<td class="td-valid">VALID</td>
|
|
<td class="td-valid">✓ ARIN</td>
|
|
<td class="td-num td-muted">12</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="td-prefix">8.8.4.0/24</td>
|
|
<td class="td-muted">Google DNS Anycast</td>
|
|
<td class="td-valid">VALID</td>
|
|
<td class="td-valid">✓ ARIN</td>
|
|
<td class="td-num td-muted">11</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="td-prefix">8.34.208.0/20</td>
|
|
<td class="td-muted">GOOGLE-CLOUD-EMEA</td>
|
|
<td class="td-valid">VALID</td>
|
|
<td class="td-valid">✓ ARIN</td>
|
|
<td class="td-num td-muted">9</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="td-prefix">34.64.0.0/10</td>
|
|
<td class="td-muted">Google Cloud GFE</td>
|
|
<td class="td-valid">VALID</td>
|
|
<td class="td-valid">✓ ARIN</td>
|
|
<td class="td-num td-muted">18</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="td-prefix">66.102.0.0/20</td>
|
|
<td class="td-muted">GOOGLE-FRONTEND</td>
|
|
<td class="td-valid">VALID</td>
|
|
<td class="td-valid">✓ ARIN</td>
|
|
<td class="td-num td-muted">7</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="td-prefix">74.125.0.0/16</td>
|
|
<td class="td-muted">GOOGLE-CORP-CORE</td>
|
|
<td class="td-valid">VALID</td>
|
|
<td class="td-valid">✓ ARIN</td>
|
|
<td class="td-num td-muted">24</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="td-prefix">142.250.0.0/15</td>
|
|
<td class="td-muted">GOOGLE-EDGE-NODES</td>
|
|
<td class="td-unknown">UNKNOWN</td>
|
|
<td class="td-valid">✓ ARIN</td>
|
|
<td class="td-num td-muted">31</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="td-prefix td-link">172.217.0.0/16</td>
|
|
<td class="td-muted">GOOGLE-PROD</td>
|
|
<td class="td-valid">VALID</td>
|
|
<td class="td-valid">✓ ARIN</td>
|
|
<td class="td-num td-muted">19</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="mt2" style="font-family:var(--body);font-size:.75rem;color:var(--dim)">
|
|
<span class="td-link" style="color:var(--accent);cursor:pointer">Show all 4,682 prefixes →</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Health Report -->
|
|
<div class="section">
|
|
<div class="section-head">
|
|
<span class="section-title">Health Report</span>
|
|
<span class="section-count">13 of 13 checks passed</span>
|
|
</div>
|
|
<hr class="rule">
|
|
<div class="health-grid">
|
|
<div class="health-item">
|
|
<div class="health-mark pass">✓</div>
|
|
<div>
|
|
<div class="health-text">RPKI fully deployed</div>
|
|
<div class="health-sub">100% of prefixes have valid ROAs</div>
|
|
</div>
|
|
</div>
|
|
<div class="health-item">
|
|
<div class="health-mark pass">✓</div>
|
|
<div>
|
|
<div class="health-text">IRR consistent</div>
|
|
<div class="health-sub">AS-SET GOOGLE matches route objects</div>
|
|
</div>
|
|
</div>
|
|
<div class="health-item">
|
|
<div class="health-mark pass">✓</div>
|
|
<div>
|
|
<div class="health-text">No RPKI invalids</div>
|
|
<div class="health-sub">0 invalid prefixes detected</div>
|
|
</div>
|
|
</div>
|
|
<div class="health-item">
|
|
<div class="health-mark pass">✓</div>
|
|
<div>
|
|
<div class="health-text">ASPA record present</div>
|
|
<div class="health-sub">RFC 9582 provider authorisation</div>
|
|
</div>
|
|
</div>
|
|
<div class="health-item">
|
|
<div class="health-mark pass">✓</div>
|
|
<div>
|
|
<div class="health-text">No bogons announced</div>
|
|
<div class="health-sub">No RFC 1918 / special-use prefixes</div>
|
|
</div>
|
|
</div>
|
|
<div class="health-item">
|
|
<div class="health-mark pass">✓</div>
|
|
<div>
|
|
<div class="health-text">No long-lived hijacks</div>
|
|
<div class="health-sub">No overlapping prefix conflicts</div>
|
|
</div>
|
|
</div>
|
|
<div class="health-item">
|
|
<div class="health-mark pass">✓</div>
|
|
<div>
|
|
<div class="health-text">Prefix not too specific</div>
|
|
<div class="health-sub">No /25+ IPv4 leaks detected</div>
|
|
</div>
|
|
</div>
|
|
<div class="health-item">
|
|
<div class="health-mark pass">✓</div>
|
|
<div>
|
|
<div class="health-text">BGP community usage</div>
|
|
<div class="health-sub">Informational communities present</div>
|
|
</div>
|
|
</div>
|
|
<div class="health-item">
|
|
<div class="health-mark pass">✓</div>
|
|
<div>
|
|
<div class="health-text">IPv6 deployed</div>
|
|
<div class="health-sub">1,104 IPv6 prefixes announced</div>
|
|
</div>
|
|
</div>
|
|
<div class="health-item">
|
|
<div class="health-mark pass">✓</div>
|
|
<div>
|
|
<div class="health-text">Route diversity</div>
|
|
<div class="health-sub">Multiple upstream paths observed</div>
|
|
</div>
|
|
</div>
|
|
<div class="health-item">
|
|
<div class="health-mark pass">✓</div>
|
|
<div>
|
|
<div class="health-text">AS path length normal</div>
|
|
<div class="health-sub">Avg prepend length ≤ 3</div>
|
|
</div>
|
|
</div>
|
|
<div class="health-item">
|
|
<div class="health-mark pass">✓</div>
|
|
<div>
|
|
<div class="health-text">PeeringDB present</div>
|
|
<div class="health-sub">Record up to date</div>
|
|
</div>
|
|
</div>
|
|
<div class="health-item">
|
|
<div class="health-mark pass">✓</div>
|
|
<div>
|
|
<div class="health-text">NOC contact reachable</div>
|
|
<div class="health-sub">Email + phone verified</div>
|
|
</div>
|
|
</div>
|
|
<div class="health-item" style="visibility:hidden"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Upstream peers table -->
|
|
<div class="section">
|
|
<div class="section-head">
|
|
<span class="section-title">Upstream / Transit</span>
|
|
<span class="section-count">top 6 by path frequency</span>
|
|
</div>
|
|
<hr class="rule" style="margin-bottom:.5rem">
|
|
<table class="data-table">
|
|
<thead>
|
|
<tr>
|
|
<th>ASN</th>
|
|
<th>Organisation</th>
|
|
<th>Relationship</th>
|
|
<th style="text-align:right">Path frequency</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td class="td-link td-prefix">AS1273</td>
|
|
<td class="td-muted">Vodafone Group PLC</td>
|
|
<td><span style="font-family:var(--mono);font-size:.65rem;color:var(--blue)">TRANSIT</span></td>
|
|
<td class="td-num td-muted">34%</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="td-link td-prefix">AS174</td>
|
|
<td class="td-muted">Cogent Communications</td>
|
|
<td><span style="font-family:var(--mono);font-size:.65rem;color:var(--blue)">TRANSIT</span></td>
|
|
<td class="td-num td-muted">28%</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="td-link td-prefix">AS3257</td>
|
|
<td class="td-muted">GTT Communications</td>
|
|
<td><span style="font-family:var(--mono);font-size:.65rem;color:var(--green)">PEER</span></td>
|
|
<td class="td-num td-muted">17%</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="td-link td-prefix">AS1239</td>
|
|
<td class="td-muted">Sprint / T-Mobile</td>
|
|
<td><span style="font-family:var(--mono);font-size:.65rem;color:var(--green)">PEER</span></td>
|
|
<td class="td-num td-muted">12%</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="td-link td-prefix">AS6453</td>
|
|
<td class="td-muted">TATA Communications</td>
|
|
<td><span style="font-family:var(--mono);font-size:.65rem;color:var(--blue)">TRANSIT</span></td>
|
|
<td class="td-num td-muted">6%</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="td-link td-prefix">AS3356</td>
|
|
<td class="td-muted">Lumen Technologies</td>
|
|
<td><span style="font-family:var(--mono);font-size:.65rem;color:var(--green)">PEER</span></td>
|
|
<td class="td-num td-muted">3%</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
</main>
|
|
|
|
<!-- ── SIDEBAR ────────────────────────────────────────── -->
|
|
<aside class="sidebar">
|
|
|
|
<!-- Identity block -->
|
|
<div class="sidebar-block">
|
|
<div class="sidebar-block-title">Registration</div>
|
|
<div class="sidebar-stat">
|
|
<span class="sidebar-stat-label">ASN</span>
|
|
<span class="sidebar-stat-val">AS15169</span>
|
|
</div>
|
|
<div class="sidebar-stat">
|
|
<span class="sidebar-stat-label">Registry</span>
|
|
<span class="sidebar-stat-val">ARIN</span>
|
|
</div>
|
|
<div class="sidebar-stat">
|
|
<span class="sidebar-stat-label">Country</span>
|
|
<span class="sidebar-stat-val">US · Mountain View</span>
|
|
</div>
|
|
<div class="sidebar-stat">
|
|
<span class="sidebar-stat-label">Type</span>
|
|
<span class="sidebar-stat-val">Content / ISP</span>
|
|
</div>
|
|
<div class="sidebar-stat">
|
|
<span class="sidebar-stat-label">Registered</span>
|
|
<span class="sidebar-stat-val">2000-03-30</span>
|
|
</div>
|
|
<div class="sidebar-stat">
|
|
<span class="sidebar-stat-label">PeeringDB</span>
|
|
<span class="sidebar-stat-val td-link" style="color:var(--accent)">Open policy</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Data Quality score -->
|
|
<div class="sidebar-block">
|
|
<div class="sidebar-block-title">Data Quality</div>
|
|
<div class="score-meter">
|
|
<div style="font-family:var(--serif);font-size:2.2rem;font-weight:800;color:var(--green);line-height:1">
|
|
97<span style="font-size:1rem;color:var(--muted);font-weight:400">/100</span>
|
|
</div>
|
|
<div class="score-track mt1">
|
|
<div class="score-fill" style="width:97%"></div>
|
|
</div>
|
|
<div class="score-label">
|
|
<span>0</span><span>50</span><span>100</span>
|
|
</div>
|
|
</div>
|
|
<div style="font-family:var(--body);font-size:.72rem;color:var(--muted);font-style:italic;margin-top:.5rem">
|
|
Composite score across 5 data sources: ARIN, RIPE, RADb, BGPstream, PeeringDB.
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Communities -->
|
|
<div class="sidebar-block">
|
|
<div class="sidebar-block-title">BGP Communities</div>
|
|
<div class="tag-cloud">
|
|
<span class="tag">15169:10</span>
|
|
<span class="tag">15169:30</span>
|
|
<span class="tag">15169:45</span>
|
|
<span class="tag">15169:70</span>
|
|
<span class="tag">65000:10</span>
|
|
<span class="tag">65100:1</span>
|
|
<span class="tag">65100:3</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- External Links -->
|
|
<div class="sidebar-block">
|
|
<div class="sidebar-block-title">External Sources</div>
|
|
<div class="ext-links">
|
|
<a class="ext-link" href="#">BGP.he.net / AS15169</a>
|
|
<a class="ext-link" href="#">RIPE Stat</a>
|
|
<a class="ext-link" href="#">PeeringDB</a>
|
|
<a class="ext-link" href="#">bgproutes.io</a>
|
|
<a class="ext-link" href="#">RPKI Validator (Cloudflare)</a>
|
|
<a class="ext-link" href="#">ARIN Whois</a>
|
|
<a class="ext-link" href="#">BGPlay (RIPE NCC)</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ASPA template -->
|
|
<div class="sidebar-block">
|
|
<div class="sidebar-block-title">ASPA Record</div>
|
|
<div style="background:var(--bg-inv);padding:.9rem;font-family:var(--mono);font-size:.62rem;color:#9CA3AF;line-height:1.8;margin-top:.5rem">
|
|
<span style="color:#D6D0C4">ASPA</span>: {<br>
|
|
<span style="color:#A8A29E">customer-as</span>: <span style="color:#F5F2EC">15169</span>,<br>
|
|
<span style="color:#A8A29E">provider-set</span>: [<br>
|
|
<span style="color:#86EFAC">1273</span>, <span style="color:#86EFAC">174</span>,<br>
|
|
<span style="color:#86EFAC">3257</span><br>
|
|
]<br>
|
|
}
|
|
</div>
|
|
</div>
|
|
|
|
</aside>
|
|
|
|
</div><!-- end .page -->
|
|
|
|
<!-- ══════════════════════════════════════════════════════
|
|
FOOTER
|
|
══════════════════════════════════════════════════════ -->
|
|
<div class="footer">
|
|
<span class="footer-name">PeerCortex</span>
|
|
<nav class="footer-links">
|
|
<a href="#">API</a>
|
|
<a href="#">GitHub</a>
|
|
<a href="#">MCP Server</a>
|
|
<a href="#">Changelog</a>
|
|
<a href="#">Imprint</a>
|
|
</nav>
|
|
<div class="footer-copy">
|
|
Data sourced from RIPE NCC, ARIN, RADb, BGPstream, Cloudflare RPKI, PeeringDB.
|
|
Cached results may be up to 30 minutes old.
|
|
Not affiliated with any registry or operator. Open source under MIT.
|
|
</div>
|
|
</div>
|
|
|
|
</body>
|
|
</html>
|