[
  {
    "code": "ASN",
    "name": "ASN Introduction",
    "url": "https://github.com/CAIDA/nids-asn-introduction/blob/main/Introduction.md",
    "status": "released",
    "required": "none",
    "focus": {
      "summary": "Explore CAIDA's AS-to-Organization and AS Relationship/Customer Cone datasets to learn how Autonomous Systems are identified, organized, and measured by their sphere of influence on the Internet.",
      "teaches": [
        {
          "type": "idea",
          "text": "The Autonomous System as the unit of Internet routing, and the customer cone as a measure of an AS's sphere of influence"
        },
        {
          "type": "dataset",
          "text": "CAIDA AS Relationships / Customer Cone (ppdc-ases) file"
        },
        {
          "type": "dataset",
          "text": "CAIDA AS-to-Organization (AS2Org) mapping"
        }
      ],
      "tasks": [
        "Parse the customer cone file and classify every ASN into tiers by cone size, from edge networks to the largest transit providers",
        "Join the cone tiers with the AS-to-Organization mapping to count tiers per country and see where transit infrastructure concentrates"
      ]
    },
    "dependencies": [],
    "tags": ["Autonomous Systems", "AS Relationships", "Customer Cone"]
  },
  {
    "code": "BGP",
    "name": "BGP Control Plane",
    "url": "https://github.com/CAIDA/nids-bgp-control-plane/blob/main/Introduction.md",
    "status": "released",
    "required": "none",
    "focus": {
      "summary": "Analyze BGP routing table snapshots from RouteViews to map IP prefixes to originating ASes, measure MOAS (multi-origin AS) prefixes, and extend customer cone analysis from AS counts to address space.",
      "teaches": [
        {
          "type": "dataset",
          "text": "RouteViews BGP RIB snapshots, read from the Open Science Data Federation (OSDF)"
        },
        {
          "type": "tool",
          "text": "pybgpkit-parser for reading RIB dumps and pytricia for longest-prefix-match lookups"
        },
        {
          "type": "practice",
          "text": "Counting address space with longest-prefix match so nested prefixes are not double-counted",
          "guide": true
        },
        {
          "type": "practice",
          "text": "Reading heavy-tailed distributions with log-log CCDF plots"
        },
        {
          "type": "idea",
          "text": "Multi-origin AS (MOAS) prefixes and why they matter for routing security"
        }
      ],
      "tasks": [
        "Build a prefix-to-origin-AS mapping from a RouteViews RIB, identify MOAS prefixes, and plot CCDFs of per-AS prefix and address counts",
        "Aggregate prefix and address counts over each AS's customer cone and compare the cone CCDFs with the origin CCDFs",
        "Rank ASNs across four size metrics and attribute the top entries to organizations with AS2Org"
      ]
    },
    "dependencies": ["ASN"],
    "tags": ["BGP", "Routing", "RouteViews", "MOAS"]
  },
  {
    "code": "IRR",
    "name": "Registries: WHOIS, IRR & RPKI",
    "url": "https://github.com/CAIDA/nids-irr-rpki-whois-local/blob/main/Introduction.md",
    "status": "soon",
    "required": "NRP",
    "focus": {
      "summary": "Compare Regional Internet Registry (RIR) WHOIS/RDAP records, Internet Routing Registry (IRR) route objects, and RPKI Route Origin Authorizations (ROAs) against observed BGP prefix-origin pairs to understand where registry data agrees, disagrees, and signals routing risk.",
      "teaches": [
        {
          "type": "dataset",
          "text": "Daily IRR database snapshots (RADB, NTTCOM, the RIR-operated IRRs, and others)"
        },
        {
          "type": "dataset",
          "text": "RIPE NCC archives of validated RPKI ROA payloads (VRPs)"
        },
        {
          "type": "idea",
          "text": "Registration, delegation, and origination as distinct claims, and how IRR filtering differs from RPKI origin validation"
        },
        {
          "type": "practice",
          "text": "Greedy ordering of IRR databases by the new prefixes and origins each one contributes",
          "guide": true
        },
        {
          "type": "practice",
          "text": "Classifying prefix-origin pairs as valid, invalid-ASN, invalid-length, or not-found against a covering record",
          "guide": true
        },
        { "type": "tool", "text": "py-radix for covering-prefix lookups" }
      ],
      "tasks": [
        "Order one day's IRR databases greedily by the unique prefixes and origin ASes each adds on top of the others",
        "Classify one day of observed BGP prefix-origin pairs against each IRR database and against RPKI",
        "Repeat the IRR-versus-RPKI comparison monthly across January to June 2023 and explain any trend or spike in disagreement"
      ]
    },
    "dependencies": ["ASN", "BGP"],
    "tags": ["WHOIS", "IRR", "RPKI", "Routing Security"]
  },
  {
    "code": "ITDK",
    "name": "ITDK",
    "url": "https://github.com/CAIDA/nids-itdk/blob/main/Introduction.md",
    "status": "soon",
    "required": "NRP",
    "focus": {
      "summary": "Work with CAIDA's Internet Topology Data Kit, derived from large-scale traceroute campaigns, to explore router-level topology, alias resolution, AS assignment, and node geolocation.",
      "teaches": [
        {
          "type": "dataset",
          "text": "CAIDA's Internet Topology Data Kit (ITDK): router-level nodes and links with alias-resolution, AS, geolocation, and hostname annotations, served from a PostgreSQL database"
        },
        {
          "type": "tool",
          "text": "SQL against a large, indexed PostgreSQL schema",
          "guide": true
        },
        {
          "type": "practice",
          "text": "Writing index-aware queries: filter on keyed columns first, prototype with LIMIT and EXPLAIN before scaling up"
        },
        {
          "type": "idea",
          "text": "When a router's inferred geolocation can be trusted: hostname-based Hoiho hints versus MaxMind, and how to read their disagreement"
        }
      ],
      "tasks": [
        "Find the router-level links between Level3 and Netflix, test whether their endpoints are geographically adjacent, and map where the two networks peer",
        "Count China Unicom's routers by country, compare the distribution with Level3, and identify the ASes its US West Coast routers connect to",
        "Query the links among 18 major ASes and interpret the interconnection heatmap"
      ]
    },
    "dependencies": ["ASN", "BGP"],
    "tags": ["Topology", "Traceroute", "Alias Resolution", "Geolocation"]
  },
  {
    "code": "DNS",
    "name": "DNS Ecosystem",
    "url": "https://github.com/CAIDA/nids-dns-ecosystem/blob/main/Introduction.md",
    "status": "soon",
    "required": "NRP",
    "focus": {
      "summary": "Use OpenINTEL active DNS measurements and the LACeS Anycast Census to study DNS hosting concentration, name server redundancy and anycast deployment, and adoption of DNS security mechanisms across the Internet.",
      "teaches": [
        {
          "type": "idea",
          "text": "Market concentration and systemic dependency, measured with the Herfindahl-Hirschman Index (HHI)"
        },
        {
          "type": "dataset",
          "text": "OpenINTEL zone-based measurements (NS, DNSKEY, DS, CAA, TXT, SOA records)"
        },
        { "type": "dataset", "text": "LACeS Anycast Census" },
        {
          "type": "tool",
          "text": "PySpark with the S3A connector, reading partitioned Parquet directly from an object store",
          "guide": true
        },
        {
          "type": "tool",
          "text": "dnspython for resolving name servers to addresses"
        },
        {
          "type": "practice",
          "text": "Prototyping a query on a small TLD before scaling it to a large one"
        }
      ],
      "tasks": [
        "Derive DNS provider market share and the HHI from raw NS records, then follow the concentration trend across years",
        "Count name servers and providers per domain, examine SOA parameters, and cross-reference the anycast census",
        "Measure DNSSEC, CAA, and SPF adoption in one snapshot, then repeat across 2019 to 2024"
      ]
    },
    "dependencies": [],
    "tags": ["DNS", "DNSSEC", "Anycast", "OpenINTEL"]
  },
  {
    "code": "TELESCOPE",
    "name": "Network Telescope Traffic",
    "url": "https://github.com/CAIDA/nids-telescope-traffic/blob/main/Introduction.md",
    "status": "soon",
    "required": "Expanse",
    "focus": {
      "summary": "Build flow records from raw UCSD Network Telescope packet captures, enrich them with geolocation and BGP-derived origin-AS data, and investigate a real traffic surge from country down to a single scanning host.",
      "teaches": [
        {
          "type": "dataset",
          "text": "UCSD Network Telescope packet captures (anonymized destinations, real sources) and a hosted GeoLite2 City snapshot"
        },
        {
          "type": "tool",
          "text": "dpkt for parsing Ethernet, IP, TCP, UDP, and ICMP frames",
          "guide": true
        },
        {
          "type": "tool",
          "text": "pyarrow for writing flow records to Parquet without a pandas round-trip",
          "guide": true
        },
        {
          "type": "practice",
          "text": "Building flow records from raw captures in a memory-efficient streaming pass, one capture at a time"
        },
        {
          "type": "idea",
          "text": "Unsolicited telescope traffic as a signal of scanning and backscatter, and why the largest flows are not the scanner"
        }
      ],
      "tasks": [
        "Extract 5-tuple flow keys from raw frames and summarize each capture's flows, packets, and protocols",
        "Resolve each flow's source to its origin AS with longest-prefix match and to a country with GeoLite2",
        "Trace the traffic surge from country to AS to a single scanner, then read its scan footprint on a Hilbert-curve map"
      ]
    },
    "dependencies": ["ASN", "BGP"],
    "tags": ["Network Telescope", "Traffic Analysis", "Geolocation", "PCAP"]
  },
  {
    "code": "UCSDNT",
    "name": "UCSD Network Telescope on Expanse",
    "url": "https://github.com/CAIDA/nids-ucsdnt-expanse/blob/main/Introduction.md",
    "status": "soon",
    "required": "Expanse",
    "focus": {
      "summary": "Scale a UCSD Network Telescope FlowTuple analysis from an interactive PySpark prototype to a Slurm batch job array on SDSC Expanse, attribute traffic by country and origin AS, and detect a real countrywide Internet blackout in the resulting time series.",
      "teaches": [
        {
          "type": "dataset",
          "text": "UCSD Network Telescope FlowTuple v4 records, stored as Avro on a CAIDA S3 endpoint"
        },
        {
          "type": "tool",
          "text": "PySpark on a single Expanse compute node, reading Avro and writing Parquet",
          "guide": true
        },
        {
          "type": "tool",
          "text": "Slurm job arrays submitted from an Expanse login node"
        },
        {
          "type": "practice",
          "text": "Porting an interactive prototype into a standalone script and a batch job array to cover a longer period"
        },
        {
          "type": "idea",
          "text": "Detecting and interpreting an anomaly, here a national Internet blackout, against a measured baseline of background traffic"
        }
      ],
      "tasks": [
        "Filter two test days of FlowTuple records to Iran-geolocated sources and compute daily, per-ASN, and hourly aggregates in Spark",
        "Measure day-over-day churn of /24 source subnets between the two test days",
        "Port the per-day logic into a script and run it as a 24-task Slurm job array over the full period",
        "Rank ASNs, plot the hourly and full-period trends, and match the sharp drop against the reported blackout dates"
      ]
    },
    "dependencies": ["ASN", "DNS", "TELESCOPE"],
    "tags": ["Network Telescope", "PySpark", "Slurm", "Anomaly Detection"]
  },
  {
    "code": "IYP",
    "name": "Internet Yellow Pages",
    "url": "https://github.com/CAIDA/nids-iyp/blob/main/Introduction.md",
    "status": "soon",
    "required": "NRP",
    "focus": {
      "summary": "Query the Internet Yellow Pages (IYP) Neo4j graph database with Cypher to explore an AS's rankings, IXP memberships, and peering relationships, trace a path from announced address space to hosted domain names, and check RPKI authorizations against observed BGP origins.",
      "teaches": [
        {
          "type": "dataset",
          "text": "The Internet Yellow Pages (IYP): dozens of Internet measurement datasets merged into one Neo4j graph"
        },
        {
          "type": "tool",
          "text": "Cypher, Neo4j's graph query language, through the Python driver",
          "guide": true
        },
        {
          "type": "practice",
          "text": "Multi-hop graph traversals that replace hand-written joins across siloed datasets"
        },
        {
          "type": "idea",
          "text": "Provenance: independent sources disagree, so record every source's claim instead of flattening them into one value"
        }
      ],
      "tasks": [
        "Resolve names, ASRank, IXP memberships, and peering degree for three example ASes and relate the measures to each other",
        "Walk from an AS's announced prefixes to the popular hostnames and name servers inside them in a single traversal",
        "Compare RPKI ROAs with observed BGP origins for one AS, then find the ASes originating the most RPKI-invalid prefixes"
      ]
    },
    "dependencies": ["ASN", "BGP", "ITDK", "IRR", "DNS"],
    "tags": ["Graph Database", "Neo4j", "Cypher", "Knowledge Graph"]
  }
]
