windivert_sys/bindings/
address.rs

1/*!
2WinDivert address types.
3
4For more info, refer to the [docs](https://reqrypt.org/windivert-doc.html#divert_address).
5*/
6
7use std::{convert::TryFrom, fmt::Debug};
8
9use super::{BitfieldUnit, WinDivertEvent, WinDivertFlags, WinDivertLayer};
10
11#[repr(C)]
12#[derive(Debug, Default, Copy, Clone)]
13/**
14Represents the associated data recieved using [`WinDivertLayer::Network`]
15*/
16pub struct WINDIVERT_DATA_NETWORK {
17    /// Interface index on whick the packet arrived (for inbound packets) or will be sent (for outbound packets).
18    pub interface_id: u32,
19    /// The sub-interface index for `interface_id`
20    pub subinterface_id: u32,
21}
22
23#[repr(C)]
24#[derive(Debug, Default, Copy, Clone)]
25/**
26Represents the associated data recieved using [`WinDivertLayer::Flow`]
27*/
28pub struct WINDIVERT_DATA_FLOW {
29    /// The endpoint ID of the flow.
30    pub endpoint_id: u64,
31    /// The parent endpoint ID of the flow.
32    pub parent_endpoint_id: u64,
33    /// The id of the process associated with the flow.
34    pub process_id: u32,
35    /**
36    The local address associated with the socket.
37
38    For IPv4, this field will contain IPv4-mapped IPv6 addresses, e.g. the IPv4 address X.Y.Z.W will be represented by ::ffff:X.Y.Z.W.
39
40    This field can contain a value o zero, since [`SocketBind`](WinDivertEvent::SocketBind) and [`SocketBind`](WinDivertEvent::SocketListen) events can occur before a connection attempt has been made.
41    */
42    pub local_addr: [u32; 4usize],
43    /**
44    The remote address associated with the socket.
45
46    For IPv4, this field will contain IPv4-mapped IPv6 addresses, e.g. the IPv4 address X.Y.Z.W will be represented by ::ffff:X.Y.Z.W.
47
48    This field can contain a value o zero, since [`SocketBind`](WinDivertEvent::SocketBind) and [`SocketBind`](WinDivertEvent::SocketListen) events can occur before a connection attempt has been made.
49    */
50    pub remote_addr: [u32; 4usize],
51    /// The local port associated with the flow.
52    pub local_port: u16,
53    /// The remote port associated with the flow.
54    pub remote_port: u16,
55    /// The flow protocol.
56    pub protocol: u8,
57}
58
59#[repr(C)]
60#[derive(Debug, Default, Copy, Clone)]
61/**
62Represents the associated data recieved using [`WinDivertLayer::Socket`]
63*/
64pub struct WINDIVERT_DATA_SOCKET {
65    /// The endpoint ID of the socket.
66    pub endpoint_id: u64,
67    /// The parent endpoint ID of the socket.
68    pub parent_endpoint_id: u64,
69    /// The id of the process associated with the socket.
70    pub process_id: u32,
71    /**
72    The local address associated with the socket.
73
74    For IPv4, this field will contain IPv4-mapped IPv6 addresses, e.g. the IPv4 address X.Y.Z.W will be represented by ::ffff:X.Y.Z.W.
75    */
76    pub local_addr: [u32; 4usize],
77    /**
78    The remote address associated with the socket.
79
80    For IPv4, this field will contain IPv4-mapped IPv6 addresses, e.g. the IPv4 address X.Y.Z.W will be represented by ::ffff:X.Y.Z.W.
81    */
82    pub remote_addr: [u32; 4usize],
83    /// The local port associated with the socket.
84    pub local_port: u16,
85    /// The remote port associated with the socket.
86    pub remote_port: u16,
87    /// The socket protocol.
88    pub protocol: u8,
89}
90
91#[repr(C)]
92#[derive(Debug, Copy, Clone)]
93/**
94Represents the associated data recieved using [`WinDivertLayer::Reflect`]
95*/
96pub struct WINDIVERT_DATA_REFLECT {
97    /// Timestamp indicating when the handle was opened.
98    pub timestamp: i64,
99    /// Process if of the process that opened the handle.
100    pub process_id: u32,
101    /// [`WinDivertLayer`] parameter on [`WinDivertOpen`](super::WinDivertOpen) for the specified handle.
102    pub layer: WinDivertLayer,
103    /// [`WinDivertFlags`] parameter on [`WinDivertOpen`](super::WinDivertOpen) for the specified handle.
104    pub flags: WinDivertFlags,
105    /// Priority parameter on [`WinDivertOpen`](super::WinDivertOpen) for the specified handle.
106    pub priority: i16,
107}
108
109impl Default for WINDIVERT_DATA_REFLECT {
110    fn default() -> Self {
111        unsafe { ::std::mem::zeroed() }
112    }
113}
114
115#[repr(C)]
116#[derive(Copy, Clone)]
117/// Union of the different data types associated with the possible layer values.
118pub union WINDIVERT_ADDRESS_UNION_FIELD {
119    /// Address data related to [`Network`](WinDivertLayer::Network) and [`Forward`](WinDivertLayer::Forward) layers.
120    pub Network: WINDIVERT_DATA_NETWORK,
121    /// Address data related to [`Flow`](WinDivertLayer::Flow) layer.
122    pub Flow: WINDIVERT_DATA_FLOW,
123    /// Address data related to [`Socket`](WinDivertLayer::Socket) layer.
124    pub Socket: WINDIVERT_DATA_SOCKET,
125    /// Address data related to [`Reflect`](WinDivertLayer::Reflect) layer.
126    pub Reflect: WINDIVERT_DATA_REFLECT,
127    reserved: [u8; 64usize],
128    _union_align: [u64; 8usize],
129}
130
131impl Default for WINDIVERT_ADDRESS_UNION_FIELD {
132    fn default() -> Self {
133        unsafe { ::std::mem::zeroed() }
134    }
135}
136
137#[repr(C)]
138#[derive(Copy, Clone)]
139/**
140Base data type returned by [`recv`](fn@super::WinDivertRecv) and required by [`send`](fn@super::WinDivertSend)
141
142Most address fields are ignored by [`WinDivertSend()`](fn@super::WinDivertSend). The exceptions are Outbound (for [`WinDivertLayer::Network`] layer only), Impostor, IPChecksum, TCPChecksum, UDPChecksum, [`Network.interface_id`](WINDIVERT_DATA_NETWORK::interface_id) and [`Network.subinterface_id`](WINDIVERT_DATA_NETWORK::subinterface_id).
143*/
144pub struct WINDIVERT_ADDRESS {
145    /// Timestamp indicating when the event occurred.
146    pub timestamp: i64,
147    addr_bitfield: BitfieldUnit<[u8; 4usize], u8>,
148    reserved: u32,
149    /// Union of the different data types associated with the possible layer values.
150    pub union_field: WINDIVERT_ADDRESS_UNION_FIELD,
151}
152
153impl Default for WINDIVERT_ADDRESS {
154    fn default() -> Self {
155        unsafe { ::std::mem::zeroed() }
156    }
157}
158
159impl WINDIVERT_ADDRESS {
160    #[inline]
161    /// Getter for the handle [`layer`](super::WinDivertLayer)
162    pub fn layer(&self) -> WinDivertLayer {
163        WinDivertLayer::try_from(self.addr_bitfield.get(0usize, 8u8) as u32)
164            .expect("Layer always is correct since it would have produced an error in Open()")
165    }
166    #[inline]
167    /// Setter for the handle [`layer`](super::WinDivertLayer)
168    pub fn set_layer(&mut self, val: WinDivertLayer) {
169        self.addr_bitfield.set(0usize, 8u8, u32::from(val) as u64)
170    }
171    #[inline]
172    /// Getter for the handle [`event`](super::WinDivertEvent)
173    pub fn event(&self) -> WinDivertEvent {
174        WinDivertEvent::try_from(self.addr_bitfield.get(8usize, 8u8) as u8)
175            .expect("Event always is correct since the value comes from the DLL functions.")
176    }
177    #[inline]
178    /// Setter for the handle [`event`](super::WinDivertEvent)
179    pub fn set_event(&mut self, val: WinDivertEvent) {
180        self.addr_bitfield.set(8usize, 8u8, u32::from(val) as u64)
181    }
182    #[inline]
183    /// Set to true if the packet was sniffed (not blocked).
184    pub fn sniffed(&self) -> bool {
185        self.addr_bitfield.get(16usize, 1u8) == 1
186    }
187    #[inline]
188    /// Sniffed flag setter.
189    pub fn set_sniffed(&mut self, val: bool) {
190        self.addr_bitfield.set(16usize, 1u8, val as u64)
191    }
192    #[inline]
193    /// Set to true for outbound packet events.
194    pub fn outbound(&self) -> bool {
195        self.addr_bitfield.get(17usize, 1u8) == 1
196    }
197    #[inline]
198    /// Outbound flag setter.
199    pub fn set_outbound(&mut self, val: bool) {
200        self.addr_bitfield.set(17usize, 1u8, val as u64)
201    }
202    #[inline]
203    /// Set to true for loopback packets.
204    pub fn loopback(&self) -> bool {
205        self.addr_bitfield.get(18usize, 1u8) == 1
206    }
207    #[inline]
208    /// Loopback flag setter.
209    pub fn set_loopback(&mut self, val: bool) {
210        self.addr_bitfield.set(18usize, 1u8, val as u64)
211    }
212    #[inline]
213    /// Set to true for "impostor" packets.
214    pub fn impostor(&self) -> bool {
215        self.addr_bitfield.get(19usize, 1u8) == 1
216    }
217    #[inline]
218    /// Impostor flag setter.
219    pub fn set_impostor(&mut self, val: bool) {
220        self.addr_bitfield.set(19usize, 1u8, val as u64)
221    }
222    #[inline]
223    /// Set to true for IPv6 packets.
224    pub fn ipv6(&self) -> bool {
225        self.addr_bitfield.get(20usize, 1u8) == 1
226    }
227    #[inline]
228    /// IPv6 flag setter.
229    pub fn set_ipv6(&mut self, val: bool) {
230        self.addr_bitfield.set(20usize, 1u8, val as u64)
231    }
232    #[inline]
233    /// Set to true if the IPv4 checksum is valid.
234    pub fn ipchecksum(&self) -> bool {
235        self.addr_bitfield.get(21usize, 1u8) == 1
236    }
237    #[inline]
238    /// IPv4 checksum flag setter.
239    pub fn set_ipchecksum(&mut self, val: bool) {
240        self.addr_bitfield.set(21usize, 1u8, val as u64)
241    }
242    #[inline]
243    /// Set to true if the TCP checksum is valid.
244    pub fn tcpchecksum(&self) -> bool {
245        self.addr_bitfield.get(22usize, 1u8) == 1
246    }
247    #[inline]
248    /// TCP checksum flag setter.
249    pub fn set_tcpchecksum(&mut self, val: bool) {
250        self.addr_bitfield.set(22usize, 1u8, val as u64)
251    }
252    #[inline]
253    /// Set to true if the UDP checksum is valid.
254    pub fn udpchecksum(&self) -> bool {
255        self.addr_bitfield.get(23usize, 1u8) == 1
256    }
257    #[inline]
258    /// UDP checksum flag setter.
259    pub fn set_udpchecksum(&mut self, val: bool) {
260        self.addr_bitfield.set(23usize, 1u8, val as u64)
261    }
262}
263
264impl Debug for WINDIVERT_ADDRESS {
265    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
266        let union_str = match self.event() {
267            WinDivertEvent::NetworkPacket => {
268                format!("{:?}", unsafe { self.union_field.Network })
269            }
270            WinDivertEvent::FlowStablished | WinDivertEvent::FlowDeleted => {
271                format!("{:?}", unsafe { self.union_field.Flow })
272            }
273            WinDivertEvent::SocketBind
274            | WinDivertEvent::SocketConnect
275            | WinDivertEvent::SocketListen
276            | WinDivertEvent::SocketAccept
277            | WinDivertEvent::SocketClose => {
278                format!("{:?}", unsafe { self.union_field.Socket })
279            }
280            WinDivertEvent::ReflectOpen | WinDivertEvent::ReflectClose => {
281                format!("{:?}", unsafe { self.union_field.Reflect })
282            }
283        };
284        write!(f, "WINDIVERT_ADDRESS {{ Timestamp: {:?}, Layer: {:?}, Event: {:?}, Sniffed: {:?}, Outbound: {:?}, Loopback: {:?}, Impostor: {:?}, IPv6: {:?}, IPChecksum: {:?}, TCPChecksum: {:?}, UDPChecksum: {:?}, {}}}",
285        self.timestamp, self.layer(), self.event(), self.sniffed(), self.outbound(), self.loopback(), self.impostor(), self.ipv6(), self.ipchecksum(), self.tcpchecksum(), self.udpchecksum(), union_str)
286    }
287}