route_verification_bgp/cmp/
as_regex.rs1use itertools::Itertools;
2use lazy_regex::Regex;
3
4use super::*;
5
6pub struct AsRegex<'a> {
7 pub c: &'a CheckFilter<'a>,
8 pub interpreter: Interpreter,
9 pub expr: &'a str,
10 pub report: AnyReportCase,
11}
12
13impl<'a> AsRegex<'a> {
14 pub fn check(&mut self, path: Vec<u32>) -> AnyReport {
15 let converted = match self.interpreter.run(self.expr) {
16 Ok(c) => c,
17 Err(HasTilde) => {
18 return self
19 .c
20 .skip_any_report(|| SkipAsRegexWithTilde(self.expr.into()))
21 }
22 Err(_) => return self.invalid_err(),
23 };
24 let converted_regex = match Regex::new(converted) {
25 Ok(c) => c,
26 Err(_) => return self.invalid_err(),
27 };
28 let replacements = path.iter().map(|n| self.asn_chars(*n)).collect::<Vec<_>>();
29 for chars in replacements.iter().multi_cartesian_product() {
30 let haystack: String = chars.into_iter().collect();
31 if converted_regex.is_match(&haystack) {
32 return None;
33 }
34 }
35 match mem::take(&mut self.report) {
36 BadAnyReport(_) => self.c.bad_any_report(|| MatchRegex(self.expr.into())),
37 non_bad => Some(non_bad),
38 }
39 }
40
41 pub fn asn_chars(&mut self, asn: u32) -> Vec<char> {
44 let mut result: Vec<_> = self.interpreter.get_asn(asn).into_iter().collect();
45 for (set, c) in self.interpreter.as_sets_with_char() {
46 match self.c.set_has_member(set, asn) {
47 Ok(true) => result.push(c),
48 Ok(false) => (),
49 Err(r) => self.report |= r.unwrap(),
50 }
51 }
52 if asn == self.c.accept_num {
53 result.push(self.interpreter.peer_as_char());
54 }
55 if result.is_empty() {
56 vec!['¿']
57 } else {
58 result
59 }
60 }
61
62 fn invalid_err(&self) -> AnyReport {
63 self.c
64 .bad_any_report(|| RpslInvalidAsRegex(self.expr.into()))
65 }
66}