1use alloc::collections::BTreeMap;
7use alloc::sync::Arc;
8use alloc::vec::Vec;
9use core::sync::atomic::{AtomicU32, Ordering};
10use spin::{Mutex, RwLock};
11
12use crate::early_println;
13use crate::network::ipv4::Ipv4Address;
14use crate::network::protocol_stack::get_network_manager;
15use crate::network::protocol_stack::{LayerContext, NetworkLayer, NetworkLayerStats};
16use crate::network::socket::SocketError;
17
18pub mod operation {
20 pub const REQUEST: u16 = 0x0001;
22 pub const REPLY: u16 = 0x0002;
24}
25
26pub const HTYPE_ETHERNET: u16 = 0x0001;
28
29pub const PTYPE_IPV4: u16 = 0x0800;
31
32pub const HLEN_ETHERNET: u8 = 6;
34
35pub const PLEN_IPV4: u8 = 4;
37
38#[derive(Debug, Clone, Copy)]
40#[repr(C, packed)]
41pub struct ArpPacket {
42 pub htype: u16,
44 pub ptype: u16,
46 pub hlen: u8,
48 pub plen: u8,
50 pub operation: u16,
52 pub sender_mac: [u8; 6],
54 pub sender_ip: [u8; 4],
56 pub target_mac: [u8; 6],
58 pub target_ip: [u8; 4],
60}
61
62impl ArpPacket {
63 pub fn new(operation: u16) -> Self {
65 Self {
66 htype: HTYPE_ETHERNET,
67 ptype: PTYPE_IPV4,
68 hlen: HLEN_ETHERNET,
69 plen: PLEN_IPV4,
70 operation,
71 sender_mac: [0; 6],
72 sender_ip: [0; 4],
73 target_mac: [0; 6],
74 target_ip: [0; 4],
75 }
76 }
77
78 pub fn request(sender_ip: [u8; 4], target_ip: [u8; 4]) -> Self {
80 let mut packet = Self::new(operation::REQUEST);
81 packet.sender_ip = sender_ip;
82 packet.target_ip = target_ip;
83 packet
84 }
85
86 pub fn reply(sender_mac: [u8; 6], sender_ip: [u8; 4], target_mac: [u8; 6]) -> Self {
88 let mut packet = Self::new(operation::REPLY);
89 packet.sender_mac = sender_mac;
90 packet.sender_ip = sender_ip;
91 packet.target_mac = target_mac;
92 packet.target_ip = sender_ip; packet
94 }
95
96 pub fn to_bytes(&self) -> Vec<u8> {
98 let mut bytes = Vec::with_capacity(28);
99 bytes.extend_from_slice(&self.htype.to_be_bytes());
100 bytes.extend_from_slice(&self.ptype.to_be_bytes());
101 bytes.push(self.hlen);
102 bytes.push(self.plen);
103 bytes.extend_from_slice(&self.operation.to_be_bytes());
104 bytes.extend_from_slice(&self.sender_mac);
105 bytes.extend_from_slice(&self.sender_ip);
106 bytes.extend_from_slice(&self.target_mac);
107 bytes.extend_from_slice(&self.target_ip);
108 bytes
109 }
110
111 pub fn from_bytes(bytes: &[u8]) -> Option<Self> {
113 if bytes.len() < 28 {
114 return None;
115 }
116
117 Some(Self {
118 htype: u16::from_be_bytes([bytes[0], bytes[1]]),
119 ptype: u16::from_be_bytes([bytes[2], bytes[3]]),
120 hlen: bytes[4],
121 plen: bytes[5],
122 operation: u16::from_be_bytes([bytes[6], bytes[7]]),
123 sender_mac: [
124 bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13],
125 ],
126 sender_ip: [bytes[14], bytes[15], bytes[16], bytes[17]],
127 target_mac: [
128 bytes[18], bytes[19], bytes[20], bytes[21], bytes[22], bytes[23],
129 ],
130 target_ip: [bytes[24], bytes[25], bytes[26], bytes[27]],
131 })
132 }
133
134 pub fn is_request(&self) -> bool {
136 self.operation == operation::REQUEST
137 }
138
139 pub fn is_reply(&self) -> bool {
141 self.operation == operation::REPLY
142 }
143}
144
145#[derive(Debug, Clone)]
147pub struct ArpCacheEntry {
148 pub ip_address: Ipv4Address,
150 pub mac_address: [u8; 6],
152 pub timestamp: u64,
154 pub state: ArpEntryState,
156}
157
158#[derive(Debug, Clone, Copy, PartialEq, Eq)]
160pub enum ArpEntryState {
161 Valid,
163 Pending,
165 Expired,
167}
168
169impl ArpCacheEntry {
170 pub fn new(ip_address: Ipv4Address, mac_address: [u8; 6]) -> Self {
172 Self {
173 ip_address,
174 mac_address,
175 timestamp: 0,
176 state: ArpEntryState::Valid,
177 }
178 }
179
180 pub fn pending(ip_address: Ipv4Address) -> Self {
182 Self {
183 ip_address,
184 mac_address: [0; 6],
185 timestamp: 0,
186 state: ArpEntryState::Pending,
187 }
188 }
189
190 pub fn is_expired(&self) -> bool {
193 self.state == ArpEntryState::Expired || self.state == ArpEntryState::Pending
196 }
197}
198
199#[derive(Debug)]
201struct ArpPendingEntry {
202 entry: ArpCacheEntry,
204 packet_queue: Mutex<Vec<Vec<u8>>>,
206}
207
208type ArpCacheKey = (alloc::string::String, u32);
210
211type ArpPendingKey = (alloc::string::String, u32);
213
214pub struct ArpLayer {
226 cache: RwLock<BTreeMap<ArpCacheKey, ArpCacheEntry>>,
228 pending: RwLock<BTreeMap<ArpPendingKey, ArpPendingEntry>>,
230 timeout_ticks: u64,
232 cache_timeout: u64,
234 stats: RwLock<NetworkLayerStats>,
236 packet_counter: AtomicU32,
238}
239
240impl ArpLayer {
241 pub fn new() -> Arc<Self> {
243 Arc::new(Self {
244 cache: RwLock::new(BTreeMap::new()),
245 pending: RwLock::new(BTreeMap::new()),
246 timeout_ticks: 1000, cache_timeout: 60000, stats: RwLock::new(NetworkLayerStats::default()),
249 packet_counter: AtomicU32::new(0),
250 })
251 }
252
253 pub fn init(network_manager: &crate::network::NetworkManager) {
262 let layer = Self::new();
263 network_manager.register_layer("arp", layer.clone());
264
265 let ethernet = network_manager
267 .get_layer("ethernet")
268 .expect("EthernetLayer must be initialized before ArpLayer");
269 ethernet.register_protocol(crate::network::ethernet::ether_type::ARP, layer);
270 }
271
272 fn get_local_mac_for_interface(&self, interface: &str) -> Option<[u8; 6]> {
274 get_network_manager().get_layer("ethernet").and_then(|eth| {
275 eth.as_any()
276 .downcast_ref::<crate::network::ethernet::EthernetLayer>()
277 .and_then(|e| e.get_mac(interface).map(|m| *m.as_bytes()))
278 })
279 }
280
281 fn get_local_ip_for_interface(&self, interface: &str) -> Option<Ipv4Address> {
283 get_network_manager().get_layer("ip").and_then(|ip| {
284 ip.as_any()
285 .downcast_ref::<crate::network::ipv4::Ipv4Layer>()
286 .and_then(|i| i.get_primary_ip(interface))
287 })
288 }
289
290 fn get_default_interface(&self) -> Option<alloc::string::String> {
292 get_network_manager().get_layer("ethernet").and_then(|eth| {
293 eth.as_any()
294 .downcast_ref::<crate::network::ethernet::EthernetLayer>()
295 .and_then(|e| e.get_default_interface())
296 })
297 }
298
299 pub fn lookup_on_interface(&self, interface: &str, ip_address: Ipv4Address) -> Option<[u8; 6]> {
301 let cache = self.cache.read();
302 let key = (
303 alloc::string::String::from(interface),
304 u32::from_be_bytes(ip_address.0),
305 );
306
307 cache.get(&key).and_then(|entry| {
308 if entry.state == ArpEntryState::Valid {
309 Some(entry.mac_address)
310 } else {
311 None
312 }
313 })
314 }
315
316 pub fn lookup(&self, ip_address: Ipv4Address) -> Option<[u8; 6]> {
318 let interface = self.get_default_interface()?;
319 self.lookup_on_interface(&interface, ip_address)
320 }
321
322 pub fn add_entry_on_interface(
324 &self,
325 interface: &str,
326 ip_address: Ipv4Address,
327 mac_address: [u8; 6],
328 ) {
329 let mut cache = self.cache.write();
330 let key = (
331 alloc::string::String::from(interface),
332 u32::from_be_bytes(ip_address.0),
333 );
334 cache.insert(
335 key,
336 ArpCacheEntry {
337 ip_address,
338 mac_address,
339 timestamp: self.get_timestamp(),
340 state: ArpEntryState::Valid,
341 },
342 );
343 }
344
345 pub fn add_entry(&self, ip_address: Ipv4Address, mac_address: [u8; 6]) {
347 if let Some(interface) = self.get_default_interface() {
348 self.add_entry_on_interface(&interface, ip_address, mac_address);
349 }
350 }
351
352 pub fn remove_entry_on_interface(&self, interface: &str, ip_address: Ipv4Address) {
354 let mut cache = self.cache.write();
355 let key = (
356 alloc::string::String::from(interface),
357 u32::from_be_bytes(ip_address.0),
358 );
359 cache.remove(&key);
360 }
361
362 pub fn remove_entry(&self, ip_address: Ipv4Address) {
364 if let Some(interface) = self.get_default_interface() {
365 self.remove_entry_on_interface(&interface, ip_address);
366 }
367 }
368
369 pub fn send_request(
377 &self,
378 target_ip: Ipv4Address,
379 context: &LayerContext,
380 next_layers: &[Arc<dyn NetworkLayer>],
381 ) -> Result<(), SocketError> {
382 let interface = context
384 .get("interface")
385 .and_then(|b| core::str::from_utf8(b).ok())
386 .map(alloc::string::String::from)
387 .or_else(|| self.get_default_interface())
388 .ok_or(SocketError::NoRoute)?;
389
390 let local_mac = self
392 .get_local_mac_for_interface(&interface)
393 .ok_or(SocketError::NoRoute)?;
394 let local_ip = self
395 .get_local_ip_for_interface(&interface)
396 .unwrap_or(Ipv4Address::new(0, 0, 0, 0));
397
398 let mut arp_packet = ArpPacket::request(local_ip.0, target_ip.0);
400 arp_packet.sender_mac = local_mac;
401
402 let target_ip_bytes = target_ip.0;
403 early_println!(
404 "[ARP] Sending request for {}.{}.{}.{} via {}",
405 target_ip_bytes[0],
406 target_ip_bytes[1],
407 target_ip_bytes[2],
408 target_ip_bytes[3],
409 interface
410 );
411
412 let pending_key = (interface.clone(), u32::from_be_bytes(target_ip.0));
414 let mut pending = self.pending.write();
415 pending.insert(
416 pending_key,
417 ArpPendingEntry {
418 entry: ArpCacheEntry::pending(target_ip),
419 packet_queue: Mutex::new(Vec::new()),
420 },
421 );
422 drop(pending);
423
424 let mut eth_context = LayerContext::new();
426 eth_context.set("eth_dst_mac", &[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]);
427 eth_context.set("eth_src_mac", &local_mac);
428 eth_context.set("interface", interface.as_bytes());
429 eth_context.set(
430 "eth_type",
431 &crate::network::ethernet::ether_type::ARP.to_be_bytes(),
432 );
433
434 let arp_bytes = arp_packet.to_bytes();
436
437 if !next_layers.is_empty() {
439 next_layers[0].send(&arp_bytes, ð_context, &next_layers[1..])?;
440
441 let mut stats = self.stats.write();
443 stats.packets_sent += 1;
444 stats.bytes_sent += (28 + 14) as u64; } else {
446 if let Some(eth_layer) = get_network_manager().get_layer("ethernet") {
448 eth_layer.send(&arp_bytes, ð_context, &[])?;
449
450 let mut stats = self.stats.write();
452 stats.packets_sent += 1;
453 stats.bytes_sent += (28 + 14) as u64; }
455 }
456
457 Ok(())
458 }
459
460 pub fn receive_packet_on_interface(
467 &self,
468 arp_bytes: &[u8],
469 interface: Option<&str>,
470 ) -> Result<(), SocketError> {
471 let arp_packet = ArpPacket::from_bytes(arp_bytes).ok_or(SocketError::InvalidPacket)?;
473
474 let iface = match interface
476 .map(alloc::string::String::from)
477 .or_else(|| self.get_default_interface())
478 .or_else(|| {
479 get_network_manager()
480 .get_default_interface()
481 .map(|i| alloc::string::String::from(i.name()))
482 }) {
483 Some(name) => name,
484 None => return Err(SocketError::NoRoute),
485 };
486
487 let local_mac = self.get_local_mac_for_interface(&iface);
489 let local_ip = self.get_local_ip_for_interface(&iface);
490
491 let sender_ip = Ipv4Address::from_bytes(arp_packet.sender_ip);
493 let target_ip = Ipv4Address::from_bytes(arp_packet.target_ip);
494
495 if arp_packet.is_request() {
497 self.add_entry_on_interface(&iface, sender_ip, arp_packet.sender_mac);
499
500 let pending_key = (iface.clone(), u32::from_be_bytes(sender_ip.0));
502 let mut pending = self.pending.write();
503 if let Some(pending_entry) = pending.remove(&pending_key) {
504 let mut queue = pending_entry.packet_queue.lock();
505 if let Some(eth_layer) = get_network_manager().get_layer("ethernet") {
506 if let Some(src_mac) = local_mac {
507 for packet_bytes in queue.drain(..) {
508 let mut eth_context = LayerContext::new();
509 eth_context.set("eth_dst_mac", &arp_packet.sender_mac);
510 eth_context.set("eth_src_mac", &src_mac);
511 eth_context.set("interface", iface.as_bytes());
512 let _ = eth_layer.send(&packet_bytes, ð_context, &[]);
513 }
514 }
515 }
516 }
517 drop(pending);
518
519 let is_for_us = local_ip.map(|ip| ip == target_ip).unwrap_or(false);
521
522 if is_for_us {
523 if let (Some(my_mac), Some(my_ip)) = (local_mac, local_ip) {
524 let reply = ArpPacket::reply(my_mac, my_ip.0, arp_packet.sender_mac);
526
527 let sender_ip_bytes = sender_ip.0;
528 early_println!(
529 "[ARP] Received request from {}.{}.{}.{} on {}, replying",
530 sender_ip_bytes[0],
531 sender_ip_bytes[1],
532 sender_ip_bytes[2],
533 sender_ip_bytes[3],
534 iface
535 );
536
537 let mut eth_context = LayerContext::new();
539 eth_context.set("eth_dst_mac", &arp_packet.sender_mac);
540 eth_context.set("eth_src_mac", &my_mac);
541 eth_context.set("interface", iface.as_bytes());
542 eth_context.set(
543 "eth_type",
544 &crate::network::ethernet::ether_type::ARP.to_be_bytes(),
545 );
546
547 if let Some(eth_layer) = get_network_manager().get_layer("ethernet") {
549 let reply_bytes = reply.to_bytes();
550 eth_layer.send(&reply_bytes, ð_context, &[])?;
551 }
552 }
553 }
554 }
555 else if arp_packet.is_reply() {
557 let is_from_us = local_ip.map(|ip| ip == sender_ip).unwrap_or(false);
559
560 if !is_from_us {
561 let pending_key = (iface.clone(), u32::from_be_bytes(sender_ip.0));
563 let mut pending = self.pending.write();
564
565 if let Some(pending_entry) = pending.remove(&pending_key) {
566 self.add_entry_on_interface(&iface, sender_ip, arp_packet.sender_mac);
568
569 let sender_ip_bytes = sender_ip.0;
570 early_println!(
571 "[ARP] Received reply for {}.{}.{}.{} -> {:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X} on {}",
572 sender_ip_bytes[0],
573 sender_ip_bytes[1],
574 sender_ip_bytes[2],
575 sender_ip_bytes[3],
576 arp_packet.sender_mac[0],
577 arp_packet.sender_mac[1],
578 arp_packet.sender_mac[2],
579 arp_packet.sender_mac[3],
580 arp_packet.sender_mac[4],
581 arp_packet.sender_mac[5],
582 iface
583 );
584
585 let mut queue = pending_entry.packet_queue.lock();
587 let queued_count = queue.len();
588 if queued_count > 0 {
589 early_println!(
590 "[ARP] Flushing {} queued packet(s) to {:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}",
591 queued_count,
592 arp_packet.sender_mac[0],
593 arp_packet.sender_mac[1],
594 arp_packet.sender_mac[2],
595 arp_packet.sender_mac[3],
596 arp_packet.sender_mac[4],
597 arp_packet.sender_mac[5]
598 );
599 }
600 if let Some(eth_layer) = get_network_manager().get_layer("ethernet") {
601 if let Some(src_mac) = local_mac {
602 for packet_bytes in queue.drain(..) {
603 let mut eth_context = LayerContext::new();
604 eth_context.set("eth_dst_mac", &arp_packet.sender_mac);
605 eth_context.set("eth_src_mac", &src_mac);
606 eth_context.set("interface", iface.as_bytes());
607 eth_context.set(
609 "eth_type",
610 &crate::network::ethernet::ether_type::IPV4.to_be_bytes(),
611 );
612
613 early_println!(
614 "[ARP] Sending queued packet ({} bytes) via {}",
615 packet_bytes.len(),
616 iface
617 );
618 let _ = eth_layer.send(&packet_bytes, ð_context, &[]);
619 }
620 }
621 }
622 } else {
623 let sender_ip_bytes = sender_ip.0;
625 early_println!(
626 "[ARP] Received unsolicited reply for {}.{}.{}.{} on {}",
627 sender_ip_bytes[0],
628 sender_ip_bytes[1],
629 sender_ip_bytes[2],
630 sender_ip_bytes[3],
631 iface
632 );
633 self.add_entry_on_interface(&iface, sender_ip, arp_packet.sender_mac);
634 }
635
636 drop(pending);
637
638 let mut stats = self.stats.write();
639 stats.packets_received += 1;
640 stats.bytes_received += (arp_bytes.len() + 14) as u64;
641 }
642 }
643
644 Ok(())
645 }
646
647 pub fn receive_packet(&self, arp_bytes: &[u8]) -> Result<(), SocketError> {
649 self.receive_packet_on_interface(arp_bytes, None)
650 }
651
652 pub fn queue_packet_on_interface(
654 &self,
655 interface: &str,
656 ip_address: Ipv4Address,
657 packet: Vec<u8>,
658 ) {
659 let pending_key = (
660 alloc::string::String::from(interface),
661 u32::from_be_bytes(ip_address.0),
662 );
663 let mut pending = self.pending.write();
664
665 if let Some(entry) = pending.get_mut(&pending_key) {
666 entry.packet_queue.lock().push(packet);
667 } else {
668 let ip_bytes = ip_address.0;
671 early_println!(
672 "[ARP] Creating pending entry for {}.{}.{}.{} to queue packet",
673 ip_bytes[0],
674 ip_bytes[1],
675 ip_bytes[2],
676 ip_bytes[3]
677 );
678 let mut queue = Vec::new();
679 queue.push(packet);
680 pending.insert(
681 pending_key,
682 ArpPendingEntry {
683 entry: ArpCacheEntry::pending(ip_address),
684 packet_queue: Mutex::new(queue),
685 },
686 );
687 }
688
689 drop(pending);
690 }
691
692 pub fn queue_packet(&self, ip_address: Ipv4Address, packet: Vec<u8>) {
694 if let Some(interface) = self.get_default_interface() {
695 self.queue_packet_on_interface(&interface, ip_address, packet);
696 }
697 }
698
699 fn get_timestamp(&self) -> u64 {
701 self.packet_counter.fetch_add(1, Ordering::SeqCst) as u64
702 }
703
704 pub fn is_resolved(&self, ip_address: Ipv4Address) -> bool {
706 self.lookup(ip_address).is_some()
707 }
708
709 pub fn is_resolved_on_interface(&self, interface: &str, ip_address: Ipv4Address) -> bool {
711 self.lookup_on_interface(interface, ip_address).is_some()
712 }
713}
714
715impl NetworkLayer for ArpLayer {
716 fn register_protocol(&self, _proto_num: u16, _handler: Arc<dyn NetworkLayer>) {
717 }
719
720 fn send(
721 &self,
722 _packet: &[u8],
723 _context: &LayerContext,
724 _next_layers: &[Arc<dyn NetworkLayer>],
725 ) -> Result<(), SocketError> {
726 Ok(())
728 }
729
730 fn receive(&self, packet: &[u8], _context: Option<&LayerContext>) -> Result<(), SocketError> {
731 let mut stats = self.stats.write();
732 stats.packets_received += 1;
733 stats.bytes_received += packet.len() as u64;
734
735 self.receive_packet(packet)
736 }
737
738 fn name(&self) -> &'static str {
739 "ARP"
740 }
741
742 fn stats(&self) -> NetworkLayerStats {
743 self.stats.read().clone()
744 }
745
746 fn as_any(&self) -> &dyn core::any::Any {
747 self
748 }
749}
750
751#[cfg(test)]
752mod tests {
753 use super::*;
754
755 #[test_case]
756 fn test_arp_packet_request() {
757 let sender_ip = [192, 168, 1, 100];
758 let target_ip = [192, 168, 1, 1];
759
760 let packet = ArpPacket::request(sender_ip, target_ip);
761
762 assert!(packet.is_request());
763 assert!(!packet.is_reply());
764 assert_eq!(packet.sender_ip, sender_ip);
765 assert_eq!(packet.target_ip, target_ip);
766 let operation_value = unsafe { core::ptr::addr_of!(packet.operation).read_unaligned() };
767 assert_eq!(operation_value, operation::REQUEST);
768 }
769
770 #[test_case]
771 fn test_arp_packet_reply() {
772 let sender_mac = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55];
773 let sender_ip = [192, 168, 1, 1];
774
775 let packet = ArpPacket::reply(sender_mac, sender_ip, sender_mac);
776
777 assert!(!packet.is_request());
778 assert!(packet.is_reply());
779 assert_eq!(packet.sender_mac, sender_mac);
780 assert_eq!(packet.target_mac, sender_mac);
781 let operation_value = unsafe { core::ptr::addr_of!(packet.operation).read_unaligned() };
782 assert_eq!(operation_value, operation::REPLY);
783 }
784
785 #[test_case]
786 fn test_arp_packet_serialization() {
787 let sender_mac = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55];
788 let sender_ip = [192, 168, 1, 1];
789 let target_ip = [192, 168, 1, 2];
790
791 let packet = ArpPacket::reply(sender_mac, sender_ip, sender_mac);
792 let bytes = packet.to_bytes();
793
794 assert_eq!(bytes.len(), 28);
795 assert_eq!(&bytes[0..2], HTYPE_ETHERNET.to_be_bytes()); assert_eq!(&bytes[2..4], PTYPE_IPV4.to_be_bytes()); assert_eq!(bytes[4], HLEN_ETHERNET); assert_eq!(bytes[5], PLEN_IPV4); assert_eq!(&bytes[6..8], operation::REPLY.to_be_bytes()); assert_eq!(&bytes[8..14], &sender_mac); assert_eq!(&bytes[14..18], &sender_ip); assert_eq!(&bytes[18..24], &sender_mac); assert_eq!(&bytes[24..28], &sender_ip); }
805
806 #[test_case]
807 fn test_arp_packet_parsing() {
808 let sender_mac = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55];
809 let sender_ip = [192, 168, 1, 1];
810
811 let original = ArpPacket::reply(sender_mac, sender_ip, sender_mac);
812 let bytes = original.to_bytes();
813
814 let parsed = ArpPacket::from_bytes(&bytes).unwrap();
815
816 let parsed_htype = unsafe { core::ptr::addr_of!(parsed.htype).read_unaligned() };
817 let original_htype = unsafe { core::ptr::addr_of!(original.htype).read_unaligned() };
818 assert_eq!(parsed_htype, original_htype);
819 let parsed_ptype = unsafe { core::ptr::addr_of!(parsed.ptype).read_unaligned() };
820 let original_ptype = unsafe { core::ptr::addr_of!(original.ptype).read_unaligned() };
821 assert_eq!(parsed_ptype, original_ptype);
822 assert_eq!(parsed.hlen, original.hlen);
823 assert_eq!(parsed.plen, original.plen);
824 let parsed_operation = unsafe { core::ptr::addr_of!(parsed.operation).read_unaligned() };
825 let original_operation =
826 unsafe { core::ptr::addr_of!(original.operation).read_unaligned() };
827 assert_eq!(parsed_operation, original_operation);
828 assert_eq!(parsed.sender_mac, original.sender_mac);
829 assert_eq!(parsed.sender_ip, original.sender_ip);
830 assert_eq!(parsed.target_mac, original.target_mac);
831 assert_eq!(parsed.target_ip, original.target_ip);
832 }
833
834 #[test_case]
835 fn test_arp_cache_entry() {
836 let ip = Ipv4Address::new(192, 168, 1, 1);
837 let mac = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55];
838
839 let entry = ArpCacheEntry::new(ip, mac);
840
841 assert_eq!(entry.ip_address, ip);
842 assert_eq!(entry.mac_address, mac);
843 assert_eq!(entry.state, ArpEntryState::Valid);
844 }
845
846 #[test_case]
847 fn test_arp_constants() {
848 assert_eq!(HTYPE_ETHERNET, 0x0001);
849 assert_eq!(PTYPE_IPV4, 0x0800);
850 assert_eq!(HLEN_ETHERNET, 6);
851 assert_eq!(PLEN_IPV4, 4);
852 }
853}