windivert_sys/bindings/
header.rs

1/*!
2WinDivert header types.
3*/
4#![allow(missing_docs)]
5use std::{
6    fmt::Debug,
7    net::{Ipv4Addr, Ipv6Addr},
8};
9
10use super::BitfieldUnit;
11
12/**
13IPV4 header.
14
15For more info, refer to the [docs](https://reqrypt.org/windivert-doc.html#divert_iphdr)
16*/
17#[repr(C)]
18#[derive(Default, Copy, Clone)]
19pub struct WINDIVERT_IPHDR {
20    addr_bitfield: BitfieldUnit<[u8; 1usize], u8>,
21    pub tos: u8,
22    length: u16,
23    id: u16,
24    fragment_offset_and_flags: u16,
25    pub ttl: u8,
26    pub protocol: u8,
27    checksum: u16,
28    src_addr: u32,
29    dst_addr: u32,
30}
31
32impl WINDIVERT_IPHDR {
33    #[inline]
34    pub fn header_length(&self) -> u8 {
35        self.addr_bitfield.get(0usize, 4u8) as u8
36    }
37    #[inline]
38    pub fn set_header_length(&mut self, val: u8) {
39        self.addr_bitfield.set(0usize, 4u8, val as u64)
40    }
41    #[inline]
42    pub fn version(&self) -> u8 {
43        self.addr_bitfield.get(4usize, 4u8) as u8
44    }
45    #[inline]
46    pub fn set_version(&mut self, val: u8) {
47        self.addr_bitfield.set(4usize, 4u8, val as u64)
48    }
49    #[inline]
50    pub fn length(&self) -> u16 {
51        u16::from_be(self.length)
52    }
53    #[inline]
54    pub fn set_length(&mut self, value: u16) {
55        self.length = value.to_be();
56    }
57    #[inline]
58    pub fn id(&self) -> u16 {
59        u16::from_be(self.id)
60    }
61    #[inline]
62    pub fn set_id(&mut self, value: u16) {
63        self.id = value.to_be();
64    }
65    #[inline]
66    pub fn fragment_offset(&self) -> u16 {
67        u16::from_be(self.fragment_offset_and_flags & 0xFF1F)
68    }
69    #[inline]
70    pub fn set_fragment_offset(&mut self, value: u16) {
71        self.fragment_offset_and_flags =
72            self.fragment_offset_and_flags & 0x00E0 | (value & 0x1FFF).to_be()
73    }
74    #[inline]
75    pub fn MF(&self) -> bool {
76        self.fragment_offset_and_flags & 0x0020 != 0
77    }
78    #[inline]
79    pub fn set_MF(&mut self, value: bool) {
80        self.fragment_offset_and_flags =
81            self.fragment_offset_and_flags & 0xFFDF | ((value as u16) << 5)
82    }
83    #[inline]
84    pub fn DF(&self) -> bool {
85        self.fragment_offset_and_flags & 0x0040 != 0
86    }
87    #[inline]
88    pub fn set_DF(&mut self, value: bool) {
89        self.fragment_offset_and_flags =
90            self.fragment_offset_and_flags & 0xFFBF | ((value as u16) << 6)
91    }
92    #[inline]
93    pub fn checksum(&self) -> u16 {
94        u16::from_be(self.checksum)
95    }
96    #[inline]
97    pub fn set_checksum(&mut self, value: u16) {
98        self.checksum = value.to_be();
99    }
100    #[inline]
101    pub fn src_addr(&self) -> u32 {
102        u32::from_be(self.src_addr)
103    }
104    #[inline]
105    pub fn src_ip_addr(&self) -> Ipv4Addr {
106        Ipv4Addr::from(self.src_addr)
107    }
108    #[inline]
109    pub fn set_src_addr(&mut self, value: u32) {
110        self.src_addr = value.to_be();
111    }
112    #[inline]
113    pub fn dst_addr(&self) -> u32 {
114        u32::from_be(self.dst_addr)
115    }
116    #[inline]
117    pub fn dst_ip_addr(&self) -> Ipv4Addr {
118        Ipv4Addr::from(self.dst_addr)
119    }
120    #[inline]
121    pub fn set_dst_addr(&mut self, value: u32) {
122        self.dst_addr = value.to_be();
123    }
124}
125
126impl Debug for WINDIVERT_IPHDR {
127    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
128        write!(f, "WINDIVERT_IPHDR {{ header_length: {:?}, version: {:?}, tos: {:?}, length: {:?}, id: {:?}, MF: {:?}, DF: {:?}, fragment_offset: {:?}, ttl: {:?}, protocol: {:?}, checksum: {:?}, src_addr: {:?}, dst_addr: {:?} }}",
129        self.header_length(), self.version(), self.tos, self.length(), self.id(), self.MF(), self.DF(), self.fragment_offset(), self.ttl, self.protocol, self.checksum(), self.src_addr(), self.dst_addr())
130    }
131}
132
133/// [IPV4 header](WINDIVERT_IPHDR) pointer type.
134pub type PWINDIVERT_IPHDR = *mut WINDIVERT_IPHDR;
135
136/**
137IPV6 header.
138
139For more info, refer to the [docs](https://reqrypt.org/windivert-doc.html#divert_ipv6hdr)
140*/
141#[repr(C)]
142#[derive(Default, Copy, Clone)]
143pub struct WINDIVERT_IPV6HDR {
144    addr_bitfield: BitfieldUnit<[u8; 2usize], u8>,
145    flow_label_1: u16,
146    length: u16,
147    pub next_header: u8,
148    pub hop_limit: u8,
149    src_addr: [u32; 4usize],
150    dst_addr: [u32; 4usize],
151}
152
153impl WINDIVERT_IPV6HDR {
154    #[inline]
155    pub fn version(&self) -> u8 {
156        self.addr_bitfield.get(4usize, 4u8) as u8
157    }
158    #[inline]
159    pub fn set_version(&mut self, val: u8) {
160        self.addr_bitfield.set(4usize, 4u8, val as u64)
161    }
162    #[inline]
163    pub fn traffic_class(&self) -> u8 {
164        u8::from_be(self.traffic_class0() << 4 | self.traffic_class1())
165    }
166    pub fn set_traffic_class(&mut self, value: u8) {
167        let value = value.to_be();
168        self.set_traffic_class0(value >> 4);
169        self.set_traffic_class1(value);
170    }
171    #[inline]
172    fn traffic_class0(&self) -> u8 {
173        self.addr_bitfield.get(0usize, 4u8) as u8
174    }
175    #[inline]
176    fn set_traffic_class0(&mut self, val: u8) {
177        self.addr_bitfield.set(0usize, 4u8, val as u64)
178    }
179    #[inline]
180    fn traffic_class1(&self) -> u8 {
181        self.addr_bitfield.get(12usize, 4u8) as u8
182    }
183    #[inline]
184    fn set_traffic_class1(&mut self, val: u8) {
185        self.addr_bitfield.set(12usize, 4u8, val as u64)
186    }
187    #[inline]
188    pub fn flow_label(&self) -> u32 {
189        u32::from_be((self.flow_label0() as u32) << 16 | self.flow_label_1 as u32)
190    }
191    #[inline]
192    pub fn set_flow_label(&mut self, value: u32) {
193        let value = value.to_be();
194        self.set_flow_label0((value >> 16) as u8);
195        self.flow_label_1 = value as u16;
196    }
197    #[inline]
198    fn flow_label0(&self) -> u8 {
199        self.addr_bitfield.get(8usize, 4u8) as u8
200    }
201    #[inline]
202    fn set_flow_label0(&mut self, val: u8) {
203        self.addr_bitfield.set(8usize, 4u8, val as u64)
204    }
205    #[inline]
206    pub fn length(&self) -> u16 {
207        u16::from_be(self.length)
208    }
209    #[inline]
210    pub fn src_addr(&self) -> u128 {
211        u128::from_be(
212            self.src_addr
213                .iter()
214                .rev()
215                .fold(0u128, |acc, &x| (acc << 32) | x as u128),
216        )
217    }
218    #[inline]
219    pub fn src_ip_addr(&self) -> Ipv6Addr {
220        Ipv6Addr::from(self.src_addr())
221    }
222    #[inline]
223    pub fn set_src_addr(&mut self, value: u128) {
224        let tmp = value
225            .to_be_bytes()
226            .chunks(4)
227            .map(|x| {
228                let mut tmp: [u8; 4] = Default::default();
229                tmp.copy_from_slice(x);
230                u32::from_ne_bytes(tmp)
231            })
232            .collect::<Vec<u32>>();
233        self.src_addr.copy_from_slice(&tmp);
234    }
235    #[inline]
236    pub fn dst_addr(&self) -> u128 {
237        u128::from_be(
238            self.dst_addr
239                .iter()
240                .rev()
241                .fold(0u128, |acc, &x| (acc << 32) | x as u128),
242        )
243    }
244    #[inline]
245    pub fn dst_ip_addr(&self) -> Ipv6Addr {
246        Ipv6Addr::from(self.dst_addr())
247    }
248    #[inline]
249    pub fn set_dst_addr(&mut self, value: u128) {
250        let tmp = value
251            .to_be_bytes()
252            .chunks(4)
253            .map(|x| {
254                let mut tmp: [u8; 4] = Default::default();
255                tmp.copy_from_slice(x);
256                u32::from_ne_bytes(tmp)
257            })
258            .collect::<Vec<u32>>();
259        self.dst_addr.copy_from_slice(&tmp);
260    }
261}
262
263impl Debug for WINDIVERT_IPV6HDR {
264    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
265        write!(f, "WINDIVERT_IPV6HDR {{ version: {:?}, traffic_class: {:?}, flow_label: {:?}, length: {:?}, MextHdr: {:?}, hop_limit: {:?}, src_addr: {:?}, dst_addr: {:?} }}", self.version(), self.traffic_class(), self.flow_label(), self.length(), self.next_header, self.hop_limit, self.src_addr(), self.dst_addr())
266    }
267}
268
269/// [IPV6 header](WINDIVERT_IPV6HDR) pointer type.
270pub type PWINDIVERT_IPV6HDR = *mut WINDIVERT_IPV6HDR;
271
272/**
273ICMP header.
274
275For more info, refer to the [docs](https://reqrypt.org/windivert-doc.html#divert_icmphdr)
276*/
277#[repr(C)]
278#[derive(Default, Copy, Clone)]
279pub struct WINDIVERT_ICMPHDR {
280    pub msg_type: u8,
281    pub msg_code: u8,
282    checksum: u16,
283    body: u32,
284}
285
286impl WINDIVERT_ICMPHDR {
287    #[inline]
288    pub fn checksum(&self) -> u16 {
289        u16::from_be(self.checksum)
290    }
291    #[inline]
292    pub fn set_Checksum(&mut self, value: u16) {
293        self.checksum = value.to_be();
294    }
295    #[inline]
296    pub fn body(&self) -> u32 {
297        u32::from_be(self.body)
298    }
299    #[inline]
300    pub fn set_Body(&mut self, value: u32) {
301        self.body = value.to_be();
302    }
303}
304
305impl Debug for WINDIVERT_ICMPHDR {
306    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
307        write!(
308            f,
309            "WINDIVERT_ICMPHDR {{ msg_type: {:?}, msg_code: {:?}, checksum: {:?}, body: {:?} }}",
310            self.msg_type,
311            self.msg_code,
312            self.checksum(),
313            self.body()
314        )
315    }
316}
317
318/// [ICMP header](WINDIVERT_ICMPHDR) pointer type.
319pub type PWINDIVERT_ICMPHDR = *mut WINDIVERT_ICMPHDR;
320
321/**
322ICMPV6 header.
323
324For more info, refer to the [docs](https://reqrypt.org/windivert-doc.html#divert_icmpv6hdr)
325*/
326#[repr(C)]
327#[derive(Default, Copy, Clone)]
328pub struct WINDIVERT_ICMPV6HDR {
329    pub msg_type: u8,
330    pub msg_code: u8,
331    checksum: u16,
332    body: u32,
333}
334
335impl WINDIVERT_ICMPV6HDR {
336    #[inline]
337    pub fn checksum(&self) -> u16 {
338        u16::from_be(self.checksum)
339    }
340    #[inline]
341    pub fn set_Checksum(&mut self, value: u16) {
342        self.checksum = value.to_be();
343    }
344    #[inline]
345    pub fn body(&self) -> u32 {
346        u32::from_be(self.body)
347    }
348    #[inline]
349    pub fn set_Body(&mut self, value: u32) {
350        self.body = value.to_be();
351    }
352}
353
354impl Debug for WINDIVERT_ICMPV6HDR {
355    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
356        write!(
357            f,
358            "WINDIVERT_ICMPHDR {{ msg_type: {:?}, msg_code: {:?}, checksum: {:?}, body: {:?} }}",
359            self.msg_type,
360            self.msg_code,
361            self.checksum(),
362            self.body()
363        )
364    }
365}
366
367/// [ICMPV6 header](WINDIVERT_ICMPV6HDR) pointer type.
368pub type PWINDIVERT_ICMPV6HDR = *mut WINDIVERT_ICMPV6HDR;
369
370/**
371TCP header.
372
373For more info, refer to the [docs](https://reqrypt.org/windivert-doc.html#divert_tcphdr)
374*/
375#[repr(C)]
376#[derive(Default, Copy, Clone)]
377pub struct WINDIVERT_TCPHDR {
378    src_port: u16,
379    dst_port: u16,
380    seq_number: u32,
381    ACK_number: u32,
382    addr_bitfield: BitfieldUnit<[u8; 2usize], u8>,
383    window: u16,
384    checksum: u16,
385    urg_ptr: u16,
386}
387
388impl WINDIVERT_TCPHDR {
389    #[inline]
390    pub fn src_port(&self) -> u16 {
391        u16::from_be(self.src_port)
392    }
393    #[inline]
394    pub fn set_src_port(&mut self, value: u16) {
395        self.src_port = value.to_be();
396    }
397    #[inline]
398    pub fn dst_port(&self) -> u16 {
399        u16::from_be(self.dst_port)
400    }
401    #[inline]
402    pub fn set_dst_port(&mut self, value: u16) {
403        self.dst_port = value.to_be();
404    }
405    #[inline]
406    pub fn seq_number(&self) -> u32 {
407        u32::from_be(self.seq_number)
408    }
409    #[inline]
410    pub fn set_seq_number(&mut self, value: u32) {
411        self.seq_number = value.to_be();
412    }
413    #[inline]
414    pub fn ACK_number(&self) -> u32 {
415        u32::from_be(self.ACK_number)
416    }
417    #[inline]
418    pub fn set_ACK_number(&mut self, value: u32) {
419        self.ACK_number = value.to_be();
420    }
421    #[inline]
422    pub fn header_length(&self) -> u16 {
423        self.addr_bitfield.get(4usize, 4u8) as u16
424    }
425    #[inline]
426    pub fn set_header_length(&mut self, val: u16) {
427        self.addr_bitfield.set(4usize, 4u8, val as u64)
428    }
429    #[inline]
430    pub fn FIN(&self) -> u16 {
431        self.addr_bitfield.get(8usize, 1u8) as u16
432    }
433    #[inline]
434    pub fn set_FIN(&mut self, val: u16) {
435        self.addr_bitfield.set(8usize, 1u8, val as u64)
436    }
437    #[inline]
438    pub fn SYN(&self) -> u16 {
439        self.addr_bitfield.get(9usize, 1u8) as u16
440    }
441    #[inline]
442    pub fn set_SYN(&mut self, val: u16) {
443        self.addr_bitfield.set(9usize, 1u8, val as u64)
444    }
445    #[inline]
446    pub fn RST(&self) -> u16 {
447        self.addr_bitfield.get(10usize, 1u8) as u16
448    }
449    #[inline]
450    pub fn set_RST(&mut self, val: u16) {
451        self.addr_bitfield.set(10usize, 1u8, val as u64)
452    }
453    #[inline]
454    pub fn PSH(&self) -> u16 {
455        self.addr_bitfield.get(11usize, 1u8) as u16
456    }
457    #[inline]
458    pub fn set_PSH(&mut self, val: u16) {
459        self.addr_bitfield.set(11usize, 1u8, val as u64)
460    }
461    #[inline]
462    pub fn ACK(&self) -> u16 {
463        self.addr_bitfield.get(12usize, 1u8) as u16
464    }
465    #[inline]
466    pub fn set_ACK(&mut self, val: u16) {
467        self.addr_bitfield.set(12usize, 1u8, val as u64)
468    }
469    #[inline]
470    pub fn URG(&self) -> u16 {
471        self.addr_bitfield.get(13usize, 1u8) as u16
472    }
473    #[inline]
474    pub fn set_URG(&mut self, val: u16) {
475        self.addr_bitfield.set(13usize, 1u8, val as u64)
476    }
477    #[inline]
478    pub fn window(&self) -> u16 {
479        u16::from_be(self.window)
480    }
481    #[inline]
482    pub fn set_window(&mut self, value: u16) {
483        self.window = value.to_be();
484    }
485    #[inline]
486    pub fn checksum(&self) -> u16 {
487        u16::from_be(self.checksum)
488    }
489    #[inline]
490    pub fn set_Checksum(&mut self, value: u16) {
491        self.checksum = value.to_be();
492    }
493    #[inline]
494    pub fn urg_ptr(&self) -> u16 {
495        u16::from_be(self.urg_ptr)
496    }
497    #[inline]
498    pub fn set_urg_ptr(&mut self, value: u16) {
499        self.urg_ptr = value.to_be();
500    }
501}
502
503impl Debug for WINDIVERT_TCPHDR {
504    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
505        write!(f, "WINDIVERT_TCPHDR {{ src_port: {:?}, dst_port: {:?}, seq_number: {:?}, ACK_number: {:?}, header_length: {:?}, URG: {:?}, ACK: {:?}, PSH: {:?}, RST: {:?}, SYN: {:?}, FIN: {:?}, window: {:?}, checksum: {:?}, urg_ptr: {:?} }}", self.src_port(), self.dst_port(), self.seq_number(), self.ACK_number(), self.header_length(), self.URG(), self.ACK(), self.PSH(), self.RST(), self.SYN(), self.FIN(), self.window(), self.checksum(), self.urg_ptr())
506    }
507}
508
509/// [TCP header](WINDIVERT_TCPHDR) pointer type.
510pub type PWINDIVERT_TCPHDR = *mut WINDIVERT_TCPHDR;
511
512/**
513UDP header.
514
515For more info, refer to the [docs](https://reqrypt.org/windivert-doc.html#divert_udphdr)
516*/
517#[repr(C)]
518#[derive(Default, Copy, Clone)]
519pub struct WINDIVERT_UDPHDR {
520    src_port: u16,
521    dst_port: u16,
522    length: u16,
523    checksum: u16,
524}
525
526impl WINDIVERT_UDPHDR {
527    #[inline]
528    pub fn src_port(&self) -> u16 {
529        u16::from_be(self.src_port)
530    }
531    #[inline]
532    pub fn set_src_port(&mut self, value: u16) {
533        self.src_port = value.to_be();
534    }
535    #[inline]
536    pub fn dst_port(&self) -> u16 {
537        u16::from_be(self.dst_port)
538    }
539    #[inline]
540    pub fn set_dst_port(&mut self, value: u16) {
541        self.dst_port = value.to_be();
542    }
543    #[inline]
544    pub fn length(&self) -> u16 {
545        u16::from_be(self.length)
546    }
547    #[inline]
548    pub fn set_length(&mut self, value: u16) {
549        self.length = value.to_be();
550    }
551    #[inline]
552    pub fn checksum(&self) -> u16 {
553        u16::from_be(self.checksum)
554    }
555    #[inline]
556    pub fn set_Checksum(&mut self, value: u16) {
557        self.checksum = value.to_be();
558    }
559}
560
561impl Debug for WINDIVERT_UDPHDR {
562    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
563        write!(
564            f,
565            "WINDIVERT_UDPHDR {{ src_port: {:?}, dst_port: {:?}, length: {:?}, checksum: {:?} }}",
566            self.src_port(),
567            self.dst_port(),
568            self.length(),
569            self.checksum()
570        )
571    }
572}
573
574/// [UDP header](WINDIVERT_UDPHDR) pointer type.
575pub type PWINDIVERT_UDPHDR = *mut WINDIVERT_UDPHDR;