diff options
-rw-r--r-- | src/chain.rs | 4 | ||||
-rw-r--r-- | src/expr/bitwise.rs | 59 | ||||
-rw-r--r-- | src/expr/immediate.rs | 33 | ||||
-rw-r--r-- | src/expr/log.rs | 36 | ||||
-rw-r--r-- | src/expr/meta.rs | 45 | ||||
-rw-r--r-- | src/expr/mod.rs | 64 | ||||
-rw-r--r-- | src/expr/reject.rs | 34 | ||||
-rw-r--r-- | src/expr/verdict.rs | 46 | ||||
-rw-r--r-- | src/parser.rs | 190 |
9 files changed, 103 insertions, 408 deletions
diff --git a/src/chain.rs b/src/chain.rs index 8bdf95b..7a62fb2 100644 --- a/src/chain.rs +++ b/src/chain.rs @@ -4,11 +4,11 @@ use rustables_macros::nfnetlink_struct; use crate::nlmsg::{NfNetlinkAttribute, NfNetlinkDeserializable, NfNetlinkObject, NfNetlinkWriter}; use crate::parser::{DecodeError, Parsable}; use crate::sys::{ - self, NFTA_CHAIN_FLAGS, NFTA_CHAIN_HOOK, NFTA_CHAIN_NAME, NFTA_CHAIN_POLICY, NFTA_CHAIN_TABLE, + NFTA_CHAIN_FLAGS, NFTA_CHAIN_HOOK, NFTA_CHAIN_NAME, NFTA_CHAIN_POLICY, NFTA_CHAIN_TABLE, NFTA_CHAIN_TYPE, NFTA_CHAIN_USERDATA, NFTA_HOOK_HOOKNUM, NFTA_HOOK_PRIORITY, NFT_MSG_DELCHAIN, NFT_MSG_NEWCHAIN, NLM_F_ACK, NLM_F_CREATE, }; -use crate::{create_wrapper_type, MsgType, ProtocolFamily, Table}; +use crate::{MsgType, ProtocolFamily, Table}; use std::convert::TryFrom; use std::fmt::Debug; diff --git a/src/expr/bitwise.rs b/src/expr/bitwise.rs index 73c2467..29d2d63 100644 --- a/src/expr/bitwise.rs +++ b/src/expr/bitwise.rs @@ -1,46 +1,25 @@ +use rustables_macros::nfnetlink_struct; + use super::{Expression, ExpressionData, Register}; -use crate::create_wrapper_type; use crate::parser::DecodeError; -use crate::sys; +use crate::sys::{ + NFTA_BITWISE_DREG, NFTA_BITWISE_LEN, NFTA_BITWISE_MASK, NFTA_BITWISE_SREG, NFTA_BITWISE_XOR, +}; -create_wrapper_type!( - inline: Bitwise, - [ - ( - get_sreg, - set_sreg, - with_sreg, - sys::NFTA_BITWISE_SREG, - sreg, - Register - ), - ( - get_dreg, - set_dreg, - with_dreg, - sys::NFTA_BITWISE_DREG, - dreg, - Register - ), - (get_len, set_len, with_len, sys::NFTA_BITWISE_LEN, len, u32), - ( - get_mask, - set_mask, - with_mask, - sys::NFTA_BITWISE_MASK, - mask, - ExpressionData - ), - ( - get_xor, - set_xor, - with_xor, - sys::NFTA_BITWISE_XOR, - xor, - ExpressionData - ) - ] -); +#[derive(Clone, PartialEq, Eq, Default, Debug)] +#[nfnetlink_struct] +pub struct Bitwise { + #[field(NFTA_BITWISE_SREG)] + sreg: Register, + #[field(NFTA_BITWISE_DREG)] + dreg: Register, + #[field(NFTA_BITWISE_LEN)] + len: u32, + #[field(NFTA_BITWISE_MASK)] + mask: ExpressionData, + #[field(NFTA_BITWISE_XOR)] + xor: ExpressionData, +} impl Expression for Bitwise { fn get_name() -> &'static str { diff --git a/src/expr/immediate.rs b/src/expr/immediate.rs index 925ca06..134f7e1 100644 --- a/src/expr/immediate.rs +++ b/src/expr/immediate.rs @@ -1,27 +1,16 @@ +use rustables_macros::nfnetlink_struct; + use super::{Expression, ExpressionData, Register}; -use crate::{create_wrapper_type, sys}; +use crate::sys::{NFTA_IMMEDIATE_DATA, NFTA_IMMEDIATE_DREG}; -create_wrapper_type!( - inline: Immediate, - [ - ( - get_dreg, - set_dreg, - with_dreg, - sys::NFTA_IMMEDIATE_DREG, - dreg, - Register - ), - ( - get_data, - set_data, - with_data, - sys::NFTA_IMMEDIATE_DATA, - data, - ExpressionData - ) - ] -); +#[derive(Clone, PartialEq, Eq, Default, Debug)] +#[nfnetlink_struct] +pub struct Immediate { + #[field(NFTA_IMMEDIATE_DREG)] + dreg: Register, + #[field(NFTA_IMMEDIATE_DATA)] + data: ExpressionData, +} impl Immediate { pub fn new_data(data: Vec<u8>, register: Register) -> Self { diff --git a/src/expr/log.rs b/src/expr/log.rs index 82c201d..3c72257 100644 --- a/src/expr/log.rs +++ b/src/expr/log.rs @@ -1,29 +1,17 @@ +use rustables_macros::nfnetlink_struct; + use super::{Expression, ExpressionError}; -use crate::create_wrapper_type; -use crate::sys; +use crate::sys::{NFTA_LOG_GROUP, NFTA_LOG_PREFIX}; -// A Log expression will log all packets that match the rule. -create_wrapper_type!( - inline: Log, - [ - ( - get_group, - set_group, - with_group, - sys::NFTA_LOG_GROUP, - group, - u32 - ), - ( - get_prefix, - set_prefix, - with_prefix, - sys::NFTA_LOG_PREFIX, - prefix, - String - ) - ] -); +#[derive(Clone, PartialEq, Eq, Default, Debug)] +#[nfnetlink_struct] +/// A Log expression will log all packets that match the rule. +pub struct Log { + #[field(NFTA_LOG_GROUP)] + group: u32, + #[field(NFTA_LOG_PREFIX)] + prefix: String, +} impl Log { pub fn new( diff --git a/src/expr/meta.rs b/src/expr/meta.rs index bb8023d..c4c1adb 100644 --- a/src/expr/meta.rs +++ b/src/expr/meta.rs @@ -1,11 +1,11 @@ -use super::{Expression, Register, Rule}; +use rustables_macros::nfnetlink_struct; + +use super::{Expression, Register}; use crate::{ - create_wrapper_type, nlmsg::{NfNetlinkAttribute, NfNetlinkDeserializable}, parser::DecodeError, sys, }; -use std::convert::TryFrom; /// A meta expression refers to meta data associated with a packet. #[derive(Debug, Copy, Clone, Eq, PartialEq)] @@ -78,35 +78,16 @@ impl NfNetlinkDeserializable for MetaType { } } -create_wrapper_type!( - inline: Meta, - [ - ( - get_dreg, - set_dreg, - with_dreg, - sys::NFTA_META_DREG, - dreg, - Register - ), - ( - get_key, - set_key, - with_key, - sys::NFTA_META_KEY, - key, - MetaType - ), - ( - get_sreg, - set_sreg, - with_sreg, - sys::NFTA_META_SREG, - sreg, - Register - ) - ] -); +#[derive(Clone, PartialEq, Eq, Default, Debug)] +#[nfnetlink_struct] +pub struct Meta { + #[field(sys::NFTA_META_DREG)] + dreg: Register, + #[field(sys::NFTA_META_KEY)] + key: MetaType, + #[field(sys::NFTA_META_SREG)] + sreg: Register, +} impl Expression for Meta { fn get_name() -> &'static str { diff --git a/src/expr/mod.rs b/src/expr/mod.rs index e5c2729..63385e0 100644 --- a/src/expr/mod.rs +++ b/src/expr/mod.rs @@ -6,8 +6,6 @@ use std::fmt::Debug; use std::mem::transmute; -use super::rule::Rule; -use crate::create_wrapper_type; use crate::nlmsg::NfNetlinkAttribute; use crate::nlmsg::NfNetlinkDeserializable; use crate::parser::pad_netlink_object; @@ -15,7 +13,10 @@ use crate::parser::pad_netlink_object_with_variable_size; use crate::parser::write_attribute; use crate::parser::DecodeError; use crate::sys::{self, nlattr}; -use libc::NLA_TYPE_MASK; +use crate::sys::{ + NFTA_DATA_VALUE, NFTA_DATA_VERDICT, NFTA_EXPR_DATA, NFTA_EXPR_NAME, NLA_TYPE_MASK, +}; +use rustables_macros::nfnetlink_struct; use thiserror::Error; mod bitwise; @@ -105,26 +106,14 @@ pub trait Expression { fn get_name() -> &'static str; } -create_wrapper_type!( - nested without_deser : RawExpression, [ - // Define the action netfilter will apply to packets processed by this chain, but that did not match any rules in it. - ( - get_name, - set_name, - with_name, - sys::NFTA_EXPR_NAME, - name, - String - ), - ( - get_data, - set_data, - with_data, - sys::NFTA_EXPR_DATA, - data, - ExpressionVariant - ) -]); +#[derive(Clone, PartialEq, Eq, Default, Debug)] +#[nfnetlink_struct(nested = true, derive_decoder = false)] +pub struct RawExpression { + #[field(NFTA_EXPR_NAME)] + name: String, + #[field(NFTA_EXPR_DATA)] + data: ExpressionVariant, +} impl RawExpression { pub fn new<T>(expr: T) -> Self @@ -338,27 +327,14 @@ where } } -create_wrapper_type!( - nested : ExpressionData, - [ - ( - get_value, - set_value, - with_value, - sys::NFTA_DATA_VALUE, - value, - Vec<u8> - ), - ( - get_verdict, - set_verdict, - with_verdict, - sys::NFTA_DATA_VERDICT, - verdict, - VerdictAttribute - ) - ] -); +#[derive(Clone, PartialEq, Eq, Default, Debug)] +#[nfnetlink_struct(nested = true)] +pub struct ExpressionData { + #[field(NFTA_DATA_VALUE)] + value: Vec<u8>, + #[field(NFTA_DATA_VERDICT)] + verdict: VerdictAttribute, +} // default type for expressions that we do not handle yet #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/src/expr/reject.rs b/src/expr/reject.rs index e15f905..10b95ea 100644 --- a/src/expr/reject.rs +++ b/src/expr/reject.rs @@ -1,5 +1,6 @@ +use rustables_macros::nfnetlink_struct; + use crate::{ - create_wrapper_type, nlmsg::{NfNetlinkAttribute, NfNetlinkDeserializable}, parser::DecodeError, sys, @@ -13,28 +14,15 @@ impl Expression for Reject { } } -// A reject expression that defines the type of rejection message sent when discarding a packet. -create_wrapper_type!( - inline: Reject, - [ - ( - get_type, - set_type, - with_type, - sys::NFTA_REJECT_TYPE, - reject_type, - RejectType - ), - ( - get_icmp_code, - set_icmp_code, - with_icmp_code, - sys::NFTA_REJECT_ICMP_CODE, - icmp_code, - IcmpCode - ) - ] -); +#[derive(Clone, PartialEq, Eq, Default, Debug)] +#[nfnetlink_struct] +/// A reject expression that defines the type of rejection message sent when discarding a packet. +pub struct Reject { + #[field(sys::NFTA_REJECT_TYPE, name_in_functions = "type")] + reject_type: RejectType, + #[field(sys::NFTA_REJECT_ICMP_CODE)] + icmp_code: IcmpCode, +} /// An ICMP reject code. #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] diff --git a/src/expr/verdict.rs b/src/expr/verdict.rs index 547ba91..fc13f8a 100644 --- a/src/expr/verdict.rs +++ b/src/expr/verdict.rs @@ -1,13 +1,16 @@ use std::fmt::Debug; use libc::{NF_ACCEPT, NF_DROP, NF_QUEUE}; +use rustables_macros::nfnetlink_struct; use super::{ExpressionData, Immediate, Register}; use crate::{ - create_wrapper_type, nlmsg::{NfNetlinkAttribute, NfNetlinkDeserializable}, parser::DecodeError, - sys::{self, NFT_BREAK, NFT_CONTINUE, NFT_GOTO, NFT_JUMP, NFT_RETURN}, + sys::{ + NFTA_VERDICT_CHAIN, NFTA_VERDICT_CHAIN_ID, NFTA_VERDICT_CODE, NFT_BREAK, NFT_CONTINUE, + NFT_GOTO, NFT_JUMP, NFT_RETURN, + }, }; #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] @@ -53,35 +56,16 @@ impl NfNetlinkDeserializable for VerdictType { } } -create_wrapper_type!( - nested: VerdictAttribute, - [ - ( - get_code, - set_code, - with_code, - sys::NFTA_VERDICT_CODE, - code, - VerdictType - ), - ( - get_chain, - set_chain, - with_chain, - sys::NFTA_VERDICT_CHAIN, - chain, - String - ), - ( - get_chain_id, - set_chain_id, - with_chain_id, - sys::NFTA_VERDICT_CHAIN_ID, - chain_id, - u32 - ) - ] -); +#[derive(Clone, PartialEq, Eq, Default, Debug)] +#[nfnetlink_struct(nested = true)] +pub struct VerdictAttribute { + #[field(NFTA_VERDICT_CODE)] + code: VerdictType, + #[field(NFTA_VERDICT_CHAIN)] + chain: String, + #[field(NFTA_VERDICT_CHAIN_ID)] + chain_id: u32, +} #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub enum VerdictKind { diff --git a/src/parser.rs b/src/parser.rs index 834874c..7d89a1e 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -400,81 +400,6 @@ pub trait InnerFormat { ) -> Result<DebugStruct<'a, 'b>, std::fmt::Error>; } -#[macro_export] -macro_rules! impl_attr_getters_and_setters { - (without_deser $struct:ident, [$(($getter_name:ident, $setter_name:ident, $in_place_edit_name:ident, $attr_name:expr, $internal_name:ident, $type:ty)),+]) => { - impl $struct { - $( - #[allow(dead_code)] - pub fn $getter_name(&self) -> Option<&$type> { - self.$internal_name.as_ref() - } - - #[allow(dead_code)] - pub fn $setter_name(&mut self, val: impl Into<$type>) { - self.$internal_name = Some(val.into()); - } - - #[allow(dead_code)] - pub fn $in_place_edit_name(mut self, val: impl Into<$type>) -> Self { - self.$internal_name = Some(val.into()); - self - } - - )+ - } - - impl $crate::parser::InnerFormat for $struct { - fn inner_format_struct<'a, 'b: 'a>(&'a self, mut s: std::fmt::DebugStruct<'a, 'b>) -> Result<std::fmt::DebugStruct<'a, 'b>, std::fmt::Error> { - $( - // Rewrite attributes names to be readable: 'sys::NFTA_CHAIN_NAME' -> 'name' - // Performance must be terrible, but this is the Debug impl anyway, so that - // must mean we can afford to be slow, right? ;) - if let Some(val) = self.$getter_name() { - let mut attr = stringify!($attr_name); - if let Some((nfta_idx, _match )) = attr.rmatch_indices("NFTA_").next() { - if let Some(underscore_idx) = &attr[nfta_idx+5..].find('_') { - attr = &attr[nfta_idx+underscore_idx+6..]; - } - } - let attr = attr.to_lowercase(); - s.field(&attr, val); - } - )+ - Ok(s) - } - } - - }; - (deser $struct:ident, [$(($getter_name:ident, $setter_name:ident, $in_place_edit_name:ident, $attr_name:expr, $internal_name:ident, $type:ty)),+]) => { - impl $crate::nlmsg::AttributeDecoder for $struct { - #[allow(dead_code)] - fn decode_attribute(&mut self, attr_type: u16, buf: &[u8]) -> Result<(), $crate::parser::DecodeError> { - use $crate::nlmsg::NfNetlinkDeserializable; - debug!("Decoding attribute {} in type {}", attr_type, std::any::type_name::<$struct>()); - match attr_type { - $( - x if x == $attr_name => { - debug!("Calling {}::deserialize()", std::any::type_name::<$type>()); - let (val, remaining) = <$type>::deserialize(buf)?; - if remaining.len() != 0 { - return Err($crate::parser::DecodeError::InvalidDataSize); - } - self.$setter_name(val); - Ok(()) - }, - )+ - _ => Err($crate::parser::DecodeError::UnsupportedAttributeType(attr_type)), - } - } - } - }; - ($struct:ident, [$(($getter_name:ident, $setter_name:ident, $in_place_edit_name:ident, $attr_name:expr, $internal_name:ident, $type:ty)),+]) => { - $crate::impl_attr_getters_and_setters!(without_deser $struct, [$(($getter_name, $setter_name, $in_place_edit_name, $attr_name, $internal_name, $type)),+]); - $crate::impl_attr_getters_and_setters!(deser $struct, [$(($getter_name, $setter_name, $in_place_edit_name, $attr_name, $internal_name, $type)),+]); - }; -} - pub trait Parsable where Self: Sized, @@ -520,118 +445,3 @@ where Ok((res, nfgenmsg, remaining_data)) } } - -#[macro_export] -macro_rules! impl_nfnetlinkattribute { - (__inner : $struct:ident, [$(($attr_name:expr, $internal_name:ident)),+]) => { - impl $struct { - fn inner_get_size(&self) -> usize { - use $crate::nlmsg::NfNetlinkAttribute; - use $crate::parser::{pad_netlink_object, pad_netlink_object_with_variable_size}; - use $crate::sys::nlattr; - let mut size = 0; - - $( - if let Some(val) = &self.$internal_name { - // Attribute header + attribute value - size += pad_netlink_object::<nlattr>() - + pad_netlink_object_with_variable_size(val.get_size()); - } - )+ - - size - } - - unsafe fn inner_write_payload(&self, mut addr: *mut u8) { - use $crate::nlmsg::NfNetlinkAttribute; - use $crate::parser::{pad_netlink_object, pad_netlink_object_with_variable_size}; - use $crate::sys::nlattr; - $( - if let Some(val) = &self.$internal_name { - debug!("writing attribute {} - {:?}", $attr_name, val); - - unsafe { - $crate::parser::write_attribute($attr_name, val, addr); - } - let size = pad_netlink_object::<nlattr>() - + pad_netlink_object_with_variable_size(val.get_size()); - #[allow(unused)] - { - addr = addr.offset(size as isize); - } - } - )+ - } - } - }; - (inline : $struct:ident, [$(($attr_name:expr, $internal_name:ident)),+]) => { - $crate::impl_nfnetlinkattribute!(__inner : $struct, [$(($attr_name, $internal_name)),+]); - - impl $crate::nlmsg::NfNetlinkAttribute for $struct { - fn get_size(&self) -> usize { - self.inner_get_size() - } - - unsafe fn write_payload(&self, addr: *mut u8) { - self.inner_write_payload(addr); - } - } - }; - (nested : $struct:ident, [$(($attr_name:expr, $internal_name:ident)),+]) => { - $crate::impl_nfnetlinkattribute!(__inner : $struct, [$(($attr_name, $internal_name)),+]); - - impl $crate::nlmsg::NfNetlinkAttribute for $struct { - fn is_nested(&self) -> bool { - true - } - - fn get_size(&self) -> usize { - self.inner_get_size() - } - - unsafe fn write_payload(&self, addr: *mut u8) { - self.inner_write_payload(addr); - } - } - }; -} - -#[macro_export] -macro_rules! create_wrapper_type { - (without_deser : $struct:ident, [$(($getter_name:ident, $setter_name:ident, $in_place_edit_name:ident, $attr_name:expr, $internal_name:ident, $type:ty)),+]) => { - #[derive(Clone, PartialEq, Eq, Default)] - pub struct $struct { - $( - $internal_name: Option<$type> - ),+ - } - - $crate::impl_attr_getters_and_setters!(without_deser $struct, [$(($getter_name, $setter_name, $in_place_edit_name, $attr_name, $internal_name, $type)),+]); - - impl std::fmt::Debug for $struct { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - use $crate::parser::InnerFormat; - self.inner_format_struct(f.debug_struct(stringify!($struct)))? - .finish() - } - } - - impl $crate::nlmsg::NfNetlinkDeserializable for $struct { - fn deserialize(buf: &[u8]) -> Result<(Self, &[u8]), $crate::parser::DecodeError> { - Ok(($crate::parser::read_attributes(buf)?, &[])) - } - } - }; - ($struct:ident, [$(($getter_name:ident, $setter_name:ident, $in_place_edit_name:ident, $attr_name:expr, $internal_name:ident, $type:ty)),+]) => { - create_wrapper_type!(without_deser : $struct, [$(($getter_name, $setter_name, $in_place_edit_name, $attr_name, $internal_name, $type)),+]); - $crate::impl_attr_getters_and_setters!(deser $struct, [$(($getter_name, $setter_name, $in_place_edit_name, $attr_name, $internal_name, $type)),+]); - }; - (inline $($($attrs:ident) +)? : $struct:ident, [$(($getter_name:ident, $setter_name:ident, $in_place_edit_name:ident, $attr_name:expr, $internal_name:ident, $type:ty)),+]) => { - create_wrapper_type!($($($attrs) + :)? $struct, [$(($getter_name, $setter_name, $in_place_edit_name, $attr_name, $internal_name, $type)),+]); - $crate::impl_nfnetlinkattribute!(inline : $struct, [$(($attr_name, $internal_name)),+]); - }; - (nested $($($attrs:ident) +)? : $struct:ident, [$(($getter_name:ident, $setter_name:ident, $in_place_edit_name:ident, $attr_name:expr, $internal_name:ident, $type:ty)),+]) => { - create_wrapper_type!($($($attrs) + :)? $struct, [$(($getter_name, $setter_name, $in_place_edit_name, $attr_name, $internal_name, $type)),+]); - $crate::impl_nfnetlinkattribute!(nested : $struct, [$(($attr_name, $internal_name)),+]); - }; -} |