diff options
Diffstat (limited to 'src/chain.rs')
-rw-r--r-- | src/chain.rs | 76 |
1 files changed, 55 insertions, 21 deletions
diff --git a/src/chain.rs b/src/chain.rs index 000a196..60f5f10 100644 --- a/src/chain.rs +++ b/src/chain.rs @@ -1,4 +1,5 @@ -use crate::nlmsg::NfNetlinkSerializable; +use libc::{NF_ACCEPT, NF_DROP}; + use crate::nlmsg::{ NfNetlinkAttribute, NfNetlinkAttributes, NfNetlinkDeserializable, NfNetlinkObject, NfNetlinkWriter, @@ -7,10 +8,11 @@ use crate::parser::{ parse_object, DecodeError, InnerFormat, NestedAttribute, NfNetlinkAttributeReader, }; use crate::sys::{self, NFT_MSG_DELCHAIN, NFT_MSG_NEWCHAIN, NLM_F_ACK}; -use crate::{impl_attr_getters_and_setters, MsgType, ProtoFamily, Table}; +use crate::{impl_attr_getters_and_setters, MsgType, ProtocolFamily, Table}; +use std::convert::TryFrom; use std::fmt::Debug; -pub type Priority = i32; +pub type ChainPriority = i32; /// The netfilter event hooks a chain can register for. #[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)] @@ -34,7 +36,7 @@ pub struct Hook { } impl Hook { - pub fn new(class: HookClass, priority: Priority) -> Self { + pub fn new(class: HookClass, priority: ChainPriority) -> Self { Hook { inner: NestedAttribute::new(), } @@ -73,6 +75,10 @@ impl_attr_getters_and_setters!( ); impl NfNetlinkAttribute for Hook { + fn is_nested(&self) -> bool { + true + } + fn get_size(&self) -> usize { self.inner.get_size() } @@ -93,12 +99,36 @@ impl NfNetlinkDeserializable for Hook { /// A chain policy. Decides what to do with a packet that was processed by the chain but did not /// match any rules. #[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)] -#[repr(u32)] -pub enum Policy { +#[repr(i32)] +pub enum ChainPolicy { /// Accept the packet. - Accept = libc::NF_ACCEPT as u32, + Accept = NF_ACCEPT, /// Drop the packet. - Drop = libc::NF_DROP as u32, + Drop = NF_DROP, +} + +impl NfNetlinkAttribute for ChainPolicy { + fn get_size(&self) -> usize { + (*self as i32).get_size() + } + + unsafe fn write_payload(&self, addr: *mut u8) { + (*self as i32).write_payload(addr); + } +} + +impl NfNetlinkDeserializable for ChainPolicy { + fn deserialize(buf: &[u8]) -> Result<(Self, &[u8]), DecodeError> { + let (v, remaining_data) = i32::deserialize(buf)?; + Ok(( + match v { + NF_ACCEPT => ChainPolicy::Accept, + NF_DROP => ChainPolicy::Accept, + _ => return Err(DecodeError::UnknownChainPolicy), + }, + remaining_data, + )) + } } /// Base chain type. @@ -160,6 +190,7 @@ impl NfNetlinkDeserializable for ChainType { /// [`set_hook`]: #method.set_hook #[derive(PartialEq, Eq)] pub struct Chain { + family: ProtocolFamily, inner: NfNetlinkAttributes, } @@ -169,6 +200,7 @@ impl Chain { /// [`Table`]: struct.Table.html pub fn new(table: &Table) -> Chain { let mut chain = Chain { + family: table.get_family(), inner: NfNetlinkAttributes::new(), }; @@ -207,7 +239,9 @@ impl PartialEq for Chain { impl Debug for Chain { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.inner_format_struct(f.debug_struct("Chain"))?.finish() + let mut res = f.debug_struct("Chain"); + res.field("family", &self.family); + self.inner_format_struct(res)?.finish() } } @@ -217,13 +251,7 @@ impl NfNetlinkObject for Chain { MsgType::Add => NFT_MSG_NEWCHAIN, MsgType::Del => NFT_MSG_DELCHAIN, } as u16; - writer.write_header( - raw_msg_type, - ProtoFamily::Unspec, - NLM_F_ACK as u16, - seq, - None, - ); + writer.write_header(raw_msg_type, self.family, NLM_F_ACK as u16, seq, None); self.inner.serialize(writer); writer.finalize_writing_object(); } @@ -231,10 +259,16 @@ impl NfNetlinkObject for Chain { impl NfNetlinkDeserializable for Chain { fn deserialize(buf: &[u8]) -> Result<(Self, &[u8]), DecodeError> { - let (inner, _nfgenmsg, remaining_data) = + let (inner, nfgenmsg, remaining_data) = parse_object::<Self>(buf, NFT_MSG_NEWCHAIN, NFT_MSG_DELCHAIN)?; - Ok((Self { inner }, remaining_data)) + Ok(( + Self { + inner, + family: ProtocolFamily::try_from(nfgenmsg.nfgen_family as i32)?, + }, + remaining_data, + )) } } @@ -250,11 +284,11 @@ impl_attr_getters_and_setters!( // By calling `set_hook` with a hook the chain that is created will be registered with that // hook and is thus a "base chain". A "base chain" is an entry point for packets from the // networking stack. - (set_hook, get_hook, with_hook, sys::NFTA_CHAIN_HOOK, ChainHook, Hook), - (get_policy, set_policy, with_policy, sys::NFTA_CHAIN_POLICY, U32, u32), + (get_hook, set_hook, with_hook, sys::NFTA_CHAIN_HOOK, ChainHook, Hook), + (get_policy, set_policy, with_policy, sys::NFTA_CHAIN_POLICY, ChainPolicy, ChainPolicy), (get_table, set_table, with_table, sys::NFTA_CHAIN_TABLE, String, String), // This only applies if the chain has been registered with a hook by calling `set_hook`. - (get_type, set_type, with_type, sys::NFTA_CHAIN_TYPE, String, String), + (get_type, set_type, with_type, sys::NFTA_CHAIN_TYPE, ChainType, ChainType), ( get_userdata, set_userdata, |