Skip to main content

net_wire/arp/
builder.rs

1use core::fmt;
2
3use super::packet::{ArpPacketMut, PREFIX_LENGTH};
4use super::types::{ArpHardwareType, ArpOperation, ArpProtocolType};
5
6/// Failure while validating an ARP builder request.
7#[derive(Clone, Copy, Debug, Eq, PartialEq)]
8pub enum ArpPacketBuildError {
9    /// No hardware type was supplied.
10    MissingHardwareType,
11    /// No protocol type was supplied.
12    MissingProtocolType,
13    /// No operation was supplied.
14    MissingOperation,
15    /// The four address inputs were not supplied together.
16    MissingAddresses,
17    /// Sender and target address sizes differ for one address category.
18    AddressLengthMismatch,
19    /// A hardware or protocol address exceeds RFC 826's one-octet length field.
20    AddressLengthTooLarge,
21    /// The caller buffer cannot hold the complete RFC 826 packet.
22    BufferTooShort {
23        /// Required packet length.
24        required: usize,
25        /// Available buffer length.
26        available: usize,
27    },
28}
29
30impl fmt::Display for ArpPacketBuildError {
31    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32        match self {
33            Self::MissingHardwareType => f.write_str("missing ARP hardware type"),
34            Self::MissingProtocolType => f.write_str("missing ARP protocol type"),
35            Self::MissingOperation => f.write_str("missing ARP operation"),
36            Self::MissingAddresses => f.write_str("missing ARP addresses"),
37            Self::AddressLengthMismatch => {
38                f.write_str("ARP sender and target address lengths differ")
39            }
40            Self::AddressLengthTooLarge => f.write_str("ARP address length exceeds 255 octets"),
41            Self::BufferTooShort {
42                required,
43                available,
44            } => write!(
45                f,
46                "ARP buffer is too short: need {required} bytes, have {available}"
47            ),
48        }
49    }
50}
51
52/// Builds one RFC 826 packet in a caller-provided buffer.
53pub struct ArpPacketBuilder<'buffer, 'input> {
54    buffer: &'buffer mut [u8],
55    hardware_type: Option<ArpHardwareType>,
56    protocol_type: Option<ArpProtocolType>,
57    operation: Option<ArpOperation>,
58    sender_hardware: Option<&'input [u8]>,
59    sender_protocol: Option<&'input [u8]>,
60    target_hardware: Option<&'input [u8]>,
61    target_protocol: Option<&'input [u8]>,
62}
63
64impl<'buffer, 'input> ArpPacketBuilder<'buffer, 'input> {
65    /// Starts a builder whose result borrows only `buffer`.
66    #[inline]
67    pub fn new(buffer: &'buffer mut [u8]) -> Self {
68        Self {
69            buffer,
70            hardware_type: None,
71            protocol_type: None,
72            operation: None,
73            sender_hardware: None,
74            sender_protocol: None,
75            target_hardware: None,
76            target_protocol: None,
77        }
78    }
79    /// Supplies the RFC 826 hardware type.
80    #[inline]
81    pub fn hardware_type(mut self, value: ArpHardwareType) -> Self {
82        self.hardware_type = Some(value);
83        self
84    }
85    /// Supplies the RFC 826 protocol type.
86    #[inline]
87    pub fn protocol_type(mut self, value: ArpProtocolType) -> Self {
88        self.protocol_type = Some(value);
89        self
90    }
91    /// Supplies the RFC 826 operation.
92    #[inline]
93    pub fn operation(mut self, value: ArpOperation) -> Self {
94        self.operation = Some(value);
95        self
96    }
97    /// Supplies sender-hardware, sender-protocol, target-hardware, and target-protocol addresses.
98    #[inline]
99    pub fn addresses(
100        mut self,
101        sender_hardware: &'input [u8],
102        sender_protocol: &'input [u8],
103        target_hardware: &'input [u8],
104        target_protocol: &'input [u8],
105    ) -> Self {
106        self.sender_hardware = Some(sender_hardware);
107        self.sender_protocol = Some(sender_protocol);
108        self.target_hardware = Some(target_hardware);
109        self.target_protocol = Some(target_protocol);
110        self
111    }
112    /// Validates every field and capacity before writing; trailing buffer bytes remain unchanged.
113    #[inline]
114    pub fn build(self) -> Result<ArpPacketMut<'buffer>, ArpPacketBuildError> {
115        let hardware_type = self
116            .hardware_type
117            .ok_or(ArpPacketBuildError::MissingHardwareType)?;
118        let protocol_type = self
119            .protocol_type
120            .ok_or(ArpPacketBuildError::MissingProtocolType)?;
121        let operation = self
122            .operation
123            .ok_or(ArpPacketBuildError::MissingOperation)?;
124        let sender_hardware = self
125            .sender_hardware
126            .ok_or(ArpPacketBuildError::MissingAddresses)?;
127        let sender_protocol = self
128            .sender_protocol
129            .ok_or(ArpPacketBuildError::MissingAddresses)?;
130        let target_hardware = self
131            .target_hardware
132            .ok_or(ArpPacketBuildError::MissingAddresses)?;
133        let target_protocol = self
134            .target_protocol
135            .ok_or(ArpPacketBuildError::MissingAddresses)?;
136        if sender_hardware.len() != target_hardware.len()
137            || sender_protocol.len() != target_protocol.len()
138        {
139            return Err(ArpPacketBuildError::AddressLengthMismatch);
140        }
141        if sender_hardware.len() > u8::MAX as usize || sender_protocol.len() > u8::MAX as usize {
142            return Err(ArpPacketBuildError::AddressLengthTooLarge);
143        }
144        let length = PREFIX_LENGTH + 2 * sender_hardware.len() + 2 * sender_protocol.len();
145        if self.buffer.len() < length {
146            return Err(ArpPacketBuildError::BufferTooShort {
147                required: length,
148                available: self.buffer.len(),
149            });
150        }
151        let bytes = &mut self.buffer[..length];
152        bytes[0..2].copy_from_slice(&hardware_type.raw().to_be_bytes());
153        bytes[2..4].copy_from_slice(&protocol_type.raw().to_be_bytes());
154        bytes[4] = sender_hardware.len() as u8;
155        bytes[5] = sender_protocol.len() as u8;
156        bytes[6..8].copy_from_slice(&operation.raw().to_be_bytes());
157        let mut offset = PREFIX_LENGTH;
158        bytes[offset..offset + sender_hardware.len()].copy_from_slice(sender_hardware);
159        offset += sender_hardware.len();
160        bytes[offset..offset + sender_protocol.len()].copy_from_slice(sender_protocol);
161        offset += sender_protocol.len();
162        bytes[offset..offset + target_hardware.len()].copy_from_slice(target_hardware);
163        offset += target_hardware.len();
164        bytes[offset..].copy_from_slice(target_protocol);
165        Ok(ArpPacketMut::from_validated(
166            bytes,
167            sender_hardware.len(),
168            sender_protocol.len(),
169        ))
170    }
171}