diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nlmsg.rs | 11 | ||||
-rw-r--r-- | src/parser.rs | 62 | ||||
-rw-r--r-- | src/parser_impls.rs | 12 |
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, |