54 VRRPv2AuthNoAuth = 0x00, |
49 VRRPv2AuthNoAuth = 0x00, |
55 VRRPv2AuthReserved1 = 0x01, |
50 VRRPv2AuthReserved1 = 0x01, |
56 VRRPv2AuthReserved2 = 0x02, |
51 VRRPv2AuthReserved2 = 0x02, |
57 } |
52 } |
58 |
53 |
59 /// Helper function to let compiler infer generic parameters. |
54 trait ByteReader { |
60 fn take_nibble(input: BitInput) -> IResult<BitInput, u8> { |
55 fn read_u8(&mut self) -> io::Result<u8>; |
61 take(4usize)(input) |
56 fn read_u16(&mut self) -> io::Result<u16>; |
62 } |
57 fn read_u32(&mut self) -> io::Result<u32>; |
63 |
58 } |
64 fn parse(input: &[u8]) -> Result<VRRPv2, VRRPv2Error> { |
59 |
65 let Ok(((input, _), version)) = take_nibble((input, 0)) else { |
60 impl<T: AsRef<[u8]>> ByteReader for Cursor<T> { |
66 return Err(VRRPv2Error::ParseError); |
61 fn read_u8(&mut self) -> io::Result<u8> { |
67 }; |
62 let mut buffer = [0; 1]; |
68 if version != 2 { |
63 self.read_exact(&mut buffer)?; |
|
64 Ok(u8::from_be_bytes(buffer)) |
|
65 } |
|
66 |
|
67 fn read_u16(&mut self) -> io::Result<u16> { |
|
68 let mut buffer = [0; 2]; |
|
69 self.read_exact(&mut buffer)?; |
|
70 Ok(u16::from_be_bytes(buffer)) |
|
71 } |
|
72 |
|
73 fn read_u32(&mut self) -> io::Result<u32> { |
|
74 let mut buffer = [0; 4]; |
|
75 self.read_exact(&mut buffer)?; |
|
76 Ok(u32::from_be_bytes(buffer)) |
|
77 } |
|
78 } |
|
79 |
|
80 fn parse(bytes: &[u8]) -> Result<VRRPv2, VRRPv2Error> { |
|
81 let mut rdr = Cursor::new(bytes); |
|
82 let Ok(vertype) = rdr.read_u8() else { |
|
83 return Err(VRRPv2Error::ParseError); |
|
84 }; |
|
85 if (vertype & 0xF) != 1 { |
69 return Err(VRRPv2Error::InvalidVersion); |
86 return Err(VRRPv2Error::InvalidVersion); |
70 } |
87 } |
71 let Ok(((input, _), type_)) = take_nibble((input, 4)) else { |
88 if (vertype >> 4) != 2 { |
72 return Err(VRRPv2Error::ParseError); |
|
73 }; |
|
74 //Advertisement |
|
75 if type_ != 1 { |
|
76 return Err(VRRPv2Error::InvalidType); |
89 return Err(VRRPv2Error::InvalidType); |
77 } |
90 } |
78 let Ok((input, virtual_router_id)) = u8::<&[u8], Error<&[u8]>>(input) else { |
91 let Ok(virtual_router_id) = rdr.read_u8() else { |
79 return Err(VRRPv2Error::ParseError); |
92 return Err(VRRPv2Error::ParseError); |
80 }; |
93 }; |
81 let Ok((input, priority)) = u8::<&[u8], Error<&[u8]>>(input) else { |
94 let Ok(priority) = rdr.read_u8() else { |
82 return Err(VRRPv2Error::ParseError); |
95 return Err(VRRPv2Error::ParseError); |
83 }; |
96 }; |
84 let Ok((input, count_ip_addrs)) = u8::<&[u8], Error<&[u8]>>(input) else { |
97 let Ok(count_ip_addrs) = rdr.read_u8() else { |
85 return Err(VRRPv2Error::ParseError); |
98 return Err(VRRPv2Error::ParseError); |
86 }; |
99 }; |
87 let Ok((input, auth_type)) = u8::<&[u8], Error<&[u8]>>(input) else { |
100 let Ok(auth_type) = rdr.read_u8() else { |
88 return Err(VRRPv2Error::ParseError); |
101 return Err(VRRPv2Error::ParseError); |
89 }; |
102 }; |
90 let auth_type = match auth_type { |
103 let auth_type = match auth_type { |
91 0 => VRRPv2AuthType::VRRPv2AuthNoAuth, |
104 0 => VRRPv2AuthType::VRRPv2AuthNoAuth, |
92 1 => VRRPv2AuthType::VRRPv2AuthReserved1, |
105 1 => VRRPv2AuthType::VRRPv2AuthReserved1, |
93 2 => VRRPv2AuthType::VRRPv2AuthReserved2, |
106 2 => VRRPv2AuthType::VRRPv2AuthReserved2, |
94 _ => return Err(VRRPv2Error::InvalidAuthType), |
107 _ => return Err(VRRPv2Error::InvalidAuthType), |
95 }; |
108 }; |
96 let Ok((input, advertisement_interval)) = u8::<&[u8], Error<&[u8]>>(input) else { |
109 let Ok(advertisement_interval) = rdr.read_u8() else { |
97 return Err(VRRPv2Error::ParseError); |
110 return Err(VRRPv2Error::ParseError); |
98 }; |
111 }; |
99 let Ok((input, checksum)) = be_u16::<&[u8], Error<&[u8]>>(input) else { |
112 let Ok(checksum) = rdr.read_u16() else { |
100 return Err(VRRPv2Error::ParseError); |
113 return Err(VRRPv2Error::ParseError); |
101 }; |
114 }; |
102 let Ok((_, xs)) = count(be_u32::<&[u8], Error<&[u8]>>, usize::from(count_ip_addrs))(input) |
115 let mut ip_addrs = Vec::new(); |
103 else { |
116 for _i in 0..count_ip_addrs { |
104 return Err(VRRPv2Error::ParseError); |
117 let Ok(b) = rdr.read_u32() else { |
105 }; |
118 return Err(VRRPv2Error::ParseError); |
106 let ip_addrs: Vec<Ipv4Addr> = xs.into_iter().map(Ipv4Addr::from).collect(); |
119 }; |
|
120 ip_addrs.push(Ipv4Addr::from(b)); |
|
121 } |
107 Ok(VRRPv2 { |
122 Ok(VRRPv2 { |
108 virtual_router_id, |
123 virtual_router_id, |
109 priority, |
124 priority, |
110 count_ip_addrs, |
125 count_ip_addrs, |
111 auth_type, |
126 auth_type, |
164 return Err(VRRPv2Error::InvalidChecksum); |
161 return Err(VRRPv2Error::InvalidChecksum); |
165 } |
162 } |
166 Ok(vrrpv2) |
163 Ok(vrrpv2) |
167 } |
164 } |
168 |
165 |
|
166 fn checksum(bytes: &[u8]) -> u16 { |
|
167 let mut sum: u32 = 0; |
|
168 for chunk in bytes.chunks(2) { |
|
169 // Left over byte if any |
|
170 if chunk.len() == 1 { |
|
171 sum += u32::from(chunk[0]); |
|
172 } else { |
|
173 sum += u32::from(u16::from_be_bytes(chunk.try_into().unwrap())); |
|
174 } |
|
175 } |
|
176 while (sum >> 16) > 0 { |
|
177 sum = (sum & 0xffff) + (sum >> 16); |
|
178 } |
|
179 !(sum as u16) |
|
180 } |
|
181 |
169 #[test] |
182 #[test] |
170 fn test_incomplete_bytes() { |
183 fn test_incomplete_bytes() { |
171 let bytes = [0x21, 0x01]; |
184 let bytes = [0x21, 0x01]; |
172 assert_eq!(from_bytes(&bytes), Err(VRRPv2Error::ParseError)); |
185 assert_eq!(from_bytes(&bytes), Err(VRRPv2Error::ParseError)); |
173 } |
186 } |
174 |
187 |
175 #[test] |
188 #[test] |
176 fn test_invalid_version() { |
189 fn test_invalid_version() { |
177 let bytes = [ |
190 let bytes = [ |
|
191 0x20, 0x1, 0x2a, 0x0, 0x0, 0x1, 0xb5, 0xfd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
|
192 0x0, 0x0, 0x0, |
|
193 ]; |
|
194 assert_eq!(from_bytes(&bytes), Err(VRRPv2Error::InvalidVersion)); |
|
195 } |
|
196 |
|
197 #[test] |
|
198 fn test_invalid_type() { |
|
199 let bytes = [ |
178 0x31, 0x2a, 0x64, 0x1, 0x0, 0x1, 0xaa, 0x29, 0xc0, 0xa8, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, |
200 0x31, 0x2a, 0x64, 0x1, 0x0, 0x1, 0xaa, 0x29, 0xc0, 0xa8, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, |
179 0x0, 0x0, 0x0, |
|
180 ]; |
|
181 assert_eq!(from_bytes(&bytes), Err(VRRPv2Error::InvalidVersion)); |
|
182 } |
|
183 |
|
184 #[test] |
|
185 fn test_invalid_type() { |
|
186 let bytes = [ |
|
187 0x20, 0x1, 0x2a, 0x0, 0x0, 0x1, 0xb5, 0xfd, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
|
188 0x0, 0x0, 0x0, |
201 0x0, 0x0, 0x0, |
189 ]; |
202 ]; |
190 assert_eq!(from_bytes(&bytes), Err(VRRPv2Error::InvalidType)); |
203 assert_eq!(from_bytes(&bytes), Err(VRRPv2Error::InvalidType)); |
191 } |
204 } |
192 |
205 |