1 use arrayvec::ArrayVec; 2 use err::arp::{ArpHwAddrError, ArpNewError, ArpProtoAddrError}; 3 4 use crate::*; 5 use core::mem::MaybeUninit; 6 7 /// "Address Resolution Protocol" Packet. 8 #[derive(Clone)] 9 pub struct ArpPacket { 10 /// Network link protocol type (e.g. `ArpHardwareId::ETHERNET`). 11 pub hw_addr_type: ArpHardwareId, 12 13 /// Protocol for which the ARP request is intended (e.g. `EtherType::IPV4`). 14 pub proto_addr_type: EtherType, 15 16 /// Length (in octets) of a hardware address (e.g. 6 for Ethernet). 17 hw_addr_size: u8, 18 19 /// Length (in octets) of internetwork addresses (e.g. 4 for IPv4 or 16 for IPv6). 20 proto_addr_size: u8, 21 22 /// Specifies the operation that the sender is performing 23 pub operation: ArpOperation, 24 25 /// Buffer containing the sender hardware address (e.g. MAC address). 26 sender_hw_addr_buf: [MaybeUninit<u8>; 0xff], 27 28 /// Buffer containing the sender protocol address (e.g. IPv4 address). 29 sender_protocol_addr_buf: [MaybeUninit<u8>; 0xff], 30 31 /// Buffer containing the target hardware address (e.g. MAC address). 32 target_hw_addr_buf: [MaybeUninit<u8>; 0xff], 33 34 /// Buffer containing the target protocol address (e.g. IPv4 address).. 35 target_protocol_addr_buf: [MaybeUninit<u8>; 0xff], 36 } 37 38 impl ArpPacket { 39 /// Maximum length of an ARP packet in bytes/octets. 40 /// 41 /// This number is calculated by taking the maximum values 42 /// that `hw_addr_size`(255/u8::MAX) & `proto_addr_size` (255/u8::MAX) 43 /// can take and calculate the maximum packet size from that. 44 pub const MAX_LEN: usize = 8 + 2 * 255 + 2 * 255; 45 46 /// Create a new ARP packet with the given values. new( hw_addr_type: ArpHardwareId, proto_addr_type: EtherType, operation: ArpOperation, sender_hw_addr: &[u8], sender_protocol_addr: &[u8], target_hw_addr: &[u8], target_protocol_addr: &[u8], ) -> Result<ArpPacket, ArpNewError>47 pub const fn new( 48 hw_addr_type: ArpHardwareId, 49 proto_addr_type: EtherType, 50 operation: ArpOperation, 51 sender_hw_addr: &[u8], 52 sender_protocol_addr: &[u8], 53 target_hw_addr: &[u8], 54 target_protocol_addr: &[u8], 55 ) -> Result<ArpPacket, ArpNewError> { 56 if sender_hw_addr.len() != target_hw_addr.len() { 57 return Err(ArpNewError::HwAddr(ArpHwAddrError::LenNonMatching( 58 sender_hw_addr.len(), 59 target_hw_addr.len(), 60 ))); 61 } 62 if sender_protocol_addr.len() != target_protocol_addr.len() { 63 return Err(ArpNewError::ProtoAddr(ArpProtoAddrError::LenNonMatching( 64 sender_protocol_addr.len(), 65 target_protocol_addr.len(), 66 ))); 67 } 68 if sender_hw_addr.len() > 255 { 69 return Err(ArpNewError::HwAddr(ArpHwAddrError::LenTooBig( 70 sender_hw_addr.len(), 71 ))); 72 } 73 if sender_protocol_addr.len() > 255 { 74 return Err(ArpNewError::ProtoAddr(ArpProtoAddrError::LenTooBig( 75 sender_protocol_addr.len(), 76 ))); 77 } 78 Ok(ArpPacket { 79 hw_addr_type, 80 proto_addr_type, 81 // cast ok as we verfied the len to be less equal then 255. 82 hw_addr_size: sender_hw_addr.len() as u8, 83 // cast ok as we verfied the len to be less equal then 255. 84 proto_addr_size: sender_protocol_addr.len() as u8, 85 operation, 86 sender_hw_addr_buf: { 87 let mut buf: [MaybeUninit<u8>; 255] = [const { MaybeUninit::uninit() }; 255]; 88 // SAFETY: Safe as 89 // * sender_hw_addr.len() is guranteed to be <= 255 (checked in if above) 90 // * memory areas guranteed to be non overlapping (buf created in this function). 91 unsafe { 92 core::ptr::copy_nonoverlapping( 93 sender_hw_addr.as_ptr(), 94 buf.as_mut_ptr() as *mut u8, 95 sender_hw_addr.len(), 96 ); 97 } 98 buf 99 }, 100 sender_protocol_addr_buf: { 101 let mut buf: [MaybeUninit<u8>; 255] = [const { MaybeUninit::uninit() }; 255]; 102 // SAFETY: Safe as 103 // * sender_protocol_addr.len() is guranteed to be <= 255 (checked in if above) 104 // * memory areas guranteed to be non overlapping (buf created in this function). 105 unsafe { 106 core::ptr::copy_nonoverlapping( 107 sender_protocol_addr.as_ptr(), 108 buf.as_mut_ptr() as *mut u8, 109 sender_protocol_addr.len(), 110 ); 111 } 112 buf 113 }, 114 target_hw_addr_buf: { 115 let mut buf: [MaybeUninit<u8>; 255] = [const { MaybeUninit::uninit() }; 255]; 116 // SAFETY: Safe as 117 // * target_hw_addr.len() is guranteed to be <= 255 (checked in if above) 118 // * memory areas guranteed to be non overlapping (buf created in this function). 119 unsafe { 120 core::ptr::copy_nonoverlapping( 121 target_hw_addr.as_ptr(), 122 buf.as_mut_ptr() as *mut u8, 123 target_hw_addr.len(), 124 ); 125 } 126 buf 127 }, 128 target_protocol_addr_buf: { 129 let mut buf: [MaybeUninit<u8>; 255] = [const { MaybeUninit::uninit() }; 255]; 130 // SAFETY: Safe as 131 // * target_protocol_addr.len() is guranteed to be <= 255 (checked in if above) 132 // * memory areas guranteed to be non overlapping (buf created in this function). 133 unsafe { 134 core::ptr::copy_nonoverlapping( 135 target_protocol_addr.as_ptr(), 136 buf.as_mut_ptr() as *mut u8, 137 target_protocol_addr.len(), 138 ); 139 } 140 buf 141 }, 142 }) 143 } 144 145 /// Create a new ARP packet with the given values without checking 146 /// hardware & protocol address sizes. 147 /// 148 /// # Safety 149 /// 150 /// The caller must gurantee that 151 /// 152 /// * `sender_hw_addr` & `target_hw_addr` have the same length and the length must be smaller or equal than 255. 153 /// * `sender_protocol_addr` & `target_protocol_addr` have the same length and the length must be smaller or equal than 255. 154 /// 155 /// The gurantees the caller must fullfill are equal to the following 156 /// preconditions: 157 /// 158 /// * `sender_hw_addr.len() == target_hw_addr.len()` 159 /// * `sender_hw_addr.len() <= 255` 160 /// * `target_hw_addr.len() <= 255` 161 /// * `sender_protocol_addr.len() == target_protocol_addr.len()` 162 /// * `sender_protocol_addr.len() <= 255` 163 /// * `target_protocol_addr.len() <= 255` new_unchecked( hw_addr_type: ArpHardwareId, proto_addr_type: EtherType, operation: ArpOperation, sender_hw_addr: &[u8], sender_protocol_addr: &[u8], target_hw_addr: &[u8], target_protocol_addr: &[u8], ) -> ArpPacket164 pub const unsafe fn new_unchecked( 165 hw_addr_type: ArpHardwareId, 166 proto_addr_type: EtherType, 167 operation: ArpOperation, 168 sender_hw_addr: &[u8], 169 sender_protocol_addr: &[u8], 170 target_hw_addr: &[u8], 171 target_protocol_addr: &[u8], 172 ) -> ArpPacket { 173 debug_assert!(sender_hw_addr.len() == target_hw_addr.len()); 174 debug_assert!(sender_protocol_addr.len() == target_protocol_addr.len()); 175 debug_assert!(sender_hw_addr.len() <= 255); 176 debug_assert!(sender_protocol_addr.len() <= 255); 177 178 ArpPacket { 179 hw_addr_type, 180 proto_addr_type, 181 // cast ok as we verfied the len to be less equal then 255. 182 hw_addr_size: sender_hw_addr.len() as u8, 183 // cast ok as we verfied the len to be less equal then 255. 184 proto_addr_size: sender_protocol_addr.len() as u8, 185 operation, 186 sender_hw_addr_buf: { 187 let mut buf: [MaybeUninit<u8>; 255] = [const { MaybeUninit::uninit() }; 255]; 188 // SAFETY: Safe as 189 // * the caller must gurantee that sender_hw_addr.len() is <= 255 190 // * memory areas guranteed to be non overlapping (buf created in this function). 191 unsafe { 192 core::ptr::copy_nonoverlapping( 193 sender_hw_addr.as_ptr(), 194 buf.as_mut_ptr() as *mut u8, 195 sender_hw_addr.len(), 196 ); 197 } 198 buf 199 }, 200 sender_protocol_addr_buf: { 201 let mut buf: [MaybeUninit<u8>; 255] = [const { MaybeUninit::uninit() }; 255]; 202 // SAFETY: Safe as 203 // * the caller must gurantee that sender_protocol_addr.len() is <= 255 204 // * memory areas guranteed to be non overlapping (buf created in this function). 205 unsafe { 206 core::ptr::copy_nonoverlapping( 207 sender_protocol_addr.as_ptr(), 208 buf.as_mut_ptr() as *mut u8, 209 sender_protocol_addr.len(), 210 ); 211 } 212 buf 213 }, 214 target_hw_addr_buf: { 215 let mut buf: [MaybeUninit<u8>; 255] = [const { MaybeUninit::uninit() }; 255]; 216 // SAFETY: Safe as 217 // * the caller must gurantee that target_hw_addr.len() is <= 255 218 // * memory areas guranteed to be non overlapping (buf created in this function). 219 unsafe { 220 core::ptr::copy_nonoverlapping( 221 target_hw_addr.as_ptr(), 222 buf.as_mut_ptr() as *mut u8, 223 target_hw_addr.len(), 224 ); 225 } 226 buf 227 }, 228 target_protocol_addr_buf: { 229 let mut buf: [MaybeUninit<u8>; 255] = [const { MaybeUninit::uninit() }; 255]; 230 // SAFETY: Safe as 231 // * the caller must gurantee that target_protocol_addr.len() is <= 255 232 // * memory areas guranteed to be non overlapping (buf created in this function). 233 unsafe { 234 core::ptr::copy_nonoverlapping( 235 target_protocol_addr.as_ptr(), 236 buf.as_mut_ptr() as *mut u8, 237 target_protocol_addr.len(), 238 ); 239 } 240 buf 241 }, 242 } 243 } 244 245 /// Reads an ARP packet from a slice. from_slice(slice: &[u8]) -> Result<ArpPacket, err::LenError>246 pub fn from_slice(slice: &[u8]) -> Result<ArpPacket, err::LenError> { 247 ArpPacketSlice::from_slice(slice).map(|v| v.to_packet()) 248 } 249 250 /// Length (in octets) of a hardware address (e.g. 6 for Ethernet). 251 #[inline] hw_addr_size(&self) -> u8252 pub const fn hw_addr_size(&self) -> u8 { 253 self.hw_addr_size 254 } 255 256 /// Length (in octets) of internetwork addresses (e.g. 4 for IPv4 or 16 for IPv6). 257 #[inline] protocol_addr_size(&self) -> u8258 pub const fn protocol_addr_size(&self) -> u8 { 259 self.proto_addr_size 260 } 261 262 /// Sender hardware address (e.g. MAC address). 263 #[inline] sender_hw_addr(&self) -> &[u8]264 pub const fn sender_hw_addr(&self) -> &[u8] { 265 unsafe { 266 core::slice::from_raw_parts( 267 self.sender_hw_addr_buf.as_ptr() as *const u8, 268 self.hw_addr_size as usize, 269 ) 270 } 271 } 272 273 /// Sender protocol address (e.g. IPv4 address). 274 #[inline] sender_protocol_addr(&self) -> &[u8]275 pub const fn sender_protocol_addr(&self) -> &[u8] { 276 unsafe { 277 core::slice::from_raw_parts( 278 self.sender_protocol_addr_buf.as_ptr() as *const u8, 279 self.proto_addr_size as usize, 280 ) 281 } 282 } 283 284 /// Target hardware address (e.g. MAC address). 285 #[inline] target_hw_addr(&self) -> &[u8]286 pub const fn target_hw_addr(&self) -> &[u8] { 287 unsafe { 288 core::slice::from_raw_parts( 289 self.target_hw_addr_buf.as_ptr() as *const u8, 290 self.hw_addr_size as usize, 291 ) 292 } 293 } 294 295 /// Target protocol address (e.g. IPv4 address). 296 #[inline] target_protocol_addr(&self) -> &[u8]297 pub const fn target_protocol_addr(&self) -> &[u8] { 298 unsafe { 299 core::slice::from_raw_parts( 300 self.target_protocol_addr_buf.as_ptr() as *const u8, 301 self.proto_addr_size as usize, 302 ) 303 } 304 } 305 306 /// Set the sender & target hardware addresses (e.g. MAC address). 307 #[inline] set_hw_addrs( &mut self, sender_hw_addr: &[u8], target_hw_addr: &[u8], ) -> Result<(), ArpHwAddrError>308 pub const fn set_hw_addrs( 309 &mut self, 310 sender_hw_addr: &[u8], 311 target_hw_addr: &[u8], 312 ) -> Result<(), ArpHwAddrError> { 313 if sender_hw_addr.len() != target_hw_addr.len() { 314 return Err(ArpHwAddrError::LenNonMatching( 315 sender_hw_addr.len(), 316 target_hw_addr.len(), 317 )); 318 } 319 if sender_hw_addr.len() > 255 { 320 return Err(ArpHwAddrError::LenTooBig(sender_hw_addr.len())); 321 } 322 { 323 // SAFETY: Safe as 324 // * the caller must gurantee that sender_hw_addr.len() is <= 255 325 // * memory areas guranteed to be non overlapping (buf created in this function). 326 unsafe { 327 core::ptr::copy_nonoverlapping( 328 sender_hw_addr.as_ptr(), 329 self.sender_hw_addr_buf.as_mut_ptr() as *mut u8, 330 sender_hw_addr.len(), 331 ); 332 } 333 } 334 { 335 // SAFETY: Safe as 336 // * the caller must gurantee that target_hw_addr.len() is <= 255 337 // * memory areas guranteed to be non overlapping (buf created in this function). 338 unsafe { 339 core::ptr::copy_nonoverlapping( 340 target_hw_addr.as_ptr(), 341 self.target_hw_addr_buf.as_mut_ptr() as *mut u8, 342 target_hw_addr.len(), 343 ); 344 } 345 } 346 self.hw_addr_size = sender_hw_addr.len() as u8; 347 Ok(()) 348 } 349 350 /// Set the sender & target protocol addresses (e.g. IPv4 address). 351 #[inline] set_protocol_addrs( &mut self, sender_protocol_addr: &[u8], target_protocol_addr: &[u8], ) -> Result<(), ArpProtoAddrError>352 pub const fn set_protocol_addrs( 353 &mut self, 354 sender_protocol_addr: &[u8], 355 target_protocol_addr: &[u8], 356 ) -> Result<(), ArpProtoAddrError> { 357 if sender_protocol_addr.len() != target_protocol_addr.len() { 358 return Err(ArpProtoAddrError::LenNonMatching( 359 sender_protocol_addr.len(), 360 target_protocol_addr.len(), 361 )); 362 } 363 if sender_protocol_addr.len() > 255 { 364 return Err(ArpProtoAddrError::LenTooBig(sender_protocol_addr.len())); 365 } 366 { 367 // SAFETY: Safe as 368 // * sender_protocol_addr.len() is guranteed to be <= 255 (checked in if above) 369 // * memory areas guranteed to be non overlapping (buf created in this function). 370 unsafe { 371 core::ptr::copy_nonoverlapping( 372 sender_protocol_addr.as_ptr(), 373 self.sender_protocol_addr_buf.as_mut_ptr() as *mut u8, 374 sender_protocol_addr.len(), 375 ); 376 } 377 } 378 { 379 // SAFETY: Safe as 380 // * target_protocol_addr.len() is guranteed to be <= 255 (checked in if above) 381 // * memory areas guranteed to be non overlapping (buf created in this function). 382 unsafe { 383 core::ptr::copy_nonoverlapping( 384 target_protocol_addr.as_ptr(), 385 self.target_protocol_addr_buf.as_mut_ptr() as *mut u8, 386 target_protocol_addr.len(), 387 ); 388 } 389 } 390 self.proto_addr_size = sender_protocol_addr.len() as u8; 391 Ok(()) 392 } 393 394 /// Serialized length of this ARP packet. 395 #[inline] packet_len(&self) -> usize396 pub fn packet_len(&self) -> usize { 397 8 + usize::from(self.hw_addr_size) * 2 + usize::from(self.proto_addr_size) * 2 398 } 399 400 /// Returns the serialized header. 401 #[inline] to_bytes(&self) -> ArrayVec<u8,402 pub fn to_bytes(&self) -> ArrayVec<u8, { ArpPacket::MAX_LEN }> { 403 let hw_addr_type = self.hw_addr_type.0.to_be_bytes(); 404 let proto_addr_type = self.proto_addr_type.0.to_be_bytes(); 405 let operation = self.operation.0.to_be_bytes(); 406 let mut result = ArrayVec::<u8, { ArpPacket::MAX_LEN }>::new_const(); 407 result.extend([ 408 hw_addr_type[0], 409 hw_addr_type[1], 410 proto_addr_type[0], 411 proto_addr_type[1], 412 self.hw_addr_size, 413 self.proto_addr_size, 414 operation[0], 415 operation[1], 416 ]); 417 result.try_extend_from_slice(self.sender_hw_addr()).unwrap(); 418 result 419 .try_extend_from_slice(self.sender_protocol_addr()) 420 .unwrap(); 421 result.try_extend_from_slice(self.target_hw_addr()).unwrap(); 422 result 423 .try_extend_from_slice(self.target_protocol_addr()) 424 .unwrap(); 425 result 426 } 427 428 /// Writes the header to the given writer. 429 #[cfg(feature = "std")] write<T: std::io::Write + Sized>(&self, writer: &mut T) -> Result<(), std::io::Error>430 pub fn write<T: std::io::Write + Sized>(&self, writer: &mut T) -> Result<(), std::io::Error> { 431 writer.write_all(&self.to_bytes())?; 432 Ok(()) 433 } 434 435 #[cfg(feature = "std")] 436 #[cfg_attr(docsrs, doc(cfg(feature = "std")))] read<T: std::io::Read + std::io::Seek + Sized>( reader: &mut T, ) -> Result<ArpPacket, std::io::Error>437 pub fn read<T: std::io::Read + std::io::Seek + Sized>( 438 reader: &mut T, 439 ) -> Result<ArpPacket, std::io::Error> { 440 let mut start = [0u8; 8]; 441 reader.read_exact(&mut start[..])?; 442 443 let mut result = ArpPacket { 444 hw_addr_type: ArpHardwareId(u16::from_be_bytes([start[0], start[1]])), 445 proto_addr_type: EtherType(u16::from_be_bytes([start[2], start[3]])), 446 hw_addr_size: start[4], 447 proto_addr_size: start[5], 448 operation: ArpOperation(u16::from_be_bytes([start[6], start[7]])), 449 sender_hw_addr_buf: [const { MaybeUninit::uninit() }; 255], 450 sender_protocol_addr_buf: [const { MaybeUninit::uninit() }; 255], 451 target_hw_addr_buf: [const { MaybeUninit::uninit() }; 255], 452 target_protocol_addr_buf: [const { MaybeUninit::uninit() }; 255], 453 }; 454 455 { 456 // SAFETY: Safe as the maximum u8 value is equal to the array size 255. 457 let sender_hw_addr_slice = unsafe { 458 core::slice::from_raw_parts_mut( 459 result.sender_hw_addr_buf.as_mut_ptr() as *mut u8, 460 result.hw_addr_size as usize, 461 ) 462 }; 463 reader.read_exact(sender_hw_addr_slice)?; 464 } 465 { 466 // SAFETY: Safe as the maximum u8 value is equal to the array size 255. 467 let sender_protocol_addr = unsafe { 468 core::slice::from_raw_parts_mut( 469 result.sender_protocol_addr_buf.as_mut_ptr() as *mut u8, 470 result.proto_addr_size as usize, 471 ) 472 }; 473 reader.read_exact(sender_protocol_addr)?; 474 } 475 { 476 // SAFETY: Safe as the maximum u8 value is equal to the array size 255. 477 let target_hw_addr = unsafe { 478 core::slice::from_raw_parts_mut( 479 result.target_hw_addr_buf.as_mut_ptr() as *mut u8, 480 result.hw_addr_size as usize, 481 ) 482 }; 483 reader.read_exact(target_hw_addr)?; 484 } 485 { 486 // SAFETY: Safe as the maximum u8 value is equal to the array size 255. 487 let target_protocol_addr = unsafe { 488 core::slice::from_raw_parts_mut( 489 result.target_protocol_addr_buf.as_mut_ptr() as *mut u8, 490 result.proto_addr_size as usize, 491 ) 492 }; 493 reader.read_exact(target_protocol_addr)?; 494 } 495 496 Ok(result) 497 } 498 499 /// Returns an [`ArpEthIpv4Packet`] if the current packet 500 /// is an ethernet & IPv4 ARP packet. try_eth_ipv4(&self) -> Result<ArpEthIpv4Packet, err::arp::ArpEthIpv4FromError>501 pub fn try_eth_ipv4(&self) -> Result<ArpEthIpv4Packet, err::arp::ArpEthIpv4FromError> { 502 use err::arp::ArpEthIpv4FromError::*; 503 if self.hw_addr_type != ArpHardwareId::ETHERNET { 504 return Err(NonMatchingHwType(self.hw_addr_type)); 505 } 506 if self.proto_addr_type != EtherType::IPV4 { 507 return Err(NonMatchingProtocolType(self.proto_addr_type)); 508 } 509 if self.hw_addr_size != 6 { 510 return Err(NonMatchingHwAddrSize(self.hw_addr_size)); 511 } 512 if self.proto_addr_size != 4 { 513 return Err(NonMatchingProtoAddrSize(self.proto_addr_size)); 514 } 515 Ok(ArpEthIpv4Packet { 516 operation: self.operation, 517 sender_mac: unsafe { 518 // SAFE as we check above that hw_addr_size is 6 519 [ 520 self.sender_hw_addr_buf[0].assume_init(), 521 self.sender_hw_addr_buf[1].assume_init(), 522 self.sender_hw_addr_buf[2].assume_init(), 523 self.sender_hw_addr_buf[3].assume_init(), 524 self.sender_hw_addr_buf[4].assume_init(), 525 self.sender_hw_addr_buf[5].assume_init(), 526 ] 527 }, 528 sender_ipv4: unsafe { 529 // SAFE as we check above that proto_addr_size is 6 530 [ 531 self.sender_protocol_addr_buf[0].assume_init(), 532 self.sender_protocol_addr_buf[1].assume_init(), 533 self.sender_protocol_addr_buf[2].assume_init(), 534 self.sender_protocol_addr_buf[3].assume_init(), 535 ] 536 }, 537 target_mac: unsafe { 538 // SAFE as we check above that hw_addr_size is 6 539 [ 540 self.target_hw_addr_buf[0].assume_init(), 541 self.target_hw_addr_buf[1].assume_init(), 542 self.target_hw_addr_buf[2].assume_init(), 543 self.target_hw_addr_buf[3].assume_init(), 544 self.target_hw_addr_buf[4].assume_init(), 545 self.target_hw_addr_buf[5].assume_init(), 546 ] 547 }, 548 target_ipv4: unsafe { 549 // SAFE as we check above that proto_addr_size is 6 550 [ 551 self.target_protocol_addr_buf[0].assume_init(), 552 self.target_protocol_addr_buf[1].assume_init(), 553 self.target_protocol_addr_buf[2].assume_init(), 554 self.target_protocol_addr_buf[3].assume_init(), 555 ] 556 }, 557 }) 558 } 559 } 560 561 impl core::fmt::Debug for ArpPacket { fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result562 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 563 f.debug_struct("ArpPacket") 564 .field("hw_addr_type", &self.hw_addr_type) 565 .field("proto_addr_type", &self.proto_addr_type) 566 .field("hw_addr_size", &self.hw_addr_size) 567 .field("proto_addr_size", &self.proto_addr_size) 568 .field("operation", &self.operation) 569 .field("sender_hw_addr", &self.sender_hw_addr()) 570 .field("sender_protocol_addr", &self.sender_protocol_addr()) 571 .field("target_hw_addr", &self.target_hw_addr()) 572 .field("target_protocol_addr", &self.target_protocol_addr()) 573 .finish() 574 } 575 } 576 577 impl core::cmp::PartialEq for ArpPacket { eq(&self, other: &Self) -> bool578 fn eq(&self, other: &Self) -> bool { 579 self.hw_addr_type == other.hw_addr_type 580 && self.proto_addr_type == other.proto_addr_type 581 && self.hw_addr_size == other.hw_addr_size 582 && self.proto_addr_size == other.proto_addr_size 583 && self.operation == other.operation 584 && self.sender_hw_addr() == other.sender_hw_addr() 585 && self.sender_protocol_addr() == other.sender_protocol_addr() 586 && self.target_hw_addr() == other.target_hw_addr() 587 && self.target_protocol_addr() == other.target_protocol_addr() 588 } 589 } 590 591 impl core::cmp::Eq for ArpPacket {} 592 593 impl core::hash::Hash for ArpPacket { hash<H: core::hash::Hasher>(&self, state: &mut H)594 fn hash<H: core::hash::Hasher>(&self, state: &mut H) { 595 self.hw_addr_type.hash(state); 596 self.proto_addr_type.hash(state); 597 self.hw_addr_size.hash(state); 598 self.proto_addr_size.hash(state); 599 self.operation.hash(state); 600 self.sender_hw_addr().hash(state); 601 self.sender_protocol_addr().hash(state); 602 self.target_hw_addr().hash(state); 603 self.target_protocol_addr().hash(state); 604 } 605 } 606 607 #[cfg(test)] 608 mod tests { 609 use crate::{test_gens::*, *}; 610 use err::arp::{ArpHwAddrError, ArpNewError, ArpProtoAddrError}; 611 use proptest::prelude::*; 612 613 #[test] new()614 fn new() { 615 // ok case 616 { 617 let actual = ArpPacket::new( 618 ArpHardwareId::ASH, 619 EtherType::PROVIDER_BRIDGING, 620 ArpOperation::REQUEST, 621 &[1, 2, 3], 622 &[4, 5, 6, 7, 8], 623 &[9, 10, 11], 624 &[12, 13, 14, 15, 16], 625 ) 626 .unwrap(); 627 assert_eq!(3, actual.hw_addr_size()); 628 assert_eq!(5, actual.protocol_addr_size()); 629 assert_eq!(ArpHardwareId::ASH, actual.hw_addr_type); 630 assert_eq!(EtherType::PROVIDER_BRIDGING, actual.proto_addr_type); 631 assert_eq!(ArpOperation::REQUEST, actual.operation); 632 assert_eq!(&[1, 2, 3], actual.sender_hw_addr()); 633 assert_eq!(&[4, 5, 6, 7, 8], actual.sender_protocol_addr()); 634 assert_eq!(&[9, 10, 11], actual.target_hw_addr()); 635 assert_eq!(&[12, 13, 14, 15, 16], actual.target_protocol_addr()); 636 } 637 638 // ok case (upper hw size) 639 { 640 let actual = ArpPacket::new( 641 ArpHardwareId::ASH, 642 EtherType::PROVIDER_BRIDGING, 643 ArpOperation::REQUEST, 644 &[1; 255], 645 &[4, 5, 6, 7, 8], 646 &[2; 255], 647 &[12, 13, 14, 15, 16], 648 ) 649 .unwrap(); 650 assert_eq!(255, actual.hw_addr_size()); 651 assert_eq!(5, actual.protocol_addr_size()); 652 assert_eq!(ArpHardwareId::ASH, actual.hw_addr_type); 653 assert_eq!(EtherType::PROVIDER_BRIDGING, actual.proto_addr_type); 654 assert_eq!(ArpOperation::REQUEST, actual.operation); 655 assert_eq!(&[1; 255], actual.sender_hw_addr()); 656 assert_eq!(&[4, 5, 6, 7, 8], actual.sender_protocol_addr()); 657 assert_eq!(&[2; 255], actual.target_hw_addr()); 658 assert_eq!(&[12, 13, 14, 15, 16], actual.target_protocol_addr()); 659 } 660 661 // ok case (protocol hw size) 662 { 663 let actual = ArpPacket::new( 664 ArpHardwareId::ASH, 665 EtherType::PROVIDER_BRIDGING, 666 ArpOperation::REQUEST, 667 &[3, 4, 5], 668 &[1; 255], 669 &[6, 7, 8], 670 &[2; 255], 671 ) 672 .unwrap(); 673 assert_eq!(3, actual.hw_addr_size()); 674 assert_eq!(255, actual.protocol_addr_size()); 675 assert_eq!(ArpHardwareId::ASH, actual.hw_addr_type); 676 assert_eq!(EtherType::PROVIDER_BRIDGING, actual.proto_addr_type); 677 assert_eq!(ArpOperation::REQUEST, actual.operation); 678 assert_eq!(&[3, 4, 5], actual.sender_hw_addr()); 679 assert_eq!(&[1; 255], actual.sender_protocol_addr()); 680 assert_eq!(&[6, 7, 8], actual.target_hw_addr()); 681 assert_eq!(&[2; 255], actual.target_protocol_addr()); 682 } 683 684 // hw slice len differ error 685 { 686 let actual = ArpPacket::new( 687 ArpHardwareId::ASH, 688 EtherType::PROVIDER_BRIDGING, 689 ArpOperation::REQUEST, 690 &[1, 2, 3], 691 &[], 692 &[4, 5, 6, 7], 693 &[], 694 ); 695 assert_eq!( 696 Err(ArpNewError::HwAddr(ArpHwAddrError::LenNonMatching(3, 4))), 697 actual 698 ); 699 } 700 // protocol slice len differ error 701 { 702 let actual = ArpPacket::new( 703 ArpHardwareId::ASH, 704 EtherType::PROVIDER_BRIDGING, 705 ArpOperation::REQUEST, 706 &[], 707 &[1, 2, 3], 708 &[], 709 &[4, 5, 6, 7], 710 ); 711 assert_eq!( 712 Err(ArpNewError::ProtoAddr(ArpProtoAddrError::LenNonMatching( 713 3, 4 714 ))), 715 actual 716 ); 717 } 718 719 // hardware length error 720 { 721 let actual = ArpPacket::new( 722 ArpHardwareId::ASH, 723 EtherType::PROVIDER_BRIDGING, 724 ArpOperation::REQUEST, 725 &[0; 256], 726 &[1, 2, 3, 4], 727 &[0; 256], 728 &[5, 6, 7, 8], 729 ); 730 assert_eq!( 731 Err(ArpNewError::HwAddr(ArpHwAddrError::LenTooBig(256))), 732 actual 733 ); 734 } 735 736 // protocol length error 737 { 738 let actual = ArpPacket::new( 739 ArpHardwareId::ASH, 740 EtherType::PROVIDER_BRIDGING, 741 ArpOperation::REQUEST, 742 &[1, 2, 3, 4], 743 &[0; 256], 744 &[5, 6, 7, 8], 745 &[0; 256], 746 ); 747 assert_eq!( 748 Err(ArpNewError::ProtoAddr(ArpProtoAddrError::LenTooBig(256))), 749 actual 750 ); 751 } 752 } 753 754 #[test] new_unchecked()755 fn new_unchecked() { 756 // ok case 757 { 758 let actual = unsafe { 759 ArpPacket::new_unchecked( 760 ArpHardwareId::ASH, 761 EtherType::PROVIDER_BRIDGING, 762 ArpOperation::REQUEST, 763 &[1, 2, 3], 764 &[4, 5, 6, 7, 8], 765 &[9, 10, 11], 766 &[12, 13, 14, 15, 16], 767 ) 768 }; 769 assert_eq!(3, actual.hw_addr_size()); 770 assert_eq!(5, actual.protocol_addr_size()); 771 assert_eq!(ArpHardwareId::ASH, actual.hw_addr_type); 772 assert_eq!(EtherType::PROVIDER_BRIDGING, actual.proto_addr_type); 773 assert_eq!(ArpOperation::REQUEST, actual.operation); 774 assert_eq!(&[1, 2, 3], actual.sender_hw_addr()); 775 assert_eq!(&[4, 5, 6, 7, 8], actual.sender_protocol_addr()); 776 assert_eq!(&[9, 10, 11], actual.target_hw_addr()); 777 assert_eq!(&[12, 13, 14, 15, 16], actual.target_protocol_addr()); 778 } 779 780 // ok case (upper hw size) 781 { 782 let actual = unsafe { 783 ArpPacket::new_unchecked( 784 ArpHardwareId::ASH, 785 EtherType::PROVIDER_BRIDGING, 786 ArpOperation::REQUEST, 787 &[0; 255], 788 &[4, 5, 6, 7, 8], 789 &[0; 255], 790 &[12, 13, 14, 15, 16], 791 ) 792 }; 793 assert_eq!(255, actual.hw_addr_size()); 794 assert_eq!(5, actual.protocol_addr_size()); 795 assert_eq!(ArpHardwareId::ASH, actual.hw_addr_type); 796 assert_eq!(EtherType::PROVIDER_BRIDGING, actual.proto_addr_type); 797 assert_eq!(ArpOperation::REQUEST, actual.operation); 798 assert_eq!(&[0; 255], actual.sender_hw_addr()); 799 assert_eq!(&[4, 5, 6, 7, 8], actual.sender_protocol_addr()); 800 assert_eq!(&[0; 255], actual.target_hw_addr()); 801 assert_eq!(&[12, 13, 14, 15, 16], actual.target_protocol_addr()); 802 } 803 804 // ok case (protocol hw size) 805 { 806 let actual = ArpPacket::new( 807 ArpHardwareId::ASH, 808 EtherType::PROVIDER_BRIDGING, 809 ArpOperation::REQUEST, 810 &[1, 2, 3], 811 &[0; 255], 812 &[9, 10, 11], 813 &[0; 255], 814 ) 815 .unwrap(); 816 assert_eq!(3, actual.hw_addr_size()); 817 assert_eq!(255, actual.protocol_addr_size()); 818 assert_eq!(ArpHardwareId::ASH, actual.hw_addr_type); 819 assert_eq!(EtherType::PROVIDER_BRIDGING, actual.proto_addr_type); 820 assert_eq!(ArpOperation::REQUEST, actual.operation); 821 assert_eq!(&[1, 2, 3], actual.sender_hw_addr()); 822 assert_eq!(&[0; 255], actual.sender_protocol_addr()); 823 assert_eq!(&[9, 10, 11], actual.target_hw_addr()); 824 assert_eq!(&[0; 255], actual.target_protocol_addr()); 825 } 826 } 827 828 proptest! { 829 #[test] 830 fn debug(arp in arp_packet_any()) { 831 use std::format; 832 assert_eq!( 833 format!("{:?}", arp), 834 format!( 835 "ArpPacket {{ hw_addr_type: {:?}, proto_addr_type: {:?}, hw_addr_size: {:?}, proto_addr_size: {:?}, operation: {:?}, sender_hw_addr: {:?}, sender_protocol_addr: {:?}, target_hw_addr: {:?}, target_protocol_addr: {:?} }}", 836 arp.hw_addr_type, 837 arp.proto_addr_type, 838 arp.hw_addr_size(), 839 arp.protocol_addr_size(), 840 arp.operation, 841 arp.sender_hw_addr(), 842 arp.sender_protocol_addr(), 843 arp.target_hw_addr(), 844 arp.target_protocol_addr() 845 ) 846 ); 847 } 848 } 849 850 proptest! { 851 #[test] 852 fn clone_eq(arp in arp_packet_any()) { 853 assert_eq!(&arp.clone(), &arp); 854 } 855 } 856 857 proptest! { 858 #[test] 859 fn hash(arp in arp_packet_any()) { 860 use core::hash::{Hash, Hasher}; 861 use std::collections::hash_map::DefaultHasher; 862 863 let expected_hash = { 864 let mut s = DefaultHasher::new(); 865 866 arp.hw_addr_type.hash(&mut s); 867 arp.proto_addr_type.hash(&mut s); 868 arp.hw_addr_size().hash(&mut s); 869 arp.protocol_addr_size().hash(&mut s); 870 arp.operation.hash(&mut s); 871 arp.sender_hw_addr().hash(&mut s); 872 arp.sender_protocol_addr().hash(&mut s); 873 arp.target_hw_addr().hash(&mut s); 874 arp.target_protocol_addr().hash(&mut s); 875 876 s.finish() 877 }; 878 879 let actual_hash = { 880 let mut s = DefaultHasher::new(); 881 arp.hash(&mut s); 882 s.finish() 883 }; 884 885 assert_eq!(expected_hash, actual_hash); 886 } 887 } 888 889 #[test] arp_packet_works()890 fn arp_packet_works() { 891 let bytes = [ 892 0, 1, // hardware type 893 8, 0, // proto type 894 6, 4, // sizes 895 0, 1, // arp operation 896 0x00, 0x1b, 0x21, 0x0f, 0x91, 0x9b, // src mac 897 10, 10, 1, 135, // src ip 898 0xde, 0xad, 0xc0, 0x00, 0xff, 0xee, // dest mac 899 192, 168, 1, 253, // dest ip 900 ]; 901 902 let expected = ArpPacket::new( 903 ArpHardwareId::ETHERNET, 904 EtherType::IPV4, 905 ArpOperation::REQUEST, 906 &[0x00, 0x1b, 0x21, 0x0f, 0x91, 0x9b], 907 &[10, 10, 1, 135], 908 &[0xde, 0xad, 0xc0, 0x00, 0xff, 0xee], 909 &[192, 168, 1, 253], 910 ) 911 .unwrap(); 912 913 let actual = ArpPacket::from_slice(&bytes).unwrap(); 914 915 assert_eq!(expected, actual); 916 } 917 918 proptest! { 919 #[test] 920 fn read( 921 arp in arp_packet_any() 922 ) { 923 use std::vec::Vec; 924 use std::io::Cursor; 925 926 // ok case 927 let mut buf = Vec::with_capacity(arp.packet_len()); 928 arp.write(&mut buf).unwrap(); 929 { 930 let mut cursor = Cursor::new(&buf); 931 let actual = ArpPacket::read(&mut cursor).unwrap(); 932 assert_eq!(arp, actual); 933 } 934 935 // len io error 936 for len in 0..arp.packet_len() { 937 let mut cursor = Cursor::new(&buf[..len]); 938 let actual = ArpPacket::read(&mut cursor); 939 assert!(actual.is_err()); 940 } 941 } 942 } 943 944 proptest! { 945 #[test] 946 fn write_error( 947 arp in arp_packet_any() 948 ) { 949 use std::vec::Vec; 950 use std::io::Cursor; 951 952 let mut buf = Vec::with_capacity(arp.packet_len()); 953 buf.resize(arp.packet_len(), 0u8); 954 955 // check that the write produces an error if not enough memory is present 956 for len in 0..arp.packet_len() { 957 let mut cursor = Cursor::new(&mut buf[..len]); 958 let actual = arp.write(&mut cursor); 959 assert!(actual.is_err()); 960 } 961 } 962 } 963 964 #[test] set_hw_addrs()965 fn set_hw_addrs() { 966 let start = ArpPacket::new( 967 ArpHardwareId::ASH, 968 EtherType::PROVIDER_BRIDGING, 969 ArpOperation::REQUEST, 970 &[1, 2, 3], 971 &[4, 5, 6, 7, 8], 972 &[9, 10, 11], 973 &[12, 13, 14, 15, 16], 974 ) 975 .unwrap(); 976 977 // ok case 978 { 979 let mut arp = start.clone(); 980 arp.set_hw_addrs(&[17, 18], &[19, 20]).unwrap(); 981 assert_eq!(2, arp.hw_addr_size()); 982 assert_eq!(&[17, 18], arp.sender_hw_addr()); 983 assert_eq!(&[19, 20], arp.target_hw_addr()); 984 } 985 986 // non matching error 987 { 988 let mut arp = start.clone(); 989 assert_eq!( 990 arp.set_hw_addrs(&[17, 18], &[19]), 991 Err(ArpHwAddrError::LenNonMatching(2, 1)) 992 ); 993 } 994 995 // above 255 error 996 { 997 let mut arp = start.clone(); 998 assert_eq!( 999 arp.set_hw_addrs(&[0; 260], &[0; 260]), 1000 Err(ArpHwAddrError::LenTooBig(260)) 1001 ); 1002 } 1003 } 1004 1005 #[test] set_proto_addrs()1006 fn set_proto_addrs() { 1007 let start = ArpPacket::new( 1008 ArpHardwareId::ASH, 1009 EtherType::PROVIDER_BRIDGING, 1010 ArpOperation::REQUEST, 1011 &[1, 2, 3], 1012 &[4, 5, 6, 7, 8], 1013 &[9, 10, 11], 1014 &[12, 13, 14, 15, 16], 1015 ) 1016 .unwrap(); 1017 1018 // ok case 1019 { 1020 let mut arp = start.clone(); 1021 arp.set_protocol_addrs(&[17, 18], &[19, 20]).unwrap(); 1022 assert_eq!(2, arp.protocol_addr_size()); 1023 assert_eq!(&[17, 18], arp.sender_protocol_addr()); 1024 assert_eq!(&[19, 20], arp.target_protocol_addr()); 1025 } 1026 1027 // non matching error 1028 { 1029 let mut arp = start.clone(); 1030 assert_eq!( 1031 arp.set_protocol_addrs(&[17, 18], &[19]), 1032 Err(ArpProtoAddrError::LenNonMatching(2, 1)) 1033 ); 1034 } 1035 1036 // above 255 error 1037 { 1038 let mut arp = start.clone(); 1039 assert_eq!( 1040 arp.set_protocol_addrs(&[0; 260], &[0; 260]), 1041 Err(ArpProtoAddrError::LenTooBig(260)) 1042 ); 1043 } 1044 } 1045 1046 proptest! { 1047 #[test] 1048 fn try_eth_ipv4( 1049 arp_eth_ipv4 in arp_eth_ipv4_packet_any() 1050 ) { 1051 use err::arp::ArpEthIpv4FromError::*; 1052 1053 // ok case 1054 { 1055 let arp: ArpPacket = arp_eth_ipv4.clone().into(); 1056 assert_eq!(arp.try_eth_ipv4(), Ok(arp_eth_ipv4.clone())); 1057 } 1058 1059 // hw type error 1060 { 1061 let mut arp: ArpPacket = arp_eth_ipv4.clone().into(); 1062 arp.hw_addr_type = ArpHardwareId::AX25; 1063 assert_eq!( 1064 arp.try_eth_ipv4(), 1065 Err(NonMatchingHwType(ArpHardwareId::AX25)) 1066 ); 1067 } 1068 1069 // proto type error 1070 { 1071 let mut arp: ArpPacket = arp_eth_ipv4.clone().into(); 1072 arp.proto_addr_type = EtherType::IPV6; 1073 assert_eq!( 1074 arp.try_eth_ipv4(), 1075 Err(NonMatchingProtocolType(EtherType::IPV6)) 1076 ); 1077 } 1078 1079 // hw address size error 1080 { 1081 let mut arp: ArpPacket = arp_eth_ipv4.clone().into(); 1082 arp.set_hw_addrs(&[1], &[2]).unwrap(); 1083 assert_eq!( 1084 arp.try_eth_ipv4(), 1085 Err(NonMatchingHwAddrSize(1)) 1086 ); 1087 } 1088 1089 // protocol address size error 1090 { 1091 let mut arp: ArpPacket = arp_eth_ipv4.clone().into(); 1092 arp.set_protocol_addrs(&[1], &[2]).unwrap(); 1093 assert_eq!( 1094 arp.try_eth_ipv4(), 1095 Err(NonMatchingProtoAddrSize(1)) 1096 ); 1097 } 1098 } 1099 } 1100 } 1101