use crate::error::*;
use std::net::IpAddr;
use bgp_models::mrt::tabledump::TableDumpMessage;
use bgp_models::network::{AddrMeta, Afi, AsnLength, NetworkPrefix};
use crate::parser::bgp::attributes::AttributeParser;
use crate::parser::DataBytes;
fn parse_sub_type(sub_type: u16) -> Result<AddrMeta, ParserError> {
let asn_len = AsnLength::Bits16;
let afi = match sub_type {
1 => Afi::Ipv4,
2 => Afi::Ipv6,
_ => {
return Err(ParserError::ParseError(format!(
"Invalid subtype found for TABLE_DUMP (V1) message: {}",
sub_type
)))
}
};
Ok(AddrMeta { afi, asn_len })
}
pub fn parse_table_dump_message(
sub_type: u16,
input: &mut DataBytes,
) -> Result<TableDumpMessage, ParserError> {
let meta = parse_sub_type(sub_type)?;
let view_number = input.read_16b()?;
let sequence_number = input.read_16b()?;
let prefix = match meta.afi {
Afi::Ipv4 => input.read_ipv4_prefix().map(ipnet::IpNet::V4),
Afi::Ipv6 => input.read_ipv6_prefix().map(ipnet::IpNet::V6),
}?;
let status = input.read_8b()?;
let time = input.read_32b()? as u64;
let peer_address: IpAddr = input.read_address(&meta.afi)?;
let peer_asn = input.read_asn(&meta.asn_len)?;
let attribute_length = input.read_16b()? as usize;
let attr_parser = AttributeParser::new(false);
let attributes = attr_parser.parse_attributes(input, &meta.asn_len, None, None, None, attribute_length)?;
Ok(TableDumpMessage {
view_number,
sequence_number,
prefix: NetworkPrefix::new(prefix, 0),
status,
originated_time: time,
peer_address,
peer_asn,
attributes,
})
}