kernel/device/network/
mod.rs

1//! Network device interface
2//!
3//! This module defines the interface for network devices in the kernel.
4//! It provides abstractions for network packet operations and device management.
5
6use alloc::{boxed::Box, vec::Vec};
7use core::any::Any;
8use spin::Mutex;
9
10use alloc::sync::Arc;
11
12use super::{Device, DeviceType, manager::DeviceManager};
13use crate::object::capability::{ControlOps, MemoryMappingOps, Selectable};
14
15/// Get the first available network device
16///
17/// This is a convenience function to get the first network device registered in the system.
18/// Returns None if no network devices are available.
19pub fn get_network_device() -> Option<Arc<dyn Device>> {
20    let manager = DeviceManager::get_manager();
21    if let Some(device_id) = manager.get_first_device_by_type(DeviceType::Network) {
22        return manager.get_device(device_id);
23    }
24    None
25}
26
27/// MAC (Media Access Control) address
28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29pub struct MacAddress([u8; 6]);
30
31impl MacAddress {
32    /// Create a new MAC address from bytes
33    pub const fn new(bytes: [u8; 6]) -> Self {
34        Self(bytes)
35    }
36
37    /// Create a MAC address from a slice (must be exactly 6 bytes)
38    pub fn from_slice(bytes: &[u8]) -> Result<Self, &'static str> {
39        if bytes.len() != 6 {
40            return Err("MAC address must be exactly 6 bytes");
41        }
42        let mut mac = [0u8; 6];
43        mac.copy_from_slice(bytes);
44        Ok(Self(mac))
45    }
46
47    /// Get the MAC address as bytes
48    pub fn as_bytes(&self) -> &[u8; 6] {
49        &self.0
50    }
51
52    /// Check if this is a broadcast MAC address (FF:FF:FF:FF:FF:FF)
53    pub fn is_broadcast(&self) -> bool {
54        self.0 == [0xFF; 6]
55    }
56
57    /// Check if this is a multicast MAC address (first bit of first byte is 1)
58    pub fn is_multicast(&self) -> bool {
59        (self.0[0] & 0x01) != 0
60    }
61
62    /// Check if this is a unicast MAC address (not multicast)
63    pub fn is_unicast(&self) -> bool {
64        !self.is_multicast()
65    }
66}
67
68/// Device-level network packet for raw data transmission
69#[derive(Debug, Clone)]
70pub struct DevicePacket {
71    /// Raw packet data
72    pub data: Vec<u8>,
73    /// Length of valid data in the packet
74    pub len: usize,
75}
76
77impl DevicePacket {
78    /// Create a new empty packet
79    pub fn new() -> Self {
80        Self {
81            data: Vec::new(),
82            len: 0,
83        }
84    }
85
86    /// Create a new packet with the given data
87    pub fn with_data(data: Vec<u8>) -> Self {
88        let len = data.len();
89        Self { data, len }
90    }
91
92    /// Create a new packet with the given capacity
93    pub fn with_capacity(capacity: usize) -> Self {
94        Self {
95            data: Vec::with_capacity(capacity),
96            len: 0,
97        }
98    }
99
100    /// Get the packet data as a slice
101    pub fn as_slice(&self) -> &[u8] {
102        &self.data[..self.len]
103    }
104
105    /// Get the packet data as a mutable slice
106    pub fn as_mut_slice(&mut self) -> &mut [u8] {
107        &mut self.data[..self.len]
108    }
109
110    /// Set the packet data
111    pub fn set_data(&mut self, data: &[u8]) {
112        self.data.clear();
113        self.data.extend_from_slice(data);
114        self.len = data.len();
115    }
116
117    /// Resize the packet data buffer
118    pub fn resize(&mut self, new_len: usize) {
119        self.data.resize(new_len, 0);
120        self.len = new_len;
121    }
122}
123
124/// Network interface configuration
125#[derive(Debug, Clone)]
126pub struct NetworkInterfaceConfig {
127    /// MAC address of the interface
128    pub mac_address: MacAddress,
129    /// Maximum Transmission Unit (MTU) in bytes
130    pub mtu: usize,
131    /// Interface name
132    pub name: &'static str,
133    /// Whether the interface supports multicast
134    pub multicast_support: bool,
135}
136
137impl NetworkInterfaceConfig {
138    /// Create a new network interface configuration
139    pub fn new(mac_address: MacAddress, mtu: usize, name: &'static str) -> Self {
140        Self {
141            mac_address,
142            mtu,
143            name,
144            multicast_support: false,
145        }
146    }
147
148    /// Enable multicast support
149    pub fn with_multicast(mut self) -> Self {
150        self.multicast_support = true;
151        self
152    }
153}
154
155/// Network operation requests
156#[derive(Debug)]
157pub enum NetworkRequest {
158    /// Get interface configuration
159    GetInterfaceConfig,
160    /// Send a packet
161    SendPacket(DevicePacket),
162    /// Receive packets (non-blocking)
163    ReceivePackets,
164    /// Set promiscuous mode
165    SetPromiscuous(bool),
166}
167
168/// Result of network operations
169#[derive(Debug)]
170pub struct NetworkResult {
171    pub request: Box<NetworkRequest>,
172    pub result: Result<NetworkResponse, &'static str>,
173}
174
175/// Response from network operations
176#[derive(Debug)]
177pub enum NetworkResponse {
178    /// Interface configuration
179    InterfaceConfig(NetworkInterfaceConfig),
180    /// Packet sent successfully
181    PacketSent,
182    /// Received packets
183    ReceivedPackets(Vec<DevicePacket>),
184    /// Operation completed successfully
185    Success,
186}
187
188/// Network device interface
189///
190/// This trait defines the interface for network devices.
191/// It provides methods for packet transmission, reception, and interface management.
192pub trait NetworkDevice: Device {
193    /// Get the network interface name
194    fn get_interface_name(&self) -> &'static str;
195
196    /// Get the MAC address of the interface
197    fn get_mac_address(&self) -> Result<MacAddress, &'static str>;
198
199    /// Get the MTU (Maximum Transmission Unit) of the interface
200    fn get_mtu(&self) -> Result<usize, &'static str>;
201
202    /// Get the full interface configuration
203    fn get_interface_config(&self) -> Result<NetworkInterfaceConfig, &'static str>;
204
205    /// Send a packet
206    fn send_packet(&self, packet: DevicePacket) -> Result<(), &'static str>;
207
208    /// Receive packets (non-blocking)
209    /// Returns all currently available packets
210    fn receive_packets(&self) -> Result<Vec<DevicePacket>, &'static str>;
211
212    /// Set promiscuous mode (receive all packets on the network)
213    fn set_promiscuous_mode(&self, enabled: bool) -> Result<(), &'static str>;
214
215    /// Initialize the network device
216    fn init_network(&mut self) -> Result<(), &'static str>;
217
218    /// Check if the link is up
219    fn is_link_up(&self) -> bool;
220
221    /// Get network device statistics
222    fn get_stats(&self) -> NetworkStats;
223}
224
225/// Ethernet-capable network device.
226///
227/// This is the concrete link-layer device type used by the IPv4/ARP stack.
228pub trait EthernetDevice: NetworkDevice {
229    /// Get the Ethernet MAC address for this device.
230    fn mac_address(&self) -> Result<MacAddress, &'static str>;
231}
232
233/// Network device statistics
234#[derive(Debug, Clone, Default)]
235pub struct NetworkStats {
236    /// Number of packets transmitted
237    pub tx_packets: u64,
238    /// Number of bytes transmitted  
239    pub tx_bytes: u64,
240    /// Number of transmission errors
241    pub tx_errors: u64,
242    /// Number of packets received
243    pub rx_packets: u64,
244    /// Number of bytes received
245    pub rx_bytes: u64,
246    /// Number of reception errors
247    pub rx_errors: u64,
248    /// Number of dropped packets
249    pub dropped: u64,
250}
251
252/// A generic implementation of a network device for testing
253pub struct GenericNetworkDevice {
254    interface_name: &'static str,
255    config: Option<NetworkInterfaceConfig>,
256    link_up: bool,
257    promiscuous: bool,
258    tx_queue: Mutex<Vec<DevicePacket>>,
259    rx_queue: Mutex<Vec<DevicePacket>>,
260    stats: Mutex<NetworkStats>,
261}
262
263impl GenericNetworkDevice {
264    /// Create a new generic network device
265    pub fn new(interface_name: &'static str) -> Self {
266        Self {
267            interface_name,
268            config: None,
269            link_up: false,
270            promiscuous: false,
271            tx_queue: Mutex::new(Vec::new()),
272            rx_queue: Mutex::new(Vec::new()),
273            stats: Mutex::new(NetworkStats::default()),
274        }
275    }
276
277    /// Set the interface configuration
278    pub fn set_config(&mut self, config: NetworkInterfaceConfig) {
279        self.config = Some(config);
280    }
281
282    /// Set link status
283    pub fn set_link_up(&mut self, up: bool) {
284        self.link_up = up;
285    }
286
287    /// Add a packet to the receive queue (for testing)
288    pub fn add_received_packet(&self, packet: DevicePacket) {
289        self.rx_queue.lock().push(packet);
290    }
291}
292
293impl Device for GenericNetworkDevice {
294    fn device_type(&self) -> super::DeviceType {
295        super::DeviceType::Network
296    }
297
298    fn name(&self) -> &'static str {
299        self.interface_name
300    }
301
302    fn as_any(&self) -> &dyn Any {
303        self
304    }
305
306    fn as_any_mut(&mut self) -> &mut dyn Any {
307        self
308    }
309
310    fn as_network_device(&self) -> Option<&dyn NetworkDevice> {
311        Some(self)
312    }
313}
314
315impl ControlOps for GenericNetworkDevice {
316    // Generic network devices don't support control operations by default
317    fn control(&self, _command: u32, _arg: usize) -> Result<i32, &'static str> {
318        Err("Control operations not supported")
319    }
320}
321
322impl MemoryMappingOps for GenericNetworkDevice {
323    fn get_mapping_info(
324        &self,
325        _offset: usize,
326        _length: usize,
327    ) -> Result<(usize, usize, bool), &'static str> {
328        Err("Memory mapping not supported by this network device")
329    }
330
331    fn on_mapped(&self, _vaddr: usize, _paddr: usize, _length: usize, _offset: usize) {
332        // Generic network devices don't support memory mapping
333    }
334
335    fn on_unmapped(&self, _vaddr: usize, _length: usize) {
336        // Generic network devices don't support memory mapping
337    }
338
339    fn supports_mmap(&self) -> bool {
340        false
341    }
342}
343
344impl Selectable for GenericNetworkDevice {
345    fn wait_until_ready(
346        &self,
347        _interest: crate::object::capability::selectable::ReadyInterest,
348        _trapframe: &mut crate::arch::Trapframe,
349        _timeout_ticks: Option<u64>,
350    ) -> crate::object::capability::selectable::SelectWaitOutcome {
351        crate::object::capability::selectable::SelectWaitOutcome::Ready
352    }
353}
354
355impl NetworkDevice for GenericNetworkDevice {
356    fn get_interface_name(&self) -> &'static str {
357        self.interface_name
358    }
359
360    fn get_mac_address(&self) -> Result<MacAddress, &'static str> {
361        self.config
362            .as_ref()
363            .map(|config| config.mac_address)
364            .ok_or("Interface not configured")
365    }
366
367    fn get_mtu(&self) -> Result<usize, &'static str> {
368        self.config
369            .as_ref()
370            .map(|config| config.mtu)
371            .ok_or("Interface not configured")
372    }
373
374    fn get_interface_config(&self) -> Result<NetworkInterfaceConfig, &'static str> {
375        self.config.clone().ok_or("Interface not configured")
376    }
377
378    fn send_packet(&self, packet: DevicePacket) -> Result<(), &'static str> {
379        if !self.link_up {
380            return Err("Link is down");
381        }
382
383        // Update statistics
384        {
385            let mut stats = self.stats.lock();
386            stats.tx_packets += 1;
387            stats.tx_bytes += packet.len as u64;
388        }
389
390        // In a real implementation, this would send the packet to hardware
391        // For testing, we just add it to the tx queue
392        self.tx_queue.lock().push(packet);
393        Ok(())
394    }
395
396    fn receive_packets(&self) -> Result<Vec<DevicePacket>, &'static str> {
397        if !self.link_up {
398            return Ok(Vec::new());
399        }
400
401        let packets = {
402            let mut rx_queue = self.rx_queue.lock();
403            core::mem::replace(&mut *rx_queue, Vec::new())
404        };
405
406        // Update statistics
407        {
408            let mut stats = self.stats.lock();
409            stats.rx_packets += packets.len() as u64;
410            stats.rx_bytes += packets.iter().map(|p| p.len as u64).sum::<u64>();
411        }
412
413        Ok(packets)
414    }
415
416    fn set_promiscuous_mode(&self, enabled: bool) -> Result<(), &'static str> {
417        // In a real implementation, this would configure hardware
418        // For testing, we just update the flag
419        // Note: This would need interior mutability in a real implementation
420        Ok(())
421    }
422
423    fn init_network(&mut self) -> Result<(), &'static str> {
424        // Generic initialization - set default config if none exists
425        if self.config.is_none() {
426            let default_mac = MacAddress::new([0x52, 0x54, 0x00, 0x12, 0x34, 0x56]);
427            let config = NetworkInterfaceConfig::new(default_mac, 1500, self.interface_name);
428            self.config = Some(config);
429        }
430        self.link_up = true;
431        Ok(())
432    }
433
434    fn is_link_up(&self) -> bool {
435        self.link_up
436    }
437
438    fn get_stats(&self) -> NetworkStats {
439        self.stats.lock().clone()
440    }
441}
442
443impl EthernetDevice for GenericNetworkDevice {
444    fn mac_address(&self) -> Result<MacAddress, &'static str> {
445        self.get_mac_address()
446    }
447}
448
449#[cfg(test)]
450mod tests {
451    use super::*;
452    use crate::device::DeviceType;
453    use alloc::vec;
454
455    #[test_case]
456    fn test_mac_address() {
457        let mac = MacAddress::new([0x00, 0x11, 0x22, 0x33, 0x44, 0x55]);
458        assert_eq!(mac.as_bytes(), &[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]);
459        assert!(!mac.is_broadcast());
460        assert!(!mac.is_multicast());
461        assert!(mac.is_unicast());
462
463        let broadcast = MacAddress::new([0xFF; 6]);
464        assert!(broadcast.is_broadcast());
465        assert!(broadcast.is_multicast());
466        assert!(!broadcast.is_unicast());
467
468        let multicast = MacAddress::new([0x01, 0x00, 0x5e, 0x00, 0x00, 0x01]);
469        assert!(!multicast.is_broadcast());
470        assert!(multicast.is_multicast());
471        assert!(!multicast.is_unicast());
472    }
473
474    #[test_case]
475    fn test_mac_address_from_slice() {
476        let bytes = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55];
477        let mac = MacAddress::from_slice(&bytes).unwrap();
478        assert_eq!(mac.as_bytes(), &bytes);
479
480        // Test invalid length
481        let invalid = [0x00, 0x11, 0x22];
482        assert!(MacAddress::from_slice(&invalid).is_err());
483    }
484
485    #[test_case]
486    fn test_network_packet() {
487        let mut packet = DevicePacket::new();
488        assert_eq!(packet.len, 0);
489        assert_eq!(packet.as_slice().len(), 0);
490
491        let data = vec![0x00, 0x11, 0x22, 0x33];
492        packet.set_data(&data);
493        assert_eq!(packet.len, 4);
494        assert_eq!(packet.as_slice(), &data);
495
496        let packet2 = DevicePacket::with_data(data.clone());
497        assert_eq!(packet2.len, 4);
498        assert_eq!(packet2.as_slice(), &data);
499
500        let mut packet3 = DevicePacket::with_capacity(10);
501        packet3.resize(6);
502        assert_eq!(packet3.len, 6);
503        assert_eq!(packet3.data.len(), 6);
504    }
505
506    #[test_case]
507    fn test_interface_config() {
508        let mac = MacAddress::new([0x00, 0x11, 0x22, 0x33, 0x44, 0x55]);
509        let config = NetworkInterfaceConfig::new(mac, 1500, "eth0");
510        assert_eq!(config.mac_address, mac);
511        assert_eq!(config.mtu, 1500);
512        assert_eq!(config.name, "eth0");
513        assert!(!config.multicast_support);
514
515        let config_mc = config.with_multicast();
516        assert!(config_mc.multicast_support);
517    }
518
519    #[test_case]
520    fn test_generic_network_device() {
521        let mut device = GenericNetworkDevice::new("test0");
522        assert_eq!(device.get_interface_name(), "test0");
523        assert_eq!(device.device_type(), DeviceType::Network);
524        assert!(!device.is_link_up());
525
526        // Test initialization
527        device.init_network().unwrap();
528        assert!(device.is_link_up());
529        assert!(device.get_mac_address().is_ok());
530        assert!(device.get_mtu().is_ok());
531        assert!(device.get_interface_config().is_ok());
532
533        // Test packet operations
534        let test_data = vec![0x00, 0x11, 0x22, 0x33, 0x44, 0x55];
535        let packet = DevicePacket::with_data(test_data);
536        assert!(device.send_packet(packet).is_ok());
537
538        // Check statistics
539        let stats = device.get_stats();
540        assert_eq!(stats.tx_packets, 1);
541        assert_eq!(stats.tx_bytes, 6);
542
543        // Test receive
544        let rx_packet = DevicePacket::with_data(vec![0xAA, 0xBB, 0xCC]);
545        device.add_received_packet(rx_packet);
546        let received = device.receive_packets().unwrap();
547        assert_eq!(received.len(), 1);
548        assert_eq!(received[0].as_slice(), &[0xAA, 0xBB, 0xCC]);
549
550        // Check updated statistics
551        let stats = device.get_stats();
552        assert_eq!(stats.rx_packets, 1);
553        assert_eq!(stats.rx_bytes, 3);
554    }
555
556    #[test_case]
557    fn test_link_down_behavior() {
558        let mut device = GenericNetworkDevice::new("test0");
559        device.init_network().unwrap();
560        device.set_link_up(false);
561
562        let packet = DevicePacket::with_data(vec![0x01, 0x02, 0x03]);
563        assert!(device.send_packet(packet).is_err());
564
565        let received = device.receive_packets().unwrap();
566        assert_eq!(received.len(), 0);
567    }
568
569    #[test_case]
570    fn test_network_stats() {
571        let mut device = GenericNetworkDevice::new("test0");
572        device.init_network().unwrap();
573
574        // Send multiple packets
575        for i in 0..5 {
576            let data = vec![i; (i + 1) as usize];
577            let packet = DevicePacket::with_data(data);
578            device.send_packet(packet).unwrap();
579        }
580
581        let stats = device.get_stats();
582        assert_eq!(stats.tx_packets, 5);
583        assert_eq!(stats.tx_bytes, 1 + 2 + 3 + 4 + 5); // Sum of packet sizes
584    }
585
586    #[test_case]
587    fn test_get_network_device_none() {
588        // Test when no network devices are registered
589        // Note: This test assumes no network devices are registered in the test environment
590        let result = get_network_device();
591        // We can't assert the exact result since it depends on test environment state
592        // But we can ensure the function doesn't panic and returns the correct type
593        match result {
594            Some(device) => {
595                // If a device is found, it should be a network device
596                assert_eq!(device.device_type(), DeviceType::Network);
597            }
598            None => {
599                // No network device found - this is expected in test environment
600            }
601        }
602    }
603}