bgpkit_parser/parser/mrt/messages/
mod.rs

1use crate::models::{AsnLength, Bgp4MpEnum, Bgp4MpType, MrtMessage, TableDumpV2Message};
2use bytes::Bytes;
3
4pub(crate) mod bgp4mp;
5pub(crate) mod table_dump;
6pub(crate) mod table_dump_v2;
7
8impl MrtMessage {
9    pub fn encode(&self, sub_type: u16) -> Bytes {
10        let msg_bytes: Bytes = match self {
11            MrtMessage::TableDumpMessage(m) => m.encode(),
12            MrtMessage::TableDumpV2Message(m) => match m {
13                TableDumpV2Message::PeerIndexTable(p) => p.encode(),
14                TableDumpV2Message::RibAfi(r) => r.encode(),
15                TableDumpV2Message::RibGeneric(_) => {
16                    todo!("RibGeneric message is not supported yet");
17                }
18                TableDumpV2Message::GeoPeerTable(g) => g.encode(),
19            },
20            MrtMessage::Bgp4Mp(m) => {
21                let msg_type = Bgp4MpType::try_from(sub_type).unwrap();
22
23                match m {
24                    Bgp4MpEnum::StateChange(msg) => {
25                        let asn_len = match matches!(msg_type, Bgp4MpType::StateChangeAs4) {
26                            true => AsnLength::Bits32,
27                            false => AsnLength::Bits16,
28                        };
29                        msg.encode(asn_len)
30                    }
31                    Bgp4MpEnum::Message(msg) => {
32                        let asn_len = match matches!(
33                            msg_type,
34                            Bgp4MpType::MessageAs4
35                                | Bgp4MpType::MessageAs4Addpath
36                                | Bgp4MpType::MessageLocalAs4Addpath
37                                | Bgp4MpType::MessageAs4Local
38                        ) {
39                            true => AsnLength::Bits32,
40                            false => AsnLength::Bits16,
41                        };
42                        msg.encode(asn_len)
43                    }
44                }
45            }
46        };
47
48        msg_bytes
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55    use crate::models::{GeoPeerTable, TableDumpV2Type};
56    use std::net::Ipv4Addr;
57    use std::str::FromStr;
58
59    #[test]
60    fn test_mrt_message_encode_geo_peer_table() {
61        // Test MrtMessage::encode path for GeoPeerTable
62        let geo_table = GeoPeerTable::new(
63            Ipv4Addr::from_str("192.0.2.1").unwrap(),
64            "test-view".to_string(),
65            0.0,
66            0.0,
67        );
68
69        let mrt_message =
70            MrtMessage::TableDumpV2Message(TableDumpV2Message::GeoPeerTable(geo_table));
71
72        let subtype = TableDumpV2Type::GeoPeerTable as u16;
73        let encoded = mrt_message.encode(subtype);
74
75        // Should produce some encoded bytes
76        assert!(!encoded.is_empty());
77    }
78}