use core::sync::atomic::{AtomicBool, Ordering};
use core::ptr;
use wdk::println;
use wdk_sys::{NTSTATUS, PVOID, STATUS_SUCCESS, HANDLE, GUID};
#[allow(non_camel_case_types)]
pub type FWP_ACTION_TYPE = u32;
#[allow(non_camel_case_types)]
pub type FWP_CLASSIFY_OUT = u8; #[allow(non_camel_case_types)]
pub type FWP_INCOMING_VALUES = u8; #[allow(non_camel_case_types)]
pub type FWPS_INCOMING_METADATA_VALUES = u8; #[allow(non_camel_case_types)]
pub type FWPS_CALLOUT = u8; #[allow(non_camel_case_types)]
pub type FWPS_FILTER = u8; #[allow(non_camel_case_types)]
pub type FWPS_CALLOUT_NOTIFY_TYPE = u32;
#[allow(non_camel_case_types)]
pub type FWPM_CALLOUT = u8; #[allow(non_camel_case_types)]
pub type FWPM_FILTER = u8; #[allow(non_camel_case_types)]
pub type FWPM_SUBLAYER = u8; #[allow(non_camel_case_types)]
pub type FWPM_DISPLAY_DATA0 = u8; #[allow(non_camel_case_types)]
pub type FWP_BYTE_BLOB = u8;
pub const FWP_ACTION_PERMIT: FWP_ACTION_TYPE = 0x00000001;
pub const FWP_ACTION_BLOCK: FWP_ACTION_TYPE = 0x00000002;
pub const FWP_ACTION_CONTINUE: FWP_ACTION_TYPE = 0x00000003;
pub const FWPS_CLASSIFY_OUT_FLAG_ABSORB: u32 = 0x00000001;
pub const RPC_C_AUTHN_WINNT: u32 = 10;
static REGISTERED: AtomicBool = AtomicBool::new(false);
static mut ENGINE_HANDLE: HANDLE = ptr::null_mut();
static mut CALLOUT_IDS: [u32; 4] = [0; 4];
pub const SUBLAYER_GUID: GUID = GUID {
Data1: 0xA1B2C3D4,
Data2: 0xE5F6,
Data3: 0x7890,
Data4: [0xAB, 0xCD, 0xEF, 0x12, 0x34, 0x56, 0x78, 0x90],
};
pub const CALLOUT_OUTBOUND_IPV4_GUID: GUID = GUID {
Data1: 0x11111111,
Data2: 0x1111,
Data3: 0x1111,
Data4: [0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11],
};
pub const CALLOUT_INBOUND_IPV4_GUID: GUID = GUID {
Data1: 0x22222222,
Data2: 0x2222,
Data3: 0x2222,
Data4: [0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22],
};
pub const CALLOUT_ALE_CONNECT_GUID: GUID = GUID {
Data1: 0x33333333,
Data2: 0x3333,
Data3: 0x3333,
Data4: [0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33],
};
pub const CALLOUT_ALE_RECV_GUID: GUID = GUID {
Data1: 0x44444444,
Data2: 0x4444,
Data3: 0x4444,
Data4: [0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44],
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NetworkAction {
Permit,
Block,
Continue,
}
#[derive(Debug)]
pub struct ConnectionInfo {
pub local_addr: [u8; 4],
pub local_port: u16,
pub remote_addr: [u8; 4],
pub remote_port: u16,
pub protocol: u8,
pub process_id: u32,
pub direction: Direction,
}
#[derive(Debug, Clone, Copy)]
pub enum Direction {
Inbound,
Outbound,
}
const BLOCKED_IPS: &[[u8; 4]] = &[
];
const BLOCKED_PORTS: &[u16] = &[
4444, 5555, 6666, 31337, ];
pub unsafe fn register(_device_object: PVOID) -> Result<(), NTSTATUS> {
if REGISTERED.load(Ordering::SeqCst) {
return Ok(());
}
println!("[Leviathan] WFP network filter registration skipped - not available in wdk-sys 0.5");
println!("[Leviathan] To enable: add WFP feature flags to wdk-sys dependency");
REGISTERED.store(true, Ordering::SeqCst);
Ok(())
}
pub unsafe fn unregister() {
if !REGISTERED.load(Ordering::SeqCst) {
return;
}
REGISTERED.store(false, Ordering::SeqCst);
println!("[Leviathan] WFP network filter unregistered");
}
unsafe fn add_sublayer(_engine_handle: HANDLE) -> Result<(), NTSTATUS> {
Ok(())
}
unsafe fn register_callouts(_device_object: PVOID) -> Result<(), NTSTATUS> {
Ok(())
}
unsafe fn add_filters(_engine_handle: HANDLE) -> Result<(), NTSTATUS> {
Ok(())
}
unsafe extern "C" fn classify_outbound(
_fixed_values: *const FWP_INCOMING_VALUES,
_meta_values: *const FWPS_INCOMING_METADATA_VALUES,
_layer_data: PVOID,
_context: PVOID,
_filter: *const FWPS_FILTER,
_flow_context: u64,
_classify_out: *mut FWP_CLASSIFY_OUT,
) {
}
unsafe extern "C" fn classify_inbound(
_fixed_values: *const FWP_INCOMING_VALUES,
_meta_values: *const FWPS_INCOMING_METADATA_VALUES,
_layer_data: PVOID,
_context: PVOID,
_filter: *const FWPS_FILTER,
_flow_context: u64,
_classify_out: *mut FWP_CLASSIFY_OUT,
) {
}
unsafe extern "C" fn classify_ale_connect(
_fixed_values: *const FWP_INCOMING_VALUES,
_meta_values: *const FWPS_INCOMING_METADATA_VALUES,
_layer_data: PVOID,
_context: PVOID,
_filter: *const FWPS_FILTER,
_flow_context: u64,
_classify_out: *mut FWP_CLASSIFY_OUT,
) {
}
unsafe extern "C" fn notify_callout(
_notify_type: FWPS_CALLOUT_NOTIFY_TYPE,
_filter_key: *const GUID,
_filter: *const FWPS_FILTER,
) -> NTSTATUS {
STATUS_SUCCESS
}
fn check_outbound_policy() -> NetworkAction {
NetworkAction::Permit
}
fn check_inbound_policy() -> NetworkAction {
NetworkAction::Permit
}
#[allow(dead_code)]
fn is_blocked_ip(ip: &[u8; 4]) -> bool {
for blocked in BLOCKED_IPS {
if ip == blocked {
return true;
}
}
false
}
#[allow(dead_code)]
fn is_blocked_port(port: u16) -> bool {
BLOCKED_PORTS.contains(&port)
}
#[allow(dead_code)]
fn log_connection(info: &ConnectionInfo, action: NetworkAction) {
println!(
"[Leviathan] {:?} {:?} -> {:?} (PID: {}) = {:?}",
info.direction,
info.local_addr,
info.remote_addr,
info.process_id,
action
);
}
fn format_ip(ip: &[u8; 4]) -> [u8; 15] {
let mut buf = [b' '; 15];
buf[0] = ip[0];
buf
}