diff -r bde5cce81a8a -r aef7eb135a0c src/vrrpv2.rs --- a/src/vrrpv2.rs Sun Jan 01 12:00:44 2023 +0530 +++ b/src/vrrpv2.rs Tue Jan 03 20:35:05 2023 +0530 @@ -77,7 +77,21 @@ })(input) } +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)?; @@ -85,7 +99,6 @@ let (input, auth_type) = parse_auth_type(input)?; let (input, advertisement_interval) = u8(input)?; let (input, checksum) = be_u16(input)?; - // TODO verify checksum let (input, xs) = count(be_u32, usize::from(count_ip_addrs))(input)?; let ip_addrs = xs.into_iter().map(Ipv4Addr::from).collect(); Ok(( @@ -164,5 +177,11 @@ #[test] fn test_invalid_checksum() { - panic!("fix me"); + let bytes = [ + 0x21, 0x01, 0x64, 0x01, 0x00, 0x01, 0xbb, 0x52, 0xc0, 0xa8, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]; + let got = from_bytes(&bytes); + assert_eq!(got.is_err(), true); + assert_eq!(got.err(), Some(VRRPv2Error::VRRPv2ParseError)); }