kernel/network/
arp.rs

1//! ARP (Address Resolution Protocol)
2//!
3//! This module provides ARP implementation for resolving IP addresses to MAC addresses.
4//! It implements the NetworkLayer trait and manages an ARP cache.
5
6use 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
18/// ARP operation types
19pub mod operation {
20    /// ARP request
21    pub const REQUEST: u16 = 0x0001;
22    /// ARP reply
23    pub const REPLY: u16 = 0x0002;
24}
25
26/// Hardware type (Ethernet)
27pub const HTYPE_ETHERNET: u16 = 0x0001;
28
29/// Protocol type (IPv4)
30pub const PTYPE_IPV4: u16 = 0x0800;
31
32/// Hardware address length for Ethernet (6 bytes)
33pub const HLEN_ETHERNET: u8 = 6;
34
35/// Protocol address length for IPv4 (4 bytes)
36pub const PLEN_IPV4: u8 = 4;
37
38/// ARP packet header (28 bytes)
39#[derive(Debug, Clone, Copy)]
40#[repr(C, packed)]
41pub struct ArpPacket {
42    /// Hardware type (e.g., Ethernet)
43    pub htype: u16,
44    /// Protocol type (e.g., IPv4)
45    pub ptype: u16,
46    /// Hardware address length
47    pub hlen: u8,
48    /// Protocol address length
49    pub plen: u8,
50    /// Operation (request/reply)
51    pub operation: u16,
52    /// Sender hardware address
53    pub sender_mac: [u8; 6],
54    /// Sender protocol address
55    pub sender_ip: [u8; 4],
56    /// Target hardware address (zeros in request)
57    pub target_mac: [u8; 6],
58    /// Target protocol address
59    pub target_ip: [u8; 4],
60}
61
62impl ArpPacket {
63    /// Create a new ARP packet
64    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    /// Create an ARP request
79    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    /// Create an ARP reply
87    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; // Target IP = sender IP in reply
93        packet
94    }
95
96    /// Serialize ARP packet to bytes
97    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    /// Parse ARP packet from bytes
112    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    /// Check if this is an ARP request
135    pub fn is_request(&self) -> bool {
136        self.operation == operation::REQUEST
137    }
138
139    /// Check if this is an ARP reply
140    pub fn is_reply(&self) -> bool {
141        self.operation == operation::REPLY
142    }
143}
144
145/// ARP cache entry
146#[derive(Debug, Clone)]
147pub struct ArpCacheEntry {
148    /// IP address
149    pub ip_address: Ipv4Address,
150    /// MAC address
151    pub mac_address: [u8; 6],
152    /// Timestamp when entry was created
153    pub timestamp: u64,
154    /// Entry state
155    pub state: ArpEntryState,
156}
157
158/// ARP entry state
159#[derive(Debug, Clone, Copy, PartialEq, Eq)]
160pub enum ArpEntryState {
161    /// Entry is valid
162    Valid,
163    /// Entry is pending (waiting for ARP reply)
164    Pending,
165    /// Entry has expired
166    Expired,
167}
168
169impl ArpCacheEntry {
170    /// Create a new ARP cache entry
171    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    /// Create a pending ARP cache entry
181    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    /// Check if the ARP cache entry has expired
191    /// An entry expires after 1 minute (60000 ticks) in the Valid state
192    pub fn is_expired(&self) -> bool {
193        // For now, check if state is Expired
194        // In a real implementation, compare timestamp with current time
195        self.state == ArpEntryState::Expired || self.state == ArpEntryState::Pending
196    }
197}
198
199/// ARP cache entry with packet queue
200#[derive(Debug)]
201struct ArpPendingEntry {
202    /// Cache entry
203    entry: ArpCacheEntry,
204    /// Packets waiting for this ARP resolution
205    packet_queue: Mutex<Vec<Vec<u8>>>,
206}
207
208/// ARP cache key: (interface_name, IP as u32)
209type ArpCacheKey = (alloc::string::String, u32);
210
211/// ARP pending key: (interface_name, IP as u32)
212type ArpPendingKey = (alloc::string::String, u32);
213
214/// ARP layer
215///
216/// Manages ARP cache and handles ARP requests/replies.
217/// Implements NetworkLayer trait for integration with protocol stack.
218///
219/// # Design
220///
221/// The ARP layer is fully interface-aware:
222/// - Cache is per-interface: (interface, IP) -> MAC
223/// - Each interface has its own ARP table
224/// - MAC/IP addresses are obtained from EthernetLayer/Ipv4Layer
225pub struct ArpLayer {
226    /// ARP cache: (interface_name, IP) -> entry
227    cache: RwLock<BTreeMap<ArpCacheKey, ArpCacheEntry>>,
228    /// Pending ARP resolutions: (interface_name, IP) -> pending entry
229    pending: RwLock<BTreeMap<ArpPendingKey, ArpPendingEntry>>,
230    /// Packet timeout (in ticks)
231    timeout_ticks: u64,
232    /// Cache timeout (in ticks)
233    cache_timeout: u64,
234    /// Statistics
235    stats: RwLock<NetworkLayerStats>,
236    /// Counter for packet queueing
237    packet_counter: AtomicU32,
238}
239
240impl ArpLayer {
241    /// Create a new ARP layer
242    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,  // 1 second
247            cache_timeout: 60000, // 1 minute
248            stats: RwLock::new(NetworkLayerStats::default()),
249            packet_counter: AtomicU32::new(0),
250        })
251    }
252
253    /// Initialize and register the ARP layer with NetworkManager
254    ///
255    /// Registers with NetworkManager and registers itself with EthernetLayer
256    /// for EtherType 0x0806 (ARP).
257    ///
258    /// # Panics
259    ///
260    /// Panics if EthernetLayer is not registered (must be initialized first).
261    pub fn init(network_manager: &crate::network::NetworkManager) {
262        let layer = Self::new();
263        network_manager.register_layer("arp", layer.clone());
264
265        // Register with Ethernet layer for ARP packets (EtherType 0x0806)
266        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    /// Get local MAC address for an interface from EthernetLayer
273    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    /// Get local IP address for an interface from Ipv4Layer
282    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    /// Get default interface name from EthernetLayer
291    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    /// Look up MAC address for an IP on a specific interface
300    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    /// Look up MAC address for an IP (uses default interface)
317    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    /// Add entry to ARP cache for a specific interface
323    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    /// Add entry to ARP cache (uses default interface)
346    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    /// Remove entry from ARP cache for a specific interface
353    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    /// Remove entry from ARP cache (uses default interface)
363    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    /// Send ARP request
370    ///
371    /// # Arguments
372    ///
373    /// * `target_ip` - IP address to resolve
374    /// * `context` - Layer context (may contain "interface" key)
375    /// * `next_layers` - Layers to pass through (typically Ethernet)
376    pub fn send_request(
377        &self,
378        target_ip: Ipv4Address,
379        context: &LayerContext,
380        next_layers: &[Arc<dyn NetworkLayer>],
381    ) -> Result<(), SocketError> {
382        // Get interface from context or use default
383        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        // Get local MAC/IP for this interface
391        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        // Create ARP request packet
399        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        // Add to pending list (interface-aware key)
413        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        // Build Ethernet frame for ARP broadcast
425        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        // ARP packet bytes
435        let arp_bytes = arp_packet.to_bytes();
436
437        // Send through Ethernet layer
438        if !next_layers.is_empty() {
439            next_layers[0].send(&arp_bytes, &eth_context, &next_layers[1..])?;
440
441            // Update statistics
442            let mut stats = self.stats.write();
443            stats.packets_sent += 1;
444            stats.bytes_sent += (28 + 14) as u64; // ARP (28) + Ethernet header (14)
445        } else {
446            // Fallback: Send directly through default interface's Ethernet layer
447            if let Some(eth_layer) = get_network_manager().get_layer("ethernet") {
448                eth_layer.send(&arp_bytes, &eth_context, &[])?;
449
450                // Update statistics
451                let mut stats = self.stats.write();
452                stats.packets_sent += 1;
453                stats.bytes_sent += (28 + 14) as u64; // ARP (28) + Ethernet header (14)
454            }
455        }
456
457        Ok(())
458    }
459
460    /// Process received ARP packet
461    ///
462    /// # Arguments
463    ///
464    /// * `arp_bytes` - Raw ARP packet bytes
465    /// * `interface` - Interface the packet was received on (optional)
466    pub fn receive_packet_on_interface(
467        &self,
468        arp_bytes: &[u8],
469        interface: Option<&str>,
470    ) -> Result<(), SocketError> {
471        // Parse ARP packet
472        let arp_packet = ArpPacket::from_bytes(arp_bytes).ok_or(SocketError::InvalidPacket)?;
473
474        // Get interface (from parameter or default)
475        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        // Get local MAC/IP for this interface
488        let local_mac = self.get_local_mac_for_interface(&iface);
489        let local_ip = self.get_local_ip_for_interface(&iface);
490
491        // Get sender and target IP addresses
492        let sender_ip = Ipv4Address::from_bytes(arp_packet.sender_ip);
493        let target_ip = Ipv4Address::from_bytes(arp_packet.target_ip);
494
495        // Process ARP request
496        if arp_packet.is_request() {
497            // Cache sender information from the request (helps avoid extra ARP round-trips)
498            self.add_entry_on_interface(&iface, sender_ip, arp_packet.sender_mac);
499
500            // If we had queued packets for this sender, flush them now
501            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, &eth_context, &[]);
513                        }
514                    }
515                }
516            }
517            drop(pending);
518
519            // Check if target IP is one of our local IPs on this interface
520            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                    // Request is for us - send reply
525                    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                    // Build Ethernet frame for unicast reply
538                    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                    // Get Ethernet layer from NetworkManager
548                    if let Some(eth_layer) = get_network_manager().get_layer("ethernet") {
549                        let reply_bytes = reply.to_bytes();
550                        eth_layer.send(&reply_bytes, &eth_context, &[])?;
551                    }
552                }
553            }
554        }
555        // Process ARP reply
556        else if arp_packet.is_reply() {
557            // Check if this is not from ourselves
558            let is_from_us = local_ip.map(|ip| ip == sender_ip).unwrap_or(false);
559
560            if !is_from_us {
561                // Check if we have a pending request for this IP on this interface
562                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                    // Update cache with resolved MAC
567                    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                    // Send queued packets
586                    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                                // Set EtherType to IPv4 (queued packets are IP packets)
608                                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, &eth_context, &[]);
619                            }
620                        }
621                    }
622                } else {
623                    // Not in pending list, but cache the reply anyway
624                    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    /// Process received ARP packet (legacy interface)
648    pub fn receive_packet(&self, arp_bytes: &[u8]) -> Result<(), SocketError> {
649        self.receive_packet_on_interface(arp_bytes, None)
650    }
651
652    /// Queue a packet waiting for ARP resolution on a specific interface
653    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            // Pending entry doesn't exist yet - create one with this packet
669            // This can happen due to timing issues
670            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    /// Queue a packet waiting for ARP resolution (uses default interface)
693    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    /// Get current timestamp (placeholder - should use actual system time)
700    fn get_timestamp(&self) -> u64 {
701        self.packet_counter.fetch_add(1, Ordering::SeqCst) as u64
702    }
703
704    /// Check if IP address is resolved on default interface
705    pub fn is_resolved(&self, ip_address: Ipv4Address) -> bool {
706        self.lookup(ip_address).is_some()
707    }
708
709    /// Check if IP address is resolved on a specific interface
710    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        // ARP doesn't register upper protocols
718    }
719
720    fn send(
721        &self,
722        _packet: &[u8],
723        _context: &LayerContext,
724        _next_layers: &[Arc<dyn NetworkLayer>],
725    ) -> Result<(), SocketError> {
726        // ARP send is handled through specific methods
727        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()); // htype
796        assert_eq!(&bytes[2..4], PTYPE_IPV4.to_be_bytes()); // ptype
797        assert_eq!(bytes[4], HLEN_ETHERNET); // hlen
798        assert_eq!(bytes[5], PLEN_IPV4); // plen
799        assert_eq!(&bytes[6..8], operation::REPLY.to_be_bytes()); // operation
800        assert_eq!(&bytes[8..14], &sender_mac); // sender_mac
801        assert_eq!(&bytes[14..18], &sender_ip); // sender_ip
802        assert_eq!(&bytes[18..24], &sender_mac); // target_mac
803        assert_eq!(&bytes[24..28], &sender_ip); // target_ip
804    }
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}