bgpkit_commons/bogons/
mod.rs1mod asn;
19mod prefix;
20mod utils;
21
22use crate::bogons::asn::load_bogon_asns;
23use crate::bogons::prefix::load_bogon_prefixes;
24use crate::errors::{data_sources, load_methods, modules};
25use crate::{BgpkitCommons, BgpkitCommonsError, LazyLoadable, Result};
26pub use asn::BogonAsn;
27use ipnet::IpNet;
28pub use prefix::BogonPrefix;
29use serde::{Deserialize, Serialize};
30
31#[derive(Clone, Debug, Serialize, Deserialize)]
32pub struct Bogons {
33 pub prefixes: Vec<BogonPrefix>,
34 pub asns: Vec<BogonAsn>,
35}
36
37impl Bogons {
38 pub fn new() -> Result<Self> {
39 Ok(Bogons {
40 prefixes: load_bogon_prefixes()?,
41 asns: load_bogon_asns()?,
42 })
43 }
44
45 pub fn matches_str(&self, s: &str) -> bool {
47 match s.parse::<IpNet>() {
48 Ok(ip) => self.is_bogon_prefix(&ip),
49 Err(_) => match s.parse::<u32>() {
50 Ok(asn) => self.is_bogon_asn(asn),
51 Err(_) => false,
52 },
53 }
54 }
55
56 pub fn is_bogon_prefix(&self, prefix: &IpNet) -> bool {
58 self.prefixes
59 .iter()
60 .any(|bogon_prefix| bogon_prefix.matches(prefix))
61 }
62
63 pub fn is_bogon_asn(&self, asn: u32) -> bool {
65 self.asns.iter().any(|bogon_asn| bogon_asn.matches(asn))
66 }
67}
68
69impl LazyLoadable for Bogons {
70 fn reload(&mut self) -> Result<()> {
71 *self = Bogons::new().map_err(|e| {
72 BgpkitCommonsError::data_source_error(data_sources::IANA, e.to_string())
73 })?;
74 Ok(())
75 }
76
77 fn is_loaded(&self) -> bool {
78 !self.prefixes.is_empty() && !self.asns.is_empty()
79 }
80
81 fn loading_status(&self) -> &'static str {
82 if self.is_loaded() {
83 "Bogons data loaded"
84 } else {
85 "Bogons data not loaded"
86 }
87 }
88}
89
90impl BgpkitCommons {
91 pub fn bogons_match(&self, s: &str) -> Result<bool> {
92 match &self.bogons {
93 Some(b) => Ok(b.matches_str(s)),
94 None => Err(BgpkitCommonsError::module_not_loaded(
95 modules::BOGONS,
96 load_methods::LOAD_BOGONS,
97 )),
98 }
99 }
100
101 pub fn bogons_match_prefix(&self, prefix: &str) -> Result<bool> {
102 let prefix: IpNet = prefix.parse().map_err(|e: ipnet::AddrParseError| {
103 BgpkitCommonsError::invalid_format("IP prefix", prefix, e.to_string())
104 })?;
105 match &self.bogons {
106 Some(b) => Ok(b.is_bogon_prefix(&prefix)),
107 None => Err(BgpkitCommonsError::module_not_loaded(
108 modules::BOGONS,
109 load_methods::LOAD_BOGONS,
110 )),
111 }
112 }
113
114 pub fn bogons_match_asn(&self, asn: u32) -> Result<bool> {
115 match &self.bogons {
116 Some(b) => Ok(b.is_bogon_asn(asn)),
117 None => Err(BgpkitCommonsError::module_not_loaded(
118 modules::BOGONS,
119 load_methods::LOAD_BOGONS,
120 )),
121 }
122 }
123
124 pub fn get_bogon_prefixes(&self) -> Result<Vec<BogonPrefix>> {
126 match &self.bogons {
127 Some(b) => Ok(b.prefixes.clone()),
128 None => Err(BgpkitCommonsError::module_not_loaded(
129 modules::BOGONS,
130 load_methods::LOAD_BOGONS,
131 )),
132 }
133 }
134
135 pub fn get_bogon_asns(&self) -> Result<Vec<BogonAsn>> {
137 match &self.bogons {
138 Some(b) => Ok(b.asns.clone()),
139 None => Err(BgpkitCommonsError::module_not_loaded(
140 modules::BOGONS,
141 load_methods::LOAD_BOGONS,
142 )),
143 }
144 }
145}