### Create and Manage TUN/TAP Interfaces in Rust Source: https://github.com/gamepad64/tunio/blob/main/README.md This example demonstrates how to initialize a default driver, configure a new network interface using the builder pattern, and perform basic read/write operations. It utilizes the standard library's Read and Write traits for data transfer. ```rust use std::io::{Read, Write}; use tunio::traits::{DriverT, InterfaceT}; use tunio::{DefaultDriver, DefaultInterface}; fn main() { let mut driver = DefaultDriver::new().unwrap(); let if_config = DefaultInterface::config_builder() .name("iface1".to_string()) .build() .unwrap(); let mut interface = DefaultInterface::new_up(&mut driver, if_config).unwrap(); let buf = [0u8; 4096]; let _ = interface.write(&buf); let mut mut_buf = [0u8; 4096]; let _ = interface.read(&mut mut_buf); } ``` -------------------------------- ### Windows Platform Configuration (Wintun) Source: https://context7.com/gamepad64/tunio/llms.txt Shows how to configure platform-specific settings for Windows using the Wintun driver. This includes setting the ring buffer capacity, interface description, and a fixed GUID. Note that Wintun on Windows only supports TUN (Layer 3), not TAP. ```rust use tunio::traits::{DriverT, InterfaceT}; use tunio::{DefaultDriver, DefaultInterface}; #[cfg(target_os = "windows")] fn main() -> Result<(), tunio::Error> { let mut driver = DefaultDriver::new()?; let config = DefaultInterface::config_builder() .name("MyVPN".to_string()) .platform(|mut builder| { builder // Ring buffer capacity: must be power of 2 between 128KiB and 64MiB .capacity(4 * 1024 * 1024) // 4 MiB // Human-readable description .description("My VPN Tunnel Interface".into()) // Fixed GUID prevents registry pollution on repeated runs .guid(0x12345678_1234_1234_1234_123456789abc_u128) .build() })? .build() .unwrap(); let interface = DefaultInterface::new_up(&mut driver, config)?; // Windows only supports TUN (Layer::L3), TAP is not available Ok(()) } ``` -------------------------------- ### Async Interface with Tokio Source: https://context7.com/gamepad64/tunio/llms.txt Demonstrates using the asynchronous interface with Tokio for reading and writing packets. It requires the 'tokio' feature to be enabled and implements `AsyncRead` and `AsyncWrite` traits. The example configures an interface, adds IP addresses, and performs asynchronous read/write operations. ```rust use futures::{AsyncReadExt, AsyncWriteExt}; use tunio::traits::{DriverT, InterfaceT}; use tunio::{DefaultAsyncInterface, DefaultDriver}; #[tokio::main] async fn main() -> Result<(), Box> { let mut driver = DefaultDriver::new()?; let mut config = DefaultAsyncInterface::config_builder(); config.name("async_tun".to_string()); #[cfg(target_os = "windows")] config .platform(|mut b| b.description("Async TUN Interface".into()).build()) .unwrap(); let config = config.build().unwrap(); let mut interface = DefaultAsyncInterface::new_up(&mut driver, config)?; // Configure IP addresses let handle = interface.handle(); handle.add_address("10.0.0.1/24".parse()?)?; handle.add_address("fd00::1/64".parse()?)?; // Async write let packet = vec![0u8; 64]; interface.write(&packet).await; // Async read with buffer management let mut buf = vec![0u8; 4096]; loop { match interface.read(&mut buf).await { Ok(n) => { println!("Received {} bytes: {:x?}", n, &buf[..n]); } Err(e) => { eprintln!("Read error: {}", e); break; } } } Ok(()) } ``` -------------------------------- ### Initialize Platform Driver with DefaultDriver Source: https://context7.com/gamepad64/tunio/llms.txt Demonstrates initializing a platform-specific driver using `DefaultDriver`. This is the first step before creating any network interfaces. `DefaultDriver` automatically selects the appropriate driver for the current operating system. ```rust use tunio::traits::DriverT; use tunio::DefaultDriver; fn main() -> Result<(), tunio::Error> { // Create a platform-specific driver instance // DefaultDriver automatically selects the correct driver for the current OS let mut driver = DefaultDriver::new()?; // Driver is now ready to create interfaces println!("Driver initialized successfully"); Ok(()) } ``` -------------------------------- ### Configuring TUN and TAP Interfaces Source: https://context7.com/gamepad64/tunio/llms.txt Shows how to use the builder pattern to configure network interfaces. It highlights the distinction between Layer 3 (TUN) interfaces, supported cross-platform, and Layer 2 (TAP) interfaces, which are Linux-specific. ```rust use tunio::{Layer, DefaultInterface}; use tunio::traits::InterfaceT; fn main() { // Layer::L3 (default) - TUN interface let tun_config = DefaultInterface::config_builder() .name("tun0".to_string()) .layer(Layer::L3) .build() .unwrap(); // Layer::L2 - TAP interface (Linux only) #[cfg(target_os = "linux")] let tap_config = DefaultInterface::config_builder() .name("tap0".to_string()) .layer(Layer::L2) .build() .unwrap(); } ``` -------------------------------- ### Network Configuration with netconfig Source: https://context7.com/gamepad64/tunio/llms.txt Illustrates how to configure network settings for a TUN interface using the `netconfig` module. The `handle()` method provides access to an `Interface` object that allows adding and removing IPv4 and IPv6 addresses with their respective subnets. ```rust use tunio::traits::{DriverT, InterfaceT}; use tunio::{DefaultDriver, DefaultInterface}; fn main() -> Result<(), Box> { let mut driver = DefaultDriver::new()?; let config = DefaultInterface::config_builder() .name("tun0".to_string()) .build() .unwrap(); let interface = DefaultInterface::new_up(&mut driver, config)?; let handle = interface.handle(); // Add IPv4 address with subnet handle.add_address("192.168.100.1/24".parse()?)?; // Add IPv6 address handle.add_address("fd3c:dea:7f96:2b14::1/64".parse()?)?; // Add another address handle.add_address("10.0.0.1/24".parse()?)?; // Remove an address handle.remove_address("10.0.0.1/24".parse()?)?; Ok(()) } ``` -------------------------------- ### Create and Manage Network Interface with InterfaceT Source: https://context7.com/gamepad64/tunio/llms.txt Shows how to create, bring up, and take down a virtual network interface using the `InterfaceT` trait and `DefaultInterface`. It includes configuring the interface name and obtaining a handle for network configuration. ```rust use tunio::traits::{DriverT, InterfaceT}; use tunio::{DefaultDriver, DefaultInterface}; fn main() -> Result<(), tunio::Error> { let mut driver = DefaultDriver::new()?; // Build interface configuration using the builder pattern let config = DefaultInterface::config_builder() .name("mytun0".to_string()) .build() .unwrap(); // Create interface and bring it up in one call let mut interface = DefaultInterface::new_up(&mut driver, config)?; // Get the netconfig handle for IP address management let handle = interface.handle(); // Bring interface down when done interface.down()?; // Bring it back up interface.up()?; Ok(()) } ``` -------------------------------- ### Configure TUN and TAP Interfaces with IfConfigBuilder Source: https://context7.com/gamepad64/tunio/llms.txt Illustrates using `IfConfigBuilder` to configure network interface parameters, specifically setting the name and layer type (L3 for TUN, L2 for TAP). The TAP configuration is conditional for Linux systems. ```rust use tunio::traits::InterfaceT; use tunio::{DefaultInterface, Layer}; fn main() { // Basic TUN interface (Layer 3, default) let tun_config = DefaultInterface::config_builder() .name("tun0".to_string()) .layer(Layer::L3) // TUN - point-to-point IP interface .build() .unwrap(); // TAP interface (Layer 2) - Linux only #[cfg(target_os = "linux")] let tap_config = DefaultInterface::config_builder() .name("tap0".to_string()) .layer(Layer::L2) // TAP - Ethernet-like interface .build() .unwrap(); } ``` -------------------------------- ### Handling Tunio Errors Source: https://context7.com/gamepad64/tunio/llms.txt Demonstrates how to match against Tunio error variants such as I/O failures, unsupported layers, and interface configuration issues. This pattern is essential for robust driver and interface initialization. ```rust use tunio::traits::{DriverT, InterfaceT}; use tunio::{DefaultDriver, DefaultInterface, Error, Layer}; fn main() { let result = DefaultDriver::new(); match result { Ok(mut driver) => { let config = DefaultInterface::config_builder() .name("test_interface".to_string()) .build() .unwrap(); match DefaultInterface::new_up(&mut driver, config) { Ok(interface) => { println!("Interface created successfully"); } Err(Error::Io(e)) => { eprintln!("I/O error (may need root/admin): {}", e); } Err(Error::LayerUnsupported(layer)) => { eprintln!("Layer {:?} not supported on this platform", layer); } Err(Error::LibraryNotLoaded { reason }) => { eprintln!("Driver library not found: {}", reason); } Err(Error::InterfaceNameTooLong(len, max)) => { eprintln!("Interface name too long: {} > {}", len, max); } Err(e) => { eprintln!("Other error: {}", e); } } } Err(e) => { eprintln!("Failed to initialize driver: {}", e); } } } ``` -------------------------------- ### Synchronous Packet Read/Write Operations Source: https://context7.com/gamepad64/tunio/llms.txt Demonstrates performing synchronous read and write operations on a network interface using the standard Rust `Read` and `Write` traits. It includes configuring an IP address and then sending and receiving packet data. ```rust use std::io::{Read, Write}; use tunio::traits::{DriverT, InterfaceT}; use tunio::{DefaultDriver, DefaultInterface}; fn main() -> Result<(), Box> { let mut driver = DefaultDriver::new()?; let config = DefaultInterface::config_builder() .name("iface1".to_string()) .build() .unwrap(); let mut interface = DefaultInterface::new_up(&mut driver, config)?; // Configure IP address using netconfig let handle = interface.handle(); handle.add_address("10.0.0.1/24".parse()?)?; // Write a packet to the interface let packet = [0u8; 64]; // Your IP packet data let bytes_written = interface.write(&packet)?; println!("Wrote {} bytes", bytes_written); // Read a packet from the interface let mut buffer = [0u8; 4096]; let bytes_read = interface.read(&mut buffer)?; println!("Read {} bytes: {:x?}", bytes_read, &buffer[..bytes_read]); Ok(()) } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.