kernel/network/protocol_stack.rs
1//! Protocol stack abstraction for network protocols
2//!
3//! This module provides the infrastructure for protocol stacks (TCP/IP, UDP, etc.)
4//! to be integrated with Scarlet's socket system.
5//!
6//! # Design
7//!
8//! Protocol stacks bridge between high-level SocketObject and low-level network devices.
9//! They handle protocol-specific operations like:
10//! - Packet encapsulation/decapsulation
11//! - Connection state management
12//! - Error handling and retransmission
13//! - Flow control and congestion control
14//!
15//! # Architecture
16//!
17//! ```text
18//! Application
19//! ↓
20//! SocketObject (ABI-specific, e.g., Linux TCP socket)
21//! ↓
22//! ProtocolStack (TCP/IP, UDP, etc.)
23//! ↓
24//! NetworkDevice (Ethernet, WiFi, etc.)
25//! ```
26//!
27//! # Layered Protocol Architecture
28//!
29//! The new NetworkLayer trait provides a flexible, composable protocol stack:
30//!
31//! ```text
32//! Socket Layer
33//! ↓
34//! Transport Layer (TCP=6, UDP=17)
35//! ↓ (register_protocol)
36//! Network Layer (IP)
37//! ↓ (register_protocol)
38//! Link Layer (Ethernet, InfiniBand)
39//! ↓
40//! Physical Device
41//! ```
42//!
43//! Each layer can:
44//! - Register protocol handlers for upper layers
45//! - Send packets to multiple lower layers
46//! - Route based on protocol numbers
47
48use alloc::{collections::BTreeMap, string::String, sync::Arc, vec, vec::Vec};
49use spin::RwLock;
50
51use super::socket::{SocketDomain, SocketError, SocketObject, SocketProtocol, SocketType};
52use crate::device::network::DevicePacket;
53
54/// Protocol stack statistics
55#[derive(Debug, Clone, Default)]
56pub struct ProtocolStackStats {
57 /// Number of packets sent
58 pub packets_sent: u64,
59 /// Number of bytes sent
60 pub bytes_sent: u64,
61 /// Number of packets received
62 pub packets_received: u64,
63 /// Number of bytes received
64 pub bytes_received: u64,
65 /// Number of packets dropped
66 pub packets_dropped: u64,
67 /// Number of protocol errors
68 pub protocol_errors: u64,
69 /// Number of active connections
70 pub active_connections: u64,
71}
72
73/// Context passed between network layers for routing decisions
74///
75/// This structure carries routing information through the protocol stack,
76/// allowing each layer to add or consume information needed for proper
77/// packet delivery. This is designed to be **protocol-agnostic** and avoids
78/// hard-coding specific protocol fields like IP addresses.
79///
80/// # Design Philosophy
81///
82/// - **Protocol-agnostic**: No IP addresses or protocol-specific fields in core structure
83/// - **Flexible key-value store**: Each protocol layer can add/read arbitrary data
84/// - **Layer composition**: Enables proper separation without tight coupling
85/// - **Follows @petitstrawberry's guidance**: Generic, not tied to specific protocols
86///
87/// # Example Flow
88///
89/// ```rust,ignore
90/// // TCP layer creates context with its info
91/// let mut ctx = LayerContext::new();
92/// ctx.set("tcp_src_port", &5000u16.to_be_bytes());
93/// ctx.set("tcp_dst_port", &80u16.to_be_bytes());
94///
95/// // TCP layer sends to IP, IP adds its info
96/// let ip_src = [192, 168, 1, 100];
97/// let ip_dst = [192, 168, 1, 1];
98/// ctx.set("ip_src", &ip_src);
99/// ctx.set("ip_dst", &ip_dst);
100/// ctx.set("ip_protocol", &[6]); // TCP
101///
102/// // IP layer sends to Ethernet, Ethernet performs ARP
103/// // Ethernet can read "ip_dst" to determine MAC address
104/// ```
105#[derive(Debug, Clone, Default)]
106pub struct LayerContext {
107 /// Protocol-agnostic key-value store for routing information
108 /// Each layer can add/read arbitrary data needed for packet delivery
109 ///
110 /// Common keys (convention, not enforced):
111 /// - "ip_src", "ip_dst": IPv4/IPv6 addresses
112 /// - "tcp_src_port", "tcp_dst_port": TCP ports
113 /// - "udp_src_port", "udp_dst_port": UDP ports
114 /// - "ip_protocol": Protocol number (6=TCP, 17=UDP)
115 /// - "ttl": Time-to-live
116 /// - "tos": Type of service
117 pub info: BTreeMap<String, Vec<u8>>,
118}
119
120impl LayerContext {
121 /// Create a new empty LayerContext
122 pub fn new() -> Self {
123 Self::default()
124 }
125
126 /// Set a value in the context
127 pub fn set(&mut self, key: &str, value: &[u8]) {
128 self.info.insert(String::from(key), value.to_vec());
129 }
130
131 /// Get a value from the context
132 pub fn get(&self, key: &str) -> Option<&[u8]> {
133 self.info.get(key).map(|v| v.as_slice())
134 }
135
136 /// Check if a key exists
137 pub fn contains(&self, key: &str) -> bool {
138 self.info.contains_key(key)
139 }
140}
141
142/// Configuration for socket creation and layer binding
143///
144/// This structure carries configuration from socket creation down through
145/// the protocol layers, allowing each layer to extract the information it
146/// needs to properly configure the socket.
147///
148/// # Design Philosophy
149///
150/// - **Solves @petitstrawberry's question**: How does IP layer get IP address?
151/// How does TCP layer get port number? Answer: Through SocketConfig at socket creation.
152/// - **Protocol-agnostic**: Generic key-value store, not tied to specific protocols
153/// - **Per-socket configuration**: Each socket gets configured independently
154///
155/// # Example: Socket Creation with Configuration
156///
157/// ```rust,ignore
158/// // User creates TCP socket and binds to address
159/// let mut config = SocketConfig::new();
160/// config.set("ip_local", &[192, 168, 1, 100]);
161/// config.set("tcp_local_port", &5000u16.to_be_bytes());
162///
163/// // Socket factory creates socket with config
164/// let socket = tcp_socket_factory(&config)?;
165///
166/// // Inside TcpSocket::new():
167/// // - TCP layer extracts "tcp_local_port" for its state
168/// // - IP layer extracts "ip_local" for source address
169/// // - Ethernet layer might extract interface name
170///
171/// // Later, when connect() is called:
172/// config.set("ip_remote", &[192, 168, 1, 1]);
173/// config.set("tcp_remote_port", &80u16.to_be_bytes());
174/// socket.connect(&config)?;
175/// ```
176#[derive(Debug, Clone, Default)]
177pub struct SocketConfig {
178 /// Protocol-agnostic configuration parameters
179 ///
180 /// Common keys (convention, not enforced):
181 /// - "ip_local": Local IP address (IPv4 or IPv6 bytes)
182 /// - "ip_remote": Remote IP address
183 /// - "tcp_local_port": TCP local port (u16 big-endian)
184 /// - "tcp_remote_port": TCP remote port
185 /// - "udp_local_port": UDP local port
186 /// - "udp_remote_port": UDP remote port
187 /// - "interface": Network interface name
188 pub params: BTreeMap<String, Vec<u8>>,
189}
190
191impl SocketConfig {
192 /// Create a new empty configuration
193 pub fn new() -> Self {
194 Self::default()
195 }
196
197 /// Set a configuration parameter
198 pub fn set(&mut self, key: &str, value: &[u8]) {
199 self.params.insert(String::from(key), value.to_vec());
200 }
201
202 /// Get a configuration parameter
203 pub fn get(&self, key: &str) -> Option<&[u8]> {
204 self.params.get(key).map(|v| v.as_slice())
205 }
206
207 /// Get a u16 value (for ports)
208 pub fn get_u16(&self, key: &str) -> Option<u16> {
209 self.get(key).and_then(|v| {
210 if v.len() >= 2 {
211 Some(u16::from_be_bytes([v[0], v[1]]))
212 } else {
213 None
214 }
215 })
216 }
217
218 /// Get an IPv4 address
219 pub fn get_ipv4(&self, key: &str) -> Option<[u8; 4]> {
220 self.get(key).and_then(|v| {
221 if v.len() >= 4 {
222 Some([v[0], v[1], v[2], v[3]])
223 } else {
224 None
225 }
226 })
227 }
228}
229
230/// Network layer trait for composable protocol stacks
231///
232/// This trait enables building flexible protocol stacks where each layer
233/// is independent and can be composed at runtime. Layers communicate through
234/// protocol numbers (e.g., IP uses protocol 6 for TCP, 17 for UDP).
235///
236/// # Design Philosophy (VFS Pattern)
237///
238/// Following VFS architecture where filesystems are shared singletons:
239/// - **NetworkLayer = FileSystemOperations**: Shared protocol implementation
240/// - **SocketObject = FileObject**: Per-connection handle with references to layers
241/// - **NetworkManager = VfsManager**: Global registry of protocol layer instances
242///
243/// Each NetworkLayer instance is shared across all sockets, similar to how
244/// a filesystem (ext2, tmpfs) is shared across all file handles. Per-socket
245/// state lives in SocketObject, not in NetworkLayer.
246///
247/// # Shared vs Per-Socket State
248///
249/// **NetworkLayer (shared, stateless for protocol logic):**
250/// - Protocol logic and packet processing
251/// - Routing tables, ARP cache (shared state)
252/// - Registered protocol handlers
253/// - Like: ext2 driver, tmpfs implementation
254///
255/// **SocketObject (per-socket, stateful):**
256/// - Connection state (ports, addresses) - configured via SocketConfig
257/// - Send/receive buffers
258/// - References to NetworkLayer instances
259/// - Like: FileObject with seek position, flags
260///
261/// # Socket Configuration Flow
262///
263/// 1. User creates socket: `socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)`
264/// 2. User binds: `bind(sockfd, {192.168.1.100:5000})`
265/// 3. ABI creates SocketConfig with "ip_local" and "tcp_local_port"
266/// 4. Socket factory creates SocketObject, passing config to each layer
267/// 5. TCP layer extracts port, IP layer extracts address
268/// 6. Socket handle stores references to shared layers + per-socket state
269///
270/// # Example: IP Layer (Shared Singleton)
271///
272/// ```rust,ignore
273/// struct IpLayer {
274/// protocols: RwLock<BTreeMap<u16, Arc<dyn NetworkLayer>>>, // Shared
275/// routing_table: RwLock<RoutingTable>, // Shared
276/// arp_cache: RwLock<ArpCache>, // Shared
277/// }
278///
279/// impl NetworkLayer for IpLayer {
280/// fn send(&self, packet: &[u8], context: &LayerContext,
281/// next_layers: &[Arc<dyn NetworkLayer>]) -> Result<(), SocketError> {
282/// // Extract destination IP from protocol-agnostic context
283/// let dest_ip = context.get("ip_dst")
284/// .ok_or(SocketError::InvalidPacket)?;
285///
286/// // Add IP header with destination
287/// let ip_packet = add_ip_header(packet, dest_ip);
288///
289/// // Route to lower layer (Ethernet, InfiniBand, etc.)
290/// for layer in next_layers {
291/// if let Ok(()) = layer.send(&ip_packet, context, &[]) {
292/// return Ok(());
293/// }
294/// }
295/// Err(SocketError::NoRoute)
296/// }
297///
298/// fn receive(&self, packet: &[u8], context: Option<&LayerContext>) -> Result<(), SocketError> {
299/// // Parse IP header
300/// let (proto_num, payload) = parse_ip_header(packet)?;
301///
302/// // Route to registered protocol handler
303/// if let Some(handler) = self.protocols.read().get(&proto_num) {
304/// handler.receive(payload, context)
305/// } else {
306/// Err(SocketError::ProtocolNotSupported)
307/// }
308/// }
309/// }
310/// ```
311///
312/// # Per-Task NetworkManager (Future)
313///
314/// Like VfsManager can be per-task for filesystem namespace isolation,
315/// NetworkManager can be per-task for network namespace isolation:
316///
317/// ```rust,ignore
318/// // Container gets isolated NetworkManager
319/// let container_net = Arc::new(NetworkManager::new());
320///
321/// // Share Ethernet layer (driver access), but separate IP/TCP
322/// let shared_eth = global_net_manager.get_layer("ethernet")?;
323/// container_net.register_layer("ethernet", shared_eth);
324///
325/// // Container gets its own IP and TCP layer instances
326/// container_net.register_layer("ip", Arc::new(IpLayer::new()));
327/// container_net.register_layer("tcp", Arc::new(TcpLayer::new()));
328///
329/// // Assign to task
330/// task.network_manager = Some(container_net);
331/// ```
332pub trait NetworkLayer: Send + Sync + core::any::Any {
333 /// Register a protocol handler for this layer
334 ///
335 /// Upper layer protocols register themselves with their protocol number.
336 /// For example, TCP registers as protocol 6 with the IP layer.
337 ///
338 /// # Important: Avoid Circular References
339 ///
340 /// **Registration is one-way only: lower layers register upper layers.**
341 ///
342 /// - ✅ **Correct**: Ethernet registers IP (for receive routing)
343 /// - ✅ **Correct**: IP registers TCP (for receive routing)
344 /// - ❌ **Wrong**: IP registers Ethernet (would create cycle)
345 ///
346 /// For sending, upper layers pass lower layers as **temporary references**
347 /// via the `send(next_layers)` parameter, not as permanent registrations.
348 /// This prevents circular Arc references.
349 ///
350 /// # Arguments
351 ///
352 /// * `proto_num` - Protocol number (e.g., 6 for TCP, 17 for UDP, 0x0800 for IPv4)
353 /// * `handler` - Protocol handler for this protocol number
354 ///
355 /// # Example
356 ///
357 /// ```rust,ignore
358 /// // Setup protocol hierarchy (initialization time)
359 /// ethernet.register_protocol(0x0800, ip.clone()); // IPv4 = 0x0800
360 /// ip.register_protocol(6, tcp.clone()); // TCP = 6
361 /// ip.register_protocol(17, udp.clone()); // UDP = 17
362 ///
363 /// // Sending (runtime) - pass lower layers temporarily
364 /// tcp.send(&segment, &ctx, &[ip.clone(), ethernet.clone()])?;
365 /// // No permanent reference stored, no circular dependency
366 /// ```
367 fn register_protocol(&self, proto_num: u16, handler: Arc<dyn NetworkLayer>);
368
369 /// Send a packet through this layer
370 ///
371 /// The layer encapsulates the packet with its own header and passes it
372 /// to one or more lower layers. The context contains routing information
373 /// in a protocol-agnostic key-value format.
374 ///
375 /// # Arguments
376 ///
377 /// * `packet` - Packet data to send
378 /// * `context` - Protocol-agnostic routing context (key-value pairs)
379 /// * `next_layers` - Lower layer options for transmission
380 ///
381 /// # Returns
382 ///
383 /// Ok(()) if successfully sent through at least one lower layer,
384 /// Err if all lower layers failed or routing information is insufficient
385 ///
386 /// # Example
387 ///
388 /// ```rust,ignore
389 /// // TCP layer adds its info to context
390 /// let mut ctx = LayerContext::new();
391 /// ctx.set("tcp_src_port", &5000u16.to_be_bytes());
392 /// ctx.set("tcp_dst_port", &80u16.to_be_bytes());
393 ///
394 /// tcp_layer.send(&tcp_segment, &ctx, &[ip_layer])?;
395 ///
396 /// // IP layer adds its info and forwards
397 /// ctx.set("ip_src", &[192, 168, 1, 100]);
398 /// ctx.set("ip_dst", &[192, 168, 1, 1]);
399 /// ip_layer.send(&ip_packet, &ctx, &[ethernet_layer])?;
400 /// ```
401 fn send(
402 &self,
403 packet: &[u8],
404 context: &LayerContext,
405 next_layers: &[Arc<dyn NetworkLayer>],
406 ) -> Result<(), SocketError>;
407
408 /// Receive and process a packet at this layer
409 ///
410 /// The layer parses its header, extracts the protocol number, and routes
411 /// the payload to the appropriate upper layer protocol handler.
412 ///
413 /// # Arguments
414 ///
415 /// * `packet` - Packet data received from lower layer
416 /// * `context` - Optional routing context from lower layer
417 ///
418 /// # Returns
419 ///
420 /// Ok(()) if successfully processed and delivered,
421 /// Err if packet is malformed or no handler for the protocol
422 ///
423 /// # Example
424 ///
425 /// ```rust,ignore
426 /// // IP layer receives packet, parses header, routes to TCP (proto=6)
427 /// ip_layer.receive(&packet)?;
428 /// ```
429 fn receive(&self, packet: &[u8], context: Option<&LayerContext>) -> Result<(), SocketError>;
430
431 /// Get layer name for debugging
432 fn name(&self) -> &'static str;
433
434 /// Get layer statistics
435 fn stats(&self) -> NetworkLayerStats {
436 NetworkLayerStats::default()
437 }
438
439 /// Cast to Any for safe downcasting
440 fn as_any(&self) -> &dyn core::any::Any;
441
442 /// Configure this layer with socket-specific parameters
443 ///
444 /// Called at socket bind time to configure the layer for a specific socket.
445 /// The configuration flows DOWN through the protocol stack, with each layer
446 /// extracting relevant parameters and passing the config to lower layers.
447 ///
448 /// # Purpose
449 ///
450 /// Solves the "reception configuration problem": How does IP layer know
451 /// "deliver packets for 192.168.1.100 to this socket"? Answer: This method
452 /// allows each layer to register itself for packet delivery based on the
453 /// socket's configuration.
454 ///
455 /// # Arguments
456 ///
457 /// * `config` - Socket configuration with protocol-agnostic key-value pairs
458 /// * `next_layers` - Lower layers to pass configuration to
459 ///
460 /// # Returns
461 ///
462 /// Ok(()) if configuration successful, Err if required parameters missing
463 ///
464 /// # Example
465 ///
466 /// ```rust,ignore
467 /// // User binds socket to 192.168.1.100:5000
468 /// let mut config = SocketConfig::new();
469 /// config.set("tcp_local_port", &5000u16.to_be_bytes());
470 /// config.set("ip_local", &[192, 168, 1, 100]);
471 ///
472 /// // TCP layer
473 /// tcp_layer.configure(&config, &[ip_layer, eth_layer])?;
474 ///
475 /// // Inside TCP configure():
476 /// let port = config.get_u16("tcp_local_port").ok_or(...)?;
477 /// self.register_socket(port, socket_handle);
478 /// ip_layer.configure(&config, &[eth_layer])?; // Pass down
479 ///
480 /// // IP layer registers for this address
481 /// let addr = config.get_ipv4("ip_local").ok_or(...)?;
482 /// self.register_address(addr, tcp_handler);
483 /// ```
484 fn configure(
485 &self,
486 config: &SocketConfig,
487 next_layers: &[Arc<dyn NetworkLayer>],
488 ) -> Result<(), SocketError> {
489 // Default implementation: just pass config down
490 for layer in next_layers {
491 layer.configure(config, &[])?;
492 }
493 Ok(())
494 }
495}
496
497/// Statistics for a network layer
498#[derive(Debug, Clone, Default)]
499pub struct NetworkLayerStats {
500 /// Packets sent through this layer
501 pub packets_sent: u64,
502 /// Packets received by this layer
503 pub packets_received: u64,
504 /// Packets dropped due to errors
505 pub packets_dropped: u64,
506 /// Protocol errors encountered
507 pub protocol_errors: u64,
508 /// Bytes sent through this layer
509 pub bytes_sent: u64,
510 /// Bytes received by this layer
511 pub bytes_received: u64,
512}
513
514/// Protocol stack trait for network protocols
515///
516/// This trait defines the interface for protocol stack implementations.
517/// ABI modules can implement this to provide TCP/IP, UDP, or other protocol support.
518///
519/// # Example: TCP/IP Stack
520///
521/// ```rust,ignore
522/// struct TcpIpStack {
523/// // TCP/IP implementation details
524/// }
525///
526/// impl ProtocolStack for TcpIpStack {
527/// fn domain(&self) -> SocketDomain {
528/// SocketDomain::Inet
529/// }
530///
531/// fn create_socket(&self, socket_type: SocketType, protocol: SocketProtocol)
532/// -> Result<Arc<dyn SocketObject>, SocketError> {
533/// match (socket_type, protocol) {
534/// (SocketType::Stream, SocketProtocol::Tcp) => {
535/// Ok(Arc::new(TcpSocket::new(self.clone())))
536/// }
537/// (SocketType::Datagram, SocketProtocol::Udp) => {
538/// Ok(Arc::new(UdpSocket::new(self.clone())))
539/// }
540/// _ => Err(SocketError::NotSupported),
541/// }
542/// }
543///
544/// fn process_incoming_packet(&self, packet: &DevicePacket) -> Result<(), SocketError> {
545/// // Parse IP header, route to appropriate socket
546/// // ...
547/// Ok(())
548/// }
549/// }
550/// ```
551pub trait ProtocolStack: Send + Sync {
552 /// Get the protocol stack domain
553 ///
554 /// Returns which address family this stack handles (Inet, Inet6, etc.)
555 fn domain(&self) -> SocketDomain;
556
557 /// Create a socket for this protocol stack
558 ///
559 /// # Arguments
560 ///
561 /// * `socket_type` - Type of socket (Stream, Datagram, etc.)
562 /// * `protocol` - Specific protocol (Tcp, Udp, etc.)
563 ///
564 /// # Returns
565 ///
566 /// A new socket object that uses this protocol stack
567 fn create_socket(
568 &self,
569 socket_type: SocketType,
570 protocol: SocketProtocol,
571 ) -> Result<Arc<dyn SocketObject>, SocketError>;
572
573 /// Process an incoming packet from the network device
574 ///
575 /// The protocol stack should parse the packet and deliver it to the
576 /// appropriate socket.
577 ///
578 /// # Arguments
579 ///
580 /// * `packet` - Raw packet data from network device
581 ///
582 /// # Errors
583 ///
584 /// Returns an error if the packet is malformed or cannot be processed
585 fn process_incoming_packet(&self, packet: &DevicePacket) -> Result<(), SocketError>;
586
587 /// Send a packet through the network device
588 ///
589 /// The protocol stack should encapsulate the data with appropriate headers
590 /// and send it through the network device.
591 ///
592 /// # Arguments
593 ///
594 /// * `packet` - Packet to send
595 ///
596 /// # Errors
597 ///
598 /// Returns an error if the packet cannot be sent
599 fn send_packet(&self, packet: DevicePacket) -> Result<(), SocketError>;
600
601 /// Get protocol stack statistics
602 fn statistics(&self) -> ProtocolStackStats;
603
604 /// Get a human-readable name for this protocol stack
605 fn name(&self) -> &'static str;
606
607 /// Check if the protocol stack supports a specific socket type and protocol
608 fn supports(&self, socket_type: SocketType, protocol: SocketProtocol) -> bool;
609}
610
611/// Protocol stack manager
612///
613/// Manages registered protocol stacks and routes packets to appropriate stacks.
614pub struct ProtocolStackManager {
615 /// Registered protocol stacks by domain
616 stacks: spin::RwLock<alloc::collections::BTreeMap<SocketDomain, Arc<dyn ProtocolStack>>>,
617}
618
619impl ProtocolStackManager {
620 /// Create a new protocol stack manager
621 pub const fn new() -> Self {
622 Self {
623 stacks: spin::RwLock::new(alloc::collections::BTreeMap::new()),
624 }
625 }
626
627 /// Register a protocol stack
628 ///
629 /// # Arguments
630 ///
631 /// * `stack` - Protocol stack implementation to register
632 ///
633 /// # Example
634 ///
635 /// ```rust,ignore
636 /// let tcp_ip_stack = Arc::new(TcpIpStack::new());
637 /// protocol_stack_manager.register_stack(tcp_ip_stack);
638 /// ```
639 pub fn register_stack(&self, stack: Arc<dyn ProtocolStack>) {
640 let domain = stack.domain();
641 self.stacks.write().insert(domain, stack);
642 }
643
644 /// Get a protocol stack for a specific domain
645 ///
646 /// # Arguments
647 ///
648 /// * `domain` - Socket domain (Inet, Inet6, etc.)
649 ///
650 /// # Returns
651 ///
652 /// The protocol stack for this domain, or None if not registered
653 pub fn get_stack(&self, domain: SocketDomain) -> Option<Arc<dyn ProtocolStack>> {
654 self.stacks.read().get(&domain).cloned()
655 }
656
657 /// Process an incoming packet
658 ///
659 /// Routes the packet to the appropriate protocol stack based on packet type.
660 ///
661 /// # Arguments
662 ///
663 /// * `packet` - Raw packet from network device
664 ///
665 /// # Errors
666 ///
667 /// Returns an error if no protocol stack can handle the packet
668 pub fn process_packet(&self, packet: &DevicePacket) -> Result<(), SocketError> {
669 // In a real implementation, we would parse the packet header to determine
670 // which protocol stack should handle it (e.g., check IP version, protocol field)
671
672 // For now, try each registered stack
673 let stacks = self.stacks.read();
674 for stack in stacks.values() {
675 if let Ok(()) = stack.process_incoming_packet(packet) {
676 return Ok(());
677 }
678 }
679
680 Err(SocketError::Other(
681 "No protocol stack could handle packet".into(),
682 ))
683 }
684
685 /// Get statistics for all protocol stacks
686 pub fn get_all_statistics(&self) -> Vec<(String, ProtocolStackStats)> {
687 let stacks = self.stacks.read();
688 stacks
689 .values()
690 .map(|stack| (stack.name().into(), stack.statistics()))
691 .collect()
692 }
693}
694
695impl Default for ProtocolStackManager {
696 fn default() -> Self {
697 Self::new()
698 }
699}
700
701/// Network layer manager
702///
703/// Global registry for protocol layer instances, following the VFS pattern.
704/// Each layer (Ethernet, IP, TCP) is registered once and shared across all sockets.
705///
706/// # Design Philosophy
707///
708/// - **Singleton layers**: Each protocol layer is instantiated once and shared
709/// - **Global registry**: Similar to VfsManager, provides centralized layer management
710/// - **Namespace isolation**: Future support for per-task network namespaces
711///
712/// # Example Usage
713///
714/// ```rust,ignore
715/// // During system initialization
716/// let net_manager = NetworkManager::new();
717///
718/// // Register shared protocol layers
719/// let ethernet = Arc::new(EthernetLayer::new());
720/// let ip = Arc::new(IpLayer::new());
721/// let tcp = Arc::new(TcpLayer::new());
722///
723/// net_manager.register_layer("ethernet", ethernet.clone());
724/// net_manager.register_layer("ip", ip.clone());
725/// net_manager.register_layer("tcp", tcp.clone());
726///
727/// // Setup protocol hierarchy - ONE WAY ONLY (lower -> upper)
728/// ethernet.register_protocol(0x0800, ip.clone()); // Ethernet knows about IP
729/// ip.register_protocol(6, tcp.clone()); // IP knows about TCP
730/// // ❌ DON'T: tcp.register_protocol(X, ip.clone()) - creates circular reference!
731///
732/// // Socket creation retrieves shared layers
733/// let tcp_layer = net_manager.get_layer("tcp")?;
734/// let ip_layer = net_manager.get_layer("ip")?;
735/// let eth_layer = net_manager.get_layer("ethernet")?;
736///
737/// // Create socket with references to shared layers (temporary, no cycle)
738/// let socket = TcpSocket::new(tcp_layer, ip_layer, eth_layer);
739/// ```
740///
741/// # Avoiding Circular References
742///
743/// Protocol registration creates **permanent Arc references** for receive routing.
744/// To avoid cycles:
745///
746/// 1. **Registration**: Only lower layers register upper layers (one-way)
747/// - Ethernet → IP → TCP (receive path)
748/// 2. **Sending**: Upper layers pass lower layers as temporary parameters
749/// - `send(packet, context, &[next_layer])` (no permanent storage)
750/// 3. **Sockets**: Hold references to all layers they need (temporary per-socket)
751pub fn get_network_manager() -> &'static crate::network::NetworkManager {
752 crate::network::get_network_manager()
753}
754
755#[cfg(test)]
756mod tests {
757 use super::*;
758 use crate::network::NetworkManager;
759 use alloc::{string::ToString, sync::Arc};
760 use core::sync::atomic::{AtomicU64, Ordering};
761 use spin::RwLock;
762
763 #[test_case]
764 fn test_protocol_stack_manager_creation() {
765 let manager = ProtocolStackManager::new();
766 assert!(manager.get_stack(SocketDomain::Inet4).is_none());
767 }
768
769 #[test_case]
770 fn test_protocol_stack_stats_default() {
771 let stats = ProtocolStackStats::default();
772 assert_eq!(stats.packets_sent, 0);
773 assert_eq!(stats.bytes_sent, 0);
774 assert_eq!(stats.packets_received, 0);
775 }
776
777 #[test_case]
778 fn test_network_manager_creation() {
779 let manager = NetworkManager::new();
780 assert_eq!(manager.layer_count(), 0);
781 assert!(!manager.has_layer("tcp"));
782 }
783
784 #[test_case]
785 fn test_network_manager_register_and_get() {
786 let manager = NetworkManager::new();
787
788 // Create a simple mock layer for testing
789 struct SimpleMockLayer;
790 impl NetworkLayer for SimpleMockLayer {
791 fn register_protocol(&self, _: u16, _: Arc<dyn NetworkLayer>) {}
792 fn send(
793 &self,
794 _: &[u8],
795 _: &LayerContext,
796 _: &[Arc<dyn NetworkLayer>],
797 ) -> Result<(), SocketError> {
798 Ok(())
799 }
800 fn receive(&self, _: &[u8], _: Option<&LayerContext>) -> Result<(), SocketError> {
801 Ok(())
802 }
803 fn name(&self) -> &'static str {
804 "simple"
805 }
806
807 fn as_any(&self) -> &dyn core::any::Any {
808 self
809 }
810 }
811
812 let layer = Arc::new(SimpleMockLayer);
813 manager.register_layer("test", layer.clone());
814
815 assert_eq!(manager.layer_count(), 1);
816 assert!(manager.has_layer("test"));
817 assert!(manager.get_layer("test").is_some());
818 assert!(manager.get_layer("nonexistent").is_none());
819 }
820
821 #[test_case]
822 fn test_network_manager_list_layers() {
823 let manager = NetworkManager::new();
824
825 struct SimpleMockLayer(&'static str);
826 impl NetworkLayer for SimpleMockLayer {
827 fn register_protocol(&self, _: u16, _: Arc<dyn NetworkLayer>) {}
828 fn send(
829 &self,
830 _: &[u8],
831 _: &LayerContext,
832 _: &[Arc<dyn NetworkLayer>],
833 ) -> Result<(), SocketError> {
834 Ok(())
835 }
836 fn receive(&self, _: &[u8], _: Option<&LayerContext>) -> Result<(), SocketError> {
837 Ok(())
838 }
839 fn name(&self) -> &'static str {
840 self.0
841 }
842
843 fn as_any(&self) -> &dyn core::any::Any {
844 self
845 }
846 }
847
848 manager.register_layer("tcp", Arc::new(SimpleMockLayer("tcp")));
849 manager.register_layer("udp", Arc::new(SimpleMockLayer("udp")));
850 manager.register_layer("ip", Arc::new(SimpleMockLayer("ip")));
851
852 let layers = manager.list_layers();
853 assert_eq!(layers.len(), 3);
854 assert!(layers.contains(&"tcp".to_string()));
855 assert!(layers.contains(&"udp".to_string()));
856 assert!(layers.contains(&"ip".to_string()));
857 }
858
859 #[test_case]
860 fn test_network_manager_unregister() {
861 let manager = NetworkManager::new();
862
863 struct SimpleMockLayer;
864 impl NetworkLayer for SimpleMockLayer {
865 fn register_protocol(&self, _: u16, _: Arc<dyn NetworkLayer>) {}
866 fn send(
867 &self,
868 _: &[u8],
869 _: &LayerContext,
870 _: &[Arc<dyn NetworkLayer>],
871 ) -> Result<(), SocketError> {
872 Ok(())
873 }
874 fn receive(&self, _: &[u8], _: Option<&LayerContext>) -> Result<(), SocketError> {
875 Ok(())
876 }
877 fn name(&self) -> &'static str {
878 "simple"
879 }
880
881 fn as_any(&self) -> &dyn core::any::Any {
882 self
883 }
884 }
885
886 let layer = Arc::new(SimpleMockLayer);
887 manager.register_layer("test", layer);
888
889 assert!(manager.has_layer("test"));
890
891 let removed = manager.unregister_layer("test");
892 assert!(removed.is_some());
893 assert!(!manager.has_layer("test"));
894 assert_eq!(manager.layer_count(), 0);
895 }
896
897 #[test_case]
898 fn test_global_network_manager() {
899 // Test that we can get the global manager
900 let manager = get_network_manager();
901
902 // It should start empty (or have layers from other tests, but be valid)
903 let initial_count = manager.layer_count();
904
905 struct SimpleMockLayer;
906 impl NetworkLayer for SimpleMockLayer {
907 fn register_protocol(&self, _: u16, _: Arc<dyn NetworkLayer>) {}
908 fn send(
909 &self,
910 _: &[u8],
911 _: &LayerContext,
912 _: &[Arc<dyn NetworkLayer>],
913 ) -> Result<(), SocketError> {
914 Ok(())
915 }
916 fn receive(&self, _: &[u8], _: Option<&LayerContext>) -> Result<(), SocketError> {
917 Ok(())
918 }
919 fn name(&self) -> &'static str {
920 "global_test"
921 }
922
923 fn as_any(&self) -> &dyn core::any::Any {
924 self
925 }
926 }
927
928 manager.register_layer("global_test", Arc::new(SimpleMockLayer));
929 assert_eq!(manager.layer_count(), initial_count + 1);
930 assert!(manager.has_layer("global_test"));
931 }
932
933 #[test_case]
934 fn test_layer_context_generic() {
935 // Test that LayerContext is protocol-agnostic
936 let mut ctx = LayerContext::new();
937
938 // TCP layer can add its info
939 ctx.set("tcp_src_port", &5000u16.to_be_bytes());
940 ctx.set("tcp_dst_port", &80u16.to_be_bytes());
941
942 // IP layer can add its info
943 ctx.set("ip_src", &[192, 168, 1, 100]);
944 ctx.set("ip_dst", &[192, 168, 1, 1]);
945 ctx.set("ip_protocol", &[6]); // TCP
946
947 // Ethernet layer can add its info
948 ctx.set("eth_src_mac", &[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]);
949 ctx.set("eth_dst_mac", &[0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE]);
950
951 // Verify all info is stored
952 assert_eq!(ctx.get("tcp_src_port"), Some(&[0x13, 0x88][..])); // 5000 in big-endian
953 assert_eq!(ctx.get("tcp_dst_port"), Some(&[0x00, 0x50][..])); // 80 in big-endian
954 assert_eq!(ctx.get("ip_src"), Some(&[192, 168, 1, 100][..]));
955 assert_eq!(ctx.get("ip_dst"), Some(&[192, 168, 1, 1][..]));
956 assert_eq!(ctx.get("ip_protocol"), Some(&[6][..]));
957 assert!(ctx.contains("eth_src_mac"));
958 }
959
960 #[test_case]
961 fn test_socket_config() {
962 // Test SocketConfig for socket creation
963 let mut config = SocketConfig::new();
964
965 // Set local bind address and port
966 config.set("ip_local", &[192, 168, 1, 100]);
967 config.set("tcp_local_port", &5000u16.to_be_bytes());
968
969 // Set remote address (for connect)
970 config.set("ip_remote", &[192, 168, 1, 1]);
971 config.set("tcp_remote_port", &80u16.to_be_bytes());
972
973 // Test helper methods
974 assert_eq!(config.get_ipv4("ip_local"), Some([192, 168, 1, 100]));
975 assert_eq!(config.get_ipv4("ip_remote"), Some([192, 168, 1, 1]));
976 assert_eq!(config.get_u16("tcp_local_port"), Some(5000));
977 assert_eq!(config.get_u16("tcp_remote_port"), Some(80));
978 }
979
980 // ============================================================================
981 // Realistic TCP/IP/Ethernet Mock Protocol Layers
982 // ============================================================================
983
984 /// Mock Ethernet layer simulating real Ethernet II frames
985 ///
986 /// Frame format:
987 /// - Destination MAC (6 bytes)
988 /// - Source MAC (6 bytes)
989 /// - EtherType (2 bytes): 0x0800 for IPv4, 0x0806 for ARP
990 /// - Payload (variable)
991 /// - FCS (omitted in this mock)
992 struct MockEthernetLayer {
993 name: &'static str,
994 mac_address: [u8; 6],
995 arp_table: RwLock<BTreeMap<[u8; 4], [u8; 6]>>, // IP -> MAC mapping
996 protocols: RwLock<BTreeMap<u16, Arc<dyn NetworkLayer>>>, // EtherType -> Handler
997 packets_sent: AtomicU64,
998 packets_received: AtomicU64,
999 last_sent_frame: RwLock<Vec<u8>>,
1000 }
1001
1002 impl MockEthernetLayer {
1003 fn new(name: &'static str, mac: [u8; 6]) -> Self {
1004 let layer = Self {
1005 name,
1006 mac_address: mac,
1007 arp_table: RwLock::new(BTreeMap::new()),
1008 protocols: RwLock::new(BTreeMap::new()),
1009 packets_sent: AtomicU64::new(0),
1010 packets_received: AtomicU64::new(0),
1011 last_sent_frame: RwLock::new(Vec::new()),
1012 };
1013 // Pre-populate some ARP entries for testing
1014 layer
1015 .arp_table
1016 .write()
1017 .insert([192, 168, 1, 1], [0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE]);
1018 layer
1019 .arp_table
1020 .write()
1021 .insert([192, 168, 1, 100], [0x00, 0x11, 0x22, 0x33, 0x44, 0x55]);
1022 layer
1023 }
1024
1025 fn get_last_frame(&self) -> Vec<u8> {
1026 self.last_sent_frame.read().clone()
1027 }
1028 }
1029
1030 impl NetworkLayer for MockEthernetLayer {
1031 fn register_protocol(&self, proto_num: u16, handler: Arc<dyn NetworkLayer>) {
1032 // EtherType registration (e.g., 0x0800 for IPv4, 0x0806 for ARP)
1033 self.protocols.write().insert(proto_num, handler);
1034 }
1035
1036 fn send(
1037 &self,
1038 packet: &[u8],
1039 context: &LayerContext,
1040 _next_layers: &[Arc<dyn NetworkLayer>],
1041 ) -> Result<(), SocketError> {
1042 // Extract destination IP from context for ARP lookup
1043 let dest_ip = context
1044 .get("ip_dst")
1045 .and_then(|ip| {
1046 if ip.len() >= 4 {
1047 Some([ip[0], ip[1], ip[2], ip[3]])
1048 } else {
1049 None
1050 }
1051 })
1052 .ok_or(SocketError::InvalidPacket)?;
1053
1054 // Perform ARP lookup
1055 let dest_mac = self
1056 .arp_table
1057 .read()
1058 .get(&dest_ip)
1059 .copied()
1060 .ok_or(SocketError::NoRoute)?;
1061
1062 // Build Ethernet frame
1063 let mut frame = Vec::with_capacity(14 + packet.len());
1064 frame.extend_from_slice(&dest_mac); // Destination MAC
1065 frame.extend_from_slice(&self.mac_address); // Source MAC
1066 frame.extend_from_slice(&[0x08, 0x00]); // EtherType: IPv4
1067 frame.extend_from_slice(packet); // IP packet
1068
1069 *self.last_sent_frame.write() = frame.clone();
1070 self.packets_sent.fetch_add(1, Ordering::SeqCst);
1071
1072 Ok(())
1073 }
1074
1075 fn receive(
1076 &self,
1077 frame: &[u8],
1078 _context: Option<&LayerContext>,
1079 ) -> Result<(), SocketError> {
1080 self.packets_received.fetch_add(1, Ordering::SeqCst);
1081
1082 // Parse Ethernet header
1083 if frame.len() < 14 {
1084 return Err(SocketError::InvalidPacket);
1085 }
1086
1087 let _dest_mac = &frame[0..6];
1088 let _src_mac = &frame[6..12];
1089 let ethertype = u16::from_be_bytes([frame[12], frame[13]]);
1090 let payload = &frame[14..];
1091
1092 // Route to registered protocol handler based on EtherType
1093 if let Some(handler) = self.protocols.read().get(ðertype) {
1094 handler.receive(payload, None)
1095 } else {
1096 // No handler for this EtherType, but frame is valid
1097 Ok(())
1098 }
1099 }
1100
1101 fn name(&self) -> &'static str {
1102 self.name
1103 }
1104
1105 fn as_any(&self) -> &dyn core::any::Any {
1106 self
1107 }
1108 }
1109
1110 /// Mock IP layer simulating real IPv4 packets
1111 ///
1112 /// Simplified IPv4 header:
1113 /// - Version + IHL (1 byte): 0x45 (IPv4, 20-byte header)
1114 /// - TOS (1 byte): 0x00
1115 /// - Total Length (2 bytes)
1116 /// - Identification (2 bytes)
1117 /// - Flags + Fragment Offset (2 bytes)
1118 /// - TTL (1 byte)
1119 /// - Protocol (1 byte): 6=TCP, 17=UDP
1120 /// - Header Checksum (2 bytes)
1121 /// - Source IP (4 bytes)
1122 /// - Destination IP (4 bytes)
1123 /// - Payload (variable)
1124 struct MockIpLayer {
1125 name: &'static str,
1126 local_ip: [u8; 4],
1127 protocols: RwLock<BTreeMap<u16, Arc<dyn NetworkLayer>>>,
1128 packets_sent: AtomicU64,
1129 packets_received: AtomicU64,
1130 }
1131
1132 impl MockIpLayer {
1133 fn new(name: &'static str, ip: [u8; 4]) -> Self {
1134 Self {
1135 name,
1136 local_ip: ip,
1137 protocols: RwLock::new(BTreeMap::new()),
1138 packets_sent: AtomicU64::new(0),
1139 packets_received: AtomicU64::new(0),
1140 }
1141 }
1142 }
1143
1144 impl NetworkLayer for MockIpLayer {
1145 fn register_protocol(&self, proto_num: u16, handler: Arc<dyn NetworkLayer>) {
1146 self.protocols.write().insert(proto_num, handler);
1147 }
1148
1149 fn send(
1150 &self,
1151 packet: &[u8],
1152 context: &LayerContext,
1153 next_layers: &[Arc<dyn NetworkLayer>],
1154 ) -> Result<(), SocketError> {
1155 // Extract addresses from context
1156 let src_ip = context
1157 .get("ip_src")
1158 .and_then(|ip| {
1159 if ip.len() >= 4 {
1160 Some([ip[0], ip[1], ip[2], ip[3]])
1161 } else {
1162 None
1163 }
1164 })
1165 .unwrap_or(self.local_ip);
1166
1167 let dest_ip = context
1168 .get("ip_dst")
1169 .and_then(|ip| {
1170 if ip.len() >= 4 {
1171 Some([ip[0], ip[1], ip[2], ip[3]])
1172 } else {
1173 None
1174 }
1175 })
1176 .ok_or(SocketError::InvalidPacket)?;
1177
1178 let protocol = context
1179 .get("ip_protocol")
1180 .and_then(|p| if !p.is_empty() { Some(p[0]) } else { None })
1181 .unwrap_or(6); // Default to TCP
1182
1183 // Build simplified IPv4 header (20 bytes)
1184 let total_len = (20 + packet.len()) as u16;
1185 let mut ip_packet = Vec::with_capacity(20 + packet.len());
1186
1187 ip_packet.push(0x45); // Version=4, IHL=5 (20 bytes)
1188 ip_packet.push(0x00); // TOS
1189 ip_packet.extend_from_slice(&total_len.to_be_bytes()); // Total Length
1190 ip_packet.extend_from_slice(&[0x00, 0x00]); // Identification
1191 ip_packet.extend_from_slice(&[0x00, 0x00]); // Flags + Fragment Offset
1192 ip_packet.push(64); // TTL
1193 ip_packet.push(protocol); // Protocol
1194 ip_packet.extend_from_slice(&[0x00, 0x00]); // Checksum (simplified, not calculated)
1195 ip_packet.extend_from_slice(&src_ip); // Source IP
1196 ip_packet.extend_from_slice(&dest_ip); // Destination IP
1197 ip_packet.extend_from_slice(packet); // Payload
1198
1199 self.packets_sent.fetch_add(1, Ordering::SeqCst);
1200
1201 // Forward to Ethernet layer with updated context
1202 for layer in next_layers {
1203 if layer.send(&ip_packet, context, &[]).is_ok() {
1204 return Ok(());
1205 }
1206 }
1207
1208 Err(SocketError::NoRoute)
1209 }
1210
1211 fn receive(
1212 &self,
1213 packet: &[u8],
1214 _context: Option<&LayerContext>,
1215 ) -> Result<(), SocketError> {
1216 self.packets_received.fetch_add(1, Ordering::SeqCst);
1217
1218 // Parse IP header
1219 if packet.len() < 20 {
1220 return Err(SocketError::InvalidPacket);
1221 }
1222
1223 let protocol = packet[9];
1224 let payload = &packet[20..];
1225
1226 // Route to registered protocol handler
1227 let protocols = self.protocols.read();
1228 if let Some(handler) = protocols.get(&(protocol as u16)) {
1229 handler.receive(payload, None)
1230 } else {
1231 Err(SocketError::ProtocolNotSupported)
1232 }
1233 }
1234
1235 fn name(&self) -> &'static str {
1236 self.name
1237 }
1238
1239 fn as_any(&self) -> &dyn core::any::Any {
1240 self
1241 }
1242 }
1243
1244 /// Mock TCP layer simulating real TCP segments
1245 ///
1246 /// Simplified TCP header:
1247 /// - Source Port (2 bytes)
1248 /// - Destination Port (2 bytes)
1249 /// - Sequence Number (4 bytes)
1250 /// - Acknowledgment Number (4 bytes)
1251 /// - Data Offset + Flags (2 bytes)
1252 /// - Window Size (2 bytes)
1253 /// - Checksum (2 bytes)
1254 /// - Urgent Pointer (2 bytes)
1255 /// - Payload (variable)
1256 struct MockTcpLayer {
1257 name: &'static str,
1258 packets_sent: AtomicU64,
1259 packets_received: AtomicU64,
1260 last_received_payload: RwLock<Vec<u8>>,
1261 received_payloads: RwLock<Vec<Vec<u8>>>, // Store all received payloads
1262 }
1263
1264 impl MockTcpLayer {
1265 fn new(name: &'static str) -> Self {
1266 Self {
1267 name,
1268 packets_sent: AtomicU64::new(0),
1269 packets_received: AtomicU64::new(0),
1270 last_received_payload: RwLock::new(Vec::new()),
1271 received_payloads: RwLock::new(Vec::new()),
1272 }
1273 }
1274
1275 fn get_last_received(&self) -> Vec<u8> {
1276 self.last_received_payload.read().clone()
1277 }
1278
1279 fn get_all_received(&self) -> Vec<Vec<u8>> {
1280 self.received_payloads.read().clone()
1281 }
1282 }
1283
1284 impl NetworkLayer for MockTcpLayer {
1285 fn register_protocol(&self, _proto_num: u16, _handler: Arc<dyn NetworkLayer>) {
1286 // TCP doesn't register further protocols
1287 }
1288
1289 fn send(
1290 &self,
1291 payload: &[u8],
1292 context: &LayerContext,
1293 next_layers: &[Arc<dyn NetworkLayer>],
1294 ) -> Result<(), SocketError> {
1295 // Extract ports from context
1296 let src_port = context
1297 .get("tcp_src_port")
1298 .and_then(|p| {
1299 if p.len() >= 2 {
1300 Some(u16::from_be_bytes([p[0], p[1]]))
1301 } else {
1302 None
1303 }
1304 })
1305 .unwrap_or(0);
1306
1307 let dst_port = context
1308 .get("tcp_dst_port")
1309 .and_then(|p| {
1310 if p.len() >= 2 {
1311 Some(u16::from_be_bytes([p[0], p[1]]))
1312 } else {
1313 None
1314 }
1315 })
1316 .ok_or(SocketError::InvalidPacket)?;
1317
1318 // Build simplified TCP header (20 bytes minimum)
1319 let mut tcp_segment = Vec::with_capacity(20 + payload.len());
1320
1321 tcp_segment.extend_from_slice(&src_port.to_be_bytes()); // Source Port
1322 tcp_segment.extend_from_slice(&dst_port.to_be_bytes()); // Destination Port
1323 tcp_segment.extend_from_slice(&[0x00, 0x00, 0x00, 0x01]); // Sequence Number
1324 tcp_segment.extend_from_slice(&[0x00, 0x00, 0x00, 0x00]); // Acknowledgment Number
1325 tcp_segment.extend_from_slice(&[0x50, 0x18]); // Data Offset=5 (20 bytes), Flags (PSH+ACK)
1326 tcp_segment.extend_from_slice(&[0xFF, 0xFF]); // Window Size
1327 tcp_segment.extend_from_slice(&[0x00, 0x00]); // Checksum (not calculated)
1328 tcp_segment.extend_from_slice(&[0x00, 0x00]); // Urgent Pointer
1329 tcp_segment.extend_from_slice(payload); // Payload
1330
1331 self.packets_sent.fetch_add(1, Ordering::SeqCst);
1332
1333 // Create new context with IP protocol field
1334 let mut ip_context = context.clone();
1335 ip_context.set("ip_protocol", &[6]); // TCP protocol number
1336
1337 // Send to IP layer
1338 if !next_layers.is_empty() {
1339 next_layers[0].send(&tcp_segment, &ip_context, &next_layers[1..])
1340 } else {
1341 Err(SocketError::NoRoute)
1342 }
1343 }
1344
1345 fn receive(
1346 &self,
1347 segment: &[u8],
1348 _context: Option<&LayerContext>,
1349 ) -> Result<(), SocketError> {
1350 self.packets_received.fetch_add(1, Ordering::SeqCst);
1351
1352 // Parse TCP header
1353 if segment.len() < 20 {
1354 return Err(SocketError::InvalidPacket);
1355 }
1356
1357 let _src_port = u16::from_be_bytes([segment[0], segment[1]]);
1358 let _dst_port = u16::from_be_bytes([segment[2], segment[3]]);
1359 let data_offset = (segment[12] >> 4) * 4; // Data offset in bytes
1360
1361 if segment.len() < data_offset as usize {
1362 return Err(SocketError::InvalidPacket);
1363 }
1364
1365 let payload = &segment[data_offset as usize..];
1366
1367 *self.last_received_payload.write() = payload.to_vec();
1368 self.received_payloads.write().push(payload.to_vec());
1369
1370 Ok(())
1371 }
1372
1373 fn name(&self) -> &'static str {
1374 self.name
1375 }
1376
1377 fn as_any(&self) -> &dyn core::any::Any {
1378 self
1379 }
1380 }
1381
1382 // ============================================================================
1383 // Realistic Tests with Mock TCP/IP/Ethernet
1384 // ============================================================================
1385
1386 #[test_case]
1387 fn test_realistic_tcp_ip_ethernet_stack_send() {
1388 // Create realistic protocol stack
1389 let ethernet = Arc::new(MockEthernetLayer::new(
1390 "eth0",
1391 [0x00, 0x11, 0x22, 0x33, 0x44, 0x55],
1392 ));
1393 let ip = Arc::new(MockIpLayer::new("ip", [192, 168, 1, 100]));
1394 let tcp = Arc::new(MockTcpLayer::new("tcp"));
1395
1396 // Setup ARP entry for destination
1397 ethernet
1398 .arp_table
1399 .write()
1400 .insert([192, 168, 1, 1], [0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE]);
1401
1402 // Register TCP with IP layer
1403 ip.register_protocol(6, tcp.clone());
1404
1405 // Prepare context with addresses and ports
1406 let mut ctx = LayerContext::new();
1407 ctx.set("ip_src", &[192, 168, 1, 100]);
1408 ctx.set("ip_dst", &[192, 168, 1, 1]);
1409 ctx.set("tcp_src_port", &5000u16.to_be_bytes());
1410 ctx.set("tcp_dst_port", &80u16.to_be_bytes());
1411
1412 // Send data through the stack: TCP -> IP -> Ethernet
1413 let payload = b"GET / HTTP/1.1\r\n";
1414 let result = tcp.send(payload, &ctx, &[ip.clone(), ethernet.clone()]);
1415 assert!(result.is_ok());
1416
1417 // Verify all layers processed the packet
1418 assert_eq!(tcp.packets_sent.load(Ordering::SeqCst), 1);
1419 assert_eq!(ip.packets_sent.load(Ordering::SeqCst), 1);
1420 assert_eq!(ethernet.packets_sent.load(Ordering::SeqCst), 1);
1421
1422 // Verify Ethernet frame structure
1423 let frame = ethernet.get_last_frame();
1424 assert!(frame.len() > 14); // Ethernet header + IP + TCP + payload
1425
1426 // Check Ethernet header
1427 assert_eq!(&frame[0..6], &[0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE]); // Dest MAC (from ARP)
1428 assert_eq!(&frame[6..12], &[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]); // Src MAC
1429 assert_eq!(&frame[12..14], &[0x08, 0x00]); // EtherType: IPv4
1430
1431 // Check IP header starts at offset 14
1432 assert_eq!(frame[14], 0x45); // IPv4 version + IHL
1433 assert_eq!(frame[23], 6); // Protocol: TCP
1434 assert_eq!(&frame[26..30], &[192, 168, 1, 100]); // Source IP
1435 assert_eq!(&frame[30..34], &[192, 168, 1, 1]); // Destination IP
1436
1437 // Check TCP header starts at offset 34
1438 assert_eq!(&frame[34..36], &5000u16.to_be_bytes()); // Source port
1439 assert_eq!(&frame[36..38], &80u16.to_be_bytes()); // Destination port
1440 }
1441
1442 #[test_case]
1443 fn test_realistic_tcp_ip_ethernet_receive() {
1444 // Create protocol stack
1445 let ethernet = Arc::new(MockEthernetLayer::new(
1446 "eth0",
1447 [0x00, 0x11, 0x22, 0x33, 0x44, 0x55],
1448 ));
1449 let ip = Arc::new(MockIpLayer::new("ip", [192, 168, 1, 100]));
1450 let tcp = Arc::new(MockTcpLayer::new("tcp"));
1451
1452 // Register TCP with IP
1453 ip.register_protocol(6, tcp.clone());
1454
1455 // Build a complete Ethernet frame with IP and TCP
1456 let payload = b"HTTP/1.1 200 OK\r\n";
1457 let mut frame = Vec::new();
1458
1459 // Ethernet header
1460 frame.extend_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]); // Dest MAC
1461 frame.extend_from_slice(&[0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE]); // Src MAC
1462 frame.extend_from_slice(&[0x08, 0x00]); // EtherType: IPv4
1463
1464 // IP header
1465 let ip_total_len = (20 + 20 + payload.len()) as u16;
1466 frame.push(0x45); // Version + IHL
1467 frame.push(0x00); // TOS
1468 frame.extend_from_slice(&ip_total_len.to_be_bytes()); // Total Length
1469 frame.extend_from_slice(&[0x00, 0x00]); // ID
1470 frame.extend_from_slice(&[0x00, 0x00]); // Flags
1471 frame.push(64); // TTL
1472 frame.push(6); // Protocol: TCP
1473 frame.extend_from_slice(&[0x00, 0x00]); // Checksum
1474 frame.extend_from_slice(&[192, 168, 1, 1]); // Source IP
1475 frame.extend_from_slice(&[192, 168, 1, 100]); // Dest IP
1476
1477 // TCP header
1478 frame.extend_from_slice(&80u16.to_be_bytes()); // Source port
1479 frame.extend_from_slice(&5000u16.to_be_bytes()); // Dest port
1480 frame.extend_from_slice(&[0x00, 0x00, 0x00, 0x01]); // Sequence
1481 frame.extend_from_slice(&[0x00, 0x00, 0x00, 0x00]); // Ack
1482 frame.extend_from_slice(&[0x50, 0x18]); // Data offset + flags
1483 frame.extend_from_slice(&[0xFF, 0xFF]); // Window
1484 frame.extend_from_slice(&[0x00, 0x00]); // Checksum
1485 frame.extend_from_slice(&[0x00, 0x00]); // Urgent pointer
1486 frame.extend_from_slice(payload); // Payload
1487
1488 // Receive through Ethernet layer
1489 let result = ethernet.receive(&frame, None);
1490 assert!(result.is_ok());
1491
1492 // Extract IP packet and pass to IP layer
1493 let ip_packet = &frame[14..];
1494 let result = ip.receive(ip_packet, None);
1495 assert!(result.is_ok());
1496
1497 // Verify TCP received the payload
1498 assert_eq!(tcp.packets_received.load(Ordering::SeqCst), 1);
1499 assert_eq!(tcp.get_last_received(), payload);
1500 }
1501
1502 #[test_case]
1503 fn test_realistic_two_socket_communication() {
1504 // Simulate two sockets communicating through shared protocol layers
1505
1506 // Create shared protocol layers
1507 let ethernet = Arc::new(MockEthernetLayer::new(
1508 "eth0",
1509 [0x00, 0x11, 0x22, 0x33, 0x44, 0x55],
1510 ));
1511 let ip = Arc::new(MockIpLayer::new("ip", [192, 168, 1, 100]));
1512 let tcp = Arc::new(MockTcpLayer::new("tcp"));
1513
1514 ip.register_protocol(6, tcp.clone());
1515
1516 // Socket 1: Client (192.168.1.100:5000 -> 192.168.1.1:80)
1517 let mut client_ctx = LayerContext::new();
1518 client_ctx.set("ip_src", &[192, 168, 1, 100]);
1519 client_ctx.set("ip_dst", &[192, 168, 1, 1]);
1520 client_ctx.set("tcp_src_port", &5000u16.to_be_bytes());
1521 client_ctx.set("tcp_dst_port", &80u16.to_be_bytes());
1522
1523 // Socket 2: Server (192.168.1.1:80 -> 192.168.1.100:5000)
1524 let mut server_ctx = LayerContext::new();
1525 server_ctx.set("ip_src", &[192, 168, 1, 1]);
1526 server_ctx.set("ip_dst", &[192, 168, 1, 100]);
1527 server_ctx.set("tcp_src_port", &80u16.to_be_bytes());
1528 server_ctx.set("tcp_dst_port", &5000u16.to_be_bytes());
1529
1530 // Client sends request
1531 let request = b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n";
1532 let result = tcp.send(request, &client_ctx, &[ip.clone(), ethernet.clone()]);
1533 assert!(result.is_ok());
1534
1535 // Server sends response
1536 let response = b"HTTP/1.1 200 OK\r\nContent-Length: 13\r\n\r\nHello, World!";
1537 let result = tcp.send(response, &server_ctx, &[ip.clone(), ethernet.clone()]);
1538 assert!(result.is_ok());
1539
1540 // Verify both packets were sent
1541 assert_eq!(tcp.packets_sent.load(Ordering::SeqCst), 2);
1542 assert_eq!(ip.packets_sent.load(Ordering::SeqCst), 2);
1543 assert_eq!(ethernet.packets_sent.load(Ordering::SeqCst), 2);
1544 }
1545
1546 #[test_case]
1547 fn test_realistic_end_to_end_with_protocol_agnostic_context() {
1548 // Test that LayerContext is truly protocol-agnostic
1549
1550 let ethernet = Arc::new(MockEthernetLayer::new(
1551 "eth0",
1552 [0x00, 0x11, 0x22, 0x33, 0x44, 0x55],
1553 ));
1554 let ip = Arc::new(MockIpLayer::new("ip", [192, 168, 1, 100]));
1555 let tcp = Arc::new(MockTcpLayer::new("tcp"));
1556
1557 ip.register_protocol(6, tcp.clone());
1558
1559 // Create context using only generic set/get methods
1560 let mut ctx = LayerContext::new();
1561 ctx.set("ip_src", &[192, 168, 1, 100]);
1562 ctx.set("ip_dst", &[192, 168, 1, 1]);
1563 ctx.set("tcp_src_port", &5000u16.to_be_bytes());
1564 ctx.set("tcp_dst_port", &80u16.to_be_bytes());
1565 ctx.set("custom_metadata", b"arbitrary data"); // Can add any custom data
1566
1567 // Verify context is protocol-agnostic
1568 assert!(ctx.contains("ip_src"));
1569 assert!(ctx.contains("tcp_src_port"));
1570 assert!(ctx.contains("custom_metadata"));
1571 assert_eq!(ctx.get("custom_metadata"), Some(&b"arbitrary data"[..]));
1572
1573 // Send data
1574 let data = b"Test payload";
1575 let result = tcp.send(data, &ctx, &[ip.clone(), ethernet.clone()]);
1576 assert!(result.is_ok());
1577
1578 // Verify packet was sent successfully
1579 assert_eq!(tcp.packets_sent.load(Ordering::SeqCst), 1);
1580 let frame = ethernet.get_last_frame();
1581 assert!(!frame.is_empty());
1582 }
1583
1584 // ============================================================================
1585 // Final Design Tests - Comprehensive Test Suite
1586 // ============================================================================
1587
1588 /// Simulates a socket that holds ONLY the top-level layer (TCP)
1589 struct MockTcpSocket {
1590 tcp_layer: Arc<dyn NetworkLayer>, // ONLY top layer
1591 local_port: u16,
1592 remote_port: u16,
1593 local_ip: [u8; 4],
1594 remote_ip: [u8; 4],
1595 }
1596
1597 impl MockTcpSocket {
1598 fn new(
1599 tcp_layer: Arc<dyn NetworkLayer>,
1600 config: &SocketConfig,
1601 ) -> Result<Self, SocketError> {
1602 let local_port = config
1603 .get_u16("tcp_local_port")
1604 .ok_or(SocketError::InvalidPacket)?;
1605 let local_ip = config
1606 .get_ipv4("ip_local")
1607 .ok_or(SocketError::InvalidPacket)?;
1608
1609 Ok(Self {
1610 tcp_layer,
1611 local_port,
1612 remote_port: 0,
1613 local_ip,
1614 remote_ip: [0, 0, 0, 0],
1615 })
1616 }
1617
1618 fn connect(&mut self, config: &SocketConfig) -> Result<(), SocketError> {
1619 self.remote_port = config
1620 .get_u16("tcp_remote_port")
1621 .ok_or(SocketError::InvalidPacket)?;
1622 self.remote_ip = config
1623 .get_ipv4("ip_remote")
1624 .ok_or(SocketError::InvalidPacket)?;
1625 Ok(())
1626 }
1627
1628 fn send(
1629 &self,
1630 data: &[u8],
1631 ip_layer: &Arc<dyn NetworkLayer>,
1632 eth_layer: &Arc<dyn NetworkLayer>,
1633 ) -> Result<(), SocketError> {
1634 // Build context with hints
1635 let mut ctx = LayerContext::new();
1636 ctx.set("tcp_src_port", &self.local_port.to_be_bytes());
1637 ctx.set("tcp_dst_port", &self.remote_port.to_be_bytes());
1638 ctx.set("ip_src", &self.local_ip);
1639 ctx.set("ip_dst", &self.remote_ip);
1640
1641 // Send through TCP layer - it handles the rest
1642 self.tcp_layer
1643 .send(data, &ctx, &[ip_layer.clone(), eth_layer.clone()])
1644 }
1645 }
1646
1647 #[test_case]
1648 fn test_final_design_socket_with_top_layer_only() {
1649 // Test: Socket holds ONLY TCP layer, not IP or Ethernet
1650 let tcp = Arc::new(MockTcpLayer::new("tcp"));
1651
1652 let mut config = SocketConfig::new();
1653 config.set("tcp_local_port", &5000u16.to_be_bytes());
1654 config.set("ip_local", &[192, 168, 1, 100]);
1655
1656 let socket = MockTcpSocket::new(tcp.clone(), &config);
1657 assert!(socket.is_ok());
1658
1659 let socket = socket.unwrap();
1660 assert_eq!(socket.local_port, 5000);
1661 assert_eq!(socket.local_ip, [192, 168, 1, 100]);
1662
1663 // Socket only knows about TCP layer
1664 // IP and Ethernet are passed at send time
1665 }
1666
1667 #[test_case]
1668 fn test_final_design_send_with_hints() {
1669 // Test: Sending with LayerContext hints - each layer routes autonomously
1670 let ethernet = Arc::new(MockEthernetLayer::new(
1671 "eth0",
1672 [0x00, 0x11, 0x22, 0x33, 0x44, 0x55],
1673 ));
1674 let ip = Arc::new(MockIpLayer::new("ip", [192, 168, 1, 100]));
1675 let tcp = Arc::new(MockTcpLayer::new("tcp"));
1676
1677 // Setup ARP entry
1678 ethernet
1679 .arp_table
1680 .write()
1681 .insert([192, 168, 1, 1], [0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE]);
1682
1683 ip.register_protocol(6, tcp.clone());
1684
1685 let mut config = SocketConfig::new();
1686 config.set("tcp_local_port", &5000u16.to_be_bytes());
1687 config.set("ip_local", &[192, 168, 1, 100]);
1688
1689 let mut socket = MockTcpSocket::new(tcp.clone(), &config).unwrap();
1690
1691 let mut connect_config = SocketConfig::new();
1692 connect_config.set("tcp_remote_port", &80u16.to_be_bytes());
1693 connect_config.set("ip_remote", &[192, 168, 1, 1]);
1694 socket.connect(&connect_config).unwrap();
1695
1696 // Send - each layer adds info and routes based on hints
1697 let data = b"Hello, World!";
1698 let result = socket.send(
1699 data,
1700 &(ip.clone() as Arc<dyn NetworkLayer>),
1701 &(ethernet.clone() as Arc<dyn NetworkLayer>),
1702 );
1703 assert!(result.is_ok());
1704
1705 // Verify all layers processed packet
1706 assert_eq!(tcp.packets_sent.load(Ordering::SeqCst), 1);
1707 assert_eq!(ip.packets_sent.load(Ordering::SeqCst), 1);
1708 assert_eq!(ethernet.packets_sent.load(Ordering::SeqCst), 1);
1709 }
1710
1711 #[test_case]
1712 fn test_final_design_configure_flow() {
1713 // Test: SocketConfig flows down through layers at bind time
1714
1715 // Mock layer that tracks configure calls
1716 struct ConfigTrackingLayer {
1717 name: &'static str,
1718 configured: AtomicU64,
1719 }
1720
1721 impl ConfigTrackingLayer {
1722 fn new(name: &'static str) -> Self {
1723 Self {
1724 name,
1725 configured: AtomicU64::new(0),
1726 }
1727 }
1728 }
1729
1730 impl NetworkLayer for ConfigTrackingLayer {
1731 fn register_protocol(&self, _proto_num: u16, _handler: Arc<dyn NetworkLayer>) {}
1732
1733 fn send(
1734 &self,
1735 _packet: &[u8],
1736 _context: &LayerContext,
1737 _next_layers: &[Arc<dyn NetworkLayer>],
1738 ) -> Result<(), SocketError> {
1739 Ok(())
1740 }
1741
1742 fn receive(
1743 &self,
1744 _packet: &[u8],
1745 _context: Option<&LayerContext>,
1746 ) -> Result<(), SocketError> {
1747 Ok(())
1748 }
1749
1750 fn name(&self) -> &'static str {
1751 self.name
1752 }
1753
1754 fn configure(
1755 &self,
1756 config: &SocketConfig,
1757 next_layers: &[Arc<dyn NetworkLayer>],
1758 ) -> Result<(), SocketError> {
1759 self.configured.fetch_add(1, Ordering::SeqCst);
1760
1761 // Pass config down to lower layers
1762 for layer in next_layers {
1763 layer.configure(config, &[])?;
1764 }
1765 Ok(())
1766 }
1767
1768 fn as_any(&self) -> &dyn core::any::Any {
1769 self
1770 }
1771 }
1772
1773 let tcp = Arc::new(ConfigTrackingLayer::new("tcp"));
1774 let ip = Arc::new(ConfigTrackingLayer::new("ip"));
1775 let eth = Arc::new(ConfigTrackingLayer::new("eth"));
1776
1777 let mut config = SocketConfig::new();
1778 config.set("tcp_local_port", &5000u16.to_be_bytes());
1779 config.set("ip_local", &[192, 168, 1, 100]);
1780
1781 // Configure flows TCP -> IP -> Ethernet
1782 tcp.configure(&config, &[ip.clone(), eth.clone()]).unwrap();
1783
1784 // Verify all layers were configured
1785 assert_eq!(tcp.configured.load(Ordering::SeqCst), 1);
1786 assert_eq!(ip.configured.load(Ordering::SeqCst), 1);
1787 assert_eq!(eth.configured.load(Ordering::SeqCst), 1);
1788 }
1789
1790 #[test_case]
1791 fn test_final_design_receive_routing() {
1792 // Test: Packet receive routing up through layers
1793 let ethernet = Arc::new(MockEthernetLayer::new(
1794 "eth0",
1795 [0x00, 0x11, 0x22, 0x33, 0x44, 0x55],
1796 ));
1797 let ip = Arc::new(MockIpLayer::new("ip", [192, 168, 1, 100]));
1798 let tcp = Arc::new(MockTcpLayer::new("tcp"));
1799
1800 // Register TCP with IP (proto=6)
1801 ip.register_protocol(6, tcp.clone());
1802
1803 // Build complete packet: Ethernet -> IP -> TCP
1804 let payload = b"Received data";
1805 let mut frame = Vec::new();
1806
1807 // Ethernet header
1808 frame.extend_from_slice(&[0x00, 0x11, 0x22, 0x33, 0x44, 0x55]); // Dest MAC
1809 frame.extend_from_slice(&[0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE]); // Src MAC
1810 frame.extend_from_slice(&[0x08, 0x00]); // EtherType: IPv4
1811
1812 // IP header (20 bytes)
1813 let ip_total_len = (20 + 20 + payload.len()) as u16;
1814 frame.push(0x45); // Version + IHL
1815 frame.push(0x00); // TOS
1816 frame.extend_from_slice(&ip_total_len.to_be_bytes());
1817 frame.extend_from_slice(&[0x00, 0x00, 0x00, 0x00]); // ID + Flags
1818 frame.push(64); // TTL
1819 frame.push(6); // Protocol: TCP
1820 frame.extend_from_slice(&[0x00, 0x00]); // Checksum
1821 frame.extend_from_slice(&[192, 168, 1, 1]); // Src IP
1822 frame.extend_from_slice(&[192, 168, 1, 100]); // Dst IP
1823
1824 // TCP header (20 bytes)
1825 frame.extend_from_slice(&80u16.to_be_bytes()); // Src port
1826 frame.extend_from_slice(&5000u16.to_be_bytes()); // Dst port
1827 frame.extend_from_slice(&[0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00]); // Seq + Ack
1828 frame.extend_from_slice(&[0x50, 0x18, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00]); // Offset + flags + window + checksum + urgent
1829 frame.extend_from_slice(payload);
1830
1831 // Receive through layers
1832 assert!(ethernet.receive(&frame, None).is_ok());
1833
1834 let ip_packet = &frame[14..];
1835 assert!(ip.receive(ip_packet, None).is_ok());
1836
1837 // Verify TCP received payload
1838 assert_eq!(tcp.packets_received.load(Ordering::SeqCst), 1);
1839 assert_eq!(tcp.get_last_received(), payload);
1840 }
1841
1842 #[test_case]
1843 fn test_final_design_client_server() {
1844 // Test: Full bidirectional communication between client and server
1845 let ethernet = Arc::new(MockEthernetLayer::new(
1846 "eth0",
1847 [0x00, 0x11, 0x22, 0x33, 0x44, 0x55],
1848 ));
1849 let ip = Arc::new(MockIpLayer::new("ip", [192, 168, 1, 100]));
1850 let tcp = Arc::new(MockTcpLayer::new("tcp"));
1851
1852 // Setup ARP entries for both client and server destinations
1853 ethernet
1854 .arp_table
1855 .write()
1856 .insert([192, 168, 1, 1], [0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE]);
1857 ethernet
1858 .arp_table
1859 .write()
1860 .insert([192, 168, 1, 100], [0x00, 0x11, 0x22, 0x33, 0x44, 0x55]);
1861
1862 ip.register_protocol(6, tcp.clone());
1863
1864 // Client socket: 192.168.1.100:5000
1865 let mut client_config = SocketConfig::new();
1866 client_config.set("tcp_local_port", &5000u16.to_be_bytes());
1867 client_config.set("ip_local", &[192, 168, 1, 100]);
1868 let mut client = MockTcpSocket::new(tcp.clone(), &client_config).unwrap();
1869
1870 let mut client_connect = SocketConfig::new();
1871 client_connect.set("tcp_remote_port", &80u16.to_be_bytes());
1872 client_connect.set("ip_remote", &[192, 168, 1, 1]);
1873 client.connect(&client_connect).unwrap();
1874
1875 // Server socket: 192.168.1.1:80
1876 let mut server_config = SocketConfig::new();
1877 server_config.set("tcp_local_port", &80u16.to_be_bytes());
1878 server_config.set("ip_local", &[192, 168, 1, 1]);
1879 let mut server = MockTcpSocket::new(tcp.clone(), &server_config).unwrap();
1880
1881 let mut server_connect = SocketConfig::new();
1882 server_connect.set("tcp_remote_port", &5000u16.to_be_bytes());
1883 server_connect.set("ip_remote", &[192, 168, 1, 100]);
1884 server.connect(&server_connect).unwrap();
1885
1886 // Client sends request
1887 let request = b"GET / HTTP/1.1\r\n\r\n";
1888 assert!(
1889 client
1890 .send(
1891 request,
1892 &(ip.clone() as Arc<dyn NetworkLayer>),
1893 &(ethernet.clone() as Arc<dyn NetworkLayer>)
1894 )
1895 .is_ok()
1896 );
1897
1898 // Server sends response
1899 let response = b"HTTP/1.1 200 OK\r\n\r\n";
1900 assert!(
1901 server
1902 .send(
1903 response,
1904 &(ip.clone() as Arc<dyn NetworkLayer>),
1905 &(ethernet.clone() as Arc<dyn NetworkLayer>)
1906 )
1907 .is_ok()
1908 );
1909
1910 // Verify bidirectional communication
1911 assert_eq!(tcp.packets_sent.load(Ordering::SeqCst), 2);
1912 }
1913
1914 #[test_case]
1915 fn test_final_design_error_handling() {
1916 // Test: NoRoute error when hints insufficient
1917 let ethernet = Arc::new(MockEthernetLayer::new(
1918 "eth0",
1919 [0x00, 0x11, 0x22, 0x33, 0x44, 0x55],
1920 ));
1921 let ip = Arc::new(MockIpLayer::new("ip", [192, 168, 1, 100]));
1922 let tcp = Arc::new(MockTcpLayer::new("tcp"));
1923
1924 // Missing destination IP in context
1925 let mut ctx = LayerContext::new();
1926 ctx.set("tcp_src_port", &5000u16.to_be_bytes());
1927 ctx.set("tcp_dst_port", &80u16.to_be_bytes());
1928 // Missing: ctx.set("ip_dst", ...)
1929
1930 let data = b"test";
1931 let result = tcp.send(data, &ctx, &[ip.clone(), ethernet.clone()]);
1932
1933 // Should fail with InvalidPacket due to missing IP destination
1934 assert!(result.is_err());
1935 }
1936
1937 #[test_case]
1938 fn test_final_design_multiple_sockets() {
1939 // Test: Multiple sockets sharing layers, proper routing
1940 let ethernet = Arc::new(MockEthernetLayer::new(
1941 "eth0",
1942 [0x00, 0x11, 0x22, 0x33, 0x44, 0x55],
1943 ));
1944 let ip = Arc::new(MockIpLayer::new("ip", [192, 168, 1, 100]));
1945 let tcp = Arc::new(MockTcpLayer::new("tcp"));
1946
1947 // Setup ARP entries for both destinations
1948 ethernet
1949 .arp_table
1950 .write()
1951 .insert([192, 168, 1, 1], [0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE]);
1952 ethernet
1953 .arp_table
1954 .write()
1955 .insert([192, 168, 1, 2], [0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]);
1956
1957 ip.register_protocol(6, tcp.clone());
1958
1959 // Socket 1: Port 5000
1960 let mut config1 = SocketConfig::new();
1961 config1.set("tcp_local_port", &5000u16.to_be_bytes());
1962 config1.set("ip_local", &[192, 168, 1, 100]);
1963 let mut socket1 = MockTcpSocket::new(tcp.clone(), &config1).unwrap();
1964
1965 let mut connect1 = SocketConfig::new();
1966 connect1.set("tcp_remote_port", &80u16.to_be_bytes());
1967 connect1.set("ip_remote", &[192, 168, 1, 1]);
1968 socket1.connect(&connect1).unwrap();
1969
1970 // Socket 2: Port 6000
1971 let mut config2 = SocketConfig::new();
1972 config2.set("tcp_local_port", &6000u16.to_be_bytes());
1973 config2.set("ip_local", &[192, 168, 1, 100]);
1974 let mut socket2 = MockTcpSocket::new(tcp.clone(), &config2).unwrap();
1975
1976 let mut connect2 = SocketConfig::new();
1977 connect2.set("tcp_remote_port", &443u16.to_be_bytes());
1978 connect2.set("ip_remote", &[192, 168, 1, 2]);
1979 socket2.connect(&connect2).unwrap();
1980
1981 // Both sockets send data
1982 assert!(
1983 socket1
1984 .send(
1985 b"data1",
1986 &(ip.clone() as Arc<dyn NetworkLayer>),
1987 &(ethernet.clone() as Arc<dyn NetworkLayer>)
1988 )
1989 .is_ok()
1990 );
1991 assert!(
1992 socket2
1993 .send(
1994 b"data2",
1995 &(ip.clone() as Arc<dyn NetworkLayer>),
1996 &(ethernet.clone() as Arc<dyn NetworkLayer>)
1997 )
1998 .is_ok()
1999 );
2000
2001 // Both packets sent successfully
2002 assert_eq!(tcp.packets_sent.load(Ordering::SeqCst), 2);
2003 }
2004
2005 #[test_case]
2006 fn test_final_design_protocol_agnostic() {
2007 // Test: Verify LayerContext is truly protocol-agnostic
2008 let mut ctx = LayerContext::new();
2009
2010 // Can store any protocol data
2011 ctx.set(
2012 "ipv6_src",
2013 &[0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
2014 );
2015 ctx.set(
2016 "ipv6_dst",
2017 &[0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
2018 );
2019 ctx.set("sctp_src_port", &9000u16.to_be_bytes());
2020 ctx.set("custom_protocol_field", b"arbitrary");
2021 ctx.set("qos_class", &[1]);
2022 ctx.set("debug_trace_id", &12345u32.to_be_bytes());
2023
2024 // All data retrievable
2025 assert_eq!(ctx.get("ipv6_src").unwrap().len(), 16);
2026 assert_eq!(ctx.get("sctp_src_port"), Some(&[0x23, 0x28][..]));
2027 assert_eq!(
2028 ctx.get("custom_protocol_field"),
2029 Some(b"arbitrary" as &[u8])
2030 );
2031 assert!(ctx.contains("qos_class"));
2032 assert!(ctx.contains("debug_trace_id"));
2033 }
2034
2035 #[test_case]
2036 fn test_final_design_tcp_ip_ethernet_stack() {
2037 // Test: Complete realistic stack with all layers
2038 let ethernet = Arc::new(MockEthernetLayer::new(
2039 "eth0",
2040 [0x00, 0x11, 0x22, 0x33, 0x44, 0x55],
2041 ));
2042 let ip = Arc::new(MockIpLayer::new("ip", [192, 168, 1, 100]));
2043 let tcp = Arc::new(MockTcpLayer::new("tcp"));
2044
2045 // Setup ARP entry
2046 ethernet
2047 .arp_table
2048 .write()
2049 .insert([192, 168, 1, 1], [0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE]);
2050
2051 ip.register_protocol(6, tcp.clone());
2052
2053 // Create socket and send data
2054 let mut config = SocketConfig::new();
2055 config.set("tcp_local_port", &5000u16.to_be_bytes());
2056 config.set("ip_local", &[192, 168, 1, 100]);
2057 let mut socket = MockTcpSocket::new(tcp.clone(), &config).unwrap();
2058
2059 let mut connect_config = SocketConfig::new();
2060 connect_config.set("tcp_remote_port", &80u16.to_be_bytes());
2061 connect_config.set("ip_remote", &[192, 168, 1, 1]);
2062 socket.connect(&connect_config).unwrap();
2063
2064 let payload = b"Real packet data";
2065 assert!(
2066 socket
2067 .send(
2068 payload,
2069 &(ip.clone() as Arc<dyn NetworkLayer>),
2070 &(ethernet.clone() as Arc<dyn NetworkLayer>)
2071 )
2072 .is_ok()
2073 );
2074
2075 // Verify complete packet structure
2076 let frame = ethernet.get_last_frame();
2077 assert!(frame.len() > 54); // Eth(14) + IP(20) + TCP(20)
2078
2079 // Check all headers present
2080 assert_eq!(&frame[12..14], &[0x08, 0x00]); // EtherType
2081 assert_eq!(frame[14], 0x45); // IPv4
2082 assert_eq!(frame[23], 6); // TCP protocol
2083 assert_eq!(&frame[34..36], &5000u16.to_be_bytes()); // TCP src port
2084 assert_eq!(&frame[36..38], &80u16.to_be_bytes()); // TCP dst port
2085 }
2086
2087 #[test_case]
2088 fn test_final_design_layer_isolation() {
2089 // Test: Layers operate independently without tight coupling
2090 let tcp1 = Arc::new(MockTcpLayer::new("tcp1"));
2091 let tcp2 = Arc::new(MockTcpLayer::new("tcp2"));
2092 let ip = Arc::new(MockIpLayer::new("ip", [192, 168, 1, 100]));
2093 let ethernet = Arc::new(MockEthernetLayer::new(
2094 "eth0",
2095 [0x00, 0x11, 0x22, 0x33, 0x44, 0x55],
2096 ));
2097
2098 // Setup ARP entries for both destinations
2099 ethernet
2100 .arp_table
2101 .write()
2102 .insert([192, 168, 1, 1], [0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE]);
2103 ethernet
2104 .arp_table
2105 .write()
2106 .insert([192, 168, 1, 2], [0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]);
2107
2108 // Both TCP layers can use same IP and Ethernet
2109 ip.register_protocol(6, tcp1.clone());
2110
2111 let mut ctx1 = LayerContext::new();
2112 ctx1.set("ip_dst", &[192, 168, 1, 1]);
2113 ctx1.set("tcp_dst_port", &80u16.to_be_bytes());
2114
2115 let mut ctx2 = LayerContext::new();
2116 ctx2.set("ip_dst", &[192, 168, 1, 2]);
2117 ctx2.set("tcp_dst_port", &443u16.to_be_bytes());
2118
2119 // Both send independently
2120 assert!(
2121 tcp1.send(b"data1", &ctx1, &[ip.clone(), ethernet.clone()])
2122 .is_ok()
2123 );
2124 assert!(
2125 tcp2.send(b"data2", &ctx2, &[ip.clone(), ethernet.clone()])
2126 .is_ok()
2127 );
2128
2129 // Verify independence
2130 assert_eq!(tcp1.packets_sent.load(Ordering::SeqCst), 1);
2131 assert_eq!(tcp2.packets_sent.load(Ordering::SeqCst), 1);
2132 }
2133}