Skip to main content

rns_hooks_abi/
result.rs

1/// Verdict returned by a WASM hook program.
2#[repr(u32)]
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum Verdict {
5    /// Pass through normally.
6    Continue = 0,
7    /// Block the packet/action.
8    Drop = 1,
9    /// Replace with modified data.
10    Modify = 2,
11    /// Stop hook chain — no further hooks at this point are executed.
12    Halt = 3,
13}
14
15impl Verdict {
16    /// Convert from a raw `u32` discriminant. Returns `None` for invalid values.
17    pub fn from_u32(v: u32) -> Option<Self> {
18        match v {
19            0 => Some(Verdict::Continue),
20            1 => Some(Verdict::Drop),
21            2 => Some(Verdict::Modify),
22            3 => Some(Verdict::Halt),
23            _ => None,
24        }
25    }
26}
27
28/// Verdict constants for `no_std` contexts where the enum cannot be used directly.
29pub const VERDICT_CONTINUE: u32 = Verdict::Continue as u32;
30pub const VERDICT_DROP: u32 = Verdict::Drop as u32;
31pub const VERDICT_MODIFY: u32 = Verdict::Modify as u32;
32pub const VERDICT_HALT: u32 = Verdict::Halt as u32;
33
34/// Result returned from a WASM hook invocation.
35///
36/// Laid out as `#[repr(C)]` for direct reading from WASM linear memory.
37#[repr(C)]
38#[derive(Debug, Clone, Copy)]
39pub struct HookResult {
40    /// Verdict as `u32` discriminant (see [`Verdict`]).
41    pub verdict: u32,
42    pub modified_data_offset: u32,
43    /// Length of modified data. 0 if no modification.
44    pub modified_data_len: u32,
45    pub inject_actions_offset: u32,
46    /// Number of injected actions. 0 if no injections.
47    pub inject_actions_count: u32,
48    pub log_offset: u32,
49    /// Length of log message. 0 if no log message.
50    pub log_len: u32,
51}
52
53impl HookResult {
54    /// Whether this result drops the packet/action.
55    pub fn is_drop(&self) -> bool {
56        self.verdict == Verdict::Drop as u32
57    }
58
59    /// Create a `Continue` result with no modifications.
60    pub fn continue_result() -> Self {
61        HookResult {
62            verdict: Verdict::Continue as u32,
63            modified_data_offset: 0,
64            modified_data_len: 0,
65            inject_actions_offset: 0,
66            inject_actions_count: 0,
67            log_offset: 0,
68            log_len: 0,
69        }
70    }
71
72    /// Create a `Drop` result.
73    pub fn drop_result() -> Self {
74        HookResult {
75            verdict: Verdict::Drop as u32,
76            modified_data_offset: 0,
77            modified_data_len: 0,
78            inject_actions_offset: 0,
79            inject_actions_count: 0,
80            log_offset: 0,
81            log_len: 0,
82        }
83    }
84
85    /// Create a `Modify` result pointing at modified data.
86    pub fn modify_result(data_offset: u32, data_len: u32) -> Self {
87        HookResult {
88            verdict: Verdict::Modify as u32,
89            modified_data_offset: data_offset,
90            modified_data_len: data_len,
91            inject_actions_offset: 0,
92            inject_actions_count: 0,
93            log_offset: 0,
94            log_len: 0,
95        }
96    }
97}