1use crate::metric::Metric;
2use crate::route_tag::RouteTag;
3use crate::serializer::{Serializable, SerializeError};
4use crate::{address_family, ipv4, metric, parser::PacketParsable, parser::ParseError, route_tag};
5use std::net::Ipv4Addr;
6
7#[derive(PartialEq, Debug)]
8pub struct Entry {
9 address_family_identifier: address_family::Identifier,
10 route_tag: RouteTag,
11 ip_address: Ipv4Addr,
12 subnet_mask: Ipv4Addr,
13 next_hop: Ipv4Addr,
14 metric: Metric,
15}
16
17impl Entry {
18 pub fn new(
19 address_family_identifier: address_family::Identifier,
20 route_tag: RouteTag,
21 ip_address: Ipv4Addr,
22 subnet_mask: Ipv4Addr,
23 next_hop: Ipv4Addr,
24 metric: Metric,
25 ) -> Self {
26 Entry {
27 address_family_identifier,
28 route_tag,
29 ip_address,
30 subnet_mask,
31 next_hop,
32 metric,
33 }
34 }
35
36 pub fn get_address_family_identifier(&self) -> address_family::Identifier {
37 self.address_family_identifier
38 }
39
40 pub fn get_route_tag(&self) -> RouteTag {
41 self.route_tag
42 }
43
44 pub fn get_ip_address(&self) -> Ipv4Addr {
45 self.ip_address
46 }
47
48 pub fn get_subnet_mask(&self) -> Ipv4Addr {
49 self.subnet_mask
50 }
51
52 pub fn get_next_hop(&self) -> Ipv4Addr {
53 self.next_hop
54 }
55
56 pub fn get_metric(&self) -> Metric {
57 self.metric
58 }
59}
60
61impl Serializable for Entry {
62 fn to_bytes(&self) -> Result<Vec<u8>, SerializeError> {
63 Ok([
64 self.get_address_family_identifier().to_bytes()?,
65 route_tag::to_bytes(self.get_route_tag())?,
66 ipv4::to_bytes(self.get_ip_address())?,
67 ipv4::to_bytes(self.get_subnet_mask())?,
68 ipv4::to_bytes(self.get_next_hop())?,
69 metric::to_bytes(self.get_metric())?,
70 ]
71 .concat())
72 }
73}
74
75pub struct EntriesParser {}
76
77impl PacketParsable<Entry> for EntriesParser {
78 fn parse_entry<'a>(
79 &'a self,
80 cursor: usize,
81 bytes: &'a [u8],
82 ) -> Result<(Entry, usize), ParseError> {
83 let (address_family_identifier, cursor) = address_family::Identifier::parse(cursor, bytes)?;
84 let (route_tag, cursor) = route_tag::parse(cursor, bytes)?;
85 let (ip_address, cursor) = ipv4::parse(cursor, bytes)?;
86 let (subnet_mask, cursor) = ipv4::parse(cursor, bytes)?;
87 let (next_hop, cursor) = ipv4::parse(cursor, bytes)?;
88 let (metric, cursor) = metric::parse(cursor, bytes)?;
89
90 Ok((
91 Entry::new(
92 address_family_identifier,
93 route_tag,
94 ip_address,
95 subnet_mask,
96 next_hop,
97 metric,
98 ),
99 cursor,
100 ))
101 }
102}
103
104#[cfg(test)]
105mod tests {
106 use crate::v2::{EntriesParser, Entry};
107 use crate::{address_family, parser};
108 use std::net::Ipv4Addr;
109
110 #[test]
111 fn test_parse_packet_for_single_entry() {
112 let parser = EntriesParser {};
113 let result = parser::parse_entries(
114 &parser,
115 4,
116 vec![
117 2, 2, 0, 0, 0, 2, 1, 2, 192, 0, 2, 100, 255, 255, 255, 0, 192, 0, 2, 111, 4, 3, 2, 1, ]
124 .as_slice(),
125 );
126
127 assert_eq!(result.is_ok(), true);
128
129 let entries = result.unwrap();
130 assert_eq!(
131 entries,
132 vec![Entry {
133 address_family_identifier: address_family::Identifier::IP,
134 route_tag: 258,
135 ip_address: Ipv4Addr::new(192, 0, 2, 100),
136 subnet_mask: Ipv4Addr::new(255, 255, 255, 0),
137 next_hop: Ipv4Addr::new(192, 0, 2, 111),
138 metric: 67305985,
139 }]
140 );
141 }
142
143 #[test]
144 fn test_parse_packet_for_multiple_entry() {
145 let parser = EntriesParser {};
146 let result = parser::parse_entries(
147 &parser,
148 4,
149 vec![
150 2, 2, 0, 0, 0, 2, 1, 2, 192, 0, 2, 100, 255, 255, 255, 0, 192, 0, 2, 200, 4, 3, 2, 1, 0, 2, 0, 1, 192, 0, 2, 101, 255, 255, 255, 0, 192, 0, 2, 201, 0, 0, 0, 1, 0, 2, 0, 2, 192, 0, 2, 102, 255, 255, 255, 0, 192, 0, 2, 202, 0, 0, 0, 2, ]
167 .as_slice(),
168 );
169
170 assert_eq!(result.is_ok(), true);
171
172 let entries = result.unwrap();
173 assert_eq!(
174 entries,
175 vec![
176 Entry {
177 address_family_identifier: address_family::Identifier::IP,
178 route_tag: 258,
179 ip_address: Ipv4Addr::new(192, 0, 2, 100),
180 subnet_mask: Ipv4Addr::new(255, 255, 255, 0),
181 next_hop: Ipv4Addr::new(192, 0, 2, 200),
182 metric: 67305985,
183 },
184 Entry {
185 address_family_identifier: address_family::Identifier::IP,
186 route_tag: 1,
187 ip_address: Ipv4Addr::new(192, 0, 2, 101),
188 subnet_mask: Ipv4Addr::new(255, 255, 255, 0),
189 next_hop: Ipv4Addr::new(192, 0, 2, 201),
190 metric: 1,
191 },
192 Entry {
193 address_family_identifier: address_family::Identifier::IP,
194 route_tag: 2,
195 ip_address: Ipv4Addr::new(192, 0, 2, 102),
196 subnet_mask: Ipv4Addr::new(255, 255, 255, 0),
197 next_hop: Ipv4Addr::new(192, 0, 2, 202),
198 metric: 2,
199 },
200 ]
201 );
202 }
203}