docs: lead IP records with attribution answer

This commit is contained in:
2026-07-22 19:34:44 +00:00
parent 052306bafe
commit 652bd652d8
11 changed files with 111 additions and 6 deletions
+1 -1
View File
@@ -21,4 +21,4 @@ For every address, investigate these independently:
6. **Infrastructure relationships** — IXPs, facilities, upstreams, cables, and geography where evidence permits. 6. **Infrastructure relationships** — IXPs, facilities, upstreams, cables, and geography where evidence permits.
7. **Time and provenance** — registry and routing facts can change, so every claim needs a source and verification date. 7. **Time and provenance** — registry and routing facts can change, so every claim needs a source and verification date.
The canonical structured records are in [`data/ip-addresses.csv`](../data/ip-addresses.csv). Range-level knowledge is indexed in [`registry-ips/`](../registry-ips/README.md), using numerically sortable IP-first filenames such as `001-001-001-000--24--apnic.md`. The canonical structured records are in [`data/ip-addresses.csv`](../data/ip-addresses.csv). Use the [`IP record template`](ip/TEMPLATE.md) for new exact-address pages; its first section must answer **Who is this IP?** Range-level knowledge is indexed in [`registry-ips/`](../registry-ips/README.md), using sortable filenames such as `001-001-001-000--24--apnic.md`.
+2 -2
View File
@@ -1,8 +1,8 @@
# 0.0.0.0 # 0.0.0.0
## Answer ## Who is this IP?
`0.0.0.0` is **not an ordinary public address owned by a company**. IANA records both the exact `0.0.0.0/32` address and its `0.0.0.0/8` parent as special-purpose protocol space. **Short answer:** `0.0.0.0` belongs to no company or ordinary network operator. IANA reserves both the exact `0.0.0.0/32` address and its `0.0.0.0/8` parent as special-purpose protocol space.
| Axis | Finding | | Axis | Finding |
|---|---| |---|---|
+2 -2
View File
@@ -1,8 +1,8 @@
# 1.1.1.1 # 1.1.1.1
## Answer ## Who is this IP?
`1.1.1.1` demonstrates why “owner” must be split into multiple relationships. **Short answer:** The covering range is registered to APNIC Research and Development, while Cloudflare routes `1.1.1.1` through `AS13335` and operates its public recursive DNS service. This split demonstrates why “owner” must be treated as several relationships.
| Axis | Finding | | Axis | Finding |
|---|---| |---|---|
+26
View File
@@ -0,0 +1,26 @@
# <IP address>
## Who is this IP?
**Short answer:** <Name the registered holder and operator first. If they differ, say so immediately. If unknown, say “Unknown — investigation pending.”>
Do not begin with technical background. First answer whose registered resource contains the address, who currently routes it, and who operates the documented service when those are different entities.
| Axis | Finding |
|---|---|
| Exact address | `<address>` |
| Registered covering prefix | `<prefix>` |
| Registry | <registry> |
| Registered resource holder | <holder or unknown> |
| Current announced prefix | <prefix or none/unknown> |
| Current route origin | <ASN or none/unknown> |
| Operator/service | <operator and service or unknown> |
| Globally routed | <yes/no/unknown> |
## Interpretation
<Explain registration, routing, operation, and service relationships without collapsing them into one “owner.”>
## Sources
- [Authoritative source](https://example.invalid/), checked <YYYY-MM-DD>
@@ -1,5 +1,9 @@
# IANA range: 0.0.0.0/8 # IANA range: 0.0.0.0/8
## Who is this IP range?
**Short answer:** IANA reserves this range for protocol-defined “this network” use. It is not assigned to a company, ISP, cloud provider, or ordinary network operator.
- **Registry:** IANA - **Registry:** IANA
- **Range:** `0.0.0.0/8` - **Range:** `0.0.0.0/8`
- **IANA name:** This network - **IANA name:** This network
@@ -1,5 +1,9 @@
# Placeholder: 1.0.0.0/16 # Placeholder: 1.0.0.0/16
## Who is this IP range?
**Short answer:** Detailed attribution is not known yet. IANA delegates the encompassing `1.0.0.0/8` block to APNIC, but this placeholder does not assert one registrant, route origin, or operator for the whole `1.0.0.0/16` aggregate.
- **Status:** Placeholder — detailed investigation pending - **Status:** Placeholder — detailed investigation pending
- **Coverage role:** Fills the address-space gap after `0.0.0.0/8` - **Coverage role:** Fills the address-space gap after `0.0.0.0/8`
- **Range:** `1.0.0.0/16` - **Range:** `1.0.0.0/16`
@@ -1,5 +1,9 @@
# Placeholder: 1.1.0.0/24 # Placeholder: 1.1.0.0/24
## Who is this IP range?
**Short answer:** Detailed attribution is not known yet. IANA delegates the encompassing `1.0.0.0/8` block to APNIC, but the exact registrant, route origin, and operator for `1.1.0.0/24` still require investigation.
- **Status:** Placeholder — detailed investigation pending - **Status:** Placeholder — detailed investigation pending
- **Coverage role:** Fills the final range immediately before `1.1.1.0/24` - **Coverage role:** Fills the final range immediately before `1.1.1.0/24`
- **Range:** `1.1.0.0/24` - **Range:** `1.1.0.0/24`
@@ -1,5 +1,9 @@
# APNIC range: 1.1.1.0/24 # APNIC range: 1.1.1.0/24
## Who is this IP range?
**Short answer:** APNIC Research and Development is the registered resource holder; Cloudflare currently originates the route through `AS13335` and operates the documented 1.1.1.1 resolver service.
- **Registry:** APNIC - **Registry:** APNIC
- **Range:** `1.1.1.0/24` - **Range:** `1.1.1.0/24`
- **RDAP name/type:** `APNIC-LABS` / `ASSIGNED PORTABLE` - **RDAP name/type:** `APNIC-LABS` / `ASSIGNED PORTABLE`
+3 -1
View File
@@ -43,7 +43,9 @@ This is **not yet a list of all global ranges**. The expansion plan is in [`rese
## Required contents ## Required contents
Every range file must distinguish: Use [`TEMPLATE.md`](TEMPLATE.md) for every new range record. The **first section after the title must be `Who is this IP range?`** and must immediately name the registered holder/authority and operator—or explicitly say detailed attribution is unknown.
Every range file must then distinguish:
1. registry and registered resource holder; 1. registry and registered resource holder;
2. special-purpose classification, where applicable; 2. special-purpose classification, where applicable;
+43
View File
@@ -0,0 +1,43 @@
# <Registry>: <CIDR range>
## Who is this IP range?
**Short answer:** <Name the registry holder or protocol authority first. If unknown, say “Unknown — investigation pending.” Then state separately who routes or operates it when known.>
Do not begin with CIDR mechanics, routing tables, or long background. The first answer must tell the reader whose range this is—or clearly say that detailed attribution is not yet known.
- **Status:** <Researched | Partial | Placeholder>
- **Registry:** <IANA | AFRINIC | APNIC | ARIN | LACNIC | RIPE NCC>
- **Range:** `<network>/<prefix-length>`
- **Registered resource holder:** <name or unknown>
- **Observed route origin:** <ASN and name, or none/unknown>
- **Operator:** <name or unknown>
- **Classification:** <public unicast | special-purpose | other>
- **Globally routed:** <yes | no | unknown>
- **Verified:** <YYYY-MM-DD>
## What is known
<Verified range-level findings. Separate registration, routing, operation, and service responsibility.>
## Investigated addresses
<List notable exact addresses in the range and link their address records.>
## What is not yet known
<Explicit research gaps. Omit only when genuinely complete.>
## Relationship summary
| Axis | Finding |
|---|---|
| Registration | <finding> |
| Registered holder | <finding> |
| Route origin | <finding> |
| Operator | <finding> |
| Service | <finding> |
## Sources
- [Authoritative source](https://example.invalid/), checked <YYYY-MM-DD>
+18
View File
@@ -119,8 +119,10 @@ def main() -> int:
ROOT / "docs" / "02-first-round-investigation.md", ROOT / "docs" / "02-first-round-investigation.md",
ROOT / "address-book" / "README.md", ROOT / "address-book" / "README.md",
ROOT / "address-book" / "ip-addresses.md", ROOT / "address-book" / "ip-addresses.md",
ROOT / "address-book" / "ip" / "TEMPLATE.md",
ROOT / "docs" / "04-ip-address-model.md", ROOT / "docs" / "04-ip-address-model.md",
ROOT / "registry-ips" / "README.md", ROOT / "registry-ips" / "README.md",
ROOT / "registry-ips" / "TEMPLATE.md",
ROOT / "registry-ips" / "000-000-000-000--08--iana.md", ROOT / "registry-ips" / "000-000-000-000--08--iana.md",
ROOT / "registry-ips" / "001-000-000-000--16--placeholder.md", ROOT / "registry-ips" / "001-000-000-000--16--placeholder.md",
ROOT / "registry-ips" / "001-001-000-000--24--placeholder.md", ROOT / "registry-ips" / "001-001-000-000--24--placeholder.md",
@@ -131,6 +133,22 @@ def main() -> int:
if not path.is_file(): if not path.is_file():
errors.append(f"missing required document: {path.relative_to(ROOT)}") errors.append(f"missing required document: {path.relative_to(ROOT)}")
range_records = sorted((ROOT / "registry-ips").glob("*.md"))
for path in range_records:
if path.name in {"README.md", "TEMPLATE.md"}:
continue
headings = [line.strip() for line in path.read_text(encoding="utf-8").splitlines() if line.startswith("## ")]
if not headings or headings[0] != "## Who is this IP range?":
errors.append(f"{path.relative_to(ROOT)}: first section must be '## Who is this IP range?'")
address_records = sorted((ROOT / "address-book" / "ip").glob("*.md"))
for path in address_records:
if path.name == "TEMPLATE.md":
continue
headings = [line.strip() for line in path.read_text(encoding="utf-8").splitlines() if line.startswith("## ")]
if not headings or headings[0] != "## Who is this IP?":
errors.append(f"{path.relative_to(ROOT)}: first section must be '## Who is this IP?'")
if errors: if errors:
print("Validation failed:") print("Validation failed:")
for error in errors: for error in errors: