### List Network Interfaces in Rust Source: https://github.com/thombles/netwatcher/blob/main/README.md Returns a HashMap mapping interface index to interface details. Useful for getting the current state of network interfaces. ```rust let interfaces = netwatcher::list_interfaces().unwrap(); for i in interfaces.values() { println!("interface {} has {} IPs", i.name, i.ips.len()); } ``` -------------------------------- ### Initialize IpRecord structures Source: https://context7.com/thombles/netwatcher/llms.txt Demonstrates creating IpRecord instances for both IPv4 and IPv6 addresses with their respective prefix lengths. ```rust use netwatcher::IpRecord; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; // IpRecord structure contains: // - ip: IpAddr (can be IPv4 or IPv6) // - prefix_len: u8 (network mask bits, e.g., 24 for /24) let ipv4_record = IpRecord { ip: IpAddr::V4(Ipv4Addr::new(192, 168, 1, 100)), prefix_len: 24, // 255.255.255.0 subnet }; let ipv6_record = IpRecord { ip: IpAddr::V6(Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 1)), prefix_len: 64, // Standard link-local prefix }; println!("IPv4: {}/{}", ipv4_record.ip, ipv4_record.prefix_len); // Output: IPv4: 192.168.1.100/24 println!("IPv6: {}/{}", ipv6_record.ip, ipv6_record.prefix_len); // Output: IPv6: fe80::1/64 ``` -------------------------------- ### Access Interface details Source: https://context7.com/thombles/netwatcher/llms.txt Shows how to iterate through network interfaces and use helper methods to filter IPv4 and IPv6 addresses. ```rust use netwatcher::{list_interfaces, Interface}; // Interface structure contains: // - index: u32 (system interface index) // - name: String (e.g., "eth0", "en0", "Ethernet") // - hw_addr: String (MAC address, may be placeholder on Android) // - ips: Vec (all IP addresses on this interface) let interfaces = netwatcher::list_interfaces().unwrap(); for (ifindex, interface) in &interfaces { println!("Interface #{}: {}", ifindex, interface.name); println!(" Hardware Address: {}", interface.hw_addr); // Use helper methods to filter by IP version print!(" IPv4 addresses: "); for ipv4 in interface.ipv4_ips() { print!("{} ", ipv4); } println!(); print!(" IPv6 addresses: "); for ipv6 in interface.ipv6_ips() { print!("{} ", ipv6); } println!(); // Or iterate all IPs with full prefix info for ip_record in &interface.ips { println!(" {}/{}", ip_record.ip, ip_record.prefix_len); } } // Example output: // Interface #1: lo // Hardware Address: 00:00:00:00:00:00 // IPv4 addresses: 127.0.0.1 // IPv6 addresses: ::1 // 127.0.0.1/8 // ::1/128 ``` -------------------------------- ### Enumerate network interfaces Source: https://context7.com/thombles/netwatcher/llms.txt Retrieves a snapshot of all network interfaces and demonstrates filtering or searching for specific interface properties. ```rust use netwatcher::{list_interfaces, Error}; use std::collections::HashMap; fn enumerate_network_interfaces() -> Result<(), Error> { // Returns HashMap where u32 is the ifindex let interfaces = list_interfaces()?; println!("Found {} network interfaces:", interfaces.len()); for interface in interfaces.values() { println!("\n{} (index {})", interface.name, interface.index); println!(" MAC: {}", interface.hw_addr); println!(" IPs: {} addresses", interface.ips.len()); for ip in &interface.ips { println!(" {}/{}", ip.ip, ip.prefix_len); } } // Find a specific interface by name if let Some(eth) = interfaces.values().find(|i| i.name.starts_with("eth")) { println!("\nFound ethernet interface: {}", eth.name); } // Check for loopback with 127.0.0.1 let has_loopback = interfaces.values().any(|iface| { iface.ips.iter().any(|record| { record.ip.to_string() == "127.0.0.1" && record.prefix_len == 8 }) }); println!("Has standard loopback: {}", has_loopback); Ok(()) } fn main() { if let Err(e) = enumerate_network_interfaces() { eprintln!("Error listing interfaces: {:?}", e); } } ``` -------------------------------- ### Implement Continuous Network Monitoring in Rust Source: https://context7.com/thombles/netwatcher/llms.txt Uses the netwatcher crate to track interface changes and provides a graceful shutdown mechanism via Ctrl+C handling. ```rust use netwatcher::{list_interfaces, watch_interfaces, Update, Error}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::time::Duration; /// Network monitor that tracks and logs all interface changes struct NetworkMonitor { running: Arc, } impl NetworkMonitor { fn new() -> Self { Self { running: Arc::new(AtomicBool::new(true)), } } fn print_interface_summary(update: &Update) { println!("\n{'='*50}"); println!("NETWORK INTERFACE SUMMARY"); println!("{'='*50}"); for (idx, iface) in &update.interfaces { println!("\n[{}] {} (MAC: {})", idx, iface.name, iface.hw_addr); let ipv4_count = iface.ipv4_ips().count(); let ipv6_count = iface.ipv6_ips().count(); println!(" IPv4: {} | IPv6: {}", ipv4_count, ipv6_count); for ip in &iface.ips { let version = if ip.ip.is_ipv4() { "v4" } else { "v6" }; println!(" [{}] {}/{}", version, ip.ip, ip.prefix_len); } } } fn print_changes(update: &Update) { let diff = &update.diff; if !diff.added.is_empty() { println!("\n+ INTERFACES ADDED:"); for idx in &diff.added { if let Some(iface) = update.interfaces.get(idx) { println!(" + {} (index {})", iface.name, idx); } } } if !diff.removed.is_empty() { println!("\n- INTERFACES REMOVED: {:?}", diff.removed); } if !diff.modified.is_empty() { println!("\n~ INTERFACES MODIFIED:"); for (idx, changes) in &diff.modified { if let Some(iface) = update.interfaces.get(idx) { println!(" ~ {}", iface.name); for ip in &changes.addrs_added { println!(" + {}/{}", ip.ip, ip.prefix_len); } for ip in &changes.addrs_removed { println!(" - {}/{}", ip.ip, ip.prefix_len); } } } } } fn start(&self) -> Result<(), Error> { println!("Starting network monitor...\n"); // Initial one-time listing println!("Initial interface scan:"); let initial = list_interfaces()?; for iface in initial.values() { println!(" Found: {} with {} IPs", iface.name, iface.ips.len()); } // Start continuous monitoring let running = self.running.clone(); let mut is_first = true; let handle = watch_interfaces(move |update| { if is_first { println!("\nInitial state received"); Self::print_interface_summary(&update); is_first = false; } else { println!("\n>>> CHANGE DETECTED <<<"); Self::print_changes(&update); Self::print_interface_summary(&update); } })?; // Run until stopped println!("\nMonitoring... Press Ctrl+C to stop.\n"); while running.load(Ordering::SeqCst) { std::thread::sleep(Duration::from_millis(100)); } drop(handle); println!("\nMonitor stopped."); Ok(()) } fn stop(&self) { self.running.store(false, Ordering::SeqCst); } } fn main() { let monitor = NetworkMonitor::new(); // Handle Ctrl+C gracefully let monitor_ref = monitor.running.clone(); ctrlc::set_handler(move || { println!("\nShutting down..."); monitor_ref.store(false, Ordering::SeqCst); }).expect("Error setting Ctrl+C handler"); if let Err(e) = monitor.start() { eprintln!("Monitor error: {:?}", e); std::process::exit(1); } } ``` -------------------------------- ### Watch for Network Interface Changes in Rust Source: https://github.com/thombles/netwatcher/blob/main/README.md Sets up a callback to be notified of network interface changes. The callback receives an update object containing the latest interface snapshot and a diff of changes. Keep the returned handle alive to continue receiving updates. ```rust let handle = netwatcher::watch_interfaces(|update| { // This callback will fire once immediately with the existing state // Update includes the latest snapshot of all interfaces println!("Current interface map: {:#?}", update.interfaces); // The `UpdateDiff` describes changes since previous callback // You can choose whether to use the snapshot, diff, or both println!("ifindexes added: {:?}", update.diff.added); println!("ifindexes removed: {:?}", update.diff.removed); for (ifindex, if_diff) in update.diff.modified { println!("Interface index {} has changed", ifindex); println!("Added IPs: {:?}", if_diff.addrs_added); println!("Removed IPs: {:?}", if_diff.addrs_removed); } }).unwrap(); // keep `handle` alive as long as you want callbacks // ... drop(handle); ``` -------------------------------- ### Android Platform Support Source: https://context7.com/thombles/netwatcher/llms.txt Information regarding the Netwatcher library's support for the Android platform. ```APIDOC ## Android Platform Support This section would detail any specific setup, requirements, or considerations for using the Netwatcher library on Android devices, such as JNI integration or context setting. ``` -------------------------------- ### Initialize Android Context via JNI Source: https://context7.com/thombles/netwatcher/llms.txt This Rust function acts as a JNI bridge to set the global Android context. It must be called from the native layer before any other netwatcher functions are used. ```rust #[no_mangle] pub unsafe extern "C" fn Java_com_example_app_MainActivity_setAndroidContext( env: JNIEnv, _class: JClass, context: jobject, ) { let env_ptr = env.get_raw(); match netwatcher::set_android_context(env_ptr, context) { Ok(_) => { log::info!("Android context set successfully"); // Verify it works by listing interfaces match netwatcher::list_interfaces() { Ok(interfaces) => { log::info!("Found {} interfaces", interfaces.len()); for iface in interfaces.values() { log::debug!(" {}: {} IPs", iface.name, iface.ips.len()); } } Err(e) => { log::error!("Failed to list interfaces: {:?}", e); } } } Err(e) => { log::error!("Failed to set Android context: {:?}", e); } } } ``` ```kotlin class MainActivity : AppCompatActivity() { companion object { init { System.loadLibrary("your_native_lib") } } private external fun setAndroidContext(context: android.content.Context) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setAndroidContext(applicationContext) // Now netwatcher functions will work } } ``` -------------------------------- ### Collect and analyze network updates in Rust Source: https://context7.com/thombles/netwatcher/llms.txt Demonstrates storing Update objects in a thread-safe collection for later analysis. The Update struct provides both a full snapshot and a diff of changes. ```rust use netwatcher::{watch_interfaces, Update, UpdateDiff, InterfaceDiff}; use std::sync::{Arc, Mutex}; // Collect updates for later analysis let updates: Arc>> = Arc::new(Mutex::new(Vec::new())); let updates_clone = updates.clone(); let handle = watch_interfaces(move |update: Update| { // Update contains: // - interfaces: HashMap - current snapshot // - diff: UpdateDiff - changes from previous state let interface_count = update.interfaces.len(); let diff = &update.diff; println!("Update received:"); println!(" Current interfaces: {}", interface_count); println!(" Added: {} interfaces", diff.added.len()); println!(" Removed: {} interfaces", diff.removed.len()); println!(" Modified: {} interfaces", diff.modified.len()); // Store for analysis updates_clone.lock().unwrap().push(update); }).unwrap(); // Wait for some updates std::thread::sleep(std::time::Duration::from_secs(10)); // Analyze collected updates let collected = updates.lock().unwrap(); println!("\nCollected {} updates total", collected.len()); for (i, update) in collected.iter().enumerate() { println!("Update #{}: {} interfaces, {} changes", i, update.interfaces.len(), update.diff.added.len() + update.diff.removed.len() + update.diff.modified.len() ); } drop(handle); ``` -------------------------------- ### set_android_context Source: https://context7.com/thombles/netwatcher/llms.txt Initializes the Netwatcher library with the Android application context. This must be called before invoking any other network interface functions on Android. ```APIDOC ## set_android_context ### Description Sets the Android application context required for netwatcher to function. This function must be called before using list_interfaces or watch_interfaces on Android platforms. ### Parameters - **env** (JNIEnv) - Required - The JNI environment pointer. - **context** (jobject) - Required - The Android application context object. ### Request Example // Kotlin usage setAndroidContext(applicationContext) ### Response - **Result** (Result<(), Error>) - Returns Ok(()) on success, or an error if the context could not be set. ``` -------------------------------- ### Track Interface Changes with InterfaceDiff Source: https://context7.com/thombles/netwatcher/llms.txt Use watch_interfaces to monitor network interface modifications. InterfaceDiff provides details on hardware address changes and IP address additions or removals. ```rust use netwatcher::{watch_interfaces, InterfaceDiff}; let handle = watch_interfaces(|update| { // InterfaceDiff contains: // - hw_addr_changed: bool // - addrs_added: Vec // - addrs_removed: Vec for (ifindex, diff) in &update.diff.modified { let iface = update.interfaces.get(ifindex).unwrap(); println!("Changes to interface '{}' (index {}):", iface.name, ifindex); if diff.hw_addr_changed { println!(" Hardware address changed to: {}", iface.hw_addr); } if !diff.addrs_added.is_empty() { println!(" New IP addresses:"); for ip in &diff.addrs_added { let ip_type = if ip.ip.is_ipv4() { "IPv4" } else { "IPv6" }; println!(" [{}] {}/{}", ip_type, ip.ip, ip.prefix_len); } } if !diff.addrs_removed.is_empty() { println!(" Removed IP addresses:"); for ip in &diff.addrs_removed { println!(" {}/{}", ip.ip, ip.prefix_len); } } // Summary of current state after changes println!(" Current IP count: {}", iface.ips.len()); } }).unwrap(); std::thread::sleep(std::time::Duration::from_secs(30)); drop(handle); ``` -------------------------------- ### Monitor network interface changes in Rust Source: https://context7.com/thombles/netwatcher/llms.txt Uses watch_interfaces to track network state changes. The returned WatchHandle must be kept in scope to continue receiving updates. ```rust use netwatcher::{watch_interfaces, Update, WatchHandle}; use std::time::Duration; fn monitor_network_changes() { // The callback receives an Update containing: // - interfaces: Current snapshot of all interfaces // - diff: What changed since last callback let handle: WatchHandle = watch_interfaces(|update: Update| { println!("=== Network Change Detected ==="); println!("Total interfaces: {}", update.interfaces.len()); // Check for newly added interfaces if !update.diff.added.is_empty() { println!("New interfaces added:"); for ifindex in &update.diff.added { if let Some(iface) = update.interfaces.get(ifindex) { println!(" + {} (index {})", iface.name, ifindex); } } } // Check for removed interfaces if !update.diff.removed.is_empty() { println!("Interfaces removed: {:?}", update.diff.removed); } // Check for modified interfaces (IP changes) for (ifindex, if_diff) in &update.diff.modified { if let Some(iface) = update.interfaces.get(ifindex) { println!("Interface {} modified:", iface.name); if if_diff.hw_addr_changed { println!(" Hardware address changed"); } for added_ip in &if_diff.addrs_added { println!(" + IP added: {}/{}", added_ip.ip, added_ip.prefix_len); } for removed_ip in &if_diff.addrs_removed { println!(" - IP removed: {}/{}", removed_ip.ip, removed_ip.prefix_len); } } } // Print current state summary println!("\nCurrent interface state:"); for iface in update.interfaces.values() { let ips: Vec = iface.ips.iter() .map(|r| format!("{}/{}", r.ip, r.prefix_len)) .collect(); println!(" {}: {}", iface.name, ips.join(", ")); } }).expect("Failed to start watching interfaces"); // Keep the handle alive to continue receiving callbacks println!("Watching for network changes for 60 seconds..."); std::thread::sleep(Duration::from_secs(60)); // Dropping the handle stops the watcher // Note: Don't drop from within the callback (will deadlock) drop(handle); println!("Stopped watching."); } fn main() { monitor_network_changes(); } ``` -------------------------------- ### Android Permissions for Netwatcher Source: https://github.com/thombles/netwatcher/blob/main/README.md Required permissions for the Android app to access network state and internet. These should be added to the application's manifest file. ```xml ``` -------------------------------- ### InterfaceDiff Struct Source: https://context7.com/thombles/netwatcher/llms.txt Describes changes within a single network interface between updates. It indicates if the hardware address has changed and lists added or removed IP addresses. This struct is only populated for interfaces present in both the previous and current states. ```APIDOC ## InterfaceDiff Struct Describes what changed within a single interface between updates, including whether the hardware address changed and which IP addresses were added or removed. Only populated for interfaces that existed in both the previous and current state. ### Request Example ```rust use netwatcher::{watch_interfaces, InterfaceDiff}; let handle = watch_interfaces(|update| { // InterfaceDiff contains: // - hw_addr_changed: bool // - addrs_added: Vec // - addrs_removed: Vec for (ifindex, diff) in &update.diff.modified { let iface = update.interfaces.get(ifindex).unwrap(); println!("Changes to interface '{}' (index {})", iface.name, ifindex); if diff.hw_addr_changed { println!(" Hardware address changed to: {}", iface.hw_addr); } if !diff.addrs_added.is_empty() { println!(" New IP addresses:"); for ip in &diff.addrs_added { let ip_type = if ip.ip.is_ipv4() { "IPv4" } else { "IPv6" }; println!(" [{}] {}/{}", ip_type, ip.ip, ip.prefix_len); } } if !diff.addrs_removed.is_empty() { println!(" Removed IP addresses:"); for ip in &diff.addrs_removed { println!(" {}/{}", ip.ip, ip.prefix_len); } } // Summary of current state after changes println!(" Current IP count: {}", iface.ips.len()); } }).unwrap(); std::thread::sleep(std::time::Duration::from_secs(30)); drop(handle); ``` ``` -------------------------------- ### Error Handling Source: https://context7.com/thombles/netwatcher/llms.txt Details the comprehensive error enum provided by the Netwatcher library, covering various failure modes across different platforms and system interactions. It implements `std::error::Error` for seamless integration with Rust's error handling mechanisms. ```APIDOC ## Error Handling ### Error Enum Comprehensive error type covering all possible failure modes across platforms, including socket creation, binding, system call failures, Windows-specific errors, and Android JNI errors. Implements `std::error::Error` for easy integration with error handling libraries. ### Request Example ```rust use netwatcher::{list_interfaces, watch_interfaces, Error}; fn handle_network_operations() { // Error variants include: // - CreateSocket(String) - Failed to create network socket // - Bind(String) - Failed to bind socket // - CreatePipe(String) - Failed to create pipe for signaling // - Getifaddrs(String) - Unix getifaddrs() failed // - GetInterfaceName(String) - Could not resolve interface name // - FormatMacAddress - MAC address formatting failed // - UnexpectedWindowsResult(u32) - Windows API returned unexpected code // - AddressNotAssociated - Windows: address not associated with interface // - InvalidParameter - Invalid parameter passed to system call // - NotEnoughMemory - Memory allocation failed // - InvalidHandle - Invalid handle (Windows) // - NoAndroidContext - Android: context not set // - Jni(String) - Android JNI error // - Io(std::io::Error) - General I/O error match list_interfaces() { Ok(interfaces) => { println!("Successfully listed {} interfaces", interfaces.len()); } Err(Error::Getifaddrs(msg)) => { eprintln!("System call failed: {}", msg); } Err(Error::NoAndroidContext) => { eprintln!("Android context not set - call set_android_context first"); } Err(e) => { // Error implements Display and Debug eprintln!("Network error: {}", e); eprintln!("Debug info: {:?}", e); } } // Watch with error handling match watch_interfaces(|_update| { println!("Interface change detected"); }) { Ok(handle) => { println!("Watcher started successfully"); std::thread::sleep(std::time::Duration::from_secs(5)); drop(handle); } Err(Error::CreateSocket(msg)) => { eprintln!("Could not create socket for watching: {}", msg); } Err(Error::Bind(msg)) => { eprintln!("Could not bind to netlink socket: {}", msg); } Err(e) => { eprintln!("Failed to start watcher: {:?}", e); } } } fn main() { handle_network_operations(); } ``` ``` -------------------------------- ### Handle Network Errors Source: https://context7.com/thombles/netwatcher/llms.txt The Error enum covers platform-specific and general network failures. It implements std::error::Error for compatibility with standard error handling patterns. ```rust use netwatcher::{list_interfaces, watch_interfaces, Error}; fn handle_network_operations() { // Error variants include: // - CreateSocket(String) - Failed to create network socket // - Bind(String) - Failed to bind socket // - CreatePipe(String) - Failed to create pipe for signaling // - Getifaddrs(String) - Unix getifaddrs() failed // - GetInterfaceName(String) - Could not resolve interface name // - FormatMacAddress - MAC address formatting failed // - UnexpectedWindowsResult(u32) - Windows API returned unexpected code // - AddressNotAssociated - Windows: address not associated with interface // - InvalidParameter - Invalid parameter passed to system call // - NotEnoughMemory - Memory allocation failed // - InvalidHandle - Invalid handle (Windows) // - NoAndroidContext - Android: context not set // - Jni(String) - Android JNI error // - Io(std::io::Error) - General I/O error match list_interfaces() { Ok(interfaces) => { println!("Successfully listed {} interfaces", interfaces.len()); } Err(Error::Getifaddrs(msg)) => { eprintln!("System call failed: {}", msg); } Err(Error::NoAndroidContext) => { eprintln!("Android context not set - call set_android_context first"); } Err(e) => { // Error implements Display and Debug eprintln!("Network error: {}", e); eprintln!("Debug info: {:?}", e); } } // Watch with error handling match watch_interfaces(|_update| { println!("Interface change detected"); }) { Ok(handle) => { println!("Watcher started successfully"); std::thread::sleep(std::time::Duration::from_secs(5)); drop(handle); } Err(Error::CreateSocket(msg)) => { eprintln!("Could not create socket for watching: {}", msg); } Err(Error::Bind(msg)) => { eprintln!("Could not bind to netlink socket: {}", msg); } Err(e) => { eprintln!("Failed to start watcher: {:?}", e); } } } fn main() { handle_network_operations(); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.