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