Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

160 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BGPKIT Commons

Crates.io Docs.rs License Discord

bgpkit-commons is a library for common BGP-related data and functions. It provides a unified interface to multiple BGP data sources through a lazy-loading architecture — modules are independently enabled via feature flags and data is only fetched when explicitly requested.

Architecture

graph TD
    B[BgpkitCommons]

    B -->|load_asinfo| M1[asinfo]
    B -->|load_as2rel| M2[as2rel]
    B -->|load_bogons| M3[bogons]
    B -->|load_countries| M4[countries]
    B -->|load_mrt_collectors| M5[mrt_collectors]
    B -->|load_rpki| M6[rpki]

    M1 -->|asinfo_get, asinfo_all| A1[RIPE NCC / CAIDA / APNIC / PeeringDB]
    M2 -->|as2rel_lookup| A2[BGPKIT inference]
    M3 -->|bogons_match| A3[IANA registries]
    M4 -->|country_by_code| A4[GeoNames]
    M5 -->|mrt_collectors_all| A5[RouteViews / RIPE RIS]
    M6 -->|rpki_validate| A6[Cloudflare / RIPE NCC / RPKIviews / RPKISPOOL]
Loading

Each module is gated by a feature flag. The all feature (default) enables everything. Data is fetched on the first load_xxx() call and kept in memory until reload() is called. The Cloudflare RPKI module also exposes a validator-aware polling API for avoiding full re-downloads when the source has not changed; see Conditional RPKI loading.

Modules

Module Feature Data Sources Key Functions
[asinfo] asinfo RIPE NCC, CAIDA as2org, APNIC, IIJ IHR, PeeringDB asinfo_get, asinfo_all, asinfo_are_siblings
[as2rel] as2rel BGPKIT AS relationship inference as2rel_lookup
[bogons] bogons IANA special registries bogons_match, bogons_match_prefix, bogons_match_asn
[countries] countries GeoNames country_by_code, country_by_code3, country_by_name
[mrt_collectors] mrt_collectors RouteViews, RIPE RIS mrt_collectors_all, mrt_collector_peers_all
[rpki] rpki Cloudflare, RIPE NCC, RPKIviews, RPKISPOOL rpki_validate, rpki_validate_check_expiry, rpki_lookup_by_prefix

RPKI data sources

Source Data and scope Wire/file compression Main entry points
Cloudflare Current aggregate ROA, ASPA, and BGPsec data HTTP Content-Encoding: gzip RpkiTrie::from_cloudflare, RpkiTrie::from_cloudflare_conditional
RIPE NCC Historical data from all five RIRs output.json.xz RpkiTrie::from_ripe_historical, list_ripe_files
RPKIviews Historical collector-specific snapshots .tgz (gzip-compressed tar) RpkiTrie::from_rpkiviews, list_rpkiviews_files
RPKISPOOL Historical CCR snapshots from a collector .tar.zst RpkiTrie::from_rpkispools, parse_rpkispools_archive

Collector-specific sources represent the selected collector's vantage point and snapshot; they should not be interpreted as a complete global view by themselves.

Quick Start

[dependencies]
bgpkit-commons = "0.10"
use bgpkit_commons::BgpkitCommons;

let mut commons = BgpkitCommons::new();

// Load the modules you need
commons.load_bogons().unwrap();
commons.load_asinfo(false, false, false, false).unwrap();

// Access the data
if let Ok(is_bogon) = commons.bogons_match("23456") {
    println!("ASN 23456 is bogon: {}", is_bogon);
}
if let Ok(Some(info)) = commons.asinfo_get(13335) {
    println!("AS13335: {} ({})", info.name, info.country);
}

Examples

RPKI Validation

use bgpkit_commons::BgpkitCommons;

let mut commons = BgpkitCommons::new();
commons.load_rpki(None).unwrap(); // None = real-time from Cloudflare

let result = commons.rpki_validate(13335, "1.1.1.0/24").unwrap();
println!("Validation result: {:?}", result);

Conditional RPKI loading

