1use super::MAGIC;
2use crate::v4::error::Result;
3use log::trace;
4
5pub trait EncodeMessage {
16 fn encode_op(&self) -> u8;
18 fn encode_htype(&self) -> u8;
20 fn encode_hlen(&self) -> u8;
22 fn encode_hops(&self) -> u8;
24 fn encode_xid(&self) -> [u8; 4];
26 fn encode_secs(&self) -> [u8; 2];
28 fn encode_flags(&self) -> [u8; 2];
30 fn encode_ciaddr(&self) -> [u8; 4];
32 fn encode_yiaddr(&self) -> [u8; 4];
34 fn encode_siaddr(&self) -> [u8; 4];
36 fn encode_giaddr(&self) -> [u8; 4];
38 fn encode_chaddr(&self) -> [u8; 16];
40 fn encode_sname(&self) -> [u8; 64];
42 fn encode_file(&self) -> [u8; 128];
44 fn encode_options(&self) -> Vec<u8>;
46
47 fn encode_magic(&self) -> [u8; 4] {
49 MAGIC
50 }
51
52 fn to_bytes(&self) -> Result<Vec<u8>> {
56 trace!("to_bytes");
57
58 let mut encoder = Encoder {
59 output: Vec::with_capacity(552),
60 };
61
62 trace!("encode op");
63 encoder.encode_byte(self.encode_op());
64 trace!("encode htype");
65 encoder.encode_byte(self.encode_htype());
66 trace!("encode hlen");
67 encoder.encode_byte(self.encode_hlen());
68 trace!("encode hops");
69 encoder.encode_byte(self.encode_hops());
70 trace!("encode xid");
71 encoder.encode_bytes(&self.encode_xid());
72 trace!("encode secs");
73 encoder.encode_bytes(&self.encode_secs());
74 trace!("encode flags");
75 encoder.encode_bytes(&self.encode_flags());
76 trace!("encode ciaddr");
77 encoder.encode_bytes(&self.encode_ciaddr());
78 trace!("encode yiaddr");
79 encoder.encode_bytes(&self.encode_yiaddr());
80 trace!("encode siaddr");
81 encoder.encode_bytes(&self.encode_siaddr());
82 trace!("encode giaddr");
83 encoder.encode_bytes(&self.encode_giaddr());
84 trace!("encode chaddr");
85 encoder.encode_bytes(&self.encode_chaddr());
86 trace!("encode sname");
87 encoder.encode_bytes(&self.encode_sname());
88 trace!("encode file");
89 encoder.encode_bytes(&self.encode_file());
90 trace!("encode magic");
91 encoder.encode_bytes(&self.encode_magic());
92 trace!("encode options");
93 encoder.encode_bytes(self.encode_options().as_slice());
94
95 encoder.encode_byte(255);
97
98 Ok(encoder.output)
99 }
100}
101
102pub struct Encoder {
104 output: Vec<u8>,
106}
107
108impl Encoder {
110 #[inline]
111 fn encode_bytes(&mut self, v: &[u8]) {
112 trace!("encode_bytes");
113 self.output.extend_from_slice(v);
114 }
115
116 #[inline]
117 fn encode_byte(&mut self, v: u8) {
118 trace!("encode_byte");
119 self.output.push(v);
120 }
121}
122
123#[cfg(test)]
126mod tests {
127 use std::net::Ipv4Addr;
128
129 use super::*;
130 use crate::v4::*;
131
132 fn init_logger() {
135 let _ = env_logger::builder().is_test(true).try_init();
136 }
137
138 #[test]
139 fn test_to_bytes() {
140 init_logger();
141
142 let message = Message {
143 op: Ops::Request,
144 htype: HTypes::Ethernet,
145 hlen: 6,
146 hops: 1,
147 xid: 4,
148 secs: 2,
149 flags: Flags { broadcast: true },
150 ciaddr: Ipv4Addr::new(1, 1, 1, 1),
151 yiaddr: Ipv4Addr::new(1, 1, 1, 1),
152 siaddr: Ipv4Addr::new(1, 1, 1, 1),
153 giaddr: Ipv4Addr::new(1, 1, 1, 1),
154 chaddr: [3; 16],
155 sname: SName::new(c"000000000000000000000000000000000000000000000000000000000000000").unwrap(),
156 file: File::new(c"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@").unwrap(),
157 magic: [99, 130, 83, 99],
158 options: vec![
159 MessageOptions::MessageType(MessageTypes::Discover),
160 ],
161 };
162
163 let expected = vec![
164 1, 1, 6, 1, 0, 0, 0, 4, 0, 2, 128, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
165 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
166 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
167 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
168 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
169 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
170 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
171 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
172 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
173 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
174 64, 64, 64, 64, 64, 0, 99, 130, 83, 99, 53, 1, 1, 255,
175 ];
176
177 assert_eq!(message.to_bytes().unwrap(), expected);
178 }
179}