aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nlmsg.rs11
-rw-r--r--src/parser.rs62
-rw-r--r--src/parser_impls.rs12
3 files changed, 36 insertions, 49 deletions
diff --git a/src/nlmsg.rs b/src/nlmsg.rs
index 0e32588..b8fa857 100644
--- a/src/nlmsg.rs
+++ b/src/nlmsg.rs
@@ -39,6 +39,8 @@ pub fn get_operation_from_nlmsghdr_type(x: u16) -> u8 {
pub struct NfNetlinkWriter<'a> {
buf: &'a mut Vec<u8>,
+ // hold the position of the nlmsghdr and nfgenmsg structures for the object currently being
+ // written
headers: Option<(usize, usize)>,
}
@@ -52,6 +54,7 @@ impl<'a> NfNetlinkWriter<'a> {
let start = self.buf.len();
self.buf.resize(start + padded_size, 0);
+ // if we are *inside* an object begin written, extend the netlink object size
if let Some((msghdr_idx, _nfgenmsg_idx)) = self.headers {
let mut hdr: &mut nlmsghdr = unsafe {
std::mem::transmute(self.buf[msghdr_idx..].as_mut_ptr() as *mut nlmsghdr)
@@ -78,6 +81,7 @@ impl<'a> NfNetlinkWriter<'a> {
let nlmsghdr_len = pad_netlink_object::<nlmsghdr>();
let nfgenmsg_len = pad_netlink_object::<nfgenmsg>();
+ // serialize the nlmsghdr
let nlmsghdr_buf = self.add_data_zeroed(nlmsghdr_len);
let mut hdr: &mut nlmsghdr =
unsafe { std::mem::transmute(nlmsghdr_buf.as_mut_ptr() as *mut nlmsghdr) };
@@ -90,6 +94,7 @@ impl<'a> NfNetlinkWriter<'a> {
hdr.nlmsg_flags = libc::NLM_F_REQUEST as u16 | flags;
hdr.nlmsg_seq = seq;
+ // serialize the nfgenmsg
let nfgenmsg_buf = self.add_data_zeroed(nfgenmsg_len);
let mut nfgenmsg: &mut nfgenmsg =
unsafe { std::mem::transmute(nfgenmsg_buf.as_mut_ptr() as *mut nfgenmsg) };
@@ -108,8 +113,10 @@ impl<'a> NfNetlinkWriter<'a> {
}
}
+pub type NetlinkType = u16;
+
pub trait AttributeDecoder {
- fn decode_attribute(&mut self, attr_type: u16, buf: &[u8]) -> Result<(), DecodeError>;
+ fn decode_attribute(&mut self, attr_type: NetlinkType, buf: &[u8]) -> Result<(), DecodeError>;
}
pub trait NfNetlinkDeserializable: Sized {
@@ -163,8 +170,6 @@ pub trait NfNetlinkObject:
}
}
-pub type NetlinkType = u16;
-
pub trait NfNetlinkAttribute: Debug + Sized {
// is it a nested argument that must be marked with a NLA_F_NESTED flag?
fn is_nested(&self) -> bool {
diff --git a/src/parser.rs b/src/parser.rs
index c8667e3..82dd27e 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -170,48 +170,30 @@ pub trait InnerFormat {
) -> Result<DebugStruct<'a, 'b>, std::fmt::Error>;
}
-pub trait Parsable
-where
- Self: Sized,
-{
- fn parse_object(
- buf: &[u8],
- add_obj: u32,
- del_obj: u32,
- ) -> Result<(Self, nfgenmsg, &[u8]), DecodeError>;
-}
-
-impl<T> Parsable for T
-where
- T: AttributeDecoder + Default + Sized,
-{
- fn parse_object(
- buf: &[u8],
- add_obj: u32,
- del_obj: u32,
- ) -> Result<(Self, nfgenmsg, &[u8]), DecodeError> {
- debug!("parse_object() started");
- let (hdr, msg) = parse_nlmsg(buf)?;
-
- let op = get_operation_from_nlmsghdr_type(hdr.nlmsg_type) as u32;
-
- if op != add_obj && op != del_obj {
- return Err(DecodeError::UnexpectedType(hdr.nlmsg_type));
- }
+pub(crate) fn parse_object<T: AttributeDecoder + Default + Sized>(
+ buf: &[u8],
+ add_obj: u32,
+ del_obj: u32,
+) -> Result<(T, nfgenmsg, &[u8]), DecodeError> {
+ debug!("parse_object() started");
+ let (hdr, msg) = parse_nlmsg(buf)?;
+
+ let op = get_operation_from_nlmsghdr_type(hdr.nlmsg_type) as u32;
+
+ if op != add_obj && op != del_obj {
+ return Err(DecodeError::UnexpectedType(hdr.nlmsg_type));
+ }
- let obj_size = hdr.nlmsg_len as usize
- - pad_netlink_object_with_variable_size(size_of::<nlmsghdr>() + size_of::<nfgenmsg>());
+ let obj_size = hdr.nlmsg_len as usize
+ - pad_netlink_object_with_variable_size(size_of::<nlmsghdr>() + size_of::<nfgenmsg>());
- let remaining_data_offset = pad_netlink_object_with_variable_size(hdr.nlmsg_len as usize);
- let remaining_data = &buf[remaining_data_offset..];
+ let remaining_data_offset = pad_netlink_object_with_variable_size(hdr.nlmsg_len as usize);
+ let remaining_data = &buf[remaining_data_offset..];
- let (nfgenmsg, res) = match msg {
- NlMsg::NfGenMsg(nfgenmsg, content) => {
- (nfgenmsg, read_attributes(&content[..obj_size])?)
- }
- _ => return Err(DecodeError::UnexpectedType(hdr.nlmsg_type)),
- };
+ let (nfgenmsg, res) = match msg {
+ NlMsg::NfGenMsg(nfgenmsg, content) => (nfgenmsg, read_attributes(&content[..obj_size])?),
+ _ => return Err(DecodeError::UnexpectedType(hdr.nlmsg_type)),
+ };
- Ok((res, nfgenmsg, remaining_data))
- }
+ Ok((res, nfgenmsg, remaining_data))
}
diff --git a/src/parser_impls.rs b/src/parser_impls.rs
index 887a9a2..c49c876 100644
--- a/src/parser_impls.rs
+++ b/src/parser_impls.rs
@@ -9,10 +9,10 @@ use crate::{
error::DecodeError,
expr::Verdict,
nlmsg::{
- pad_netlink_object, pad_netlink_object_with_variable_size, NfNetlinkAttribute,
- NfNetlinkDeserializable, NfNetlinkObject,
+ pad_netlink_object, pad_netlink_object_with_variable_size, AttributeDecoder,
+ NfNetlinkAttribute, NfNetlinkDeserializable, NfNetlinkObject,
},
- parser::{write_attribute, Parsable},
+ parser::{parse_object, write_attribute},
sys::{nlattr, NFTA_DATA_VALUE, NFTA_DATA_VERDICT, NFTA_LIST_ELEM, NLA_TYPE_MASK},
ProtocolFamily,
};
@@ -232,10 +232,10 @@ where
impl<T> NfNetlinkDeserializable for T
where
- T: NfNetlinkObject + Parsable,
+ T: NfNetlinkObject + AttributeDecoder + Default + Sized,
{
- fn deserialize(buf: &[u8]) -> Result<(Self, &[u8]), DecodeError> {
- let (mut obj, nfgenmsg, remaining_data) = Self::parse_object(
+ fn deserialize(buf: &[u8]) -> Result<(T, &[u8]), DecodeError> {
+ let (mut obj, nfgenmsg, remaining_data) = parse_object::<T>(
buf,
<T as NfNetlinkObject>::MSG_TYPE_ADD,
<T as NfNetlinkObject>::MSG_TYPE_DEL,