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 Afi::LinkState => 4 * 2, };
48 let asn_size = match asn_len {
49 AsnLength::Bits16 => 2 * 2,
50 AsnLength::Bits32 => 2 * 4,
51 };
52 total_size - asn_size - 2 - 2 - ip_size
53}
54pub fn parse_bgp4mp_message(
70 mut data: Bytes,
71 add_path: bool,
72 asn_len: AsnLength,
73 msg_type: &Bgp4MpType,
74) -> Result<Bgp4MpMessage, ParserError> {
75 let total_size = data.len();
76
77 let peer_asn: Asn = data.read_asn(asn_len)?;
78 let local_asn: Asn = data.read_asn(asn_len)?;
79 let interface_index: u16 = data.read_u16()?;
80 let afi: Afi = data.read_afi()?;
81 let peer_ip = data.read_address(&afi)?;
82 let local_ip = data.read_address(&afi)?;
83
84 let should_read = total_should_read(&afi, &asn_len, total_size);
85 if should_read != data.remaining() {
86 return Err(ParserError::TruncatedMsg(format!(
87 "truncated bgp4mp message: should read {} bytes, have {} bytes available",
88 should_read,
89 data.remaining()
90 )));
91 }
92 let bgp_message: BgpMessage = parse_bgp_message(&mut data, add_path, &asn_len)?;
93
94 Ok(Bgp4MpMessage {
95 msg_type: *msg_type,
96 peer_asn,
97 local_asn,
98 interface_index,
99 peer_ip,
100 local_ip,
101 bgp_message,
102 })
103}
104
105impl Bgp4MpMessage {
106 pub fn encode(&self, asn_len: AsnLength) -> Bytes {
107 let mut bytes = BytesMut::new();
108 bytes.extend(self.peer_asn.encode());
109 bytes.extend(self.local_asn.encode());
110 bytes.put_u16(self.interface_index);
111 bytes.put_u16(address_family(&self.peer_ip));
112 bytes.extend(encode_ipaddr(&self.peer_ip));
113 bytes.extend(encode_ipaddr(&self.local_ip));
114 bytes.extend(&self.bgp_message.encode(asn_len));
115 bytes.freeze()
116 }
117}
118
119pub fn parse_bgp4mp_state_change(
151 mut input: Bytes,
152 asn_len: AsnLength,
153 msg_type: &Bgp4MpType,
154) -> Result<Bgp4MpStateChange, ParserError> {
155 let peer_asn: Asn = input.read_asn(asn_len)?;
156 let local_asn: Asn = input.read_asn(asn_len)?;
157 let interface_index: u16 = input.read_u16()?;
158 let address_family: Afi = input.read_afi()?;
159 let peer_ip = input.read_address(&address_family)?;
160 let local_addr = input.read_address(&address_family)?;
161 let old_state = BgpState::try_from(input.read_u16()?)?;
162 let new_state = BgpState::try_from(input.read_u16()?)?;
163 Ok(Bgp4MpStateChange {
164 msg_type: *msg_type,
165 peer_asn,
166 local_asn,
167 interface_index,
168 peer_ip,
169 local_addr,
170 old_state,
171 new_state,
172 })
173}
174
175impl Bgp4MpStateChange {
176 pub fn encode(&self, asn_len: AsnLength) -> Bytes {
177 let mut bytes = BytesMut::new();
178 bytes.extend(encode_asn(&self.peer_asn, &asn_len));
179 bytes.extend(encode_asn(&self.local_asn, &asn_len));
180 bytes.put_u16(self.interface_index);
181 bytes.put_u16(address_family(&self.peer_ip));
182 bytes.extend(encode_ipaddr(&self.peer_ip));
183 bytes.extend(encode_ipaddr(&self.local_addr));
184 bytes.put_u16(self.old_state as u16);
185 bytes.put_u16(self.new_state as u16);
186 bytes.freeze()
187 }
188}