windivert_sys/bindings/
newtypes.rs

1use std::{convert::TryFrom, u32};
2
3use super::WinDivertValueError;
4
5/**
6WinDivert layer to initialize the handle.
7
8WinDivert supports several layers for diverting or capturing network packets/events. Each layer has its own capabilities, such as the ability to block events or to inject new events, etc. The list of supported WinDivert layers is summarized below:
9
10| Layer     | Block?     | Inject?     | Data? | PID? | Description                                        |
11| --------- | ---------- | ----------- | ----- | ---- | -------------------------------------------------- |
12| `Network` | ✔          | ✔           | ✔     |      | Network packets to/from the local machine.         |
13| `Forward` | ✔          | ✔           | ✔     |      | Network packets passing through the local machine. |
14| `Flow`    |            |             |       | ✔    | Network flow established/deleted events.           |
15| `Socket`  | ✔          |             |       | ✔    | Socket operation events.                           |
16| `Reflect` |            |             | ✔     | ✔    | WinDivert handle events.                           |
17*/
18#[repr(u32)]
19#[derive(Debug, Copy, Clone)]
20pub enum WinDivertLayer {
21    /// Network packets to/from the local machine.
22    Network = 0,
23    /// Network packets passing through the local machine.
24    Forward = 1,
25    /// Network flow established/deleted events.
26    Flow = 2,
27    /// Socket operation events
28    Socket = 3,
29    /// WinDivert handle events.
30    Reflect = 4,
31}
32
33impl TryFrom<u32> for WinDivertLayer {
34    type Error = WinDivertValueError;
35
36    fn try_from(value: u32) -> Result<Self, Self::Error> {
37        match value {
38            0 => Ok(WinDivertLayer::Network),
39            1 => Ok(WinDivertLayer::Forward),
40            2 => Ok(WinDivertLayer::Flow),
41            3 => Ok(WinDivertLayer::Socket),
42            4 => Ok(WinDivertLayer::Reflect),
43            _ => Err(WinDivertValueError::Layer(value)),
44        }
45    }
46}
47
48impl From<WinDivertLayer> for u8 {
49    fn from(value: WinDivertLayer) -> Self {
50        match value {
51            WinDivertLayer::Network => 0,
52            WinDivertLayer::Forward => 1,
53            WinDivertLayer::Flow => 2,
54            WinDivertLayer::Socket => 3,
55            WinDivertLayer::Reflect => 4,
56        }
57    }
58}
59
60impl From<WinDivertLayer> for u32 {
61    fn from(value: WinDivertLayer) -> Self {
62        u8::from(value) as u32
63    }
64}
65
66/**
67WinDivert event identifiers.
68
69Each [`WinDivertLayer`] supports one or more kind of events:
70 * [`Network`](WinDivertLayer::Network) and [`Forward`](WinDivertLayer::Forward):
71   * [`WinDivertEvent::NetworkPacket`]
72 * [`Flow`](WinDivertLayer::Flow):
73   * [`WinDivertEvent::FlowStablished`]
74   * [`WinDivertEvent::FlowDeleted`]
75 * [`Socket`](WinDivertLayer::Socket):
76   * [`WinDivertEvent::SocketBind`]
77   * [`WinDivertEvent::SocketConnect`]
78   * [`WinDivertEvent::SocketListen`]
79   * [`WinDivertEvent::SocketAccept`]
80   * [`WinDivertEvent::SocketClose`]
81 * [`Reflect`](WinDivertLayer::Reflect):
82   * [`WinDivertEvent::ReflectOpen`]
83   * [`WinDivertEvent::ReflectClose`]
84*/
85#[repr(C)]
86#[derive(Debug, Copy, Clone)]
87pub enum WinDivertEvent {
88    /// Network packet.
89    NetworkPacket = 0,
90    /// Flow established.
91    FlowStablished = 1,
92    /// Flow deleted.
93    FlowDeleted = 2,
94    /// Socket bind.
95    SocketBind = 3,
96    /// Socket connect.
97    SocketConnect = 4,
98    /// Socket listen.
99    SocketListen = 5,
100    /// Socket accept.
101    SocketAccept = 6,
102    /// Socket close.
103    SocketClose = 7,
104    /// WinDivert handle opened.
105    ReflectOpen = 8,
106    /// WinDivert handle closed.
107    ReflectClose = 9,
108}
109
110impl TryFrom<u8> for WinDivertEvent {
111    type Error = WinDivertValueError;
112
113    fn try_from(value: u8) -> Result<Self, Self::Error> {
114        match value {
115            0 => Ok(Self::NetworkPacket),
116            1 => Ok(Self::FlowStablished),
117            2 => Ok(Self::FlowDeleted),
118            3 => Ok(Self::SocketBind),
119            4 => Ok(Self::SocketConnect),
120            5 => Ok(Self::SocketListen),
121            6 => Ok(Self::SocketAccept),
122            7 => Ok(Self::SocketClose),
123            8 => Ok(Self::ReflectOpen),
124            9 => Ok(Self::ReflectClose),
125            _ => Err(WinDivertValueError::Event(value)),
126        }
127    }
128}
129
130impl From<WinDivertEvent> for u8 {
131    fn from(value: WinDivertEvent) -> Self {
132        match value {
133            WinDivertEvent::NetworkPacket => 0,
134            WinDivertEvent::FlowStablished => 1,
135            WinDivertEvent::FlowDeleted => 2,
136            WinDivertEvent::SocketBind => 3,
137            WinDivertEvent::SocketConnect => 4,
138            WinDivertEvent::SocketListen => 5,
139            WinDivertEvent::SocketAccept => 6,
140            WinDivertEvent::SocketClose => 7,
141            WinDivertEvent::ReflectOpen => 8,
142            WinDivertEvent::ReflectClose => 9,
143        }
144    }
145}
146
147impl From<WinDivertEvent> for u32 {
148    fn from(value: WinDivertEvent) -> Self {
149        u8::from(value) as u32
150    }
151}
152
153/**
154WinDivert shutdown mode.
155*/
156#[repr(u32)]
157#[derive(Debug, Copy, Clone)]
158pub enum WinDivertShutdownMode {
159    /// Stops new packets being queued for [`WinDivertRecv`](fn@super::WinDivertRecv)
160    Recv = 1,
161    /// Stops new packets being injected via [`WinDivertSend`](fn@super::WinDivertSend)
162    Send = 2,
163    /// Equivalent to [`WinDivertShutdownMode::Recv`] | [`WinDivertShutdownMode::Send`]
164    Both = 3,
165}
166
167impl TryFrom<u32> for WinDivertShutdownMode {
168    type Error = WinDivertValueError;
169
170    fn try_from(value: u32) -> Result<Self, Self::Error> {
171        match value {
172            1 => Ok(WinDivertShutdownMode::Recv),
173            2 => Ok(WinDivertShutdownMode::Send),
174            3 => Ok(WinDivertShutdownMode::Both),
175            _ => Err(WinDivertValueError::Shutdown(value)),
176        }
177    }
178}
179
180impl From<WinDivertShutdownMode> for u32 {
181    fn from(value: WinDivertShutdownMode) -> Self {
182        match value {
183            WinDivertShutdownMode::Recv => 1,
184            WinDivertShutdownMode::Send => 2,
185            WinDivertShutdownMode::Both => 3,
186        }
187    }
188}
189
190/**
191WinDivert parameter enum.
192
193Used to specify the parameter in [`WinDivertGetParam()`](fn@super::WinDivertGetParam) and [`WinDivertSetParam()`](fn@super::WinDivertSetParam).
194*/
195#[repr(u32)]
196#[derive(Debug, Copy, Clone)]
197pub enum WinDivertParam {
198    /**
199    WINDIVERT_PARAM_QUEUE_TIME parameter.
200
201    Sets the maximum length of the packet queue for [`WinDivertRecv()`](fn@super::WinDivertRecv).
202
203    The range of valid values goes from [`WINDIVERT_PARAM_QUEUE_LENGTH_MIN`](value@super::WINDIVERT_PARAM_QUEUE_LENGTH_MIN) to [`WINDIVERT_PARAM_QUEUE_LENGTH_MAX`](value@super::WINDIVERT_PARAM_QUEUE_LENGTH_MAX), with a default value of [`WINDIVERT_PARAM_QUEUE_LENGTH_DEFAULT`](`value@super::WINDIVERT_PARAM_QUEUE_LENGTH_DEFAULT`).
204    */
205    QueueLength = 0,
206    /**
207    WINDIVERT_PARAM_QUEUE_LENGTH parameter.
208
209    Sets the minimum time, in milliseconds, a packet can be queued before it is automatically dropped. Packets cannot be queued indefinitely, and ideally, packets should be processed by the application as soon as is possible. Note that this sets the minimum time a packet can be queued before it can be dropped. The actual time may be exceed this value.
210
211    The range of valid values goes from [`WINDIVERT_PARAM_QUEUE_TIME_MIN`](value@super::WINDIVERT_PARAM_QUEUE_TIME_MIN) to [`WINDIVERT_PARAM_QUEUE_TIME_MAX`](value@super::WINDIVERT_PARAM_QUEUE_TIME_MAX), with a fefault value of [`WINDIVERT_PARAM_QUEUE_TIME_DEFAULT`](`value@super::WINDIVERT_PARAM_QUEUE_TIME_DEFAULT`).
212    */
213    QueueTime = 1,
214    /**
215    WINDIVERT_PARAM_QUEUE_SIZE parameter.
216
217    Sets the maximum number of bytes that can be stored in the packet queue for [`WinDivertRecv()`](fn@super::WinDivertRecv).
218
219    The range of valid values goes from [`WINDIVERT_PARAM_QUEUE_SIZE_MIN`](value@super::WINDIVERT_PARAM_QUEUE_SIZE_MIN) to [`WINDIVERT_PARAM_QUEUE_SIZE_MAX`](value@super::WINDIVERT_PARAM_QUEUE_SIZE_MAX), with a fefault value of [`WINDIVERT_PARAM_QUEUE_SIZE_DEFAULT`](`value@super::WINDIVERT_PARAM_QUEUE_SIZE_DEFAULT`).
220    */
221    QueueSize = 2,
222    /// Obtains the major version of the driver.
223    VersionMajor = 3,
224    /// Obtains the minor version of the driver.
225    VersionMinor = 4,
226}
227
228impl TryFrom<u32> for WinDivertParam {
229    type Error = WinDivertValueError;
230
231    fn try_from(value: u32) -> Result<Self, Self::Error> {
232        match value {
233            0 => Ok(WinDivertParam::QueueLength),
234            1 => Ok(WinDivertParam::QueueTime),
235            2 => Ok(WinDivertParam::QueueSize),
236            3 => Ok(WinDivertParam::VersionMajor),
237            4 => Ok(WinDivertParam::VersionMinor),
238            _ => Err(WinDivertValueError::Parameter(value)),
239        }
240    }
241}
242
243impl From<WinDivertParam> for u32 {
244    fn from(value: WinDivertParam) -> Self {
245        match value {
246            WinDivertParam::QueueLength => 0,
247            WinDivertParam::QueueTime => 1,
248            WinDivertParam::QueueSize => 2,
249            WinDivertParam::VersionMajor => 3,
250            WinDivertParam::VersionMinor => 4,
251        }
252    }
253}
254
255/**
256Flag type required by [`WinDivertOpen()`](fn@super::WinDivertOpen). It follows a builder like style.
257
258Different flags affect how the opened handle behaves. The following flags are supported:
259 * `sniff`: This flag opens the WinDivert handle in `packet sniffing` mode. In packet sniffing mode the original packet is not dropped-and-diverted (the default) but copied-and-diverted. This mode is useful for implementing packet sniffing tools similar to those applications that currently use Winpcap.
260 * `drop`: This flag indicates that the user application does not intend to read matching packets with [`recv()`](fn@super::WinDivertRecv) (or any of it's variants), instead the packets should be silently dropped. This is useful for implementing simple packet filters using the WinDivert [filter language](https://reqrypt.org/windivert-doc.html#filter_language).
261 * `recv_only`: This flags forces the handle into receive only mode which effectively disables [`send()`](fn@super::WinDivertSend) (and any of it's variants). This means that it is possible to block/capture packets or events but not inject them.
262 * `send_only`: This flags forces the handle into send only mode which effectively disables [`recv()`](fn@super::WinDivertRecv) (and any of it's variants). This means that it is possible to inject packets or events, but not block/capture them.
263 * `no_installs`: This flags causes [`WinDivertOpen`](fn@super::WinDivertOpen) to fail with ERROR_SERVICE_DOES_NOT_EXIST (1060) if the WinDivert driver is not already installed. This flag is useful for querying the WinDivert driver state using [`Reflect`](super::WinDivertLayer::Reflect) layer.
264 * `fragments`: If set, the handle will capture inbound IP fragments, but not inbound reassembled IP packets. Otherwise, if not set (the default), the handle will capture inbound reassembled IP packets, but not inbound IP fragments. This flag only affects inbound packets at the [`Network`](super::WinDivertLayer::Network) layer, else the flag is ignored.
265Note that any combination of (`snif` | `drop`) or (`recv_only` | `send_only`) are considered invalid.
266
267Some layers have mandatory flags:
268 * [`WinDivertLayer::Flow`](type@WinDivertLayer::Flow): (`sniff` | `recv_only`)
269 * [`WinDivertLayer::Socket`](type@WinDivertLayer::Socket): `recv_only`
270 * [`WinDivertLayer::Reflect`](type@WinDivertLayer::Reflect): (`sniff` | `recv_only`)
271*/
272#[derive(Debug, Default, Copy, Clone)]
273#[repr(transparent)]
274pub struct WinDivertFlags(u64);
275
276/// WinDivertFlags builder methods.
277impl WinDivertFlags {
278    /// Creates a new flag field with all options unset.
279    pub const fn new() -> Self {
280        Self(0)
281    }
282
283    /// Sets `sniff` flag.
284    pub const fn set_sniff(mut self) -> Self {
285        self.0 |= 0x0001;
286        self
287    }
288
289    /// Unsets `sniff` flag.
290    pub const fn unset_sniff(mut self) -> Self {
291        self.0 &= !0x001;
292        self
293    }
294
295    /// Sets `sniff` flag to `value`.
296    pub fn set_sniff_value(&mut self, value: bool) {
297        self.0 = (self.0 & !0x0001) | (value as u64);
298    }
299
300    /// Sets `drop` flag.
301    pub const fn set_drop(mut self) -> Self {
302        self.0 |= 0x0002;
303        self
304    }
305
306    /// Unsets `drop` flag.
307    pub const fn unset_drop(mut self) -> Self {
308        self.0 &= !0x0002;
309        self
310    }
311
312    /// Sets `drop` flag to `value`.
313    pub fn set_drop_value(&mut self, value: bool) {
314        self.0 = (self.0 & !0x0002) | ((value as u64) << 1);
315    }
316
317    /// Sets `recv_only` flag
318    pub const fn set_recv_only(mut self) -> Self {
319        self.0 |= 0x0004;
320        self
321    }
322
323    /// Unsets `recv_only` flag
324    pub const fn unset_recv_only(mut self) -> Self {
325        self.0 &= !0x0004;
326        self
327    }
328
329    /// Sets `recv_only` flag to `value`.
330    pub fn set_recv_only_value(&mut self, value: bool) {
331        self.0 = (self.0 & !0x0004) | ((value as u64) << 2);
332    }
333
334    /// Sets `send_only` flag.
335    pub const fn set_send_only(mut self) -> Self {
336        self.0 |= 0x0008;
337        self
338    }
339
340    /// Unsets `send_only` flag.
341    pub const fn unset_send_only(mut self) -> Self {
342        self.0 &= !0x0008;
343        self
344    }
345
346    /// Sets `send_only` flag to `value`.
347    pub fn set_send_only_value(&mut self, value: bool) {
348        self.0 = (self.0 & !0x0008) | ((value as u64) << 3);
349    }
350
351    /// Sets `no_installs` flag.
352    pub const fn set_no_installs(mut self) -> Self {
353        self.0 |= 0x0010;
354        self
355    }
356
357    /// Unsets `no_installs` flag.
358    pub const fn unset_no_installs(mut self) -> Self {
359        self.0 &= !0x0010;
360        self
361    }
362
363    /// Sets `no_installs` flag to `value`.
364    pub fn set_no_installs_value(&mut self, value: bool) {
365        self.0 = (self.0 & !0x0010) | ((value as u64) << 4);
366    }
367
368    /// Sets `fragments` flag.
369    pub const fn set_fragments(mut self) -> Self {
370        self.0 |= 0x0020;
371        self
372    }
373
374    /// Unsets `fragments` flag.
375    pub const fn unset_fragments(mut self) -> Self {
376        self.0 &= !0x0020;
377        self
378    }
379
380    /// Sets `fragments` flag to `value`.
381    pub fn set_fragments_value(&mut self, value: bool) {
382        self.0 = (self.0 & !0x0020) | ((value as u64) << 5);
383    }
384}
385
386impl From<WinDivertFlags> for u64 {
387    fn from(flags: WinDivertFlags) -> Self {
388        flags.0
389    }
390}
391
392/**
393Wrapper helper struct around u64.
394
395The type uses transparent representation to enforce using the provided methods to set the values of the flags used by [`WinDivertHelperCalcChecksums()`](fn@super::WinDivertHelperCalcChecksums)
396
397The different flag values are:
398 * `no_ip`: Do not calculate the IPv4 checksum.
399 * `no_icmp`: Do not calculate the ICMP checksum.
400 * `no_icmpv6`: Do not calculate the ICMPv6 checksum.
401 * `no_tcp`: Do not calculate the TCP checksum.
402 * `no_udp`: Do not calculate the UDP checksum.
403*/
404#[derive(Debug, Default, Copy, Clone)]
405#[repr(transparent)]
406pub struct ChecksumFlags(u64);
407
408impl ChecksumFlags {
409    /// Creates a new flag field with default zero value.
410    pub const fn new() -> Self {
411        Self(0)
412    }
413
414    /// Sets `no_ip` flag
415    pub const fn set_no_ip(mut self) -> Self {
416        self.0 |= 0x0001;
417        self
418    }
419
420    /// Unsets `no_ip` flag
421    pub const fn unset_no_ip(mut self) -> Self {
422        self.0 &= !0x0001;
423        self
424    }
425
426    /// Sets `no_ip` flag to `value`.
427    pub fn set_no_ip_value(&mut self, value: bool) {
428        self.0 = (self.0 & !0x0001) | (value as u64);
429    }
430
431    /// Sets `no_icmp` flag
432    pub const fn set_no_icmp(mut self) -> Self {
433        self.0 |= 0x0002;
434        self
435    }
436
437    /// Unsets `no_icmp` flag
438    pub const fn unset_no_icmp(mut self) -> Self {
439        self.0 &= !0x0002;
440        self
441    }
442
443    /// Sets `no_icmp` flag to `value`.
444    pub fn set_no_icmp_value(&mut self, value: bool) {
445        self.0 = (self.0 & !0x0002) | ((value as u64) << 1);
446    }
447
448    /// Sets `no_icmpv6` flag
449    pub const fn set_no_icmpv6(mut self) -> Self {
450        self.0 |= 0x0004;
451        self
452    }
453
454    /// Unsets `no_icmpv6` flag
455    pub const fn unset_no_icmpv6(mut self) -> Self {
456        self.0 &= !0x0004;
457        self
458    }
459
460    /// Sets `no_icmpv6` flag to `value`.
461    pub fn set_no_icmpv6_value(&mut self, value: bool) {
462        self.0 = (self.0 & !0x0004) | ((value as u64) << 2);
463    }
464
465    /// Sets `no_tcp` flag
466    pub const fn set_no_tcp(mut self) -> Self {
467        self.0 |= 0x0008;
468        self
469    }
470
471    /// Unsets `no_tcp` flag
472    pub const fn unset_no_tcp(mut self) -> Self {
473        self.0 &= !0x0008;
474        self
475    }
476
477    /// Sets `no_tcp` flag to `value`.
478    pub fn set_no_tcp_value(&mut self, value: bool) {
479        self.0 = (self.0 & !0x0008) | ((value as u64) << 3);
480    }
481
482    /// Sets `no_udp` flag
483    pub const fn set_no_udp(mut self) -> Self {
484        self.0 |= 0x0010;
485        self
486    }
487
488    /// Unsets `no_udp` flag
489    pub const fn unset_no_udp(mut self) -> Self {
490        self.0 &= !0x0010;
491        self
492    }
493
494    /// Sets `no_udp` flag to `value`.
495    pub fn set_no_udp_value(&mut self, value: bool) {
496        self.0 = (self.0 & !0x0010) | ((value as u64) << 4);
497    }
498}
499
500impl From<ChecksumFlags> for u64 {
501    fn from(flags: ChecksumFlags) -> Self {
502        flags.0
503    }
504}