From a111f0a48db86a371552a095e709bb57a7c6e743 Mon Sep 17 00:00:00 2001 From: Mingwei Zhang Date: Tue, 14 Dec 2021 21:57:23 -0800 Subject: [PATCH 1/9] use extended types for bgp-models --- Cargo.toml | 4 +++- examples/parse-files-from-broker.rs | 2 +- .../real-time-routeviews-kafka-openbmp.rs | 2 +- src/lib.rs | 2 +- src/parser/bgp/attributes.rs | 10 ++++---- src/parser/bgp/messages.rs | 4 ++-- src/parser/filter.rs | 3 ++- src/parser/mrt/messages/bgp4mp.rs | 18 +++++++------- .../mrt/messages/table_dump_v2_message.rs | 1 + src/parser/rislive/messages/mod.rs | 2 +- src/parser/rislive/messages/raw_bytes.rs | 7 +++--- src/parser/rislive/messages/ris_message.rs | 7 +++--- src/parser/rislive/mod.rs | 8 +++---- src/parser/utils.rs | 24 +++++++++++++++---- 14 files changed, 59 insertions(+), 35 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8c0572a..e2e36b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,9 +26,11 @@ ipnetwork = {version="0.18", default-features=false} enum-primitive-derive = "0.2" num-traits = "0.1" chrono = "0.4" -bgp-models = "0.6.3" regex = "1" +# bgp-models = "0.6.3" +bgp-models = {git="https://github.com/bgpkit/bgp-models.git", branch="feature_extend_types"} + # logging log="0.4" env_logger="0.9" diff --git a/examples/parse-files-from-broker.rs b/examples/parse-files-from-broker.rs index 2cc3cac..7d90b10 100644 --- a/examples/parse-files-from-broker.rs +++ b/examples/parse-files-from-broker.rs @@ -23,7 +23,7 @@ fn main() { // iterating through the parser. the iterator returns `BgpElem` one at a time. let elems = parser.into_elem_iter().map(|elem|{ if let Some(origins) = &elem.origin_asns { - if origins.contains(&13335) { + if origins.contains(&13335.into()) { Some(elem) } else { None diff --git a/examples/real-time-routeviews-kafka-openbmp.rs b/examples/real-time-routeviews-kafka-openbmp.rs index 38d7686..fe54dae 100644 --- a/examples/real-time-routeviews-kafka-openbmp.rs +++ b/examples/real-time-routeviews-kafka-openbmp.rs @@ -42,7 +42,7 @@ fn consume_and_print(group: String, topic: String, brokers: Vec) -> Resu m.bgp_message, header.timestamp, &per_peer_header.peer_ip, - &per_peer_header.peer_asn + &per_peer_header.peer_asn.into() ) { info!("{}", elem); diff --git a/src/lib.rs b/src/lib.rs index d212167..d46bb11 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -82,7 +82,7 @@ fn main(){ // iterating through the parser. the iterator returns `BgpElem` one at a time. let elems = parser.into_elem_iter().map(|elem|{ if let Some(origins) = &elem.origin_asns { - if origins.contains(&13335) { + if origins.contains(&13335.into()) { Some(elem) } else { None diff --git a/src/parser/bgp/attributes.rs b/src/parser/bgp/attributes.rs index 53b1872..c3f9cd4 100644 --- a/src/parser/bgp/attributes.rs +++ b/src/parser/bgp/attributes.rs @@ -226,7 +226,7 @@ impl AttributeParser { COMMUNITY_NO_ADVERTISE => Community::NoAdvertise, COMMUNITY_NO_EXPORT_SUBCONFED => Community::NoExportSubConfed, value => { - let asn = (value >> 16) & 0xffff; + let asn = Asn{asn: ((value >> 16) & 0xffff) as i32, len: AsnLength::Bits16}; let value = (value & 0xffff) as u16; Community::Custom(asn, value) } @@ -432,7 +432,7 @@ impl AttributeParser { ExtendedCommunity::TransitiveTwoOctetAsSpecific( TwoOctetAsSpecific{ ec_type: ec_type_u8, ec_subtype: sub_type, - global_administrator: global as u32, + global_administrator: Asn{asn:global as i32, len: AsnLength::Bits16}, local_administrator: <[u8; 4]>::try_from(local).unwrap() } ) } @@ -443,7 +443,7 @@ impl AttributeParser { ExtendedCommunity::NonTransitiveTwoOctetAsSpecific( TwoOctetAsSpecific{ ec_type: ec_type_u8, ec_subtype: sub_type, - global_administrator: global as u32, + global_administrator: Asn{asn:global as i32, len: AsnLength::Bits16}, local_administrator: <[u8; 4]>::try_from(local).unwrap() } ) } @@ -477,7 +477,7 @@ impl AttributeParser { ExtendedCommunity::TransitiveFourOctetAsSpecific( FourOctetAsSpecific{ ec_type: ec_type_u8, ec_subtype: sub_type, - global_administrator: global, + global_administrator: Asn{asn:global as i32, len: AsnLength::Bits32}, local_administrator: <[u8; 2]>::try_from(local).unwrap() } ) } @@ -488,7 +488,7 @@ impl AttributeParser { ExtendedCommunity::NonTransitiveFourOctetAsSpecific( FourOctetAsSpecific{ ec_type: ec_type_u8, ec_subtype: sub_type, - global_administrator: global, + global_administrator: Asn{asn:global as i32, len: AsnLength::Bits32}, local_administrator: <[u8; 2]>::try_from(local).unwrap() } ) } diff --git a/src/parser/bgp/messages.rs b/src/parser/bgp/messages.rs index d53d66f..fe644b3 100644 --- a/src/parser/bgp/messages.rs +++ b/src/parser/bgp/messages.rs @@ -99,9 +99,9 @@ pub fn parse_bgp_notification_message(input: &mut T, bgp_msg_length: u6 }) } -pub fn parse_bgp_open_message(input: &mut T, ) -> Result { +pub fn parse_bgp_open_message(input: &mut T) -> Result { let version = input.read_8b()?; - let asn = input.read_16b()? as Asn; + let asn = Asn{asn: input.read_16b()? as i32, len: AsnLength::Bits16}; let hold_time = input.read_16b()?; let sender_ip = input.read_ipv4_address()?; let opt_parm_len = input.read_8b()?; diff --git a/src/parser/filter.rs b/src/parser/filter.rs index 96d5c18..ed4c751 100644 --- a/src/parser/filter.rs +++ b/src/parser/filter.rs @@ -254,8 +254,9 @@ impl Filterable for BgpElem { fn match_filter(&self, filter: &Filter) -> bool { match filter { Filter::OriginAsn(v) => { + let asn: Asn = (*v).into(); if let Some(origins) = &self.origin_asns { - origins.contains(v) + origins.contains(&asn) } else { false } diff --git a/src/parser/mrt/messages/bgp4mp.rs b/src/parser/mrt/messages/bgp4mp.rs index e1377e7..beb9a41 100644 --- a/src/parser/mrt/messages/bgp4mp.rs +++ b/src/parser/mrt/messages/bgp4mp.rs @@ -14,22 +14,22 @@ pub fn parse_bgp4mp(sub_type: u16, input: &mut T, total_size: usize) -> }; let msg: Bgp4Mp = match bgp4mp_type { Bgp4MpType::Bgp4MpStateChange => { - Bgp4Mp::Bgp4MpStateChange(parse_bgp4mp_state_change(input, AsnLength::Bits16)?) + Bgp4Mp::Bgp4MpStateChange(parse_bgp4mp_state_change(input, AsnLength::Bits16, &bgp4mp_type)?) } Bgp4MpType::Bgp4MpStateChangeAs4 => { - Bgp4Mp::Bgp4MpStateChangeAs4(parse_bgp4mp_state_change(input, AsnLength::Bits32)?) + Bgp4Mp::Bgp4MpStateChangeAs4(parse_bgp4mp_state_change(input, AsnLength::Bits32, &bgp4mp_type)?) } Bgp4MpType::Bgp4MpMessage|Bgp4MpType::Bgp4MpMessageLocal => { - Bgp4Mp::Bgp4MpMessage(parse_bgp4mp_message(input, false, AsnLength::Bits16, total_size)?) + Bgp4Mp::Bgp4MpMessage(parse_bgp4mp_message(input, false, AsnLength::Bits16, total_size, &bgp4mp_type)?) } Bgp4MpType::Bgp4MpMessageAs4 | Bgp4MpType::Bgp4MpMessageAs4Local => { - Bgp4Mp::Bgp4MpMessage(parse_bgp4mp_message(input, false, AsnLength::Bits32, total_size)?) + Bgp4Mp::Bgp4MpMessage(parse_bgp4mp_message(input, false, AsnLength::Bits32, total_size, &bgp4mp_type)?) } Bgp4MpType::Bgp4MpMessageAddpath| Bgp4MpType::Bgp4MpMessageLocalAddpath => { - Bgp4Mp::Bgp4MpMessage(parse_bgp4mp_message(input, true, AsnLength::Bits16, total_size)?) + Bgp4Mp::Bgp4MpMessage(parse_bgp4mp_message(input, true, AsnLength::Bits16, total_size, &bgp4mp_type)?) } Bgp4MpType::Bgp4MpMessageAs4Addpath | Bgp4MpType::Bgp4MpMessageLocalAs4Addpath => { - Bgp4Mp::Bgp4MpMessage(parse_bgp4mp_message(input, true, AsnLength::Bits32, total_size)?) + Bgp4Mp::Bgp4MpMessage(parse_bgp4mp_message(input, true, AsnLength::Bits32, total_size, &bgp4mp_type)?) } }; @@ -62,7 +62,7 @@ fn total_should_read(afi: &Afi, asn_len: &AsnLength, total_size: usize) -> usize | BGP Message... (variable) +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -pub fn parse_bgp4mp_message(input: &mut T, add_path: bool, asn_len: AsnLength, total_size: usize) -> Result { +pub fn parse_bgp4mp_message(input: &mut T, add_path: bool, asn_len: AsnLength, total_size: usize, msg_type: &Bgp4MpType) -> Result { let peer_asn: Asn = input.read_asn(&asn_len)?; let local_asn: Asn = input.read_asn(&asn_len)?; let interface_index: u16 = input.read_16b()?; @@ -74,6 +74,7 @@ pub fn parse_bgp4mp_message(input: &mut T, add_path: bool, asn_len: Asn let bgp_message: BgpMessage = parse_bgp_message(input,add_path, &afi, &asn_len, should_read)?; Ok(Bgp4MpMessage{ + msg_type: msg_type.clone(), peer_asn, local_asn, interface_index, @@ -115,7 +116,7 @@ pub fn parse_bgp4mp_message(input: &mut T, add_path: bool, asn_len: Asn | Old State | New State | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ -pub fn parse_bgp4mp_state_change(input: &mut T, asn_len: AsnLength) -> Result { +pub fn parse_bgp4mp_state_change(input: &mut T, asn_len: AsnLength, msg_type: &Bgp4MpType) -> Result { let peer_asn: Asn = input.read_asn(&asn_len)?; let local_asn: Asn = input.read_asn(&asn_len)?; let interface_index: u16 = input.read_16b()?; @@ -132,6 +133,7 @@ pub fn parse_bgp4mp_state_change(input: &mut T, asn_len: AsnLength) -> }; Ok( Bgp4MpStateChange{ + msg_type: msg_type.clone(), peer_asn, local_asn, interface_index, diff --git a/src/parser/mrt/messages/table_dump_v2_message.rs b/src/parser/mrt/messages/table_dump_v2_message.rs index 66f0662..9e7fd88 100644 --- a/src/parser/mrt/messages/table_dump_v2_message.rs +++ b/src/parser/mrt/messages/table_dump_v2_message.rs @@ -144,6 +144,7 @@ pub fn parse_rib_afi_entries(input: &mut Take, rib_type: Ta Ok( RibAfiEntries{ + rib_type, sequence_number, prefix, rib_entries diff --git a/src/parser/rislive/messages/mod.rs b/src/parser/rislive/messages/mod.rs index 8c3fc98..483c599 100644 --- a/src/parser/rislive/messages/mod.rs +++ b/src/parser/rislive/messages/mod.rs @@ -46,7 +46,7 @@ mod tests { raw: None, host: "host1".to_string(), msg: Some(RisMessageEnum::UPDATE { - path: Some(vec![PathSeg::Asn(1), PathSeg::AsSet(vec![1,2,3])]), + path: Some(vec![PathSeg::Asn(1.into()), PathSeg::AsSet(vec![1,2,3].into_iter().map(|v|{v.into()}).collect())]), community: None, origin: None, med: None, diff --git a/src/parser/rislive/messages/raw_bytes.rs b/src/parser/rislive/messages/raw_bytes.rs index 1b3880c..1aebc3d 100644 --- a/src/parser/rislive/messages/raw_bytes.rs +++ b/src/parser/rislive/messages/raw_bytes.rs @@ -1,7 +1,7 @@ use std::io::Cursor; use std::net::IpAddr; use std::str::FromStr; -use bgp_models::mrt::{CommonHeader, EntryType, MrtMessage, MrtRecord}; +use bgp_models::mrt::{Bgp4MpType, CommonHeader, EntryType, MrtMessage, MrtRecord}; use bgp_models::network::{Afi, Asn, AsnLength}; use serde_json::Value; use crate::{BgpElem, Elementor}; @@ -36,7 +36,7 @@ pub fn parse_raw_bytes(msg_str: &str) -> Result, ParserRisliveError let peer_asn_str =data.get("peer_asn").unwrap().as_str().unwrap().to_owned(); - let peer_asn = peer_asn_str.parse::().unwrap() as Asn; + let peer_asn = peer_asn_str.parse::().unwrap().into(); let bgp_msg = match parse_bgp_message(&mut cursor, false, &afi, &AsnLength::Bits32, 40960) { Ok(m) => {m} @@ -61,8 +61,9 @@ pub fn parse_raw_bytes(msg_str: &str) -> Result, ParserRisliveError let record = MrtRecord{ common_header: header, message: MrtMessage::Bgp4Mp( bgp_models::mrt::bgp4mp::Bgp4Mp::Bgp4MpMessage(bgp_models::mrt::bgp4mp::Bgp4MpMessage{ + msg_type: Bgp4MpType::Bgp4MpMessageAs4, peer_asn, - local_asn: 0, + local_asn: 0.into(), interface_index: 0, afi, peer_ip, diff --git a/src/parser/rislive/messages/ris_message.rs b/src/parser/rislive/messages/ris_message.rs index d3bf6ba..9e12d70 100644 --- a/src/parser/rislive/messages/ris_message.rs +++ b/src/parser/rislive/messages/ris_message.rs @@ -1,5 +1,6 @@ use bgp_models::bgp::attributes::AsPath; use bgp_models::bgp::attributes::AsPathSegment::{AsSequence, AsSet}; +use bgp_models::network::Asn; use serde::{Serialize, Deserialize}; use serde_json::Value; @@ -61,14 +62,14 @@ pub struct Announcement { #[derive(Debug, Serialize, Deserialize)] #[serde(untagged)] pub enum PathSeg { - Asn(u32), - AsSet(Vec) + Asn(Asn), + AsSet(Vec) } pub fn path_to_as_path(path: Vec) -> AsPath { let mut as_path = AsPath::new(); let mut sequence = vec![]; - let mut set: Option> = None; + let mut set: Option> = None; for node in path { match node { PathSeg::Asn(asn) => {sequence.push(asn.clone())} diff --git a/src/parser/rislive/mod.rs b/src/parser/rislive/mod.rs index 85fbdb9..68e69e1 100644 --- a/src/parser/rislive/mod.rs +++ b/src/parser/rislive/mod.rs @@ -47,7 +47,7 @@ use std::net::IpAddr; use bgp_models::bgp::community::Community; use bgp_models::bgp::attributes::Origin::{EGP, IGP, INCOMPLETE}; use bgp_models::bgp::MetaCommunity; -use bgp_models::network::NetworkPrefix; +use bgp_models::network::{Asn, NetworkPrefix}; use ipnetwork::IpNetwork; use crate::parser::ElemType; @@ -97,7 +97,7 @@ pub fn parse_ris_live_message(msg_str: &str) -> Result, ParserRisli let mut elems: Vec = vec![]; let peer_ip = unwrap_or_return!(ris_msg.peer.parse::(), msg_string); - let peer_asn = unwrap_or_return!(ris_msg.peer_asn.parse::(), msg_string); + let peer_asn: Asn = unwrap_or_return!(ris_msg.peer_asn.parse::(), msg_string).into(); // parse path let as_path = match path{ @@ -112,7 +112,7 @@ pub fn parse_ris_live_message(msg_str: &str) -> Result, ParserRisli let mut comms: Vec = vec![]; for c in cs { comms.push( - MetaCommunity::Community(Community::Custom(c.0,c.1))); + MetaCommunity::Community(Community::Custom((c.0 as i32).into(),c.1))); } Some(comms) } @@ -147,7 +147,7 @@ pub fn parse_ris_live_message(msg_str: &str) -> Result, ParserRisli if parts.len()!=2 { return Err(ParserRisliveError::ElemIncorrectAggregator(aggr_str)) } - let asn = unwrap_or_return!(parts[0].to_owned().parse::(), msg_string); + let asn = unwrap_or_return!(parts[0].to_owned().parse::(), msg_string).into(); let ip = unwrap_or_return!(parts[1].to_owned().parse::(), msg_string); (Some(asn), Some(ip)) } diff --git a/src/parser/utils.rs b/src/parser/utils.rs index 3b74dec..ed6d268 100644 --- a/src/parser/utils.rs +++ b/src/parser/utils.rs @@ -168,8 +168,24 @@ pub trait ReadUtils: io::Read { fn read_asn(&mut self, as_length: &AsnLength) -> io::Result { match as_length { - AsnLength::Bits16 => Ok(self.read_u16::()? as u32), - AsnLength::Bits32 => self.read_u32::(), + AsnLength::Bits16 => { + let asn = self.read_u16::()? as i32; + Ok( + Asn{ + asn, + len: AsnLength::Bits16 + } + ) + }, + AsnLength::Bits32 => { + let asn = self.read_u32::()? as i32; + Ok( + Asn{ + asn, + len: AsnLength::Bits32 + } + ) + }, } } @@ -178,12 +194,12 @@ pub trait ReadUtils: io::Read { match as_length { AsnLength::Bits16 => { for _ in 0..count { - path.push(self.read_u16::()? as u32); + path.push(Asn{asn: self.read_u16::()? as i32, len: *as_length}); } } AsnLength::Bits32 => { for _ in 0..count { - path.push(self.read_u32::()?); + path.push(Asn{asn: self.read_u32::()? as i32, len: *as_length}); } } }; From ac05659909a114aa0c5e4700d56edb981a1f37d5 Mon Sep 17 00:00:00 2001 From: Mingwei Zhang Date: Wed, 15 Dec 2021 17:24:47 -0800 Subject: [PATCH 2/9] re-export ReadUtils trait --- src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib.rs b/src/lib.rs index d46bb11..69a161c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -340,3 +340,4 @@ pub use parser::bmp::parse_bmp_msg; pub use parser::bmp::parse_openbmp_header; pub use parser::rislive::parse_ris_live_message; pub use parser::filter::*; +pub use parser::utils::ReadUtils; From 8c85e16690b036f2f97c71c552a3611c6aa73d87 Mon Sep 17 00:00:00 2001 From: Mingwei Zhang Date: Wed, 15 Dec 2021 22:04:13 -0800 Subject: [PATCH 3/9] update attribute to include flag --- src/parser/bgp/attributes.rs | 70 ++++++++++++------------ src/parser/mrt/mrt_elem.rs | 30 +++++----- src/parser/rislive/messages/raw_bytes.rs | 2 +- 3 files changed, 51 insertions(+), 51 deletions(-) diff --git a/src/parser/bgp/attributes.rs b/src/parser/bgp/attributes.rs index c3f9cd4..b02d786 100644 --- a/src/parser/bgp/attributes.rs +++ b/src/parser/bgp/attributes.rs @@ -95,7 +95,7 @@ impl AttributeParser { AttrType::NEXT_HOP => self.parse_next_hop(&mut attr_input, &afi), AttrType::MULTI_EXIT_DISCRIMINATOR => self.parse_med(&mut attr_input), AttrType::LOCAL_PREFERENCE => self.parse_local_pref(&mut attr_input), - AttrType::ATOMIC_AGGREGATE => Ok(Attribute::AtomicAggregate(AtomicAggregate::AG)), + AttrType::ATOMIC_AGGREGATE => Ok(AttributeValue::AtomicAggregate(AtomicAggregate::AG)), AttrType::AGGREGATOR => self.parse_aggregator(&mut attr_input, asn_len, &afi), AttrType::ORIGINATOR_ID => self.parse_originator_id(&mut attr_input, &afi), AttrType::CLUSTER_LIST => self.parse_clusters(&mut attr_input, &afi), @@ -114,7 +114,7 @@ impl AttributeParser { AttrType::DEVELOPMENT => { let mut buf=Vec::with_capacity(length as usize); attr_input.read_to_end(&mut buf)?; - Ok(Attribute::Development(buf)) + Ok(AttributeValue::Development(buf)) }, _ => { let mut buf=Vec::with_capacity(length as usize); @@ -122,9 +122,9 @@ impl AttributeParser { Err(crate::error::ParserErrorKind::Unsupported(format!("unsupported attribute type: {:?}", attr_type))) } }; - let _attr = match attr{ - Ok(v) => { - attributes.push(v); + match attr{ + Ok(value) => { + attributes.push(Attribute{value, flag }); } Err(e) => { if partial { @@ -145,23 +145,23 @@ impl AttributeParser { Ok(attributes) } - fn parse_origin(&self, input: &mut Take) -> Result { + fn parse_origin(&self, input: &mut Take) -> Result { let origin = input.read_u8()?; match Origin::from_u8(origin) { - Some(v) => Ok(Attribute::Origin(v)), + Some(v) => Ok(AttributeValue::Origin(v)), None => { return Err(crate::error::ParserErrorKind::UnknownAttr(format!("Failed to parse attribute type: origin"))) } } } - fn parse_as_path(&self, input: &mut Take, asn_len: &AsnLength) -> Result { + fn parse_as_path(&self, input: &mut Take, asn_len: &AsnLength) -> Result { let mut output = AsPath::new(); while input.limit() > 0 { let segment = self.parse_as_segment(input, asn_len)?; output.add_segment(segment); } - Ok(Attribute::AsPath(output)) + Ok(AttributeValue::AsPath(output)) } fn parse_as_segment(&self, input: &mut Take, asn_len: &AsnLength) -> Result { @@ -180,40 +180,40 @@ impl AttributeParser { } } - fn parse_next_hop(&self, input: &mut Take, afi: &Option) -> Result { + fn parse_next_hop(&self, input: &mut Take, afi: &Option) -> Result { if let Some(afi) = afi { if *afi==Afi::Ipv6{ print!("break here"); } - Ok(input.read_address(afi).map(Attribute::NextHop)?) + Ok(input.read_address(afi).map(AttributeValue::NextHop)?) } else { - Ok(input.read_address(&Afi::Ipv4).map(Attribute::NextHop)?) + Ok(input.read_address(&Afi::Ipv4).map(AttributeValue::NextHop)?) } } - fn parse_med(&self, input: &mut Take) -> Result { + fn parse_med(&self, input: &mut Take) -> Result { Ok(input .read_u32::() - .map(Attribute::MultiExitDiscriminator)?) + .map(AttributeValue::MultiExitDiscriminator)?) } - fn parse_local_pref(&self, input: &mut Take) -> Result { + fn parse_local_pref(&self, input: &mut Take) -> Result { Ok(input .read_u32::() - .map(Attribute::LocalPreference)?) + .map(AttributeValue::LocalPreference)?) } - fn parse_aggregator(&self, input: &mut Take, asn_len: &AsnLength, afi: &Option) -> Result { + fn parse_aggregator(&self, input: &mut Take, asn_len: &AsnLength, afi: &Option) -> Result { let asn = input.read_asn(asn_len)?; let afi = match afi { None => { &Afi::Ipv4 } Some(a) => {a} }; let addr = input.read_address(afi)?; - Ok(Attribute::Aggregator(asn, addr)) + Ok(AttributeValue::Aggregator(asn, addr)) } - fn parse_regular_communities(&self, input: &mut Take) -> Result { + fn parse_regular_communities(&self, input: &mut Take) -> Result { const COMMUNITY_NO_EXPORT: u32 = 0xFFFFFF01; const COMMUNITY_NO_ADVERTISE: u32 = 0xFFFFFF02; const COMMUNITY_NO_EXPORT_SUBCONFED: u32 = 0xFFFFFF03; @@ -233,29 +233,29 @@ impl AttributeParser { } ) } - Ok(Attribute::Communities(communities)) + Ok(AttributeValue::Communities(communities)) } - fn parse_originator_id(&self, input: &mut Take, afi: &Option) -> Result { + fn parse_originator_id(&self, input: &mut Take, afi: &Option) -> Result { let afi = match afi { None => { &Afi::Ipv4 } Some(a) => {a} }; let addr = input.read_address(afi)?; - Ok(Attribute::OriginatorId(addr)) + Ok(AttributeValue::OriginatorId(addr)) } #[allow(unused)] - fn parse_cluster_id(&self, input: &mut Take, afi: &Option) -> Result { + fn parse_cluster_id(&self, input: &mut Take, afi: &Option) -> Result { let afi = match afi { None => { &Afi::Ipv4 } Some(a) => {a} }; let addr = input.read_address(afi)?; - Ok(Attribute::Clusters(vec![addr])) + Ok(AttributeValue::Clusters(vec![addr])) } - fn parse_clusters(&self, input: &mut Take, afi: &Option) -> Result { + fn parse_clusters(&self, input: &mut Take, afi: &Option) -> Result { // FIXME: in https://tools.ietf.org/html/rfc4456, the CLUSTER_LIST is a set of CLUSTER_ID each represented by a 4-byte number let mut clusters = Vec::new(); while input.limit() > 0 { @@ -266,7 +266,7 @@ impl AttributeParser { let addr = input.read_address(afi)?; clusters.push(addr); } - Ok(Attribute::Clusters(clusters)) + Ok(AttributeValue::Clusters(clusters)) } /// @@ -289,7 +289,7 @@ impl AttributeParser { afi: &Option, safi: &Option, prefixes: &Option>, reachable: bool, - ) -> Result { + ) -> Result { let mut buf=Vec::with_capacity(input.limit() as usize); input.read_to_end(&mut buf)?; let first_byte_zero = buf[0]==0; @@ -358,8 +358,8 @@ impl AttributeParser { // Reserved field, should ignore match reachable { - true => Ok(Attribute::MpReachNlri(Nlri {afi,safi, next_hop, prefixes})), - false => Ok(Attribute::MpUnreachNlri(Nlri {afi,safi, next_hop, prefixes})) + true => Ok(AttributeValue::MpReachNlri(Nlri {afi,safi, next_hop, prefixes})), + false => Ok(AttributeValue::MpUnreachNlri(Nlri {afi,safi, next_hop, prefixes})) } } @@ -388,7 +388,7 @@ impl AttributeParser { fn parse_large_communities( &self, input: &mut Take, - ) -> Result { + ) -> Result { let mut communities = Vec::new(); while input.limit() > 0 { let global_administrator = input.read_u32::()?; @@ -398,13 +398,13 @@ impl AttributeParser { ]; communities.push(LargeCommunity::new(global_administrator, local_data)); } - Ok(Attribute::LargeCommunities(communities)) + Ok(AttributeValue::LargeCommunities(communities)) } fn parse_extended_community( &self, input: &mut Take, - ) -> Result { + ) -> Result { let mut communities = Vec::new(); while input.limit() > 0 { let ec_type_u8 = input.read_8b()?; @@ -514,13 +514,13 @@ impl AttributeParser { communities.push(ec); } - Ok(Attribute::ExtendedCommunities(communities)) + Ok(AttributeValue::ExtendedCommunities(communities)) } fn parse_ipv6_extended_community( &self, input: &mut Take, - ) -> Result { + ) -> Result { let mut communities = Vec::new(); while input.limit() > 0 { let ec_type_u8 = input.read_8b()?; @@ -537,7 +537,7 @@ impl AttributeParser { ); communities.push(ec); } - Ok(Attribute::ExtendedCommunities(communities)) + Ok(AttributeValue::ExtendedCommunities(communities)) } } diff --git a/src/parser/mrt/mrt_elem.rs b/src/parser/mrt/mrt_elem.rs index bfc21cd..cbb2616 100644 --- a/src/parser/mrt/mrt_elem.rs +++ b/src/parser/mrt/mrt_elem.rs @@ -56,21 +56,21 @@ fn get_relevant_attributes( let mut communities_vec: Vec = vec![]; for attr in attributes { - match attr { - Attribute::Origin(v) => {origin = Some(v)} - Attribute::AsPath(v) => {as_path = Some(v)} - Attribute::As4Path(v) => {as4_path = Some(v)} - Attribute::NextHop(v) => {next_hop = Some(v)} - Attribute::MultiExitDiscriminator(v) => {med = Some(v)} - Attribute::LocalPreference(v) => {local_pref = Some(v)} - Attribute::AtomicAggregate(v) => {atomic = Some(v)} - Attribute::Communities(v) => {communities_vec.extend(v.into_iter().map(|x| MetaCommunity::Community(x)).collect::>())} - Attribute::ExtendedCommunities(v) => {communities_vec.extend(v.into_iter().map(|x| MetaCommunity::ExtendedCommunity(x)).collect::>())} - Attribute::LargeCommunities(v) => {communities_vec.extend(v.into_iter().map(|x| MetaCommunity::LargeCommunity(x)).collect::>())} - Attribute::Aggregator(v, v2) => {aggregator = Some((v,v2))} - Attribute::MpReachNlri(nlri) => {announced = Some(nlri)} - Attribute::MpUnreachNlri(nlri) => {withdrawn = Some(nlri)} - Attribute::OriginatorId(_) | Attribute::Clusters(_)| Attribute::Development(_) => {} + match attr.value { + AttributeValue::Origin(v) => {origin = Some(v)} + AttributeValue::AsPath(v) => {as_path = Some(v)} + AttributeValue::As4Path(v) => {as4_path = Some(v)} + AttributeValue::NextHop(v) => {next_hop = Some(v)} + AttributeValue::MultiExitDiscriminator(v) => {med = Some(v)} + AttributeValue::LocalPreference(v) => {local_pref = Some(v)} + AttributeValue::AtomicAggregate(v) => {atomic = Some(v)} + AttributeValue::Communities(v) => {communities_vec.extend(v.into_iter().map(|x| MetaCommunity::Community(x)).collect::>())} + AttributeValue::ExtendedCommunities(v) => {communities_vec.extend(v.into_iter().map(|x| MetaCommunity::ExtendedCommunity(x)).collect::>())} + AttributeValue::LargeCommunities(v) => {communities_vec.extend(v.into_iter().map(|x| MetaCommunity::LargeCommunity(x)).collect::>())} + AttributeValue::Aggregator(v, v2) => {aggregator = Some((v,v2))} + AttributeValue::MpReachNlri(nlri) => {announced = Some(nlri)} + AttributeValue::MpUnreachNlri(nlri) => {withdrawn = Some(nlri)} + AttributeValue::OriginatorId(_) | AttributeValue::Clusters(_)| AttributeValue::Development(_) => {} }; } diff --git a/src/parser/rislive/messages/raw_bytes.rs b/src/parser/rislive/messages/raw_bytes.rs index 1aebc3d..fe77501 100644 --- a/src/parser/rislive/messages/raw_bytes.rs +++ b/src/parser/rislive/messages/raw_bytes.rs @@ -2,7 +2,7 @@ use std::io::Cursor; use std::net::IpAddr; use std::str::FromStr; use bgp_models::mrt::{Bgp4MpType, CommonHeader, EntryType, MrtMessage, MrtRecord}; -use bgp_models::network::{Afi, Asn, AsnLength}; +use bgp_models::network::{Afi, AsnLength}; use serde_json::Value; use crate::{BgpElem, Elementor}; use crate::parser::bgp::parse_bgp_message; From e0bcd5c3b723604c03b8a7ca63cf55b90925431b Mon Sep 17 00:00:00 2001 From: Mingwei Zhang Date: Wed, 15 Dec 2021 22:08:30 -0800 Subject: [PATCH 4/9] add attr_type to attribute --- src/parser/bgp/attributes.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parser/bgp/attributes.rs b/src/parser/bgp/attributes.rs index b02d786..3d8fb91 100644 --- a/src/parser/bgp/attributes.rs +++ b/src/parser/bgp/attributes.rs @@ -124,7 +124,7 @@ impl AttributeParser { }; match attr{ Ok(value) => { - attributes.push(Attribute{value, flag }); + attributes.push(Attribute{value, flag, attr_type}); } Err(e) => { if partial { From 402767ffd7f040ac7ce931f12eabcb0e3114f78c Mon Sep 17 00:00:00 2001 From: Mingwei Zhang Date: Thu, 16 Dec 2021 07:32:23 -0800 Subject: [PATCH 5/9] fix ris-live after Asn refactor --- src/parser/bgp/attributes.rs | 3 --- src/parser/rislive/messages/ris_message.rs | 10 ++++++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/parser/bgp/attributes.rs b/src/parser/bgp/attributes.rs index 3d8fb91..e9f880e 100644 --- a/src/parser/bgp/attributes.rs +++ b/src/parser/bgp/attributes.rs @@ -182,9 +182,6 @@ impl AttributeParser { fn parse_next_hop(&self, input: &mut Take, afi: &Option) -> Result { if let Some(afi) = afi { - if *afi==Afi::Ipv6{ - print!("break here"); - } Ok(input.read_address(afi).map(AttributeValue::NextHop)?) } else { Ok(input.read_address(&Afi::Ipv4).map(AttributeValue::NextHop)?) diff --git a/src/parser/rislive/messages/ris_message.rs b/src/parser/rislive/messages/ris_message.rs index 9e12d70..ac37ea8 100644 --- a/src/parser/rislive/messages/ris_message.rs +++ b/src/parser/rislive/messages/ris_message.rs @@ -62,8 +62,8 @@ pub struct Announcement { #[derive(Debug, Serialize, Deserialize)] #[serde(untagged)] pub enum PathSeg { - Asn(Asn), - AsSet(Vec) + Asn(u32), + AsSet(Vec) } pub fn path_to_as_path(path: Vec) -> AsPath { @@ -72,8 +72,10 @@ pub fn path_to_as_path(path: Vec) -> AsPath { let mut set: Option> = None; for node in path { match node { - PathSeg::Asn(asn) => {sequence.push(asn.clone())} - PathSeg::AsSet(s) => {set = Some(s.clone())} + PathSeg::Asn(asn) => {sequence.push(asn.into())} + PathSeg::AsSet(s) => {set = Some( + s.into_iter().map(|i| i.into()).collect::>() + )} } } as_path.segments.push(AsSequence(sequence)); From b259c79b5e9ae6d88aba68913eaddc026ad73935 Mon Sep 17 00:00:00 2001 From: Mingwei Zhang Date: Sat, 18 Dec 2021 08:04:23 -0800 Subject: [PATCH 6/9] export MRT record parsing function --- src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib.rs b/src/lib.rs index 69a161c..27b96a9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -339,5 +339,6 @@ pub use parser::bmp::parse_openbmp_msg; pub use parser::bmp::parse_bmp_msg; pub use parser::bmp::parse_openbmp_header; pub use parser::rislive::parse_ris_live_message; +pub use parser::mrt::parse_mrt_record; pub use parser::filter::*; pub use parser::utils::ReadUtils; From 395577e80fca556c6b5314ba58a41be8a31e3cc4 Mon Sep 17 00:00:00 2001 From: Mingwei Zhang Date: Sat, 18 Dec 2021 08:09:50 -0800 Subject: [PATCH 7/9] export other parsing functions --- src/parser/mrt/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/parser/mrt/mod.rs b/src/parser/mrt/mod.rs index 9594f90..017dc45 100644 --- a/src/parser/mrt/mod.rs +++ b/src/parser/mrt/mod.rs @@ -5,7 +5,7 @@ pub mod mrt_record; pub mod mrt_elem; pub mod messages; -pub(crate) use mrt_record::parse_mrt_record; -pub(crate) use messages::bgp4mp::parse_bgp4mp; -pub(crate) use messages::table_dump_message::parse_table_dump_message; -pub(crate) use messages::table_dump_v2_message::parse_table_dump_v2_message; +pub use mrt_record::parse_mrt_record; +pub use messages::bgp4mp::parse_bgp4mp; +pub use messages::table_dump_message::parse_table_dump_message; +pub use messages::table_dump_v2_message::parse_table_dump_v2_message; From d4a0f8bd72188456c91abf2e7f16f1fa0ffe4dab Mon Sep 17 00:00:00 2001 From: Mingwei Zhang Date: Sat, 18 Dec 2021 20:55:48 -0800 Subject: [PATCH 8/9] bump version to 0.7.0-alpha.1 --- Cargo.toml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e2e36b1..7117714 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bgpkit-parser" -version = "0.6.0" +version = "0.7.0-alpha.1" authors = ["Mingwei Zhang "] edition = "2018" readme = "README.md" @@ -28,8 +28,7 @@ num-traits = "0.1" chrono = "0.4" regex = "1" -# bgp-models = "0.6.3" -bgp-models = {git="https://github.com/bgpkit/bgp-models.git", branch="feature_extend_types"} +bgp-models = "0.7.0-alpha.1" # logging log="0.4" From ac1e88aba1b0110753c85f2b823fd60818e575cb Mon Sep 17 00:00:00 2001 From: Mingwei Zhang Date: Sat, 18 Dec 2021 20:57:33 -0800 Subject: [PATCH 9/9] bump to alpha2 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 7117714..00ed99d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bgpkit-parser" -version = "0.7.0-alpha.1" +version = "0.7.0-alpha.2" authors = ["Mingwei Zhang "] edition = "2018" readme = "README.md"