rip_rs/
packet.rs

1use crate::packet::PacketError::VersionInHeaderConflicted;
2use crate::serializer::{Serializable, SerializeError};
3use crate::{header, v1, v2, version};
4use thiserror::Error;
5
6#[derive(Error, Debug, PartialEq)]
7pub enum PacketError {
8    #[error("version in the header conflicted")]
9    VersionInHeaderConflicted,
10    #[error("the number of RIP entries exceeds the maximum number. it allows to have the entries up to 25 in a packet")]
11    MaxRIPEntriesNumberExceeded,
12}
13
14#[derive(PartialEq, Debug)]
15pub struct Packet<T> {
16    header: header::Header,
17    entries: Vec<T>,
18}
19
20impl<T> Packet<T> {
21    fn new(header: header::Header, entries: Vec<T>) -> Result<Self, PacketError> {
22        if entries.len() > 25 {
23            return Err(PacketError::MaxRIPEntriesNumberExceeded);
24        }
25
26        Ok(Packet { header, entries })
27    }
28
29    pub fn get_header(&self) -> &header::Header {
30        &self.header
31    }
32
33    pub fn get_entries(&self) -> &Vec<T> {
34        &self.entries
35    }
36}
37
38impl Packet<v1::Entry> {
39    pub fn make_v1_packet(
40        header: header::Header,
41        entries: Vec<v1::Entry>,
42    ) -> Result<Self, PacketError> {
43        let ver = header.get_version();
44        if ver != version::Version::Version1 {
45            return Err(VersionInHeaderConflicted);
46        }
47        Packet::new(header, entries)
48    }
49}
50
51impl Packet<v2::Entry> {
52    pub fn make_v2_packet(
53        header: header::Header,
54        entries: Vec<v2::Entry>,
55    ) -> Result<Self, PacketError> {
56        let ver = header.get_version();
57        if ver != version::Version::Version2 {
58            return Err(VersionInHeaderConflicted);
59        }
60        Packet::new(header, entries)
61    }
62}
63
64impl<T: Serializable> Serializable for Packet<T> {
65    fn to_bytes(&self) -> Result<Vec<u8>, SerializeError> {
66        let mut entries_bytes = vec![];
67
68        for entry in self.get_entries() {
69            entries_bytes.extend(entry.to_bytes()?);
70        }
71
72        Ok([self.get_header().to_bytes()?, entries_bytes].concat())
73    }
74}
75
76#[cfg(test)]
77mod tests {
78    use crate::address_family::Identifier;
79    use crate::header::Header;
80    use crate::packet::{Packet, PacketError};
81    use crate::serializer::Serializable;
82    use crate::{command, v1, version};
83    use std::net::Ipv4Addr;
84
85    #[test]
86    fn test_make_v1_packet_on_version_conflict() {
87        assert_eq!(
88            Packet::make_v1_packet(
89                Header::new(command::Kind::Response, version::Version::Version2),
90                vec![]
91            )
92            .unwrap_err(),
93            PacketError::VersionInHeaderConflicted
94        );
95    }
96
97    #[test]
98    fn test_make_v2_packet_on_version_conflict() {
99        assert_eq!(
100            Packet::make_v2_packet(
101                Header::new(command::Kind::Response, version::Version::Version1),
102                vec![]
103            )
104            .unwrap_err(),
105            PacketError::VersionInHeaderConflicted
106        );
107    }
108
109    #[test]
110    fn test_max_entries_num_exceeded() {
111        let result = Packet::new(
112            Header::new(command::Kind::Response, version::Version::Version1),
113            vec![
114                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 101), 1),
115                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 102), 2),
116                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 103), 3),
117                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 104), 4),
118                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 105), 5),
119                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 106), 6),
120                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 107), 7),
121                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 108), 8),
122                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 109), 9),
123                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 110), 10),
124                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 111), 11),
125                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 112), 12),
126                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 113), 13),
127                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 114), 14),
128                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 115), 15),
129                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 116), 16),
130                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 117), 17),
131                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 118), 18),
132                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 119), 19),
133                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 120), 20),
134                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 121), 21),
135                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 122), 22),
136                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 123), 23),
137                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 124), 24),
138                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 125), 25),
139                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 126), 26),
140            ],
141        );
142        assert_eq!(
143            result.unwrap_err(),
144            PacketError::MaxRIPEntriesNumberExceeded
145        )
146    }
147
148    #[test]
149    fn test_parse_single_packet() {
150        let packet = Packet::new(
151            Header::new(command::Kind::Response, version::Version::Version1),
152            vec![v1::Entry::new(
153                Identifier::IP,
154                Ipv4Addr::new(192, 0, 2, 101),
155                1,
156            )],
157        )
158        .unwrap();
159
160        assert_eq!(
161            packet.to_bytes().unwrap(),
162            vec![
163                0x02, 0x01, 0x00, 0x00, //
164                0x00, 0x02, 0x00, 0x00, //
165                0xc0, 0x00, 0x02, 0x65, //
166                0x00, 0x00, 0x00, 0x00, //
167                0x00, 0x00, 0x00, 0x00, //
168                0x00, 0x00, 0x00, 0x01, //
169            ]
170        );
171    }
172
173    #[test]
174    fn test_parse_multi_packets() {
175        let packet = Packet::new(
176            Header::new(command::Kind::Response, version::Version::Version1),
177            vec![
178                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 101), 1),
179                v1::Entry::new(Identifier::IP, Ipv4Addr::new(192, 0, 2, 102), 2),
180            ],
181        )
182        .unwrap();
183
184        assert_eq!(
185            packet.to_bytes().unwrap(),
186            vec![
187                0x02, 0x01, 0x00, 0x00, //
188                0x00, 0x02, 0x00, 0x00, //
189                0xc0, 0x00, 0x02, 0x65, //
190                0x00, 0x00, 0x00, 0x00, //
191                0x00, 0x00, 0x00, 0x00, //
192                0x00, 0x00, 0x00, 0x01, //
193                0x00, 0x02, 0x00, 0x00, //
194                0xc0, 0x00, 0x02, 0x66, //
195                0x00, 0x00, 0x00, 0x00, //
196                0x00, 0x00, 0x00, 0x00, //
197                0x00, 0x00, 0x00, 0x02, //
198            ]
199        );
200    }
201}