diff --git a/examples/list_aspas.rs b/examples/list_aspas.rs new file mode 100644 index 0000000..47b4f9c --- /dev/null +++ b/examples/list_aspas.rs @@ -0,0 +1,9 @@ +use serde_json::json; + +fn main() { + let cf_data = bgpkit_commons::rpki::CfData::new().unwrap(); + println!( + "{}", + serde_json::to_string_pretty(&json!(cf_data.aspas)).unwrap() + ); +} diff --git a/src/rpki/cloudflare.rs b/src/rpki/cloudflare.rs index d1dd01b..8a2ac76 100644 --- a/src/rpki/cloudflare.rs +++ b/src/rpki/cloudflare.rs @@ -2,23 +2,91 @@ use anyhow::Result; use ipnet::IpNet; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use std::str::FromStr; use super::{Rir, RoaEntry, RpkiTrie}; -#[derive(Clone, Debug, Deserialize)] -struct CfData { - roas: Vec, +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct CfData { + pub metadata: CfMetaData, + pub roas: Vec, + pub aspas: Vec, + pub bgpsec_keys: Vec, } -#[derive(Clone, Debug, Deserialize)] -struct CfRoaEntry { - prefix: String, +impl CfData { + pub fn new() -> Result { + let data: CfData = + oneio::read_json_struct::("https://rpki.cloudflare.com/rpki.json")?; + Ok(data) + } +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct CfMetaData { + pub buildmachine: Option, + pub buildtime: Option, + pub elapsedtime: Option, + pub usertime: Option, + pub systemtime: Option, + pub roas: Option, + pub failedroas: Option, + pub invalidroas: Option, + pub spls: Option, + pub failedspls: Option, + pub invalidspls: Option, + pub aspas: Option, + pub failedaspas: Option, + pub invalidaspas: Option, + pub bgpsec_pubkeys: Option, + pub certificates: Option, + pub invalidcertificates: Option, + pub taks: Option, + pub tals: Option, + pub invalidtals: Option, + pub talfiles: Option>, + pub manifests: Option, + pub failedmanifests: Option, + pub crls: Option, + pub gbrs: Option, + pub repositories: Option, + pub vrps: Option, + pub uniquevrps: Option, + pub vsps: Option, + pub uniquevsps: Option, + pub vaps: Option, + pub uniquevaps: Option, + pub cachedir_new_files: Option, + pub cachedir_del_files: Option, + pub cachedir_del_dirs: Option, + pub cachedir_superfluous_files: Option, + pub cachedir_del_superfluous_files: Option, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct CfAspaEntry { + pub customer_asid: u32, + pub expires: i64, + pub providers: Vec, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct CfBgpsecKeysEntry { + pub asn: u32, + pub ski: String, + pub pubkey: String, + pub ta: String, + pub expires: i64, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct CfRoaEntry { + pub prefix: String, #[serde(rename = "maxLength")] - max_length: u8, - asn: String, - ta: String, + pub max_length: u8, + pub asn: u32, + pub ta: String, } impl RpkiTrie { @@ -27,15 +95,10 @@ impl RpkiTrie { oneio::read_json_struct::("https://rpki.cloudflare.com/rpki.json")?; let mut trie = RpkiTrie::default(); + trie.aspas = data.aspas; for roa in data.roas { let prefix = roa.prefix.parse::()?; - let asn = roa - .asn - .to_lowercase() - .strip_prefix("as") - .unwrap() - .parse::()?; let max_length = roa.max_length; let rir = match Rir::from_str(roa.ta.as_str()) { Ok(rir) => Some(rir), @@ -43,7 +106,7 @@ impl RpkiTrie { }; let roa_entry = RoaEntry { prefix, - asn, + asn: roa.asn, max_length, rir, not_before: None, diff --git a/src/rpki/mod.rs b/src/rpki/mod.rs index d745756..60800b7 100644 --- a/src/rpki/mod.rs +++ b/src/rpki/mod.rs @@ -21,11 +21,13 @@ use ipnet_trie::IpnetTrie; use crate::BgpkitCommons; use anyhow::{anyhow, Result}; +pub use cloudflare::*; use std::fmt::Display; use std::str::FromStr; pub struct RpkiTrie { pub trie: IpnetTrie, + pub aspas: Vec, date: Option, } @@ -33,6 +35,7 @@ impl Default for RpkiTrie { fn default() -> Self { Self { trie: IpnetTrie::new(), + aspas: vec![], date: None, } } @@ -115,10 +118,7 @@ impl Display for RpkiValidation { impl RpkiTrie { pub fn new(date: Option) -> Self { - Self { - trie: IpnetTrie::new(), - date, - } + Self::default() } /// insert an [RoaEntry]. If old value exists, it is returned.