rip_rs/
v1.rs

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, //
92                0, 2, 0, 0, //
93                192, 0, 2, 100, //
94                0, 0, 0, 0, //
95                0, 0, 0, 0, //
96                4, 3, 2, 1, //
97            ]
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, //
122                0, 2, 0, 0, //
123                192, 0, 2, 100, //
124                0, 0, 0, 0, //
125                0, 0, 0, 0, //
126                4, 3, 2, 1, //
127                0, 2, 0, 0, //
128                192, 0, 2, 101, //
129                0, 0, 0, 0, //
130                0, 0, 0, 0, //
131                0, 0, 0, 1, //
132                0, 2, 0, 0, //
133                192, 0, 2, 102, //
134                0, 0, 0, 0, //
135                0, 0, 0, 0, //
136                0, 0, 0, 2, //
137            ]
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, //
174                0, 2, 1, 0, // the third byte is not zero
175                192, 0, 2, 100, //
176                0, 0, 0, 0, //
177                0, 0, 0, 0, //
178                4, 3, 2, 1, //
179            ]
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, //
189                0, 2, 0, 1, // the fourth byte is not zero
190                192, 0, 2, 100, //
191                0, 0, 0, 0, //
192                0, 0, 0, 0, //
193                4, 3, 2, 1, //
194            ]
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, //
204                0, 2, 0, 0, //
205                192, 0, 2, 100, //
206                1, 0, 0, 0, // the first byte is not zero
207                0, 0, 0, 0, //
208                4, 3, 2, 1, //
209            ]
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, //
219                0, 2, 0, 0, //
220                192, 0, 2, 100, //
221                0, 1, 0, 0, // the second byte is not zero
222                0, 0, 0, 0, //
223                4, 3, 2, 1, //
224            ]
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, //
234                0, 2, 0, 0, //
235                192, 0, 2, 100, //
236                0, 0, 1, 0, // the third byte is not zero
237                0, 0, 0, 0, //
238                4, 3, 2, 1, //
239            ]
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, //
249                0, 2, 0, 0, //
250                192, 0, 2, 100, //
251                0, 0, 0, 1, // the fourth byte is not zero
252                0, 0, 0, 0, //
253                4, 3, 2, 1, //
254            ]
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, //
264                0, 2, 0, 0, //
265                192, 0, 2, 100, //
266                0, 0, 0, 0, //
267                1, 0, 0, 0, // the first byte is not zero
268                4, 3, 2, 1, //
269            ]
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, //
279                0, 2, 0, 0, //
280                192, 0, 2, 100, //
281                0, 0, 0, 0, //
282                0, 1, 0, 0, // the second byte is not zero
283                4, 3, 2, 1, //
284            ]
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, //
294                0, 2, 0, 0, //
295                192, 0, 2, 100, //
296                0, 0, 0, 0, //
297                0, 0, 1, 0, // the third byte is not zero
298                4, 3, 2, 1, //
299            ]
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, //
309                0, 2, 0, 0, //
310                192, 0, 2, 100, //
311                0, 0, 0, 0, //
312                0, 0, 0, 1, // the fourth byte is not zero
313                4, 3, 2, 1, //
314            ]
315            .as_slice(),
316        );
317        assert_eq!(result.unwrap_err(), NotZeroByte(1, 20));
318    }
319}