diff options
-rw-r--r-- | rustables/src/expr/counter.rs | 12 | ||||
-rw-r--r-- | rustables/src/expr/mod.rs | 16 |
2 files changed, 27 insertions, 1 deletions
diff --git a/rustables/src/expr/counter.rs b/rustables/src/expr/counter.rs index 2a8ad6f..b507e80 100644 --- a/rustables/src/expr/counter.rs +++ b/rustables/src/expr/counter.rs @@ -4,6 +4,7 @@ use std::os::raw::c_char; /// A counter expression adds a counter to the rule that is incremented to count number of packets /// and number of bytes for all packets that has matched the rule. +#[derive(Debug, PartialEq)] pub struct Counter { pub nb_bytes: u64, pub nb_packets: u64, @@ -23,6 +24,17 @@ impl Expression for Counter { b"counter\0" as *const _ as *const c_char } + fn from_expr(expr: *const sys::nftnl_expr) -> Option<Self> { + unsafe { + let nb_bytes = sys::nftnl_expr_get_u64(expr, sys::NFTNL_EXPR_CTR_BYTES as u16); + let nb_packets = sys::nftnl_expr_get_u64(expr, sys::NFTNL_EXPR_CTR_PACKETS as u16); + Some(Counter { + nb_bytes, + nb_packets, + }) + } + } + fn to_expr(&self, _rule: &Rule) -> *mut sys::nftnl_expr { unsafe { let expr = try_alloc!(sys::nftnl_expr_alloc(Self::get_raw_name())); diff --git a/rustables/src/expr/mod.rs b/rustables/src/expr/mod.rs index b028c2f..39ab2e0 100644 --- a/rustables/src/expr/mod.rs +++ b/rustables/src/expr/mod.rs @@ -25,6 +25,7 @@ impl Debug for ExpressionWrapper { } impl ExpressionWrapper { + /// Retrieves a textual description of the expression. pub fn get_str(&self) -> CString { let mut descr_buf = vec![0i8; 4096]; unsafe { @@ -39,7 +40,8 @@ impl ExpressionWrapper { } } - pub fn get_expr_kind(&self) -> Option<&CStr> { + /// Retrieves the type of expression ("log", "counter", ...). + pub fn get_kind(&self) -> Option<&CStr> { unsafe { let ptr = sys::nftnl_expr_get_str(self.expr, sys::NFTNL_EXPR_NAME as u16); if !ptr.is_null() { @@ -49,6 +51,18 @@ impl ExpressionWrapper { } } } + + /// Attempt to decode the expression as the type T, returning None if such + /// conversion is not possible or failed. + pub fn decode_expr<T: Expression>(&self) -> Option<T> { + if let Some(kind) = self.get_kind() { + let raw_name = unsafe { CStr::from_ptr(T::get_raw_name()) }; + if kind == raw_name { + return T::from_expr(self.expr); + } + } + None + } } /// Trait for every safe wrapper of an nftables expression. |