use clap::Parser;
use ndisapi::{AsyncNdisapiAdapter, DirectionFlags, FilterFlags, IntermediateBuffer, Ndisapi};
use smoltcp::wire::{
ArpPacket, EthernetFrame, EthernetProtocol, Icmpv4Packet, Icmpv6Packet, IpProtocol, Ipv4Packet,
Ipv6Packet, TcpPacket, UdpPacket,
};
use std::sync::Arc;
use tokio::sync::oneshot;
use windows::core::Result;
async fn async_loop(adapter: &mut AsyncNdisapiAdapter) -> Result<()> {
adapter.set_adapter_mode(FilterFlags::MSTCP_FLAG_SENT_RECEIVE_TUNNEL)?;
let mut packet = IntermediateBuffer::default();
loop {
let result = adapter.read_packet(&mut packet).await;
if result.is_err() {
continue;
}
if packet.get_device_flags() == DirectionFlags::PACKET_FLAG_ON_SEND {
println!("\nMSTCP --> Interface ({} bytes)\n", packet.get_length(),);
} else {
println!("\nInterface --> MSTCP ({} bytes)\n", packet.get_length(),);
}
print_packet_info(&mut packet);
if packet.get_device_flags() == DirectionFlags::PACKET_FLAG_ON_SEND {
match adapter.send_packet_to_adapter(&mut packet) {
Ok(_) => {}
Err(err) => println!("Error sending packet to adapter. Error code = {err}"),
};
} else {
match adapter.send_packet_to_mstcp(&mut packet) {
Ok(_) => {}
Err(err) => println!("Error sending packet to mstcp. Error code = {err}"),
}
}
}
}
async fn main_async(adapter: &mut AsyncNdisapiAdapter) {
println!("Press ENTER to exit");
let (tx, rx) = oneshot::channel::<()>();
tokio::spawn(async move {
let mut line = String::new();
std::io::stdin().read_line(&mut line).unwrap();
let _ = tx.send(());
});
let result = tokio::select! {
result = async_loop(adapter) => result,
_ = rx => {
println!("Shutting down...");
Ok(()) }
};
if let Err(e) = result {
eprintln!("Server error: {}", e);
}
}
#[derive(Parser)]
struct Cli {
#[clap(short, long)]
interface_index: usize,
}
#[tokio::main]
async fn main() -> Result<()> {
let Cli {
mut interface_index,
} = Cli::parse();
interface_index -= 1;
let driver = Arc::new(
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 {}", adapters[interface_index].get_name(),);
let mut adapter =
AsyncNdisapiAdapter::new(Arc::clone(&driver), adapters[interface_index].get_handle())
.unwrap();
main_async(&mut adapter).await;
Ok(())
}
fn print_packet_info(packet: &mut IntermediateBuffer) {
let mut eth_hdr = EthernetFrame::new_unchecked(packet.get_data_mut());
match eth_hdr.ethertype() {
EthernetProtocol::Ipv4 => {
let mut ipv4_packet = Ipv4Packet::new_unchecked(eth_hdr.payload_mut());
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_mut());
println!(
"ICMPv4: Type: {:?} Code: {:?}",
icmp_packet.msg_type(),
icmp_packet.msg_code()
);
}
IpProtocol::Tcp => {
let tcp_packet = TcpPacket::new_unchecked(ipv4_packet.payload_mut());
println!(
" TCP {:?} -> {:?}",
tcp_packet.src_port(),
tcp_packet.dst_port()
);
}
IpProtocol::Udp => {
let udp_packet = UdpPacket::new_unchecked(ipv4_packet.payload_mut());
println!(
" UDP {:?} -> {:?}",
udp_packet.src_port(),
udp_packet.dst_port()
);
}
_ => {
println!("Unknown IPv4 packet: {:?}", ipv4_packet);
}
}
}
EthernetProtocol::Ipv6 => {
let mut ipv6_packet = Ipv6Packet::new_unchecked(eth_hdr.payload_mut());
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_mut());
println!(
"ICMPv6 packet: Type: {:?} Code: {:?}",
icmpv6_packet.msg_type(),
icmpv6_packet.msg_code()
);
}
IpProtocol::Tcp => {
let tcp_packet = TcpPacket::new_unchecked(ipv6_packet.payload_mut());
println!(
" TCP {:?} -> {:?}",
tcp_packet.src_port(),
tcp_packet.dst_port()
);
}
IpProtocol::Udp => {
let udp_packet = UdpPacket::new_unchecked(ipv6_packet.payload_mut());
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_mut());
println!("ARP packet: {:?}", arp_packet);
}
EthernetProtocol::Unknown(_) => {
println!("Unknown Ethernet packet: {:?}", eth_hdr);
}
}
}