### Run listadapters Example in Rust Source: https://github.com/wiresock/ndisapi-rs/blob/main/README.md This command demonstrates how to compile and run the `listadapters` example provided by the NDISAPI Rust crate. It shows the output of the example, which lists detected network adapters, their properties, and status. This requires the 'ndisapi' crate and the Windows Packet Filter driver to be installed and configured. ```bash S D:\github.com\ndisapi-rs> cargo run --example listadapters Finished dev [unoptimized + debuginfo] target(s) in 0.12s Running `target\debug\examples\listadapters.exe` Detected Windows Packet Filter version 3.4.8 1. Local Area Connection* 10 \DEVICE\{EDEE8C42-F604-4A7B-BFAA-6B110923217E} Medium: 0 MAC: 9A:47:3D:60:26:9D MTU: 1500 FilterFlags: FilterFlags(0x0) Getting OID_GEN_CURRENT_PACKET_FILTER Error: Data error (cyclic redundancy check). OID_802_3_CURRENT_ADDRESS: 9A:47:3D:60:26:9D 2. vEthernet (Default Switch) \DEVICE\{BD64DB34-23DF-45C4-909E-780272A98BAE} Medium: 0 MAC: 00:15:5D:01:8C:00 MTU: 1500 FilterFlags: FilterFlags(0x0) OID_GEN_CURRENT_PACKET_FILTER: 0x0000000B OID_802_3_CURRENT_ADDRESS: 00:15:5D:01:8C:00 ... 11. vEthernet (WLAN Virtual Switch) \DEVICE\{05F9267C-C548-4822-8535-9A57F1A99DB7} Medium: 0 MAC: 18:47:3D:60:26:9D MTU: 1500 FilterFlags: FilterFlags(0x0) OID_GEN_CURRENT_PACKET_FILTER: 0x0000000B OID_802_3_CURRENT_ADDRESS: 18:47:3D:60:26:9D System wide MTU decrement: 0 System wide network adapter startup filter mode: 0 Driver intermediate buffer pool size multiplier: 0 Effective intermediate buffer pool size: 2048 ``` -------------------------------- ### Run async-packthru Example in Rust Source: https://github.com/wiresock/ndisapi-rs/blob/main/README.md This command demonstrates how to run the `async-packthru` example from the NDISAPI Rust crate. It requires specifying the interface index of the network adapter to be used. This example is useful for testing asynchronous packet throughput and requires the 'ndisapi' crate and the Windows Packet Filter driver. ```bash PS D:\github.com\ndisapi-rs> cargo run --example async-packthru -- --interface-index 11 Finished dev [unoptimized + debuginfo] target(s) in 0.11s Running `target\debug\examples\async-packthru.exe --interface-index 11` Detected Windows Packet Filter version 3.4.8 Using interface \DEVICE\{05F9267C-C548-4822-8535-9A57F1A99DB7} Press ENTER to exit ``` -------------------------------- ### Query and Modify NDIS OID Parameters in Rust Source: https://context7.com/wiresock/ndisapi-rs/llms.txt This example shows how to query and modify network adapter parameters using NDIS OID requests. It retrieves the MAC address, hardware packet filter, and adapter mode. This requires the NDISAPI driver and works with existing network adapters. The function takes no input and prints adapter information. ```rust use ndisapi::{Ndisapi, PacketOidData, MacAddress}; const OID_802_3_CURRENT_ADDRESS: u32 = 0x01010102; const OID_GEN_CURRENT_PACKET_FILTER: u32 = 0x0001010E; fn main() -> windows::core::Result<()> { let driver = Ndisapi::new("NDISRD")?; let adapters = driver.get_tcpip_bound_adapters_info()?; let adapter = &adapters[0]; // Query MAC address using OID request let mut mac_request = PacketOidData::new( adapter.get_handle(), OID_802_3_CURRENT_ADDRESS, MacAddress::default(), ); if let Ok(()) = driver.ndis_get_request::<_>(&mut mac_request) { println!("MAC Address: {}", mac_request.data); } // Query hardware packet filter using built-in wrapper match driver.get_hw_packet_filter(adapter.get_handle()) { Ok(filter) => { println!("Hardware packet filter: 0x{:08X}", filter); // Bit flags indicate: directed, multicast, broadcast, promiscuous, etc. } Err(e) => eprintln!("Failed to query filter: {}", e.message()), } // Query adapter mode (WinpkFilter specific) let mode = driver.get_adapter_mode(adapter.get_handle())?; println!("Adapter filter flags: {:?}", mode); Ok(()) } ``` -------------------------------- ### Enumerate Network Adapters using NDISAPI in Rust Source: https://github.com/wiresock/ndisapi-rs/blob/main/README.md This Rust code snippet demonstrates how to use the NDISAPI crate to enumerate network adapters on a Windows system. It initializes the Ndisapi instance, retrieves adapter information, and prints details such as adapter name, description, and MAC address. It requires the 'ndisapi' crate and the Windows Packet Filter driver to be installed. ```rust use ndisapi::{MacAddress, Ndisapi}; fn main() { let ndis = Ndisapi::new("NDISRD").expect("Failed to create NdisApi instance"); let adapters = ndis .get_tcpip_bound_adapters_info() .expect("Failed to enumerate adapters"); for adapter in adapters { println!("Adapter: {:?}", adapter.get_name()); println!( "Description: {:?}", Ndisapi::get_friendly_adapter_name(adapter.get_name()).unwrap_or("Unknown".to_string()) ); println!( "MAC Address: {:?}", MacAddress::from_slice(adapter.get_hw_address()).unwrap_or_default() ); println!("-------------------------------"); } } ``` -------------------------------- ### Filter ICMP Packets using NDIS Static Filters in Rust Source: https://context7.com/wiresock/ndisapi-rs/llms.txt This example demonstrates how to configure NDIS static filters to block all ICMP packets at the network layer. It requires the NDISAPI driver to be installed. The function takes no input and outputs a message indicating the filter's status. ```rust use ndisapi::{ Ndisapi, StaticFilterTable, StaticFilter, DirectionFlags, FilterLayerFlags, DataLinkLayerFilter, NetworkLayerFilter, NetworkLayerFilterUnion, TransportLayerFilter, IpV4Filter, IpV4FilterFlags, IpAddressV4, FILTER_PACKET_DROP, IPV4 }; fn main() -> windows::core::Result<()> { let driver = Ndisapi::new("NDISRD")?; let filter_table = StaticFilterTable::<1>::from_filters([ // Block all ICMP packets (both directions) StaticFilter::new( 0, DirectionFlags::PACKET_FLAG_ON_SEND | DirectionFlags::PACKET_FLAG_ON_RECEIVE, FILTER_PACKET_DROP, FilterLayerFlags::NETWORK_LAYER_VALID, DataLinkLayerFilter::default(), NetworkLayerFilter::new( IPV4, NetworkLayerFilterUnion { ipv4: IpV4Filter::new( IpV4FilterFlags::IP_V4_FILTER_PROTOCOL, IpAddressV4::default(), IpAddressV4::default(), 1, // ICMP protocol number ), }, ), TransportLayerFilter::default(), ), ]); driver.set_packet_filter_table(&filter_table)?; println!("ICMP drop filter active - ping will not work"); // To remove filter later: // driver.reset_packet_filter_table()?; Ok(()) } ``` -------------------------------- ### Enumerate Network Adapters Source: https://context7.com/wiresock/ndisapi-rs/llms.txt Retrieves information about all network adapters bound to TCP/IP, including hardware addresses, MTU, and internal handles. It iterates through each adapter and prints its details. ```APIDOC ## Enumerate Network Adapters ### Description Retrieves information about all network adapters bound to TCP/IP, including hardware addresses, MTU, and internal handles. ### Method N/A (This is a method call on an existing Ndisapi instance) ### Endpoint N/A ### Parameters None (operates on an initialized `Ndisapi` instance) ### Request Example ```rust use ndisapi::{Ndisapi, MacAddress, IphlpNetworkAdapterInfo}; fn main() -> windows::core::Result<()> { let driver = Ndisapi::new("NDISRD")?; let adapters = driver.get_tcpip_bound_adapters_info()?; for (index, adapter) in adapters.iter().enumerate() { // Get friendly adapter name let name = Ndisapi::get_friendly_adapter_name(adapter.get_name()) .unwrap_or_else(|_| "Unknown".to_string()); println!("{}. {}", index + 1, name); println!(" Device: {}", adapter.get_name()); println!(" MAC: {}", MacAddress::from_slice(adapter.get_hw_address()).unwrap_or_default()); println!(" MTU: {}", adapter.get_mtu()); // Get IP addresses using IP Helper API if let Some(mac) = MacAddress::from_slice(adapter.get_hw_address()) { if let Some(ip_info) = IphlpNetworkAdapterInfo::get_connection_by_hw_address(&mac) { for (ip_addr, prefix_len) in ip_info.unicast_address_list_with_prefix() { println!(" IP: {}/{}", ip_addr, prefix_len); } } } } Ok(()) } ``` ### Response #### Success Response (List of Adapters) - **adapters** (Vec) - A vector containing information about each network adapter. - **name** (String) - The device name of the adapter. - **hw_address** (Vec) - The hardware MAC address of the adapter. - **mtu** (u32) - The Maximum Transmission Unit of the adapter. #### Response Example ``` 1. Ethernet 0 Device: \Device\{GUID-1} MAC: 00:11:22:33:44:55 MTU: 1500 IP: 192.168.1.100/24 2. Wi-Fi Device: \Device\{GUID-2} MAC: AA:BB:CC:DD:EE:FF MTU: 1500 IP: 10.0.0.5/16 ``` ### Error Handling - **Err** - If there's an issue retrieving adapter information. ``` -------------------------------- ### Asynchronous Packet Capture and Re-injection (Rust) Source: https://context7.com/wiresock/ndisapi-rs/llms.txt Captures packets asynchronously using async/await, suitable for concurrent network applications. This method leverages the `tokio` runtime and `ndisapi`'s async adapter wrapper for non-blocking operations. It allows for continuous packet processing without blocking the main thread. Dependencies include `ndisapi`, `tokio`, and `windows` crates. ```rust use ndisapi::{Ndisapi, AsyncNdisapiAdapter, FilterFlags, IntermediateBuffer, DirectionFlags}; use std::sync::Arc; use tokio::sync::oneshot; #[tokio::main] async fn main() -> windows::core::Result<()> { let driver = Arc::new(Ndisapi::new("NDISRD")?); let adapters = driver.get_tcpip_bound_adapters_info()?; let adapter_index = 0; // Create async adapter wrapper let mut adapter = AsyncNdisapiAdapter::new( Arc::clone(&driver), adapters[adapter_index].get_handle() )?; // Enable tunnel mode adapter.set_adapter_mode(FilterFlags::MSTCP_FLAG_SENT_RECEIVE_TUNNEL)?; let mut packet = IntermediateBuffer::default(); let (tx, rx) = oneshot::channel::<()>(); // Spawn task to handle Ctrl-C tokio::spawn(async move { let mut line = String::new(); std::io::stdin().read_line(&mut line).unwrap(); let _ = tx.send(()); }); // Packet processing loop tokio::select! { _ = async { loop { // Async read - doesn't block thread if adapter.read_packet(&mut packet).await.is_ok() { let direction = packet.get_device_flags(); println!("Packet: {} bytes", packet.get_length()); // Re-inject packet if direction == DirectionFlags::PACKET_FLAG_ON_SEND { let _ = adapter.send_packet_to_adapter(&mut packet); } else { let _ = adapter.send_packet_to_mstcp(&mut packet); } } } } => {}, _ = rx => { println!("Shutting down..."); } } Ok(()) } ``` -------------------------------- ### Initialize NDISAPI Driver Instance Source: https://context7.com/wiresock/ndisapi-rs/llms.txt Creates a new connection to the Windows Packet Filter driver, providing the entry point for all packet filtering operations. This function initializes the driver with a default name 'NDISRD'. ```APIDOC ## Initialize NDISAPI Driver Instance ### Description Creates a new connection to the Windows Packet Filter driver, providing the entry point for all packet filtering operations. ### Method N/A (This is a constructor/initialization method) ### Endpoint N/A ### Parameters None ### Request Example ```rust use ndisapi::Ndisapi; fn main() -> windows::core::Result<()> { // Initialize driver with default name "NDISRD" let driver = Ndisapi::new("NDISRD") .expect("WinpkFilter driver is not installed or failed to load!"); // Check driver version let version = driver.get_version()?; println!("Windows Packet Filter version: {}", version); Ok(()) } ``` ### Response #### Success Response (Instance) - **driver** (Ndisapi) - An initialized Ndisapi driver instance. #### Response Example (See Request Example for successful initialization output) ### Error Handling - **Err** - If the WinpkFilter driver is not installed or fails to load. ``` -------------------------------- ### Configure DNS Traffic Redirection with Rust NDIS API Source: https://context7.com/wiresock/ndisapi-rs/llms.txt This Rust code configures layer-3/4 filters using the NDIS API to redirect only DNS traffic (UDP port 53) to user space. It includes filters for outgoing DNS requests and incoming DNS responses, and a default filter to pass all other traffic. Dependencies include the `ndisapi` crate and `windows-core`. ```rust use ndisapi::{ Ndisapi, StaticFilterTable, StaticFilter, DirectionFlags, FilterLayerFlags, DataLinkLayerFilter, NetworkLayerFilter, NetworkLayerFilterUnion, TransportLayerFilter, TransportLayerFilterUnion, IpV4Filter, IpV4FilterFlags, IpAddressV4, TcpUdpFilter, TcpUdpFilterFlags, PortRange, FILTER_PACKET_REDIRECT, FILTER_PACKET_PASS, IPV4, TCPUDP }; fn main() -> windows::core::Result<()> { let driver = Ndisapi::new("NDISRD")?; let filter_table = StaticFilterTable::<3>::from_filters([ // Redirect outgoing DNS requests (UDP dst port 53) StaticFilter::new( 0, // Apply to all adapters DirectionFlags::PACKET_FLAG_ON_SEND, FILTER_PACKET_REDIRECT, FilterLayerFlags::NETWORK_LAYER_VALID | FilterLayerFlags::TRANSPORT_LAYER_VALID, DataLinkLayerFilter::default(), NetworkLayerFilter::new( IPV4, NetworkLayerFilterUnion { ipv4: IpV4Filter::new( IpV4FilterFlags::IP_V4_FILTER_PROTOCOL, IpAddressV4::default(), IpAddressV4::default(), 17, // UDP protocol ), }, ), TransportLayerFilter::new( TCPUDP, TransportLayerFilterUnion { tcp_udp: TcpUdpFilter::new( TcpUdpFilterFlags::TCPUDP_DEST_PORT, PortRange::default(), PortRange::new(53, 53), // DNS port 0, ), }, ), ), // Redirect incoming DNS responses (UDP src port 53) StaticFilter::new( 0, DirectionFlags::PACKET_FLAG_ON_RECEIVE, FILTER_PACKET_REDIRECT, FilterLayerFlags::NETWORK_LAYER_VALID | FilterLayerFlags::TRANSPORT_LAYER_VALID, DataLinkLayerFilter::default(), NetworkLayerFilter::new( IPV4, NetworkLayerFilterUnion { ipv4: IpV4Filter::new( IpV4FilterFlags::IP_V4_FILTER_PROTOCOL, IpAddressV4::default(), IpAddressV4::default(), 17, ), }, ), TransportLayerFilter::new( TCPUDP, TransportLayerFilterUnion { tcp_udp: TcpUdpFilter::new( TcpUdpFilterFlags::TCPUDP_SRC_PORT, PortRange::new(53, 53), PortRange::default(), 0, ), }, ), ), // Pass all other packets without user mode processing StaticFilter::new( 0, DirectionFlags::PACKET_FLAG_ON_RECEIVE | DirectionFlags::PACKET_FLAG_ON_SEND, FILTER_PACKET_PASS, FilterLayerFlags::empty(), DataLinkLayerFilter::default(), NetworkLayerFilter::default(), TransportLayerFilter::default() ), ]); // Apply filter table to driver driver.set_packet_filter_table(&filter_table)?; println!("DNS filter loaded successfully"); Ok(()) } ``` -------------------------------- ### Synchronous Packet Capture and Re-injection (Rust) Source: https://context7.com/wiresock/ndisapi-rs/llms.txt Captures packets in tunnel mode using a synchronous approach. Packets are processed in user space and then re-injected into the network stack. This method utilizes Win32 events for packet notification and blocking calls for reading and writing packets. Dependencies include the `ndisapi` and `windows` crates. ```rust use ndisapi::{Ndisapi, FilterFlags, IntermediateBuffer, EthRequestMut, EthRequest, DirectionFlags}; use windows::{ Win32::Foundation::{CloseHandle, HANDLE}, Win32::System::Threading::{CreateEventW, WaitForSingleObject, ResetEvent}, }; fn main() -> windows::core::Result<()> { let driver = Ndisapi::new("NDISRD")?; let adapters = driver.get_tcpip_bound_adapters_info()?; let adapter_index = 0; // Select first adapter // Create Win32 event for packet notification let event: HANDLE = unsafe { CreateEventW(None, true, false, None)? }; driver.set_packet_event(adapters[adapter_index].get_handle(), event)?; // Enable tunnel mode (packets redirected to user space) driver.set_adapter_mode( adapters[adapter_index].get_handle(), FilterFlags::MSTCP_FLAG_SENT_RECEIVE_TUNNEL )?; let mut packet = IntermediateBuffer::default(); let mut packets_processed = 0; while packets_processed < 100 { // Wait for packet arrival unsafe { WaitForSingleObject(event, u32::MAX) }; loop { let mut read_request = EthRequestMut::new(adapters[adapter_index].get_handle()); read_request.set_packet(&mut packet); // Try to read packet from queue if driver.read_packet(&mut read_request).is_err() { break; // Queue empty } let direction = packet.get_device_flags(); println!("Captured packet: {} bytes, direction: {:?}", packet.get_length(), direction); // Re-inject packet back to network stack let write_request = EthRequest::new(adapters[adapter_index].get_handle()); write_request.set_packet(&packet); if direction == DirectionFlags::PACKET_FLAG_ON_SEND { driver.send_packet_to_adapter(&write_request)?; } else { driver.send_packet_to_mstcp(&write_request)?; } packets_processed += 1; } unsafe { ResetEvent(event) }; } // Restore default mode driver.set_adapter_mode( adapters[adapter_index].get_handle(), FilterFlags::default() )?; unsafe { CloseHandle(event) }; Ok(()) } ``` -------------------------------- ### Block Specific IP and Port TCP Packets - Rust Source: https://context7.com/wiresock/ndisapi-rs/llms.txt This Rust code snippet demonstrates how to create static filters using the NDIS API to drop outgoing TCP packets destined for a specific IP address and port. It requires the 'ndisapi' and 'windows' crates. The function takes no explicit input but manipulates network filters. The output is a confirmation message printed to the console. This filter is specific to IPv4 TCP traffic. ```rust use ndisapi::{ Ndisapi, StaticFilterTable, StaticFilter, DirectionFlags, FilterLayerFlags, DataLinkLayerFilter, NetworkLayerFilter, NetworkLayerFilterUnion, TransportLayerFilter, TransportLayerFilterUnion, IpV4Filter, IpV4FilterFlags, IpAddressV4, IpAddressV4Union, IpSubnetV4, TcpUdpFilter, TcpUdpFilterFlags, PortRange, FILTER_PACKET_DROP, FILTER_PACKET_PASS, IPV4, TCPUDP, IP_SUBNET_V4_TYPE }; use windows::Win32::Networking::WinSock::{IN_ADDR, IN_ADDR_0, IN_ADDR_0_0}; fn main() -> windows::core::Result<()> { let driver = Ndisapi::new("NDISRD")?; let filter_table = StaticFilterTable::<2>::from_filters([ // Drop outgoing TCP packets to 95.179.146.125:443 StaticFilter::new( 0, DirectionFlags::PACKET_FLAG_ON_SEND, FILTER_PACKET_DROP, FilterLayerFlags::NETWORK_LAYER_VALID | FilterLayerFlags::TRANSPORT_LAYER_VALID, DataLinkLayerFilter::default(), NetworkLayerFilter::new( IPV4, NetworkLayerFilterUnion { ipv4: IpV4Filter::new( IpV4FilterFlags::IP_V4_FILTER_PROTOCOL | IpV4FilterFlags::IP_V4_FILTER_DEST_ADDRESS, IpAddressV4::default(), IpAddressV4::new( IP_SUBNET_V4_TYPE, IpAddressV4Union { ip_subnet: IpSubnetV4::new( IN_ADDR { S_un: IN_ADDR_0 { S_un_b: IN_ADDR_0_0 { s_b1: 95, s_b2: 179, s_b3: 146, s_b4: 125, }, }, }, IN_ADDR { S_un: IN_ADDR_0 { S_un_b: IN_ADDR_0_0 { s_b1: 255, s_b2: 255, s_b3: 255, s_b4: 255, }, }, }, ), }, ), 6, // TCP protocol ), }, ), TransportLayerFilter::new( TCPUDP, TransportLayerFilterUnion { tcp_udp: TcpUdpFilter::new( TcpUdpFilterFlags::TCPUDP_DEST_PORT, PortRange::default(), PortRange::new(443, 443), // HTTPS port 0, ), }, ), ), // Pass all other packets StaticFilter::new( 0, DirectionFlags::PACKET_FLAG_ON_RECEIVE | DirectionFlags::PACKET_FLAG_ON_SEND, FILTER_PACKET_PASS, FilterLayerFlags::empty(), DataLinkLayerFilter::default(), NetworkLayerFilter::default(), TransportLayerFilter::default(), ), ]); driver.set_packet_filter_table(&filter_table)?; println!("IP blocking filter applied"); Ok(()) } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.