bgpkit_parser/parser/bmp/messages/
route_mirroring.rs

1use crate::bgp::parse_bgp_message;
2use crate::models::*;
3use crate::parser::bmp::error::ParserBmpError;
4use crate::parser::bmp::messages::BmpPeerType;
5use crate::parser::ReadUtils;
6use bytes::{Buf, Bytes};
7use num_enum::{IntoPrimitive, TryFromPrimitive};
8use std::convert::TryFrom;
9
10#[derive(Debug, PartialEq, Clone)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12pub struct RouteMirroring {
13    pub tlvs: Vec<RouteMirroringTlv>,
14}
15
16#[derive(Debug, PartialEq, Clone)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18pub struct RouteMirroringTlv {
19    pub info_len: u16,
20    pub value: RouteMirroringValue,
21}
22
23#[derive(Debug, PartialEq, Clone)]
24#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
25pub enum RouteMirroringValue {
26    BgpMessage(BgpMessage),
27    Information(RouteMirroringInfo),
28}
29
30#[derive(Debug, TryFromPrimitive, IntoPrimitive, PartialEq, Clone, Copy)]
31#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
32#[repr(u16)]
33pub enum RouteMirroringInfo {
34    ErroredPdu = 0,
35    MessageLost = 1,
36}
37
38pub fn parse_route_mirroring(
39    data: &mut Bytes,
40    asn_len: &AsnLength,
41    _peer_type: Option<&BmpPeerType>,
42) -> Result<RouteMirroring, ParserBmpError> {
43    let mut tlvs = vec![];
44    while data.remaining() > 4 {
45        match data.read_u16()? {
46            0 => {
47                let info_len = data.read_u16()?;
48                data.has_n_remaining(info_len as usize)?;
49                let mut bytes = data.split_to(info_len as usize);
50                let value = parse_bgp_message(&mut bytes, false, asn_len)?;
51                tlvs.push(RouteMirroringTlv {
52                    info_len,
53                    value: RouteMirroringValue::BgpMessage(value),
54                });
55            }
56            1 => {
57                let info_len = data.read_u16()?;
58                let value = RouteMirroringInfo::try_from(data.read_u16()?)?;
59                tlvs.push(RouteMirroringTlv {
60                    info_len,
61                    value: RouteMirroringValue::Information(value),
62                });
63            }
64            _ => {
65                return Err(ParserBmpError::CorruptedBmpMessage);
66            }
67        }
68    }
69    Ok(RouteMirroring { tlvs })
70}
71
72#[cfg(test)]
73mod tests {
74    use super::*;
75    use bytes::{BufMut, BytesMut};
76    use std::net::Ipv4Addr;
77
78    #[test]
79    fn test_route_mirroring_bgp_messsage() {
80        let bgp_message = BgpMessage::Open(BgpOpenMessage {
81            version: 4,
82            asn: Asn::new_32bit(1),
83            hold_time: 180,
84            sender_ip: Ipv4Addr::new(192, 0, 2, 1),
85            extended_length: false,
86            opt_params: vec![],
87        });
88        let bgp_message_bytes = bgp_message.encode(AsnLength::Bits32);
89        let expected_asn_len = AsnLength::Bits32;
90        let actual_info_len = bgp_message_bytes.len() as u16;
91
92        let mut message = BytesMut::new();
93        message.put_u16(0);
94        message.put_u16(actual_info_len);
95        message.put_slice(&bgp_message_bytes);
96        let mut data = message.freeze();
97        let result = parse_route_mirroring(&mut data, &expected_asn_len, None);
98
99        match result {
100            Ok(route_mirroring) => {
101                assert_eq!(route_mirroring.tlvs.len(), 1);
102                let tlv = &route_mirroring.tlvs[0];
103                assert_eq!(tlv.info_len, actual_info_len);
104            }
105            Err(_) => panic!("Error parsing route mirroring"),
106        }
107    }
108
109    #[test]
110    fn route_mirroring_information() {
111        let mut message = BytesMut::new();
112        message.put_u16(1);
113        message.put_u16(2);
114        message.put_u16(0);
115        let mut data = message.freeze();
116        let result = parse_route_mirroring(&mut data, &AsnLength::Bits32, None).unwrap();
117        assert_eq!(result.tlvs.len(), 1);
118        let tlv = &result.tlvs[0];
119        assert_eq!(tlv.info_len, 2);
120        match &tlv.value {
121            RouteMirroringValue::Information(info) => {
122                assert_eq!(info, &RouteMirroringInfo::ErroredPdu)
123            }
124            _ => panic!("Expected RouteMirroringValue::Information"),
125        }
126    }
127}