use std::fmt;
use std::io::{Error, ErrorKind, Read};
use byteorder::{BigEndian, ReadBytesExt};
pub struct MRTReader<T> where T: Read
{
pub stream: T
}
pub struct MRTHeader
{
timestamp: u32,
record_type: u16,
sub_type: u16,
length: u32
}
impl fmt::Display for MRTHeader
{
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result
{
write!(formatter, "(Timestamp: {}, Type: {}, Subtype: {}, Length: {})",
self.timestamp,
self.record_type,
self.sub_type,
self.length)
}
}
#[allow(non_camel_case_types)]
pub enum Record
{
OSPFv2,
TABLE_DUMP,
TABLE_DUMP_V2,
BGP4MP,
BGP4MP_ET,
ISIS,
ISIS_ET,
OSPFv3,
OSPFv3_ET
}
impl<T> MRTReader<T> where T: ReadBytesExt
{
pub fn read(&mut self) -> Result<Record, Error>
{
let header = MRTHeader
{
timestamp: self.stream.read_u32::<BigEndian>()?,
record_type: self.stream.read_u16::<BigEndian>()?,
sub_type: self.stream.read_u16::<BigEndian>()?,
length: self.stream.read_u32::<BigEndian>()?
};
println!("{}", header);
match header.record_type
{
11 => Ok(Record::OSPFv2),
12 => Ok(Record::TABLE_DUMP),
13 => Ok(Record::TABLE_DUMP_V2),
16 => Ok(Record::BGP4MP),
17 => Ok(Record::BGP4MP_ET),
32 => Ok(Record::ISIS),
33 => Ok(Record::ISIS_ET),
48 => Ok(Record::OSPFv3),
49 => Ok(Record::OSPFv3_ET),
_ => Err(Error::new(ErrorKind::Other, "Unknown MRT record type found in MRTHeader"))
}
}
}