mrt_rs/records/ospf.rs
1use byteorder::{BigEndian, ReadBytesExt};
2use std::io::{Error, Read};
3use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
4
5use crate::Header;
6use crate::AFI;
7
8/// The OSPFv2 struct represents the data contained in an MRT record type of OSPFv2.
9#[derive(Debug)]
10pub struct OSPFv2 {
11 /// The IPv4 address from which this message was received.
12 pub remote: Ipv4Addr,
13
14 /// The IPv4 address of the interface on which this message was received.
15 pub local: Ipv4Addr,
16
17 /// The binary OSPFv2 message.
18 pub message: Vec<u8>,
19}
20
21impl OSPFv2 {
22 ///
23 /// # Summary
24 /// Used to parse OSPFv2 MRT records.
25 ///
26 /// # Panics
27 /// This function does not panic.
28 ///
29 /// # Errors
30 /// Any IO error will be returned while reading from the stream.
31 /// If an ill-formatted stream or header is provided behavior will be undefined.
32 ///
33 /// # Safety
34 /// This function does not make use of unsafe code.
35 ///
36 pub fn parse(header: &Header, mut stream: impl Read) -> Result<OSPFv2, Error> {
37 // The fixed size of the header consisting of two IPv4 addresses.
38 let length = (header.length - 2 * AFI::IPV4.size()) as usize;
39 let mut record = OSPFv2 {
40 remote: Ipv4Addr::from(stream.read_u32::<BigEndian>()?),
41 local: Ipv4Addr::from(stream.read_u32::<BigEndian>()?),
42 message: vec![0; length as usize],
43 };
44
45 // Fill the entire buffer.
46 stream.read_exact(&mut record.message)?;
47 Ok(record)
48 }
49}
50
51/// The OSPFv3 struct represents the data contained in an MRT record type of OSPFv3 and OSPFv3_ET.
52#[derive(Debug)]
53pub struct OSPFv3 {
54 /// The IP address of the router from which this message was received.
55 pub remote: IpAddr,
56
57 /// The IP address of the interface at which this message was received.
58 pub local: IpAddr,
59
60 /// The message that has been received.
61 pub message: Vec<u8>,
62}
63
64impl OSPFv3 {
65 ///
66 /// # Summary
67 /// Used to parse OSPFv3 MRT records.
68 ///
69 /// # Panics
70 /// This function does not panic.
71 ///
72 /// # Errors
73 /// Any IO error will be returned while reading from the stream.
74 /// If an ill-formatted stream or header is provided behavior will be undefined.
75 ///
76 /// # Safety
77 /// This function does not make use of unsafe code.
78 ///
79 pub fn parse(header: &Header, mut stream: impl Read) -> Result<OSPFv3, Error> {
80 let mut record = match AFI::from(stream.read_u16::<BigEndian>()?)? {
81 AFI::IPV4 => {
82 let length = (header.length - 2 * AFI::IPV4.size()) as usize;
83 OSPFv3 {
84 remote: IpAddr::V4(Ipv4Addr::from(stream.read_u32::<BigEndian>()?)),
85 local: IpAddr::V4(Ipv4Addr::from(stream.read_u32::<BigEndian>()?)),
86 message: vec![0; length as usize],
87 }
88 }
89 AFI::IPV6 => {
90 let length: usize = (header.length - 2 * AFI::IPV6.size()) as usize;
91 OSPFv3 {
92 remote: IpAddr::V6(Ipv6Addr::from(stream.read_u128::<BigEndian>()?)),
93 local: IpAddr::V6(Ipv6Addr::from(stream.read_u128::<BigEndian>()?)),
94 message: vec![0; length as usize],
95 }
96 }
97 };
98
99 // Fill the entire buffer.
100 stream.read_exact(&mut record.message)?;
101 Ok(record)
102 }
103}