bgpkit_parser/parser/mrt/messages/
bgp4mp.rs1use crate::error::ParserError;
2use crate::models::*;
3use crate::parser::bgp::messages::parse_bgp_message;
4use crate::parser::{encode_asn, encode_ipaddr, ReadUtils};
5use bytes::{Buf, BufMut, Bytes, BytesMut};
6use std::convert::TryFrom;
7
8pub fn parse_bgp4mp(sub_type: u16, input: Bytes) -> Result<Bgp4MpEnum, ParserError> {
13 let bgp4mp_type: Bgp4MpType = Bgp4MpType::try_from(sub_type)?;
14 let msg: Bgp4MpEnum = match bgp4mp_type {
15 Bgp4MpType::StateChange => Bgp4MpEnum::StateChange(parse_bgp4mp_state_change(
16 input,
17 AsnLength::Bits16,
18 &bgp4mp_type,
19 )?),
20 Bgp4MpType::StateChangeAs4 => Bgp4MpEnum::StateChange(parse_bgp4mp_state_change(
21 input,
22 AsnLength::Bits32,
23 &bgp4mp_type,
24 )?),
25 Bgp4MpType::Message | Bgp4MpType::MessageLocal => Bgp4MpEnum::Message(
26 parse_bgp4mp_message(input, false, AsnLength::Bits16, &bgp4mp_type)?,
27 ),
28 Bgp4MpType::MessageAs4 | Bgp4MpType::MessageAs4Local => Bgp4MpEnum::Message(
29 parse_bgp4mp_message(input, false, AsnLength::Bits32, &bgp4mp_type)?,
30 ),
31 Bgp4MpType::MessageAddpath | Bgp4MpType::MessageLocalAddpath => Bgp4MpEnum::Message(
32 parse_bgp4mp_message(input, true, AsnLength::Bits16, &bgp4mp_type)?,
33 ),
34 Bgp4MpType::MessageAs4Addpath | Bgp4MpType::MessageLocalAs4Addpath => Bgp4MpEnum::Message(
35 parse_bgp4mp_message(input, true, AsnLength::Bits32, &bgp4mp_type)?,
36 ),
37 };
38
39 Ok(msg)
40}
41
42fn total_should_read(afi: &Afi, asn_len: &AsnLength, total_size: usize) -> usize {
43 let ip_size = match afi {
44 Afi::Ipv4 => 4 * 2,
45 Afi::Ipv6 => 16 * 2,
46 };
47 let asn_size = match asn_len {
48 AsnLength::Bits16 => 2 * 2,
49 AsnLength::Bits32 => 2 * 4,
50 };
51 total_size - asn_size - 2 - 2 - ip_size
52}
53pub fn parse_bgp4mp_message(
69 mut data: Bytes,
70 add_path: bool,
71 asn_len: AsnLength,
72 msg_type: &Bgp4MpType,
73) -> Result<Bgp4MpMessage, ParserError> {
74 let total_size = data.len();
75
76 let peer_asn: Asn = data.read_asn(asn_len)?;
77 let local_asn: Asn = data.read_asn(asn_len)?;
78 let interface_index: u16 = data.read_u16()?;
79 let afi: Afi = data.read_afi()?;
80 let peer_ip = data.read_address(&afi)?;
81 let local_ip = data.read_address(&afi)?;
82
83 let should_read = total_should_read(&afi, &asn_len, total_size);
84 if should_read != data.remaining() {
85 return Err(ParserError::TruncatedMsg(format!(
86 "truncated bgp4mp message: should read {} bytes, have {} bytes available",
87 should_read,
88 data.remaining()
89 )));
90 }
91 let bgp_message: BgpMessage = parse_bgp_message(&mut data, add_path, &asn_len)?;
92
93 Ok(Bgp4MpMessage {
94 msg_type: *msg_type,
95 peer_asn,
96 local_asn,
97 interface_index,
98 peer_ip,
99 local_ip,
100 bgp_message,
101 })
102}
103
104impl Bgp4MpMessage {
105 pub fn encode(&self, add_path: bool, asn_len: AsnLength) -> Bytes {
106 let mut bytes = BytesMut::new();
107 bytes.extend(self.peer_asn.encode());
108 bytes.extend(self.local_asn.encode());
109 bytes.put_u16(self.interface_index);
110 bytes.put_u16(address_family(&self.peer_ip));
111 bytes.extend(encode_ipaddr(&self.peer_ip));
112 bytes.extend(encode_ipaddr(&self.local_ip));
113 bytes.extend(&self.bgp_message.encode(add_path, asn_len));
114 bytes.freeze()
115 }
116}
117
118pub fn parse_bgp4mp_state_change(
150 mut input: Bytes,
151 asn_len: AsnLength,
152 msg_type: &Bgp4MpType,
153) -> Result<Bgp4MpStateChange, ParserError> {
154 let peer_asn: Asn = input.read_asn(asn_len)?;
155 let local_asn: Asn = input.read_asn(asn_len)?;
156 let interface_index: u16 = input.read_u16()?;
157 let address_family: Afi = input.read_afi()?;
158 let peer_addr = input.read_address(&address_family)?;
159 let local_addr = input.read_address(&address_family)?;
160 let old_state = BgpState::try_from(input.read_u16()?)?;
161 let new_state = BgpState::try_from(input.read_u16()?)?;
162 Ok(Bgp4MpStateChange {
163 msg_type: *msg_type,
164 peer_asn,
165 local_asn,
166 interface_index,
167 peer_addr,
168 local_addr,
169 old_state,
170 new_state,
171 })
172}
173
174impl Bgp4MpStateChange {
175 pub fn encode(&self, asn_len: AsnLength) -> Bytes {
176 let mut bytes = BytesMut::new();
177 bytes.extend(encode_asn(&self.peer_asn, &asn_len));
178 bytes.extend(encode_asn(&self.local_asn, &asn_len));
179 bytes.put_u16(self.interface_index);
180 bytes.put_u16(address_family(&self.peer_addr));
181 bytes.extend(encode_ipaddr(&self.peer_addr));
182 bytes.extend(encode_ipaddr(&self.local_addr));
183 bytes.put_u16(self.old_state as u16);
184 bytes.put_u16(self.new_state as u16);
185 bytes.freeze()
186 }
187}