Network & Routing Report
The full picture of how a network is put together and reaches the internet. Give it a network or address block and get a health card: what it announces, who it peers and buys transit from, whether it leans dangerously on a single upstream, and how well its routes are protected. The one-look report for network engineers assessing reach and resilience.
The alert
A routing check on 1.1.1.0/24 comes back with the withdrawn flag set, and the health card renders that line at error severity. The same node carries a ROUTES edge from AS13335, so the card's headline disagrees with the edge sitting underneath it.
The question
Do I open a routing incident on this block, and what would tell me I am wrong?
Not "is this prefix healthy". The card's headline is three booleans, and on this block one of them contradicts two other facts stored on the node it was read from.
What this cannot answer
- What the withdrawn flag counts. The prefix property table on Entities documents
isWithdrawnas currently withdrawn from the routing table. On1.1.1.0/24it readstrueon six uncached reads, while the same node holds aROUTESedge fromAS13335and one ROA authorising this exact prefix toAS13335, atrpkiStatus: "valid". Which of the three is stale is not established here. - A stable roll-up of that flag. Counting it across the 5,258 prefixes
AS13335routes alternates between two answers on consecutive runs: 900 withdrawn against 4,358 not, then 921 against 4,337, each twice. The total never moves. Read the per-prefix row, never the aggregate. - The customer cone. The reputation step selects
coneSize, and no such property exists on the node.keys()onAS13335returnsconeAsns963,conePrefixes35738andconeAddresses32408873, so the cone column renders empty with those three values sitting unread beside it. - AS-SET membership. The IRR plane is not populated:
whisper.asSetreturned zero rows for all six ASNs tried here, and the step binds it to an integer, which the procedure rejects outright withExpected string argument, got: Long.
What do we know
whisper.assess(["1.1.1.0/24"]) returns one row: label unknown, band UNKNOWN, coverage no-data — coverage: no-data. Not in coverage. This is not a verdict — nothing was looked at., no signals. AS13335 answers the same way. That is a populated row saying the threat plane holds nothing on this network — zero rows is never a verdict — and it is why this workflow reads routing rather than reputation. Coverage is the qualifier to read first.
The routing steps do return. The block is APNIC-allocated, isMoas false, isAnycast true, rpkiStatus: "valid", with one ROA authorising it to AS13335. The anycast read is more than the flag: anycastConfidence is 1.0, anycastKnownService names Cloudflare DNS, and anycastOriginAsn is 13335 — the same origin the ROA names.
The identity header resolves to CLOUDFLARENET - Cloudflare, Inc., US, 5,258 prefixes routed, AS-rank 64, present at 1,503 facilities and 356 internet exchanges. Not one of those 5,258 prefixes carries the MOAS flag.
Why
- 01BGP status. Establishes the prefix's baseline BGP state — the headline of the health card the rest of the run fills in.
- 02MOAS conflicts. Enumerates the CONFLICTS_WITH origins behind a MOAS, the concrete competing announcements that signal a hijack or misconfig.
- 03RIR allocation. Names which registry allocated the block, the authority record against which legitimacy is checked.
- 04RPKI ROA coverage. Walks ROA_AUTHORIZES_ORIGIN/PREFIX to show what the network is RPKI-authorised to announce — the basis for valid-vs-invalid routing.
- 05Announced prefixes. Enumerates what the network actually routes via ROUTES, the footprint compared against its ROA coverage.
- 06Facilities & IXes. Maps physical presence via AS_PRESENT_AT and IX_MEMBER, the interconnection context behind the routing posture.
- 07ASN reputation. Surfaces transit importance (AS-rank, customer cone) and bgp.tools tags — the reputation read that frames the whole health card.
- 08ASN identity & registration. Names the network, its home country, the organization that holds the AS number, and how many prefixes it announces — the identity header of the routing card.
- 09Prefix membership hierarchy. Lists the sub-prefixes and individual IPs nested inside the prefix, so you can see exactly what address space lives under the block.
- 10AS-SET membership (IRR). Shows which IRR-declared AS-SET the network belongs to and its member ASNs, the routing-policy grouping used by transit providers to build filters.
The pivot the score did not suggest
The MOAS line is a count, and the count is one too many.
This seed has no conflicts, so take one that does. 141.101.225.0/24 reports two, AS10 and AS201717. The ROUTES edge on that same prefix names AS201717, and roaAsn is 201717: the authorised holder is listed as one of its own conflicts. Not a one-off — of 300 prefixes carrying CONFLICTS_WITH edges, 132 also carry a roaAsn, and in 132 of 132 that roaAsn appears inside moasConflictOriginAsns. Three consecutive runs returned the same 132.
So "2 MOAS conflicts" describes one competing origin. The discriminator is on the node and the card never opens it: subtract roaAsn from moasConflictOriginAsns, AS10 is what remains, and moasObservationCount reads 102. One unauthorised origin seen 102 times is a different ticket from a number.
One field there looks like the answer and is not. moasIsLegitimate reads false on this prefix, and a graph-wide count of prefixes where it reads true returns 0. It separates nothing today.
Falsify it
Attack the withdrawn line from the two layers that fail independently of it.
Routing first. The ROUTES edge from AS13335 is still on the prefix — one edge, present on every read taken here. Withdrawn and routed cannot both be current, and the card publishes the first without naming the second.
Authorisation cannot arbitrate it. The ROA names AS13335 and the block reads valid, which is what it would read whether or not the announcement is in anybody's table. A ROA is permission, not observation.
That leaves a testable prediction: if isWithdrawn reads false on a later run with nothing else about the block changed, the flag is a sampling artefact and the error severity on this card is noise. The queries, with their measured output, are on BGP & RPKI.
The conclusion
1.1.1.0/24 is anycast, RPKI-valid and single-origin, and the withdrawn flag is not evidence of an outage. The same node holds a ROUTES edge from AS13335, one ROA authorising the block to that origin, and an anycast service name of Cloudflare DNS at confidence 1.0. Treat the withdrawn line as unresolved rather than as an incident — the open question is what that flag samples.
Four things would change that, each a query rather than an opinion:
- the
ROUTESedge fromAS13335gone on a later read, which would make withdrawn the consistent story; rpkiStatusoffvalid, or the ROA naming an origin other than 13335;- a
CONFLICTS_WITHedge appearing on this prefix with an origin that is not 13335; - the flag reading
falselater, which settles it the other way and against the card.
A health card that reports a flag it cannot reconcile with the edge beside it has published one fact and hidden two.
What this cost
10 named steps across the BGP, RPKI, physical layers. The runner reports what each step returned, row by row, so the evidence and what it took to get it arrive together rather than as one number at the end.
How it uses the graph
Traverses the BGP, RPKI, physical layers of the graph, in 10 steps:
Reading the prefix's MOAS, anycast and withdrawn flags…
Listing ASNs that also announce this prefix…
Reading the prefix's RIR allocation…
Listing prefixes the ASN's ROAs authorise…
Listing the ASN's announced prefixes…
Listing the ASN's facilities and exchanges…
Reading the ASN's rank, cone size and tags…
ASN identity & registration…
Prefix membership hierarchy…
AS-SET membership (IRR)…