For a long-running service that polls Cloudflare repeatedly, retain the validators from the previous successful load. A matching validator produces Ok(None) from the next request, so the large JSON payload is not downloaded or parsed again:

use bgpkit_commons::rpki::RpkiTrie;

let mut etag = None;
let mut last_modified = None;

if let Some(load) = RpkiTrie::from_cloudflare_conditional(
    etag.as_deref(),
    last_modified.as_deref(),
)? {
    etag = load.etag.clone();
    last_modified = load.last_modified.clone();
    // Swap `load.trie` into the serving process after the complete rebuild.
} // `None` means HTTP 304: keep the currently served trie.
# Ok::<(), bgpkit_commons::BgpkitCommonsError>(())

BgpkitCommons::reload() is not validator-aware: it performs a regular full reload. Use the direct RpkiTrie conditional API when polling needs ETag/Last-Modified reuse.

Historical RPKI Data

use bgpkit_commons::BgpkitCommons;
use bgpkit_commons::rpki::{HistoricalRpkiSource, RpkiViewsCollector};
use chrono::NaiveDate;

let mut commons = BgpkitCommons::new();
let date = NaiveDate::from_ymd_opt(2024, 1, 4).unwrap();

// From RIPE NCC historical archives
commons.load_rpki_historical(date, HistoricalRpkiSource::Ripe).unwrap();

// Or from an RPKIviews collector
let source = HistoricalRpkiSource::RpkiViews(RpkiViewsCollector::SobornostNet);
commons.load_rpki_historical(date, source).unwrap();

// Or from RPKISPOOL (CCR format, parses faster)
use bgpkit_commons::rpki::RpkiSpoolsCollector;
let source = HistoricalRpkiSource::RpkiSpools(RpkiSpoolsCollector::default());
commons.load_rpki_historical(date, source).unwrap();

Available RPKIviews collectors: SobornostNet (default), MassarsNet, AttnJp, KerfuffleNet.

Available RPKISPOOL collectors: SobornostNet (default), AttnJp, KerfuffleNet.

AS Information with Builder

use bgpkit_commons::BgpkitCommons;

let mut commons = BgpkitCommons::new();
let builder = commons.asinfo_builder()
    .with_as2org()
    .with_peeringdb();
commons.load_asinfo_with(builder).unwrap();

if let Ok(are_siblings) = commons.asinfo_are_siblings(13335, 132892) {
    println!("AS13335 and AS132892 are siblings: {}", are_siblings);
}

Direct Module Access

All modules can be used directly without BgpkitCommons:

use bgpkit_commons::bogons::Bogons;
use bgpkit_commons::rpki::RpkiTrie;

let bogons = Bogons::new().unwrap();
let trie = RpkiTrie::from_cloudflare().unwrap();

Feature Flags

Feature Description
asinfo AS information: names, countries, organizations, population, hegemony
as2rel AS relationship data
bogons Bogon prefix and ASN detection
countries Country information lookup
mrt_collectors MRT collector metadata
rpki RPKI validation (ROA and ASPA)
all (default) Enables all modules

For a minimal build:

[dependencies]
bgpkit-commons = { version = "0.10", default-features = false, features = ["bogons", "rpki"] }

Examples requiring a particular module are feature-gated in Cargo.toml. For example:

cargo run --example rpki_historical --features rpki
cargo run --example rpkispools --features rpki
cargo run --example as2org --features asinfo,countries

Operational notes

  • Loading data requires network access; sources are fetched lazily when their load method is called.
  • The Cloudflare RPKI payload is large in memory even when HTTP gzip substantially reduces transfer size.
  • .gz, .xz, and .bz2 URL suffixes are decompressed by oneio. RPKIviews .tgz archives are streamed and require the gunzip executable to be available in PATH.
  • PeeringDB loading can use PEERINGDB_API_KEY; when unset, the client sends no empty API-key header.
  • reload() replaces already-loaded module data by fetching it again. It does not provide an atomic swap or conditional HTTP polling for the RPKI module.

License

MIT

About

Common utility data and functions.

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages