use std::{
mem::{self, size_of},
ptr::write_bytes,
};
use ndisapi::{IphlpNetworkAdapterInfo, MacAddress, Ndisapi, PacketOidData, RasLinks};
use windows::core::Result;
const OID_802_3_CURRENT_ADDRESS: u32 = 0x01010102;
fn main() -> Result<()> {
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()?;
for (index, adapter) in adapters.iter().enumerate() {
let network_interface_name = Ndisapi::get_friendly_adapter_name(adapter.get_name())
.expect("Unknown network interface");
println!(
"{}. {}\n\t{}",
index + 1,
network_interface_name,
adapter.get_name(),
);
println!("\t Medium: {}", adapter.get_medium());
println!(
"\t MAC: {}",
MacAddress::from_slice(adapter.get_hw_address()).unwrap_or_default()
);
println!("\t MTU: {}", adapter.get_mtu());
if let Some(mac_addr) = MacAddress::from_slice(adapter.get_hw_address()) {
if let Some(ip_info) = IphlpNetworkAdapterInfo::get_connection_by_hw_address(&mac_addr)
{
let addresses_with_prefix = ip_info.unicast_address_list_with_prefix();
if !addresses_with_prefix.is_empty() {
println!("\t IP Addresses:");
for (ip_addr, prefix_length) in addresses_with_prefix {
println!("\t\t {}/{}", ip_addr, prefix_length);
}
} else {
println!("\t IP Addresses: None found");
}
} else {
println!("\t IP Addresses: Not available");
}
} else {
println!("\t IP Addresses: Not available");
}
println!(
"\t FilterFlags: {:?}",
driver.get_adapter_mode(adapter.get_handle()).unwrap()
);
match driver.get_hw_packet_filter(adapter.get_handle()) {
Err(err) => println!(
"Getting OID_GEN_CURRENT_PACKET_FILTER Error: {}",
err.message()
),
Ok(current_packet_filter) => {
println!("\t OID_GEN_CURRENT_PACKET_FILTER: 0x{current_packet_filter:08X}")
}
}
let mut current_address_request = PacketOidData::new(
adapter.get_handle(),
OID_802_3_CURRENT_ADDRESS,
MacAddress::default(),
);
if let Err(err) = driver.ndis_get_request::<_>(&mut current_address_request) {
println!("Getting OID_802_3_CURRENT_ADDRESS Error: {}", err.message(),)
} else {
println!(
"\t OID_802_3_CURRENT_ADDRESS: {}",
current_address_request.data
)
}
if Ndisapi::is_ndiswan_ip(adapter.get_name())
|| Ndisapi::is_ndiswan_ipv6(adapter.get_name())
{
let mut ras_links_vec: Vec<RasLinks> = Vec::with_capacity(1);
unsafe {
write_bytes::<u8>(
mem::transmute(ras_links_vec.as_mut_ptr()),
0,
size_of::<RasLinks>(),
);
ras_links_vec.set_len(1)
};
let ras_links = &mut ras_links_vec[0];
if let Ok(()) = driver.get_ras_links(adapter.get_handle(), ras_links) {
println!(
"Number of active WAN links: {}",
ras_links.get_number_of_links()
);
for k in 0..ras_links.get_number_of_links() {
println!(
"\t{}) LinkSpeed = {} MTU = {}",
k,
ras_links.ras_links[k].get_link_speed(),
ras_links.ras_links[k].get_maximum_total_size()
);
let local_mac_address =
MacAddress::from_slice(ras_links.ras_links[k].get_local_address()).unwrap();
let remote_mac_address =
MacAddress::from_slice(ras_links.ras_links[k].get_remote_address())
.unwrap();
println!("\t\tLocal MAC:\t {local_mac_address}");
println!("\t\tRemote MAC:\t {remote_mac_address}");
if Ndisapi::is_ndiswan_ip(adapter.get_name()) {
println!(
"\t\tIP address:\t {}.{}.{}.{} mask {}.{}.{}.{}",
ras_links.ras_links[k].get_protocol_buffer()[584],
ras_links.ras_links[k].get_protocol_buffer()[585],
ras_links.ras_links[k].get_protocol_buffer()[586],
ras_links.ras_links[k].get_protocol_buffer()[587],
ras_links.ras_links[k].get_protocol_buffer()[588],
ras_links.ras_links[k].get_protocol_buffer()[589],
ras_links.ras_links[k].get_protocol_buffer()[590],
ras_links.ras_links[k].get_protocol_buffer()[591],
);
} else {
println!(
"\t\tIPv6 address (without prefix):\t {:02X}{:02X}:{:02X}{:02X}:{:02X}{:02X}:{:02X}{:02X}",
ras_links.ras_links[k].get_protocol_buffer()[588],
ras_links.ras_links[k].get_protocol_buffer()[589],
ras_links.ras_links[k].get_protocol_buffer()[590],
ras_links.ras_links[k].get_protocol_buffer()[591],
ras_links.ras_links[k].get_protocol_buffer()[592],
ras_links.ras_links[k].get_protocol_buffer()[593],
ras_links.ras_links[k].get_protocol_buffer()[594],
ras_links.ras_links[k].get_protocol_buffer()[595],
);
}
}
} else {
println!("Failed to query active WAN links information.");
}
}
}
let mtu_decrement = driver.get_mtu_decrement().unwrap_or(0);
println!("\nSystem wide MTU decrement: {mtu_decrement}");
let startup_mode = driver.get_adapters_startup_mode().unwrap_or(0);
println!("\nSystem wide network adapter startup filter mode: {startup_mode}");
let pool_size = driver.get_pool_size().unwrap_or(0);
println!("\nDriver intermediate buffer pool size multiplier: {pool_size}");
let effective_pool_size = driver.get_intermediate_buffer_pool_size().unwrap_or(0);
println!("\nEffective intermediate buffer pool size: {effective_pool_size}");
Ok(())
}