summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSunil Nimmagadda <sunil@nimmagadda.net>2025-07-02 00:09:19 +0530
committerSunil Nimmagadda <sunil@nimmagadda.net>2025-07-02 00:09:19 +0530
commit03add15bd1fdcbdfc062c4b1739fb7a25fd61d86 (patch)
treefd79241f2f15a7d21c75161a2ea3e40cdd29ed2e
parent2c440c9f176da6e8e80ced0bf68279f14f5d2e0f (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.rs18
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);