use rpki::audit_trace::trace_rule_to_root; use rpki::storage::{AuditRuleKind, RocksStore, VcirOutputType}; use serde_json::Value; use std::env; use std::path::Path; fn main() { let args: Vec = env::args().collect(); if args.len() < 3 { eprintln!("usage: trace_arin_missing_vrps [ ...]"); std::process::exit(2); } let store = RocksStore::open(Path::new(&args[1])).expect("open db"); let vcirs = store.list_vcirs().expect("list vcirs"); for row in &args[2..] { let parts: Vec<&str> = row.split(',').collect(); if parts.len() != 4 { println!("ROW {row}"); println!("ERROR invalid compare row"); println!(); continue; } let asn: u32 = parts[0] .trim_start_matches("AS") .parse() .expect("parse asn"); let prefix = parts[1].to_string(); let max_length: u8 = parts[2].parse().expect("parse max length"); let mut found = false; println!("ROW {row}"); for vcir in &vcirs { for output in &vcir.local_outputs { if output.output_type != VcirOutputType::Vrp { continue; } let payload: Value = match serde_json::from_str(&output.payload_json) { Ok(value) => value, Err(_) => continue, }; let payload_asn = payload .get("asn") .and_then(|v| v.as_u64()) .map(|v| v as u32); let payload_prefix = payload .get("prefix") .and_then(|v| v.as_str()) .map(|v| v.to_string()); let payload_max = payload .get("max_length") .and_then(|v| v.as_u64()) .map(|v| v as u8); if payload_asn == Some(asn) && payload_prefix.as_ref() == Some(&prefix) && payload_max == Some(max_length) { found = true; println!("manifest_rsync_uri={}", vcir.manifest_rsync_uri); println!("source_object_uri={}", output.source_object_uri); println!("source_object_hash={}", output.source_object_hash); println!("source_ee_cert_hash={}", output.source_ee_cert_hash); println!("rule_hash={}", output.rule_hash); println!("validation_path_hint={:?}", output.validation_path_hint); if let Some(trace) = trace_rule_to_root(&store, AuditRuleKind::Roa, &output.rule_hash) .expect("trace rule") { println!( "trace_leaf_manifest={}", trace .chain_leaf_to_root .first() .map(|node| node.manifest_rsync_uri.as_str()) .unwrap_or("") ); println!( "trace_source_object_uri={}", trace.resolved_output.source_object_uri ); println!("trace_chain_len={}", trace.chain_leaf_to_root.len()); for (idx, node) in trace.chain_leaf_to_root.iter().enumerate() { println!("chain[{idx}].manifest={}", node.manifest_rsync_uri); println!( "chain[{idx}].current_manifest={}", node.current_manifest_rsync_uri ); println!("chain[{idx}].current_crl={}", node.current_crl_rsync_uri); } } println!(); } } } if !found { println!("NOT_FOUND"); println!(); } } }