diff options
Diffstat (limited to 'src/vrrpv2.rs')
-rw-r--r-- | src/vrrpv2.rs | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/src/vrrpv2.rs b/src/vrrpv2.rs index c3d5715..9a08801 100644 --- a/src/vrrpv2.rs +++ b/src/vrrpv2.rs @@ -1,5 +1,5 @@ -use std::io::Read; use std::io::{self, Cursor}; +use std::io::{Read, Write}; use std::net::Ipv4Addr; /// A VRRP version 2 packet. @@ -64,7 +64,7 @@ impl From<std::io::Error> for VRRPv2Error { } } -#[derive(Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum VRRPv2AuthType { VRRPv2AuthNoAuth = 0x00, VRRPv2AuthReserved1 = 0x01, @@ -97,6 +97,31 @@ impl<T: AsRef<[u8]>> BytesReader for Cursor<T> { } } +impl VRRPv2 { + pub fn to_bytes(&self) -> Result<Vec<u8>, std::io::Error> { + let sz = (4 + self.count_ip_addrs) * 4; + let bytes: Vec<u8> = Vec::with_capacity(sz.into()); + let mut wr = Cursor::new(bytes); + wr.write( + [ + 0x21, + self.virtual_router_id, + self.priority, + self.count_ip_addrs, + ] + .as_ref(), + )?; + wr.write([self.auth_type as u8, self.advertisement_interval].as_ref())?; + wr.write(self.checksum.to_be_bytes().as_ref())?; + for ip in self.ip_addrs.iter() { + wr.write(&ip.to_bits().to_be_bytes())?; + } + wr.write([0; 4].as_ref())?; // Authentication Data 1 + wr.write([0; 4].as_ref())?; // Authentication Data 2 + Ok(wr.into_inner()) + } +} + fn parse(bytes: &[u8]) -> Result<VRRPv2, VRRPv2Error> { let mut rdr = Cursor::new(bytes); let vertype = rdr.read_u8()?; @@ -246,3 +271,14 @@ fn test_checksum_another() { let bytes = [0xe3, 0x4f, 0x23, 0x96, 0x44, 0x27, 0x99, 0xf3]; assert_eq!(checksum(&bytes), 0x1aff); } + +#[test] +fn test_to_bytes() { + let in_bytes = [ + 0x21, 0x01, 0x64, 0x01, 0x00, 0x01, 0xba, 0x52, 0xc0, 0xa8, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + ]; + let vrrpv2 = from_bytes(&in_bytes).expect("parsing failed"); + let out_bytes = vrrpv2.to_bytes().expect("conversion failed"); + assert_eq!(in_bytes.as_ref(), out_bytes); +} |