1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
//! # Submodule: Static filter functions
//!
//! This submodule provides methods for controlling the NDIS filter driver, including retrieving and setting
//! the static filter table, resetting the filter statistics, and resetting the static filter table. These
//! methods are parameterized by the size of the static filter table. The submodule is part of a larger module
//! (NDISAPI) that provides high-level API for the Windows packet Filter on Windows.
//!
use std::mem::size_of;
use windows::{core::Result, Win32::Foundation::GetLastError, Win32::System::IO::DeviceIoControl};
use super::Ndisapi;
use crate::driver::*;
impl Ndisapi {
/// This function retrieves the static filter table from the NDIS filter driver and stores it in
/// the provided `filter_table` argument.
///
/// # Type Parameters
///
/// * `N`: The size of the static filter table.
///
/// # Arguments
///
/// * `filter_table`: A mutable reference to a `StaticFilterTable<N>` object, which will store the
/// queried static filter table.
///
/// # Returns
///
/// * `Result<()>`: If successful, returns `Ok(())`. Otherwise, returns an error.
pub fn get_packet_filter_table<const N: usize>(
&self,
filter_table: &mut StaticFilterTable<N>,
) -> Result<()> {
let result = unsafe {
DeviceIoControl(
self.driver_handle,
IOCTL_NDISRD_GET_PACKET_FILTERS,
None,
0,
Some(filter_table as *mut StaticFilterTable<N> as *mut std::ffi::c_void),
size_of::<StaticFilterTable<N>>() as u32,
None,
None,
)
};
if !result.as_bool() {
Err(unsafe { GetLastError() }.into())
} else {
Ok(())
}
}
/// This function retrieves the static filter table from the NDIS filter driver, stores it in
/// the provided `filter_table` argument, and resets the filter statistics.
///
/// # Type Parameters
///
/// * `N`: The size of the static filter table.
///
/// # Arguments
///
/// * `filter_table`: A mutable reference to a `StaticFilterTable<N>` object, which will store the
/// queried static filter table.
///
/// # Returns
///
/// * `Result<()>`: If successful, returns `Ok(())`. Otherwise, returns an error.
pub fn get_packet_filter_table_reset_stats<const N: usize>(
&self,
filter_table: &mut StaticFilterTable<N>,
) -> Result<()> {
let result = unsafe {
DeviceIoControl(
self.driver_handle,
IOCTL_NDISRD_GET_PACKET_FILTERS_RESET_STATS,
None,
0,
Some(filter_table as *mut StaticFilterTable<N> as *mut std::ffi::c_void),
size_of::<StaticFilterTable<N>>() as u32,
None,
None,
)
};
if !result.as_bool() {
Err(unsafe { GetLastError() }.into())
} else {
Ok(())
}
}
/// This function retrieves the size of the static filter table from the NDIS filter driver.
///
/// # Returns
///
/// * `Result<usize>`: If successful, returns the size of the static filter table as `Ok(usize)`.
/// Otherwise, returns an error.
pub fn get_packet_filter_table_size(&self) -> Result<usize> {
let mut size = 0u32;
let result = unsafe {
DeviceIoControl(
self.driver_handle,
IOCTL_NDISRD_GET_PACKET_FILTERS_TABLESIZE,
None,
0,
Some(&mut size as *mut u32 as *mut std::ffi::c_void),
size_of::<u32>() as u32,
None,
None,
)
};
if !result.as_bool() {
Err(unsafe { GetLastError() }.into())
} else {
Ok(size as usize)
}
}
/// This function resets the static filter table in the NDIS filter driver, effectively
/// removing all filters from the table.
///
/// # Returns
///
/// * `Result<()>`: If successful, returns `Ok(())`. Otherwise, returns an error.
pub fn reset_packet_filter_table(&self) -> Result<()> {
let result = unsafe {
DeviceIoControl(
self.driver_handle,
IOCTL_NDISRD_RESET_PACKET_FILTERS,
None,
0,
None,
0,
None,
None,
)
};
if !result.as_bool() {
Err(unsafe { GetLastError() }.into())
} else {
Ok(())
}
}
/// This function takes a static filter table and sets it as the current filter table
/// in the NDIS filter driver.
///
/// # Type Parameters
///
/// * `N`: The number of filters in the static filter table.
///
/// # Arguments
///
/// * `filter_table: &StaticFilterTable<N>`: A reference to the static filter table to be loaded.
///
/// # Returns
///
/// * `Result<()>`: If successful, returns `Ok(())`. Otherwise, returns an error.
pub fn set_packet_filter_table<const N: usize>(
&self,
filter_table: &StaticFilterTable<N>,
) -> Result<()> {
let result = unsafe {
DeviceIoControl(
self.driver_handle,
IOCTL_NDISRD_SET_PACKET_FILTERS,
Some(filter_table as *const StaticFilterTable<N> as *const std::ffi::c_void),
size_of::<StaticFilterTable<N>>() as u32,
None,
0,
None,
None,
)
};
if !result.as_bool() {
Err(unsafe { GetLastError() }.into())
} else {
Ok(())
}
}
}