use std::{convert::TryFrom, fmt::Debug};
use super::{BitfieldUnit, WinDivertEvent, WinDivertFlags, WinDivertLayer};
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct WINDIVERT_DATA_NETWORK {
pub interface_id: u32,
pub subinterface_id: u32,
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct WINDIVERT_DATA_FLOW {
pub endpoint_id: u64,
pub parent_endpoint_id: u64,
pub process_id: u32,
pub local_addr: [u32; 4usize],
pub remote_addr: [u32; 4usize],
pub local_port: u16,
pub remote_port: u16,
pub protocol: u8,
}
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub struct WINDIVERT_DATA_SOCKET {
pub endpoint_id: u64,
pub parent_endpoint_id: u64,
pub process_id: u32,
pub local_addr: [u32; 4usize],
pub remote_addr: [u32; 4usize],
pub local_port: u16,
pub remote_port: u16,
pub protocol: u8,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct WINDIVERT_DATA_REFLECT {
pub timestamp: i64,
pub process_id: u32,
pub layer: WinDivertLayer,
pub flags: WinDivertFlags,
pub priority: i16,
}
impl Default for WINDIVERT_DATA_REFLECT {
fn default() -> Self {
unsafe { ::std::mem::zeroed() }
}
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union WINDIVERT_ADDRESS_UNION_FIELD {
pub Network: WINDIVERT_DATA_NETWORK,
pub Flow: WINDIVERT_DATA_FLOW,
pub Socket: WINDIVERT_DATA_SOCKET,
pub Reflect: WINDIVERT_DATA_REFLECT,
reserved: [u8; 64usize],
_union_align: [u64; 8usize],
}
impl Default for WINDIVERT_ADDRESS_UNION_FIELD {
fn default() -> Self {
unsafe { ::std::mem::zeroed() }
}
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct WINDIVERT_ADDRESS {
pub timestamp: i64,
addr_bitfield: BitfieldUnit<[u8; 4usize], u8>,
reserved: u32,
pub union_field: WINDIVERT_ADDRESS_UNION_FIELD,
}
impl Default for WINDIVERT_ADDRESS {
fn default() -> Self {
unsafe { ::std::mem::zeroed() }
}
}
impl WINDIVERT_ADDRESS {
#[inline]
pub fn layer(&self) -> WinDivertLayer {
WinDivertLayer::try_from(self.addr_bitfield.get(0usize, 8u8) as u32)
.expect("Layer always is correct since it would have produced an error in Open()")
}
#[inline]
pub fn set_layer(&mut self, val: WinDivertLayer) {
self.addr_bitfield.set(0usize, 8u8, u32::from(val) as u64)
}
#[inline]
pub fn event(&self) -> WinDivertEvent {
WinDivertEvent::try_from(self.addr_bitfield.get(8usize, 8u8) as u8)
.expect("Event always is correct since the value comes from the DLL functions.")
}
#[inline]
pub fn set_event(&mut self, val: WinDivertEvent) {
self.addr_bitfield.set(8usize, 8u8, u32::from(val) as u64)
}
#[inline]
pub fn sniffed(&self) -> bool {
self.addr_bitfield.get(16usize, 1u8) == 1
}
#[inline]
pub fn set_sniffed(&mut self, val: bool) {
self.addr_bitfield.set(16usize, 1u8, val as u64)
}
#[inline]
pub fn outbound(&self) -> bool {
self.addr_bitfield.get(17usize, 1u8) == 1
}
#[inline]
pub fn set_outbound(&mut self, val: bool) {
self.addr_bitfield.set(17usize, 1u8, val as u64)
}
#[inline]
pub fn loopback(&self) -> bool {
self.addr_bitfield.get(18usize, 1u8) == 1
}
#[inline]
pub fn set_loopback(&mut self, val: bool) {
self.addr_bitfield.set(18usize, 1u8, val as u64)
}
#[inline]
pub fn impostor(&self) -> bool {
self.addr_bitfield.get(19usize, 1u8) == 1
}
#[inline]
pub fn set_impostor(&mut self, val: bool) {
self.addr_bitfield.set(19usize, 1u8, val as u64)
}
#[inline]
pub fn ipv6(&self) -> bool {
self.addr_bitfield.get(20usize, 1u8) == 1
}
#[inline]
pub fn set_ipv6(&mut self, val: bool) {
self.addr_bitfield.set(20usize, 1u8, val as u64)
}
#[inline]
pub fn ipchecksum(&self) -> bool {
self.addr_bitfield.get(21usize, 1u8) == 1
}
#[inline]
pub fn set_ipchecksum(&mut self, val: bool) {
self.addr_bitfield.set(21usize, 1u8, val as u64)
}
#[inline]
pub fn tcpchecksum(&self) -> bool {
self.addr_bitfield.get(22usize, 1u8) == 1
}
#[inline]
pub fn set_tcpchecksum(&mut self, val: bool) {
self.addr_bitfield.set(22usize, 1u8, val as u64)
}
#[inline]
pub fn udpchecksum(&self) -> bool {
self.addr_bitfield.get(23usize, 1u8) == 1
}
#[inline]
pub fn set_udpchecksum(&mut self, val: bool) {
self.addr_bitfield.set(23usize, 1u8, val as u64)
}
}
impl Debug for WINDIVERT_ADDRESS {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let union_str = match self.event() {
WinDivertEvent::NetworkPacket => {
format!("{:?}", unsafe { self.union_field.Network })
}
WinDivertEvent::FlowStablished | WinDivertEvent::FlowDeleted => {
format!("{:?}", unsafe { self.union_field.Flow })
}
WinDivertEvent::SocketBind
| WinDivertEvent::SocketConnect
| WinDivertEvent::SocketListen
| WinDivertEvent::SocketAccept
| WinDivertEvent::SocketClose => {
format!("{:?}", unsafe { self.union_field.Socket })
}
WinDivertEvent::ReflectOpen | WinDivertEvent::ReflectClose => {
format!("{:?}", unsafe { self.union_field.Reflect })
}
};
write!(f, "WINDIVERT_ADDRESS {{ Timestamp: {:?}, Layer: {:?}, Event: {:?}, Sniffed: {:?}, Outbound: {:?}, Loopback: {:?}, Impostor: {:?}, IPv6: {:?}, IPChecksum: {:?}, TCPChecksum: {:?}, UDPChecksum: {:?}, {}}}",
self.timestamp, self.layer(), self.event(), self.sniffed(), self.outbound(), self.loopback(), self.impostor(), self.ipv6(), self.ipchecksum(), self.tcpchecksum(), self.udpchecksum(), union_str)
}
}