1use crate::metric::Metric;
2use crate::serializer::{Serializable, SerializeError};
3use crate::{address_family, ipv4, metric, parser::PacketParsable, parser::ParseError, zero_bytes};
4use std::net::Ipv4Addr;
5
6#[derive(PartialEq, Debug)]
7pub struct Entry {
8 address_family_identifier: address_family::Identifier,
9 ip_address: Ipv4Addr,
10 metric: Metric,
11}
12
13impl Entry {
14 pub fn new(
15 address_family_identifier: address_family::Identifier,
16 ip_address: Ipv4Addr,
17 metric: Metric,
18 ) -> Self {
19 Entry {
20 address_family_identifier,
21 ip_address,
22 metric,
23 }
24 }
25
26 pub fn get_address_family_identifier(&self) -> address_family::Identifier {
27 self.address_family_identifier
28 }
29
30 pub fn get_ip_address(&self) -> Ipv4Addr {
31 self.ip_address
32 }
33
34 pub fn get_metric(&self) -> Metric {
35 self.metric
36 }
37}
38
39impl Serializable for Entry {
40 fn to_bytes(&self) -> Result<Vec<u8>, SerializeError> {
41 Ok([
42 self.get_address_family_identifier().to_bytes()?,
43 vec![0, 0],
44 ipv4::to_bytes(self.get_ip_address())?,
45 vec![0, 0, 0, 0, 0, 0, 0, 0],
46 metric::to_bytes(self.get_metric())?,
47 ]
48 .concat())
49 }
50}
51
52pub struct EntriesParser {}
53
54impl PacketParsable<Entry> for EntriesParser {
55 fn parse_entry<'a>(
56 &'a self,
57 cursor: usize,
58 bytes: &'a [u8],
59 ) -> Result<(Entry, usize), ParseError> {
60 let (address_family_identifier, cursor) = address_family::Identifier::parse(cursor, bytes)?;
61
62 let cursor = zero_bytes::skip(2, cursor, bytes)?;
63
64 let (ip_address, cursor) = ipv4::parse(cursor, bytes)?;
65
66 let cursor = zero_bytes::skip(8, cursor, bytes)?;
67
68 let (metric, cursor) = metric::parse(cursor, bytes)?;
69
70 Ok((
71 Entry::new(address_family_identifier, ip_address, metric),
72 cursor,
73 ))
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use crate::parser::ParseError::NotZeroByte;
80 use crate::v1::{EntriesParser, Entry};
81 use crate::{address_family, parser};
82 use std::net::Ipv4Addr;
83
84 #[test]
85 fn test_parse_packet_for_single_entry() {
86 let parser = EntriesParser {};
87 let result = parser::parse_entries(
88 &parser,
89 4,
90 vec![
91 2, 1, 0, 0, 0, 2, 0, 0, 192, 0, 2, 100, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 2, 1, ]
98 .as_slice(),
99 );
100
101 assert_eq!(result.is_ok(), true);
102
103 let entries = result.unwrap();
104 assert_eq!(
105 entries,
106 vec![Entry {
107 address_family_identifier: address_family::Identifier::IP,
108 ip_address: Ipv4Addr::new(192, 0, 2, 100),
109 metric: 67305985,
110 }]
111 );
112 }
113
114 #[test]
115 fn test_parse_packet_for_multiple_entry() {
116 let parser = EntriesParser {};
117 let result = parser::parse_entries(
118 &parser,
119 4,
120 vec![
121 2, 1, 0, 0, 0, 2, 0, 0, 192, 0, 2, 100, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 2, 1, 0, 2, 0, 0, 192, 0, 2, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 192, 0, 2, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, ]
138 .as_slice(),
139 );
140
141 assert_eq!(result.is_ok(), true);
142
143 let entries = result.unwrap();
144 assert_eq!(
145 entries,
146 vec![
147 Entry {
148 address_family_identifier: address_family::Identifier::IP,
149 ip_address: Ipv4Addr::new(192, 0, 2, 100),
150 metric: 67305985,
151 },
152 Entry {
153 address_family_identifier: address_family::Identifier::IP,
154 ip_address: Ipv4Addr::new(192, 0, 2, 101),
155 metric: 1,
156 },
157 Entry {
158 address_family_identifier: address_family::Identifier::IP,
159 ip_address: Ipv4Addr::new(192, 0, 2, 102),
160 metric: 2,
161 },
162 ]
163 );
164 }
165
166 #[test]
167 fn test_parse_packet_which_has_not_zero_byte() {
168 let parser = EntriesParser {};
169 let result = parser::parse_entries(
170 &parser,
171 4,
172 vec![
173 2, 1, 0, 0, 0, 2, 1, 0, 192, 0, 2, 100, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 2, 1, ]
180 .as_slice(),
181 );
182 assert_eq!(result.unwrap_err(), NotZeroByte(1, 7));
183
184 let result = parser::parse_entries(
185 &parser,
186 4,
187 vec![
188 2, 1, 0, 0, 0, 2, 0, 1, 192, 0, 2, 100, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 2, 1, ]
195 .as_slice(),
196 );
197 assert_eq!(result.unwrap_err(), NotZeroByte(1, 8));
198
199 let result = parser::parse_entries(
200 &parser,
201 4,
202 vec![
203 2, 1, 0, 0, 0, 2, 0, 0, 192, 0, 2, 100, 1, 0, 0, 0, 0, 0, 0, 0, 4, 3, 2, 1, ]
210 .as_slice(),
211 );
212 assert_eq!(result.unwrap_err(), NotZeroByte(1, 13));
213
214 let result = parser::parse_entries(
215 &parser,
216 4,
217 vec![
218 2, 1, 0, 0, 0, 2, 0, 0, 192, 0, 2, 100, 0, 1, 0, 0, 0, 0, 0, 0, 4, 3, 2, 1, ]
225 .as_slice(),
226 );
227 assert_eq!(result.unwrap_err(), NotZeroByte(1, 14));
228
229 let result = parser::parse_entries(
230 &parser,
231 4,
232 vec![
233 2, 1, 0, 0, 0, 2, 0, 0, 192, 0, 2, 100, 0, 0, 1, 0, 0, 0, 0, 0, 4, 3, 2, 1, ]
240 .as_slice(),
241 );
242 assert_eq!(result.unwrap_err(), NotZeroByte(1, 15));
243
244 let result = parser::parse_entries(
245 &parser,
246 4,
247 vec![
248 2, 1, 0, 0, 0, 2, 0, 0, 192, 0, 2, 100, 0, 0, 0, 1, 0, 0, 0, 0, 4, 3, 2, 1, ]
255 .as_slice(),
256 );
257 assert_eq!(result.unwrap_err(), NotZeroByte(1, 16));
258
259 let result = parser::parse_entries(
260 &parser,
261 4,
262 vec![
263 2, 1, 0, 0, 0, 2, 0, 0, 192, 0, 2, 100, 0, 0, 0, 0, 1, 0, 0, 0, 4, 3, 2, 1, ]
270 .as_slice(),
271 );
272 assert_eq!(result.unwrap_err(), NotZeroByte(1, 17));
273
274 let result = parser::parse_entries(
275 &parser,
276 4,
277 vec![
278 2, 1, 0, 0, 0, 2, 0, 0, 192, 0, 2, 100, 0, 0, 0, 0, 0, 1, 0, 0, 4, 3, 2, 1, ]
285 .as_slice(),
286 );
287 assert_eq!(result.unwrap_err(), NotZeroByte(1, 18));
288
289 let result = parser::parse_entries(
290 &parser,
291 4,
292 vec![
293 2, 1, 0, 0, 0, 2, 0, 0, 192, 0, 2, 100, 0, 0, 0, 0, 0, 0, 1, 0, 4, 3, 2, 1, ]
300 .as_slice(),
301 );
302 assert_eq!(result.unwrap_err(), NotZeroByte(1, 19));
303
304 let result = parser::parse_entries(
305 &parser,
306 4,
307 vec![
308 2, 1, 0, 0, 0, 2, 0, 0, 192, 0, 2, 100, 0, 0, 0, 0, 0, 0, 0, 1, 4, 3, 2, 1, ]
315 .as_slice(),
316 );
317 assert_eq!(result.unwrap_err(), NotZeroByte(1, 20));
318 }
319}