1use core::fmt;
2
3use super::packet::{ArpPacketMut, PREFIX_LENGTH};
4use super::types::{ArpHardwareType, ArpOperation, ArpProtocolType};
5
6#[derive(Clone, Copy, Debug, Eq, PartialEq)]
8pub enum ArpPacketBuildError {
9 MissingHardwareType,
11 MissingProtocolType,
13 MissingOperation,
15 MissingAddresses,
17 AddressLengthMismatch,
19 AddressLengthTooLarge,
21 BufferTooShort {
23 required: usize,
25 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
52pub 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 #[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 #[inline]
81 pub fn hardware_type(mut self, value: ArpHardwareType) -> Self {
82 self.hardware_type = Some(value);
83 self
84 }
85 #[inline]
87 pub fn protocol_type(mut self, value: ArpProtocolType) -> Self {
88 self.protocol_type = Some(value);
89 self
90 }
91 #[inline]
93 pub fn operation(mut self, value: ArpOperation) -> Self {
94 self.operation = Some(value);
95 self
96 }
97 #[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 #[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}