diff options
author | Sunil Nimmagadda <sunil@nimmagadda.net> | 2025-07-02 00:09:19 +0530 |
---|---|---|
committer | Sunil Nimmagadda <sunil@nimmagadda.net> | 2025-07-02 00:09:19 +0530 |
commit | 03add15bd1fdcbdfc062c4b1739fb7a25fd61d86 (patch) | |
tree | fd79241f2f15a7d21c75161a2ea3e40cdd29ed2e | |
parent | 2c440c9f176da6e8e80ced0bf68279f14f5d2e0f (diff) |
Check for expected packet size.
Error out with InvalidPacketSize if the bytes supplied are short of
the expected size instead of generic ParseError.
-rw-r--r-- | src/vrrpv2.rs | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/src/vrrpv2.rs b/src/vrrpv2.rs index 4e53b20..0845eee 100644 --- a/src/vrrpv2.rs +++ b/src/vrrpv2.rs @@ -29,6 +29,7 @@ use std::net::Ipv4Addr; const VERSION: u8 = 2; const TYPE: u8 = 1; const VERSION_TYPE: u8 = (VERSION << 4) | TYPE; // 0x21 +const MIN_PACKET_SIZE: usize = 16; #[derive(Debug, PartialEq)] pub struct VRRPv2 { @@ -45,6 +46,7 @@ pub enum VRRPv2Error { InvalidAuthType, InvalidChecksum, InvalidIPCount, + InvalidPacketSize, InvalidTTL, InvalidType, InvalidVersion, @@ -57,6 +59,7 @@ impl std::fmt::Display for VRRPv2Error { Self::InvalidAuthType => write!(f, "Invalid Auth Type"), Self::InvalidChecksum => write!(f, "Invalid Checksum"), Self::InvalidIPCount => write!(f, "Invalid IP Count"), + Self::InvalidPacketSize => write!(f, "Invalid Packet Size"), Self::InvalidTTL => write!(f, "Invalid TTL"), Self::InvalidType => write!(f, "Invalid Type"), Self::InvalidVersion => write!(f, "Invalid Version"), @@ -108,7 +111,7 @@ impl<T: AsRef<[u8]>> BytesReader for Cursor<T> { impl VRRPv2 { pub fn to_bytes(&self) -> Result<Vec<u8>, std::io::Error> { - let sz = 16 + (self.ip_addrs.len() * 4); + let sz = MIN_PACKET_SIZE + (self.ip_addrs.len() * 4); let bytes: Vec<u8> = Vec::with_capacity(sz); let mut wr = Cursor::new(bytes); wr.write_all( @@ -149,6 +152,11 @@ fn parse(bytes: &[u8]) -> Result<VRRPv2, VRRPv2Error> { if count_ip_addrs == 0 { return Err(VRRPv2Error::InvalidIPCount); } + let expected_size = MIN_PACKET_SIZE + (count_ip_addrs as usize * 4); + if bytes.len() < expected_size { + return Err(VRRPv2Error::InvalidPacketSize); + } + let auth_type = rdr.read_u8()?; let auth_type = match auth_type { 0 => AuthType::NoAuth, @@ -273,6 +281,14 @@ fn test_invalid_ipcount() { } #[test] +fn test_invalid_packetsize() { + let bytes = [ + 0x21, 0x01, 0x64, 0x04, 0x00, 0x01, 0xba, 0x52, 0xc0, 0xa8, 0x00, 0x01, + ]; + assert_eq!(from_bytes(&bytes), Err(VRRPv2Error::InvalidPacketSize)); +} + +#[test] fn test_checksum() { let bytes = [0x00, 0x01, 0xf2, 0x03, 0xf4, 0xf5, 0xf6, 0xf7]; assert_eq!(checksum(&bytes), 0x220d); |