1use crate::error::ParseError;
2
3use super::types::{ArpHardwareType, ArpOperation, ArpProtocolType};
4
5pub(super) const PREFIX_LENGTH: usize = 8;
6
7#[derive(Clone, Copy, Debug, Eq, PartialEq)]
12pub struct ArpPacket<'a> {
13 bytes: &'a [u8],
14 hardware_length: usize,
15 protocol_length: usize,
16}
17
18impl<'a> ArpPacket<'a> {
19 #[inline]
21 pub fn parse(bytes: &'a [u8]) -> Result<Self, ParseError> {
22 let (hardware_length, protocol_length, length) = validate(bytes)?;
23 Ok(Self {
24 bytes: &bytes[..length],
25 hardware_length,
26 protocol_length,
27 })
28 }
29 #[inline]
31 pub fn hardware_type(&self) -> ArpHardwareType {
32 ArpHardwareType::new(u16::from_be_bytes(
33 self.bytes[0..2].try_into().expect("validated ARP prefix"),
34 ))
35 }
36 #[inline]
38 pub fn protocol_type(&self) -> ArpProtocolType {
39 ArpProtocolType::new(u16::from_be_bytes(
40 self.bytes[2..4].try_into().expect("validated ARP prefix"),
41 ))
42 }
43 #[inline]
45 pub fn hardware_address_length(&self) -> u8 {
46 self.hardware_length as u8
47 }
48 #[inline]
50 pub fn protocol_address_length(&self) -> u8 {
51 self.protocol_length as u8
52 }
53 #[inline]
55 pub fn hlen(&self) -> u8 {
56 self.hardware_address_length()
57 }
58 #[inline]
60 pub fn plen(&self) -> u8 {
61 self.protocol_address_length()
62 }
63 #[inline]
65 pub fn operation(&self) -> ArpOperation {
66 ArpOperation::new(u16::from_be_bytes(
67 self.bytes[6..8].try_into().expect("validated ARP prefix"),
68 ))
69 }
70 #[inline]
72 pub fn sender_hardware_address(&self) -> &'a [u8] {
73 &self.bytes[PREFIX_LENGTH..PREFIX_LENGTH + self.hardware_length]
74 }
75 #[inline]
77 pub fn sender_protocol_address(&self) -> &'a [u8] {
78 let start = PREFIX_LENGTH + self.hardware_length;
79 &self.bytes[start..start + self.protocol_length]
80 }
81 #[inline]
83 pub fn target_hardware_address(&self) -> &'a [u8] {
84 let start = PREFIX_LENGTH + self.hardware_length + self.protocol_length;
85 &self.bytes[start..start + self.hardware_length]
86 }
87 #[inline]
89 pub fn target_protocol_address(&self) -> &'a [u8] {
90 let start = PREFIX_LENGTH + 2 * self.hardware_length + self.protocol_length;
91 &self.bytes[start..]
92 }
93 #[inline]
95 pub fn as_bytes(&self) -> &'a [u8] {
96 self.bytes
97 }
98}
99
100#[derive(Debug, Eq, PartialEq)]
102pub struct ArpPacketMut<'a> {
103 bytes: &'a mut [u8],
104 hardware_length: usize,
105 protocol_length: usize,
106}
107
108impl<'a> ArpPacketMut<'a> {
109 #[inline]
111 pub fn parse(bytes: &'a mut [u8]) -> Result<Self, ParseError> {
112 let (hardware_length, protocol_length, length) = validate(bytes)?;
113 Ok(Self::from_validated(
114 &mut bytes[..length],
115 hardware_length,
116 protocol_length,
117 ))
118 }
119 pub(super) fn from_validated(
120 bytes: &'a mut [u8],
121 hardware_length: usize,
122 protocol_length: usize,
123 ) -> Self {
124 Self {
125 bytes,
126 hardware_length,
127 protocol_length,
128 }
129 }
130 #[inline]
132 pub fn hardware_type(&self) -> ArpHardwareType {
133 ArpHardwareType::new(u16::from_be_bytes(
134 self.bytes[0..2].try_into().expect("validated ARP prefix"),
135 ))
136 }
137 #[inline]
139 pub fn protocol_type(&self) -> ArpProtocolType {
140 ArpProtocolType::new(u16::from_be_bytes(
141 self.bytes[2..4].try_into().expect("validated ARP prefix"),
142 ))
143 }
144 #[inline]
146 pub fn hardware_address_length(&self) -> u8 {
147 self.hardware_length as u8
148 }
149 #[inline]
151 pub fn protocol_address_length(&self) -> u8 {
152 self.protocol_length as u8
153 }
154 #[inline]
156 pub fn hlen(&self) -> u8 {
157 self.hardware_address_length()
158 }
159 #[inline]
161 pub fn plen(&self) -> u8 {
162 self.protocol_address_length()
163 }
164 #[inline]
166 pub fn operation(&self) -> ArpOperation {
167 ArpOperation::new(u16::from_be_bytes(
168 self.bytes[6..8].try_into().expect("validated ARP prefix"),
169 ))
170 }
171 #[inline]
173 pub fn set_hardware_type(&mut self, value: ArpHardwareType) {
174 self.bytes[0..2].copy_from_slice(&value.raw().to_be_bytes());
175 }
176 #[inline]
178 pub fn set_protocol_type(&mut self, value: ArpProtocolType) {
179 self.bytes[2..4].copy_from_slice(&value.raw().to_be_bytes());
180 }
181 #[inline]
183 pub fn set_operation(&mut self, value: ArpOperation) {
184 self.bytes[6..8].copy_from_slice(&value.raw().to_be_bytes());
185 }
186 #[inline]
188 pub fn sender_hardware_address(&self) -> &[u8] {
189 &self.bytes[PREFIX_LENGTH..PREFIX_LENGTH + self.hardware_length]
190 }
191 #[inline]
193 pub fn sender_hardware_address_mut(&mut self) -> &mut [u8] {
194 &mut self.bytes[PREFIX_LENGTH..PREFIX_LENGTH + self.hardware_length]
195 }
196 #[inline]
198 pub fn sender_protocol_address(&self) -> &[u8] {
199 let start = PREFIX_LENGTH + self.hardware_length;
200 &self.bytes[start..start + self.protocol_length]
201 }
202 #[inline]
204 pub fn sender_protocol_address_mut(&mut self) -> &mut [u8] {
205 let start = PREFIX_LENGTH + self.hardware_length;
206 &mut self.bytes[start..start + self.protocol_length]
207 }
208 #[inline]
210 pub fn target_hardware_address(&self) -> &[u8] {
211 let start = PREFIX_LENGTH + self.hardware_length + self.protocol_length;
212 &self.bytes[start..start + self.hardware_length]
213 }
214 #[inline]
216 pub fn target_hardware_address_mut(&mut self) -> &mut [u8] {
217 let start = PREFIX_LENGTH + self.hardware_length + self.protocol_length;
218 &mut self.bytes[start..start + self.hardware_length]
219 }
220 #[inline]
222 pub fn target_protocol_address(&self) -> &[u8] {
223 let start = PREFIX_LENGTH + 2 * self.hardware_length + self.protocol_length;
224 &self.bytes[start..]
225 }
226 #[inline]
228 pub fn target_protocol_address_mut(&mut self) -> &mut [u8] {
229 let start = PREFIX_LENGTH + 2 * self.hardware_length + self.protocol_length;
230 &mut self.bytes[start..]
231 }
232 #[inline]
234 pub fn as_bytes(&self) -> &[u8] {
235 self.bytes
236 }
237 #[inline]
239 pub fn as_bytes_mut(&mut self) -> &mut [u8] {
240 self.bytes
241 }
242}
243
244#[inline]
245fn validate(bytes: &[u8]) -> Result<(usize, usize, usize), ParseError> {
246 if bytes.len() < PREFIX_LENGTH {
247 return Err(ParseError::Truncated {
248 minimum: PREFIX_LENGTH,
249 available: bytes.len(),
250 });
251 }
252 let hardware_length = bytes[4] as usize;
253 let protocol_length = bytes[5] as usize;
254 let length = PREFIX_LENGTH + 2 * hardware_length + 2 * protocol_length;
255 if bytes.len() < length {
256 return Err(ParseError::Truncated {
257 minimum: length,
258 available: bytes.len(),
259 });
260 }
261 Ok((hardware_length, protocol_length, length))
262}