Skip to main content

net_wire/arp/
packet.rs

1use crate::error::ParseError;
2
3use super::types::{ArpHardwareType, ArpOperation, ArpProtocolType};
4
5pub(super) const PREFIX_LENGTH: usize = 8;
6
7/// A structurally validated immutable ARP packet view.
8///
9/// RFC 826 uses independent one-octet hardware and protocol address lengths. Parsing
10/// validates that layout and restricts the view to it, excluding supplied trailing bytes.
11#[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    /// Validates the generic RFC 826 layout without interpreting address semantics.
20    #[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    /// Returns the RFC 826 hardware type, preserving unknown values.
30    #[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    /// Returns the RFC 826 protocol type, preserving unknown values.
37    #[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    /// Returns the encoded hardware address length.
44    #[inline]
45    pub fn hardware_address_length(&self) -> u8 {
46        self.hardware_length as u8
47    }
48    /// Returns the encoded protocol address length.
49    #[inline]
50    pub fn protocol_address_length(&self) -> u8 {
51        self.protocol_length as u8
52    }
53    /// Returns the encoded hardware address length.
54    #[inline]
55    pub fn hlen(&self) -> u8 {
56        self.hardware_address_length()
57    }
58    /// Returns the encoded protocol address length.
59    #[inline]
60    pub fn plen(&self) -> u8 {
61        self.protocol_address_length()
62    }
63    /// Returns the RFC 826 operation, preserving unknown values.
64    #[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    /// Returns the sender hardware address bytes.
71    #[inline]
72    pub fn sender_hardware_address(&self) -> &'a [u8] {
73        &self.bytes[PREFIX_LENGTH..PREFIX_LENGTH + self.hardware_length]
74    }
75    /// Returns the sender protocol address bytes.
76    #[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    /// Returns the target hardware address bytes.
82    #[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    /// Returns the target protocol address bytes.
88    #[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    /// Returns all RFC 826 bytes represented by this view.
94    #[inline]
95    pub fn as_bytes(&self) -> &'a [u8] {
96        self.bytes
97    }
98}
99
100/// A structurally validated mutable ARP packet view.
101#[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    /// Validates the generic RFC 826 layout and excludes supplied trailing bytes.
110    #[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    /// Returns the RFC 826 hardware type, preserving unknown values.
131    #[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    /// Returns the RFC 826 protocol type, preserving unknown values.
138    #[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    /// Returns the encoded hardware address length, which this view cannot change.
145    #[inline]
146    pub fn hardware_address_length(&self) -> u8 {
147        self.hardware_length as u8
148    }
149    /// Returns the encoded protocol address length, which this view cannot change.
150    #[inline]
151    pub fn protocol_address_length(&self) -> u8 {
152        self.protocol_length as u8
153    }
154    /// Returns the encoded hardware address length.
155    #[inline]
156    pub fn hlen(&self) -> u8 {
157        self.hardware_address_length()
158    }
159    /// Returns the encoded protocol address length.
160    #[inline]
161    pub fn plen(&self) -> u8 {
162        self.protocol_address_length()
163    }
164    /// Returns the RFC 826 operation, preserving unknown values.
165    #[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    /// Replaces the RFC 826 hardware type without changing address lengths.
172    #[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    /// Replaces the RFC 826 protocol type without changing address lengths.
177    #[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    /// Replaces the RFC 826 operation.
182    #[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    /// Returns the sender hardware address bytes.
187    #[inline]
188    pub fn sender_hardware_address(&self) -> &[u8] {
189        &self.bytes[PREFIX_LENGTH..PREFIX_LENGTH + self.hardware_length]
190    }
191    /// Returns mutable sender hardware address bytes.
192    #[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    /// Returns the sender protocol address bytes.
197    #[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    /// Returns mutable sender protocol address bytes.
203    #[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    /// Returns the target hardware address bytes.
209    #[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    /// Returns mutable target hardware address bytes.
215    #[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    /// Returns the target protocol address bytes.
221    #[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    /// Returns mutable target protocol address bytes.
227    #[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    /// Returns all RFC 826 bytes represented by this view.
233    #[inline]
234    pub fn as_bytes(&self) -> &[u8] {
235        self.bytes
236    }
237    /// Returns all represented ARP bytes mutably.
238    #[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}