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}