use clap::Parser;
use ndisapi::{
DirectionFlags, EthRequest, EthRequestMut, FilterFlags, IntermediateBuffer, Ndisapi,
};
use smoltcp::wire::{
ArpPacket, EthernetFrame, EthernetProtocol, Icmpv4Packet, Icmpv6Packet, IpProtocol, Ipv4Packet,
Ipv6Packet, TcpPacket, UdpPacket,
};
use windows::{
core::Result,
Win32::Foundation::{CloseHandle, HANDLE},
Win32::System::Threading::{CreateEventW, ResetEvent, WaitForSingleObject},
};
#[derive(Parser)]
struct Cli {
#[clap(short, long)]
interface_index: usize,
#[clap(short, long)]
packets_number: usize,
}
fn main() -> Result<()> {
let Cli {
mut interface_index,
mut packets_number,
} = Cli::parse();
interface_index -= 1;
let driver =
Ndisapi::new("NDISRD").expect("WinpkFilter driver is not installed or failed to load!");
println!(
"Detected Windows Packet Filter version {}",
driver.get_version()?
);
let adapters = driver.get_tcpip_bound_adapters_info()?;
if interface_index + 1 > adapters.len() {
panic!("Interface index is beyond the number of available interfaces");
}
println!(
"Using interface {} with {} packets",
adapters[interface_index].get_name(),
packets_number
);
let event: HANDLE;
unsafe {
event = CreateEventW(None, true, false, None)?; }
driver.set_packet_event(adapters[interface_index].get_handle(), event)?;
driver.set_adapter_mode(
adapters[interface_index].get_handle(),
FilterFlags::MSTCP_FLAG_SENT_RECEIVE_TUNNEL,
)?;
let mut packet = IntermediateBuffer::default();
while packets_number > 0 {
unsafe {
WaitForSingleObject(event, u32::MAX); }
loop {
let mut read_request = EthRequestMut::new(adapters[interface_index].get_handle());
read_request.set_packet(&mut packet);
if driver.read_packet(&mut read_request).ok().is_none() {
break;
}
let direction_flags = packet.get_device_flags();
if direction_flags == DirectionFlags::PACKET_FLAG_ON_SEND {
println!(
"\nMSTCP --> Interface ({} bytes) remaining packets {}\n",
packet.get_length(),
packets_number
);
} else {
println!(
"\nInterface --> MSTCP ({} bytes) remaining packets {}\n",
packet.get_length(),
packets_number
);
}
packets_number -= 1;
print_packet_info(&packet);
let mut write_request = EthRequest::new(adapters[interface_index].get_handle());
write_request.set_packet(&packet);
if direction_flags == DirectionFlags::PACKET_FLAG_ON_SEND {
match driver.send_packet_to_adapter(&write_request) {
Ok(_) => {}
Err(err) => println!("Error sending packet to adapter. Error code = {err}"),
};
} else {
match driver.send_packet_to_mstcp(&write_request) {
Ok(_) => {}
Err(err) => println!("Error sending packet to mstcp. Error code = {err}"),
}
}
if packets_number == 0 {
println!("Filtering complete\n");
break;
}
}
let _ = unsafe {
ResetEvent(event) };
}
driver.set_adapter_mode(
adapters[interface_index].get_handle(),
FilterFlags::default(),
)?;
let _ = unsafe {
CloseHandle(event) };
Ok(())
}
fn print_packet_info(packet: &IntermediateBuffer) {
let eth_hdr = EthernetFrame::new_unchecked(packet.get_data());
match eth_hdr.ethertype() {
EthernetProtocol::Ipv4 => {
let ipv4_packet = Ipv4Packet::new_unchecked(eth_hdr.payload());
println!(
" Ipv4 {:?} => {:?}",
ipv4_packet.src_addr(),
ipv4_packet.dst_addr()
);
match ipv4_packet.next_header() {
IpProtocol::Icmp => {
let icmp_packet = Icmpv4Packet::new_unchecked(ipv4_packet.payload());
println!(
"ICMPv4: Type: {:?} Code: {:?}",
icmp_packet.msg_type(),
icmp_packet.msg_code()
);
}
IpProtocol::Tcp => {
let tcp_packet = TcpPacket::new_unchecked(ipv4_packet.payload());
println!(
" TCP {:?} -> {:?}",
tcp_packet.src_port(),
tcp_packet.dst_port()
);
}
IpProtocol::Udp => {
let udp_packet = UdpPacket::new_unchecked(ipv4_packet.payload());
println!(
" UDP {:?} -> {:?}",
udp_packet.src_port(),
udp_packet.dst_port()
);
}
_ => {
println!("Unknown IPv4 packet: {:?}", ipv4_packet);
}
}
}
EthernetProtocol::Ipv6 => {
let ipv6_packet = Ipv6Packet::new_unchecked(eth_hdr.payload());
println!(
" Ipv6 {:?} => {:?}",
ipv6_packet.src_addr(),
ipv6_packet.dst_addr()
);
match ipv6_packet.next_header() {
IpProtocol::Icmpv6 => {
let icmpv6_packet = Icmpv6Packet::new_unchecked(ipv6_packet.payload());
println!(
"ICMPv6 packet: Type: {:?} Code: {:?}",
icmpv6_packet.msg_type(),
icmpv6_packet.msg_code()
);
}
IpProtocol::Tcp => {
let tcp_packet = TcpPacket::new_unchecked(ipv6_packet.payload());
println!(
" TCP {:?} -> {:?}",
tcp_packet.src_port(),
tcp_packet.dst_port()
);
}
IpProtocol::Udp => {
let udp_packet = UdpPacket::new_unchecked(ipv6_packet.payload());
println!(
" UDP {:?} -> {:?}",
udp_packet.src_port(),
udp_packet.dst_port()
);
}
_ => {
println!("Unknown IPv6 packet: {:?}", ipv6_packet);
}
}
}
EthernetProtocol::Arp => {
let arp_packet = ArpPacket::new_unchecked(eth_hdr.payload());
println!("ARP packet: {:?}", arp_packet);
}
EthernetProtocol::Unknown(_) => {
println!("Unknown Ethernet packet: {:?}", eth_hdr);
}
}
}