1use super::{decode_buffer, serialize_error, serialize_success};
17use crate::protocol_handler::{DecodeOutcome, ProtocolHandler};
18use bytes::BytesMut;
19use netgauze_bgp_pkt::BgpMessage;
20use netgauze_bgp_pkt::codec::{BgpCodec, BgpCodecDecoderError};
21use netgauze_bgp_pkt::wire::deserializer::{BgpParsingContext, BgpParsingIgnoredErrors};
22use netgauze_pcap_reader::TransportProtocol;
23use std::collections::HashMap;
24use std::io;
25use std::net::IpAddr;
26
27pub struct BgpProtocolHandler {
28 ports: Vec<u16>,
29}
30
31impl BgpProtocolHandler {
32 pub fn new(ports: Vec<u16>) -> Self {
33 BgpProtocolHandler { ports }
34 }
35}
36
37impl ProtocolHandler<(BgpMessage, BgpParsingIgnoredErrors), BgpCodec, BgpCodecDecoderError>
38 for BgpProtocolHandler
39{
40 fn decode(
41 &self,
42 flow_key: (IpAddr, u16, IpAddr, u16),
43 protocol: TransportProtocol,
44 packet_data: &[u8],
45 exporter_peers: &mut HashMap<(IpAddr, u16, IpAddr, u16), (BgpCodec, BytesMut)>,
46 ) -> Option<Vec<DecodeOutcome<(BgpMessage, BgpParsingIgnoredErrors), BgpCodecDecoderError>>>
47 {
48 let dst_port: u16 = flow_key.3;
49
50 if protocol == TransportProtocol::TCP && self.ports.contains(&dst_port) {
51 let (codec, buffer) = exporter_peers.entry(flow_key).or_insert((
52 BgpCodec::new_from_ctx(
53 true,
54 BgpParsingContext::new(
55 true,
56 HashMap::new(),
57 HashMap::new(),
58 true,
59 true,
60 true,
61 true,
62 ),
63 ),
64 BytesMut::new(),
65 ));
66 buffer.extend_from_slice(packet_data);
67
68 let mut results = Vec::new();
69 decode_buffer(buffer, codec, flow_key, &mut results);
70 if !results.is_empty() {
71 return Some(results);
72 }
73 }
74 None
75 }
76
77 fn serialize(
78 &self,
79 decode_outcome: DecodeOutcome<(BgpMessage, BgpParsingIgnoredErrors), BgpCodecDecoderError>,
80 ) -> io::Result<serde_json::Value> {
81 match decode_outcome {
82 DecodeOutcome::Success(m) => {
83 let (flow_key, (bgp_message, bgp_parsing_error)) = m;
84 if !bgp_parsing_error.eq(&BgpParsingIgnoredErrors::default()) {
85 return Ok(serde_json::Value::String("Encountered BGP parsing errors that were ignored during the decoding of the bgp message, this behaviour is not expected, please file a bug report to the developers".to_string()));
89 }
90 serialize_success(flow_key, bgp_message)
91 }
92 DecodeOutcome::Error(m) => serialize_error(m),
93 }
94 }
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100 use netgauze_bgp_pkt::open::BgpOpenMessage;
101 use netgauze_bgp_pkt::path_attribute::UndefinedOrigin;
102 use netgauze_bgp_pkt::wire::deserializer::BgpMessageParsingError;
103 use netgauze_bgp_pkt::wire::deserializer::path_attribute::{
104 OriginParsingError, PathAttributeParsingError,
105 };
106 use netgauze_bgp_pkt::wire::deserializer::update::BgpUpdateMessageParsingError;
107 use serde_json::json;
108 use std::net::Ipv4Addr;
109
110 #[test]
111 fn test_bgp_handler_decode_success() {
112 let handler = BgpProtocolHandler::new(vec![179]);
113 let flow_key = (
114 IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)),
115 12345,
116 IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)),
117 179,
118 );
119 let packet_data = [
121 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
122 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, 0x00, 0x01, 0x00, 0xb4, 0x01, 0x02, 0x03, 0x04,
123 0x00,
124 ];
125 let mut exporter_peers = HashMap::new();
126
127 let result = handler.decode(
128 flow_key,
129 TransportProtocol::TCP,
130 &packet_data,
131 &mut exporter_peers,
132 );
133
134 assert_eq!(
135 result,
136 Some(vec![DecodeOutcome::Success((
137 flow_key,
138 (
139 BgpMessage::Open(BgpOpenMessage::new(
140 1,
141 180,
142 Ipv4Addr::new(1, 2, 3, 4),
143 vec![],
144 )),
145 BgpParsingIgnoredErrors::default()
146 )
147 ))]),
148 );
149 assert!(exporter_peers.get(&flow_key).unwrap().1.is_empty());
151 }
152
153 #[test]
154 fn test_bgp_handler_decode_fragmented_success() {
155 let handler = BgpProtocolHandler::new(vec![179]);
156 let flow_key = (
157 IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)),
158 12345,
159 IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)),
160 179,
161 );
162 let packet_data1 = &[
164 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
165 0xff, 0xff, 0x00, 0x1d, 0x01,
166 ];
167 let packet_data2 = &[0x04, 0x00, 0x01, 0x00, 0xb4, 0x01, 0x02, 0x03, 0x04, 0x00];
168 let mut exporter_peers = HashMap::new();
169
170 let result1 = handler.decode(
172 flow_key,
173 TransportProtocol::TCP,
174 packet_data1,
175 &mut exporter_peers,
176 );
177 assert!(result1.is_none());
178 assert!(!exporter_peers.get(&flow_key).unwrap().1.is_empty());
180
181 let result2 = handler.decode(
183 flow_key,
184 TransportProtocol::TCP,
185 packet_data2,
186 &mut exporter_peers,
187 );
188
189 assert_eq!(
190 result2,
191 Some(vec![DecodeOutcome::Success((
192 flow_key,
193 (
194 BgpMessage::Open(BgpOpenMessage::new(
195 1,
196 180,
197 Ipv4Addr::new(1, 2, 3, 4),
198 vec![],
199 )),
200 BgpParsingIgnoredErrors::default()
201 )
202 ))]),
203 );
204 assert!(exporter_peers.get(&flow_key).unwrap().1.is_empty());
206 }
207
208 #[test]
209 fn test_bgp_handler_decode_multiple_messages_success() {
210 let handler = BgpProtocolHandler::new(vec![179]);
211 let flow_key = (
212 IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)),
213 12345,
214 IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)),
215 179,
216 );
217 let packet_data = [
219 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
220 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, 0x00, 0x01, 0x00, 0xb4, 0x01, 0x02, 0x03, 0x04,
221 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
222 0xff, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, 0x00, 0x01, 0x00, 0xb4, 0x05, 0x06, 0x07,
223 0x08, 0x00,
224 ];
225 let mut exporter_peers = HashMap::new();
226
227 let result = handler.decode(
228 flow_key,
229 TransportProtocol::TCP,
230 &packet_data,
231 &mut exporter_peers,
232 );
233
234 assert_eq!(
235 result,
236 Some(vec![
237 DecodeOutcome::Success((
238 flow_key,
239 (
240 BgpMessage::Open(BgpOpenMessage::new(
241 1,
242 180,
243 Ipv4Addr::new(1, 2, 3, 4),
244 vec![],
245 )),
246 BgpParsingIgnoredErrors::default()
247 )
248 )),
249 DecodeOutcome::Success((
250 flow_key,
251 (
252 BgpMessage::Open(BgpOpenMessage::new(
253 1,
254 180,
255 Ipv4Addr::new(5, 6, 7, 8),
256 vec![],
257 )),
258 BgpParsingIgnoredErrors::default()
259 )
260 ))
261 ]),
262 );
263 assert!(exporter_peers.get(&flow_key).unwrap().1.is_empty());
265 }
266
267 #[test]
268 fn test_bgp_handler_decode_message_with_errors_that_should_not_be_ignored() {
269 let handler = BgpProtocolHandler::new(vec![179]);
270 let flow_key = (
271 IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)),
272 12345,
273 IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)),
274 179,
275 );
276 let packet_data = [
279 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
280 0xff, 0xff, 0x00, 0x59, 0x02, 0x00, 0x00, 0x00, 0x30, 0x40, 0x01, 0x01,
281 0x0ff, 0x40, 0x02, 0x06, 0x02, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x40, 0x03, 0xff, 0x0a, 0x00, 0x0e,
284 0x01, 0x80, 0x04, 0xff, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xff, 0x00, 0x00, 0x00,
287 0x64, 0x80, 0x0a, 0x04, 0x0a, 0x00, 0x22, 0x04, 0x80, 0x09, 0x04, 0x0a, 0x00, 0x0f, 0x01,
289 0x00, 0x00, 0x00, 0x01, 0x20, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x01, 0x20,
290 0xc0, 0xa8, 0x01, 0x05,
291 ];
292 let mut exporter_peers = HashMap::new();
293
294 let result = handler.decode(
295 flow_key,
296 TransportProtocol::TCP,
297 &packet_data,
298 &mut exporter_peers,
299 );
300
301 assert_eq!(
303 result,
304 Some(vec![DecodeOutcome::Error(
305 BgpCodecDecoderError::BgpMessageParsingError(
306 BgpMessageParsingError::BgpUpdateMessageParsingError(
307 BgpUpdateMessageParsingError::PathAttributeError(
308 PathAttributeParsingError::OriginError(
309 OriginParsingError::UndefinedOrigin(UndefinedOrigin(255))
310 )
311 )
312 )
313 )
314 )]),
315 );
316 assert!(exporter_peers.get(&flow_key).unwrap().1.is_empty());
318 }
319 #[test]
320 fn test_bgp_handler_decode_failure() {
321 let handler = BgpProtocolHandler::new(vec![179]);
322 let flow_key = (
323 IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)),
324 12345,
325 IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)),
326 179,
327 );
328 let packet_data = [
330 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
331 0xff, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, 0x00, 0x01, 0x00, 0xb4, 0x01, 0x02, 0x03, 0x04,
333 0x00,
334 ];
335 let mut exporter_peers = HashMap::new();
336
337 let result = handler.decode(
338 flow_key,
339 TransportProtocol::TCP,
340 &packet_data,
341 &mut exporter_peers,
342 );
343
344 assert!(result.is_some());
345 assert_eq!(
347 result,
348 Some(vec![DecodeOutcome::Error(
349 BgpCodecDecoderError::BgpMessageParsingError(
350 BgpMessageParsingError::ConnectionNotSynchronized(
351 1329227995784915872903807060280344575
352 )
353 )
354 )]),
355 );
356 assert!(exporter_peers.get(&flow_key).unwrap().1.is_empty());
358 }
359
360 #[test]
361 fn test_bgp_handler_decode_ignore_wrong_port() {
362 let handler = BgpProtocolHandler::new(vec![179]);
363 let flow_key = (
364 IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)),
365 12345,
366 IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)),
367 180, );
369 let packet_data = [0xff; 20];
370 let mut exporter_peers = HashMap::new();
371
372 let result = handler.decode(
373 flow_key,
374 TransportProtocol::TCP,
375 &packet_data,
376 &mut exporter_peers,
377 );
378
379 assert!(result.is_none());
380 }
381
382 #[test]
383 fn test_bgp_handler_decode_ignore_wrong_protocol() {
384 let handler = BgpProtocolHandler::new(vec![179]);
385 let flow_key = (
386 IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)),
387 12345,
388 IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)),
389 179,
390 );
391 let packet_data = [0xff; 20];
392 let mut exporter_peers = HashMap::new();
393
394 let result = handler.decode(
395 flow_key,
396 TransportProtocol::UDP, &packet_data,
398 &mut exporter_peers,
399 );
400
401 assert!(result.is_none());
402 }
403
404 #[test]
405 fn test_bgp_handler_serialize_success() {
406 let handler = BgpProtocolHandler::new(vec![179]);
407 let flow_key = (
408 IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)),
409 12345,
410 IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)),
411 179,
412 );
413 let open_message = BgpMessage::Open(BgpOpenMessage::new(
414 1,
415 180,
416 Ipv4Addr::new(1, 1, 1, 1),
417 vec![],
418 ));
419 let outcome =
420 DecodeOutcome::Success((flow_key, (open_message, BgpParsingIgnoredErrors::default())));
421
422 let result = handler.serialize(outcome);
423 assert!(result.is_ok());
424 let json = result.unwrap();
425 let expected = json!({
426 "source_address": "10.0.0.1:12345",
427 "destination_address": "10.0.0.2:179",
428 "info": {
429 "Open": {
430 "version": 4,
431 "my_as": 1,
432 "hold_time": 180,
433 "bgp_id": "1.1.1.1",
434 "params": []
435 }
436 }
437 });
438 assert_eq!(json, expected);
439 }
440
441 #[test]
442 fn test_bgp_handler_serialize_error() {
443 let handler = BgpProtocolHandler::new(vec![179]);
444 let error = BgpCodecDecoderError::BgpMessageParsingError(
445 BgpMessageParsingError::BadMessageLength(10),
446 );
447 let outcome = DecodeOutcome::Error(error);
448
449 let result = handler.serialize(outcome);
450 assert!(result.is_ok());
451 let json = result.unwrap();
452 let expected = json!({
453 "BgpMessageParsingError": {
454 "BadMessageLength": 10
455 }
456 });
457 assert_eq!(json, expected);
458 }
459}