toe_beans/v4/message/
message.rs1use super::*;
2use mac_address::MacAddress;
3use std::net::Ipv4Addr;
4
5#[derive(Debug, PartialEq)]
37pub struct Message {
38 pub op: Ops,
40 pub htype: HTypes,
42 pub hlen: u8,
44 pub hops: u8,
46 pub xid: u32,
48 pub secs: u16,
50 pub flags: Flags,
52 pub ciaddr: Ipv4Addr,
54 pub yiaddr: Ipv4Addr,
56 pub siaddr: Ipv4Addr,
58 pub giaddr: Ipv4Addr,
60 pub chaddr: [u8; 16],
64 pub sname: SName,
66 pub file: File,
68 pub magic: [u8; 4],
70 pub options: Vec<MessageOptions>,
74}
75
76pub const MAGIC: [u8; 4] = [99, 130, 83, 99];
78
79impl Encodable for Message {}
80impl Decodable for Message {}
81
82impl MessageHelpers for Message {
83 fn find_option(&self, tag: u8) -> Option<&MessageOptions> {
85 self.options.iter().find(|&option| option.to_tag() == tag)
86 }
87
88 fn add_option(&mut self, option: MessageOptions) {
89 self.options.push(option);
90 }
91
92 fn get_mac_address(&self) -> MacAddress {
93 MacAddress::new([
94 self.chaddr[0],
95 self.chaddr[1],
96 self.chaddr[2],
97 self.chaddr[3],
98 self.chaddr[4],
99 self.chaddr[5],
100 ])
101 }
102}
103
104impl DecodeMessage for Message {
105 type Op = Ops;
106 type Htype = HTypes;
107 type Hlen = u8;
108 type Hops = u8;
109 type Xid = u32;
110 type Secs = u16;
111 type Flags = Flags;
112 type Ciaddr = Ipv4Addr;
113 type Yiaddr = Ipv4Addr;
114 type Siaddr = Ipv4Addr;
115 type Giaddr = Ipv4Addr;
116 type Chaddr = [u8; 16];
117 type Sname = SName;
118 type File = File;
119 type Magic = [u8; 4];
120 type Options = Vec<MessageOptions>;
121
122 type Output = Self;
123
124 fn decode_op(undecoded: &UndecodedMessage) -> Self::Op {
125 Self::Op::from(undecoded.slice_op())
126 }
127
128 fn decode_htype(undecoded: &UndecodedMessage) -> Self::Htype {
129 Self::Htype::from(undecoded.slice_htype())
130 }
131
132 fn decode_hlen(undecoded: &UndecodedMessage) -> Self::Hlen {
133 undecoded.slice_hlen()
134 }
135
136 fn decode_hops(undecoded: &UndecodedMessage) -> Self::Hops {
137 undecoded.slice_hops()
138 }
139
140 fn decode_xid(undecoded: &UndecodedMessage) -> Self::Xid {
141 let bytes = undecoded.slice_xid();
142 u32::from_be_bytes(bytes)
143 }
144
145 fn decode_secs(undecoded: &UndecodedMessage) -> Self::Secs {
146 let bytes = undecoded.slice_secs();
147 u16::from_be_bytes(bytes)
148 }
149
150 fn decode_flags(undecoded: &UndecodedMessage) -> Self::Flags {
151 let byte = undecoded.slice_flags_temporary();
152 let broadcast = byte & 0b10000000 == 0b10000000;
153 Flags { broadcast }
154 }
155
156 fn decode_ciaddr(undecoded: &UndecodedMessage) -> Self::Ciaddr {
157 let bytes = undecoded.slice_ciaddr();
158 Ipv4Addr::from(bytes)
159 }
160
161 fn decode_yiaddr(undecoded: &UndecodedMessage) -> Self::Yiaddr {
162 let bytes = undecoded.slice_yiaddr();
163 Ipv4Addr::from(bytes)
164 }
165
166 fn decode_siaddr(undecoded: &UndecodedMessage) -> Self::Siaddr {
167 let bytes = undecoded.slice_siaddr();
168 Ipv4Addr::from(bytes)
169 }
170
171 fn decode_giaddr(undecoded: &UndecodedMessage) -> Self::Giaddr {
172 let bytes = undecoded.slice_giaddr();
173 Ipv4Addr::from(bytes)
174 }
175
176 fn decode_chaddr(undecoded: &UndecodedMessage) -> Self::Chaddr {
177 undecoded.slice_chaddr()
178 }
179
180 fn decode_sname(undecoded: &UndecodedMessage) -> Self::Sname {
181 SName::from_array(undecoded.slice_sname())
182 }
183
184 fn decode_file(undecoded: &UndecodedMessage) -> Self::File {
185 File::from_array(undecoded.slice_file())
186 }
187
188 fn decode_magic(_magic: &UndecodedMessage) -> Self::Magic {
189 MAGIC
190 }
191
192 fn decode_options(undecoded: &UndecodedMessage) -> Self::Options {
193 MessageOptions::from_bytes(undecoded.slice_options())
194 }
195
196 fn from_bytes(undecoded: &UndecodedMessage) -> Self::Output {
197 Message {
198 op: Self::decode_op(&undecoded),
199 htype: Self::decode_htype(&undecoded),
200 hlen: Self::decode_hlen(&undecoded),
201 hops: Self::decode_hops(&undecoded),
202 xid: Self::decode_xid(&undecoded),
203 secs: Self::decode_secs(&undecoded),
204 flags: Self::decode_flags(&undecoded),
205 ciaddr: Self::decode_ciaddr(&undecoded),
206 yiaddr: Self::decode_yiaddr(&undecoded),
207 siaddr: Self::decode_siaddr(&undecoded),
208 giaddr: Self::decode_giaddr(&undecoded),
209 chaddr: Self::decode_chaddr(&undecoded),
210 sname: Self::decode_sname(&undecoded),
211 file: Self::decode_file(&undecoded),
212 magic: Self::decode_magic(&undecoded),
213 options: Self::decode_options(&undecoded),
214 }
215 }
216}
217
218impl EncodeMessage for Message {
219 #[inline]
220 fn encode_op(&self) -> u8 {
221 (&self.op).into()
222 }
223
224 #[inline]
225 fn encode_htype(&self) -> u8 {
226 (&self.htype).into()
227 }
228
229 #[inline]
230 fn encode_hlen(&self) -> u8 {
231 self.hlen
232 }
233
234 #[inline]
235 fn encode_hops(&self) -> u8 {
236 self.hops
237 }
238
239 #[inline]
240 fn encode_xid(&self) -> [u8; 4] {
241 self.xid.to_be_bytes()
242 }
243
244 #[inline]
245 fn encode_secs(&self) -> [u8; 2] {
246 self.secs.to_be_bytes()
247 }
248
249 #[inline]
250 fn encode_flags(&self) -> [u8; 2] {
251 self.flags.temporary_to_bytes()
252 }
253
254 #[inline]
255 fn encode_ciaddr(&self) -> [u8; 4] {
256 self.ciaddr.octets()
257 }
258
259 #[inline]
260 fn encode_yiaddr(&self) -> [u8; 4] {
261 self.yiaddr.octets()
262 }
263
264 #[inline]
265 fn encode_siaddr(&self) -> [u8; 4] {
266 self.siaddr.octets()
267 }
268
269 #[inline]
270 fn encode_giaddr(&self) -> [u8; 4] {
271 self.giaddr.octets()
272 }
273
274 #[inline]
275 fn encode_chaddr(&self) -> [u8; 16] {
276 self.chaddr
277 }
278
279 #[inline]
280 fn encode_sname(&self) -> [u8; 64] {
281 (&self.sname).into()
282 }
283
284 #[inline]
285 fn encode_file(&self) -> [u8; 128] {
286 (&self.file).into()
287 }
288
289 #[inline]
290 fn encode_options(&self) -> Vec<u8> {
291 let mut encoded = Vec::with_capacity(self.options.len() * 2);
292
293 self.options
294 .iter()
295 .for_each(|option| option.extend_into(&mut encoded));
296
297 encoded
298 }
299}