aboutsummaryrefslogtreecommitdiff
path: root/src/chain.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/chain.rs')
-rw-r--r--src/chain.rs76
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,