diff -r a46fd16cc293 -r 61c484b134c8 src/vrrpv2.rs --- a/src/vrrpv2.rs Thu Jan 05 16:03:05 2023 +0530 +++ b/src/vrrpv2.rs Sat Jan 07 21:11:43 2023 +0530 @@ -77,34 +77,7 @@ })(input) } -// Nightly has a nicer array_chunks API to express it more succinctly. -// let mut chunks = bytes.array_chunks(2); -// let mut sum = chunks.map(u16::from_ne_bytes).map(|b| b as u32).sum::(); -// // handle the remainder -// if let Some([b]) = chunks.remainder() { -// sum += *b as u32 -// } - -// Shadowing can be used to avoid `mut`... -// let sum =...; -// let sum = (sum & 0xffff) + (sum >> 16); -// let sum = (sum & 0xffff) + (sum >> 16); -// manually un-rolling while loop since it's needed atmost twice for an u32. -fn validate_checksum(bytes: &[u8]) -> bool { - let mut sum: u32 = bytes.chunks(2).fold(0, |acc: u32, x| { - acc + u32::from(u16::from_ne_bytes(x.try_into().unwrap())) - }); - while (sum >> 16) > 0 { - sum = (sum & 0xffff) + (sum >> 16); - } - let checksum = !(sum as u16); - checksum == 0 -} - fn parse(input: &[u8]) -> IResult<&[u8], VRRPv2> { - if !validate_checksum(input) { - return Err(Err::Error(Error::new(input, ErrorKind::Alt))); - } let (input, (version, type_)) = parse_version_type(input)?; let (input, virtual_router_id) = u8(input)?; let (input, priority) = u8(input)?; @@ -130,7 +103,34 @@ )) } +// Nightly has a nicer array_chunks API to express it more succinctly. +// let mut chunks = bytes.array_chunks(2); +// let mut sum = chunks.map(u16::from_ne_bytes).map(|b| b as u32).sum::(); +// // handle the remainder +// if let Some([b]) = chunks.remainder() { +// sum += *b as u32 +// } + +// Shadowing can be used to avoid `mut`... +// let sum =...; +// let sum = (sum & 0xffff) + (sum >> 16); +// let sum = (sum & 0xffff) + (sum >> 16); +// manually un-rolling while loop since it's needed atmost twice for an u32. +fn validate_checksum(bytes: &[u8]) -> bool { + let mut sum: u32 = bytes.chunks(2).fold(0, |acc: u32, x| { + acc + u32::from(u16::from_ne_bytes(x.try_into().unwrap())) + }); + while (sum >> 16) > 0 { + sum = (sum & 0xffff) + (sum >> 16); + } + let checksum = !(sum as u16); + checksum == 0 +} + pub fn from_bytes(bytes: &[u8]) -> Result { + if !validate_checksum(bytes) { + return Err(VRRPv2Error::VRRPv2ParseError); + } match parse(bytes) { Ok((_, v)) => Ok(v), Err(e) => Err(e.into()),