bgpkit_parser/parser/iters/
default.rs1use crate::error::ParserError;
5use crate::models::*;
6use crate::parser::BgpkitParser;
7use crate::{Elementor, Filterable};
8use log::{error, warn};
9use std::io::Read;
10
11pub struct RecordIterator<R> {
16 pub parser: BgpkitParser<R>,
17 pub count: u64,
18 elementor: Elementor,
19}
20
21impl<R> RecordIterator<R> {
22 pub(crate) fn new(parser: BgpkitParser<R>) -> Self {
23 RecordIterator {
24 parser,
25 count: 0,
26 elementor: Elementor::new(),
27 }
28 }
29}
30
31impl<R: Read> Iterator for RecordIterator<R> {
32 type Item = MrtRecord;
33
34 fn next(&mut self) -> Option<MrtRecord> {
35 self.count += 1;
36 loop {
37 return match self.parser.next_record() {
38 Ok(v) => {
39 let filters = &self.parser.filters;
41 if filters.is_empty() {
42 Some(v)
43 } else {
44 if let MrtMessage::TableDumpV2Message(TableDumpV2Message::PeerIndexTable(
45 _,
46 )) = &v.message
47 {
48 let _ = self.elementor.record_to_elems(v.clone());
49 return Some(v);
50 }
51 let elems = self.elementor.record_to_elems(v.clone());
52 if elems.iter().any(|e| e.match_filters(&self.parser.filters)) {
53 Some(v)
54 } else {
55 continue;
56 }
57 }
58 }
59 Err(e) => {
60 match e.error {
61 ParserError::TruncatedMsg(err_str) | ParserError::Unsupported(err_str) => {
62 if self.parser.options.show_warnings {
63 warn!("parser warn: {}", err_str);
64 }
65 if let Some(bytes) = e.bytes {
66 std::fs::write("mrt_core_dump", bytes)
67 .expect("Unable to write to mrt_core_dump");
68 }
69 continue;
70 }
71 ParserError::ParseError(err_str) => {
72 error!("parser error: {}", err_str);
73 if self.parser.core_dump {
74 if let Some(bytes) = e.bytes {
75 std::fs::write("mrt_core_dump", bytes)
76 .expect("Unable to write to mrt_core_dump");
77 }
78 None
79 } else {
80 continue;
81 }
82 }
83 ParserError::EofExpected => {
84 None
86 }
87 ParserError::IoError(err) | ParserError::EofError(err) => {
88 error!("{:?}", err);
90 if self.parser.core_dump {
91 if let Some(bytes) = e.bytes {
92 std::fs::write("mrt_core_dump", bytes)
93 .expect("Unable to write to mrt_core_dump");
94 }
95 }
96 None
97 }
98 #[cfg(feature = "oneio")]
99 ParserError::OneIoError(_) => None,
100 ParserError::FilterError(_) => {
101 None
103 }
104 ParserError::InvalidLabeledNlriLength
106 | ParserError::TruncatedLabeledNlri
107 | ParserError::TruncatedPrefix
108 | ParserError::MaxLabelStackDepthExceeded
109 | ParserError::PeerMaxLabelsExceeded
110 | ParserError::InvalidPrefix => {
111 if self.parser.options.show_warnings {
112 warn!("parser warn: labeled NLRI parsing error: {:?}", e.error);
113 }
114 continue;
115 }
116 }
117 }
118 };
119 }
120 }
121}
122
123pub struct ElemIterator<R> {
128 cache_elems: Vec<BgpElem>,
129 record_iter: RecordIterator<R>,
130 elementor: Elementor,
131 count: u64,
132}
133
134impl<R> ElemIterator<R> {
135 pub(crate) fn new(parser: BgpkitParser<R>) -> Self {
136 ElemIterator {
137 record_iter: RecordIterator::new(parser),
138 count: 0,
139 cache_elems: vec![],
140 elementor: Elementor::new(),
141 }
142 }
143}
144
145impl<R: Read> Iterator for ElemIterator<R> {
146 type Item = BgpElem;
147
148 fn next(&mut self) -> Option<BgpElem> {
149 self.count += 1;
150
151 loop {
152 if self.cache_elems.is_empty() {
153 loop {
155 match self.record_iter.next() {
156 None => {
157 return None;
159 }
160 Some(r) => {
161 let mut elems = self.elementor.record_to_elems(r);
162 if elems.is_empty() {
163 continue;
165 } else {
166 elems.reverse();
167 self.cache_elems = elems;
168 break;
169 }
170 }
171 }
172 }
173 }
175
176 let elem = self.cache_elems.pop();
179 match elem {
180 None => return None,
181 Some(e) => match e.match_filters(&self.record_iter.parser.filters) {
182 true => return Some(e),
183 false => continue,
184 },
185 }
186 }
187 }
188}