aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rustables/src/expr/counter.rs12
-rw-r--r--rustables/src/expr/mod.rs16
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.