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 Ok(encoder.output)
96 }
97}
98
99pub struct Encoder {
101 output: Vec<u8>,
103}
104
105impl Encoder {
107 #[inline]
108 fn encode_bytes(&mut self, v: &[u8]) {
109 trace!("encode_bytes");
110 self.output.extend_from_slice(v);
111 }
112
113 #[inline]
114 fn encode_byte(&mut self, v: u8) {
115 trace!("encode_byte");
116 self.output.push(v);
117 }
118}
119
120#[cfg(test)]
123mod tests {
124 use std::net::Ipv4Addr;
125
126 use super::*;
127 use crate::v4::*;
128
129 fn init_logger() {
132 let _ = env_logger::builder().is_test(true).try_init();
133 }
134
135 #[test]
136 fn test_to_bytes() {
137 init_logger();
138
139 let message = Message {
140 op: Ops::Request,
141 htype: HTypes::Ethernet,
142 hlen: 6,
143 hops: 1,
144 xid: 4,
145 secs: 2,
146 flags: Flags { broadcast: true },
147 ciaddr: Ipv4Addr::new(1, 1, 1, 1),
148 yiaddr: Ipv4Addr::new(1, 1, 1, 1),
149 siaddr: Ipv4Addr::new(1, 1, 1, 1),
150 giaddr: Ipv4Addr::new(1, 1, 1, 1),
151 chaddr: [3; 16],
152 sname: SName::new(c"000000000000000000000000000000000000000000000000000000000000000").unwrap(),
153 file: File::new(c"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@").unwrap(),
154 magic: [99, 130, 83, 99],
155 options: vec![
156 MessageOptions::MessageType(MessageTypes::Discover),
157 MessageOptions::End
158 ],
159 };
160
161 let expected = vec![
162 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,
163 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,
164 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
165 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
166 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
167 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
168 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 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, 0, 99, 130, 83, 99, 53, 1, 1, 255,
173 ];
174
175 assert_eq!(message.to_bytes().unwrap(), expected);
176 }
177}