diff options
Diffstat (limited to 'rustables/src')
-rw-r--r-- | rustables/src/tests/mod.rs | 210 |
1 files changed, 166 insertions, 44 deletions
diff --git a/rustables/src/tests/mod.rs b/rustables/src/tests/mod.rs index 6e53e3b..d0bf1cc 100644 --- a/rustables/src/tests/mod.rs +++ b/rustables/src/tests/mod.rs @@ -1,9 +1,11 @@ -use crate::expr::Counter; -use crate::{nft_nlmsg_maxsize, NlMsg}; +use crate::expr::{Bitwise, Counter, Expression, Log, LogGroup, LogPrefix}; +use crate::{nft_nlmsg_maxsize, Chain, NlMsg, ProtoFamily, MsgType, Rule, Table}; use rustables_sys::libc::{nlmsghdr, AF_UNIX, NFNETLINK_V0, NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWRULE}; use std::ffi::{c_void, CStr}; use std::mem::size_of; use std::rc::Rc; +use std::net::Ipv4Addr; +//use ipnetwork::IpNetwork; use thiserror::Error; mod sys; @@ -16,6 +18,9 @@ fn get_operation_from_nlmsghdr_type(x: u16) -> u8 { (x & 0x00ff) as u8 } +const TABLE_NAME: &[u8; 10] = b"mocktable\0"; +const CHAIN_NAME: &[u8; 10] = b"mockchain\0"; + type NetLinkType = u16; #[derive(Debug, PartialEq)] @@ -94,35 +99,31 @@ impl NetlinkExpr { #[repr(C)] #[derive(Clone, Copy)] -struct nfgenmsg { +struct Nfgenmsg { family: u8, /* AF_xxx */ version: u8, /* nfnetlink version */ res_id: u16, /* resource id */ } -#[test] -fn counter_expr_is_valid() { - let table_name = b"mocktable\0"; - let chain_name = b"mockchain\0"; - let nb_bytes = 123456u64; - let nb_packets = 987u64; - - let mut counter = Counter::new(); - counter.nb_bytes = nb_bytes; - counter.nb_packets = nb_packets; - let table = Rc::new(crate::Table::new( - &CStr::from_bytes_with_nul(table_name).unwrap(), - crate::ProtoFamily::Inet, +fn get_test_rule() -> Rule { + let table = Rc::new(Table::new( + &CStr::from_bytes_with_nul(TABLE_NAME).unwrap(), + ProtoFamily::Inet, )); - let chain = Rc::new(crate::Chain::new( - &CStr::from_bytes_with_nul(chain_name).unwrap(), + let chain = Rc::new(Chain::new( + &CStr::from_bytes_with_nul(CHAIN_NAME).unwrap(), Rc::clone(&table), )); - let mut rule = crate::Rule::new(Rc::clone(&chain)); - rule.add_expr(&counter); + let rule = Rule::new(Rc::clone(&chain)); + rule +} + +fn get_test_nlmsg_from_expr(rule: &mut Rule, expr: &impl Expression) -> (nlmsghdr, Nfgenmsg, Vec<u8>){ + rule.add_expr(expr); + let mut buf = vec![0u8; nft_nlmsg_maxsize() as usize]; - let (nlmsghdr, nfgenmsg, raw_expr) = unsafe { - rule.write(buf.as_mut_ptr() as *mut c_void, 0, crate::MsgType::Add); + unsafe { + rule.write(buf.as_mut_ptr() as *mut c_void, 0, MsgType::Add); // right now the message is composed of the following parts: // - nlmsghdr (contain the message size and type) @@ -130,41 +131,56 @@ fn counter_expr_is_valid() { // - the raw expression that we want to check let size_of_hdr = size_of::<nlmsghdr>(); - let size_of_nfgenmsg = size_of::<nfgenmsg>(); + let size_of_nfgenmsg = size_of::<Nfgenmsg>(); let nlmsghdr = *(buf[0..size_of_hdr].as_ptr() as *const nlmsghdr); let nfgenmsg = - *(buf[size_of_hdr..size_of_hdr + size_of_nfgenmsg].as_ptr() as *const nfgenmsg); + *(buf[size_of_hdr..size_of_hdr + size_of_nfgenmsg].as_ptr() as *const Nfgenmsg); + let raw_expr = buf[size_of_hdr + size_of_nfgenmsg..nlmsghdr.nlmsg_len as usize] + .iter().map(|x| *x).collect(); + + // sanity checks on the global message (this should be very similar/factorisable for the + // most part in other tests) + // TODO: check the messages flags + assert_eq!( + get_subsystem_from_nlmsghdr_type(nlmsghdr.nlmsg_type), + NFNL_SUBSYS_NFTABLES as u8 + ); + assert_eq!( + get_operation_from_nlmsghdr_type(nlmsghdr.nlmsg_type), + NFT_MSG_NEWRULE as u8 + ); + assert_eq!(nlmsghdr.nlmsg_seq, 0); + assert_eq!(nlmsghdr.nlmsg_pid, 0); + assert_eq!(nfgenmsg.family, AF_UNIX as u8); + assert_eq!(nfgenmsg.version, NFNETLINK_V0 as u8); + assert_eq!(nfgenmsg.res_id.to_be(), 0); + ( nlmsghdr, nfgenmsg, - &buf[size_of_hdr + size_of_nfgenmsg..nlmsghdr.nlmsg_len as usize], + raw_expr, ) - }; + } +} - // sanity checks on the global message (this should be very similar/factorisable for the - // most part in other tests) +#[test] +fn counter_expr_is_valid() { + let nb_bytes = 123456u64; + let nb_packets = 987u64; + let mut counter = Counter::new(); + counter.nb_bytes = nb_bytes; + counter.nb_packets = nb_packets; + + let mut rule = get_test_rule(); + let (nlmsghdr, _nfgenmsg, raw_expr) = get_test_nlmsg_from_expr(&mut rule, &counter); assert_eq!(nlmsghdr.nlmsg_len, 100); - // TODO: check the messages flags - assert_eq!( - get_subsystem_from_nlmsghdr_type(nlmsghdr.nlmsg_type), - NFNL_SUBSYS_NFTABLES as u8 - ); - assert_eq!( - get_operation_from_nlmsghdr_type(nlmsghdr.nlmsg_type), - NFT_MSG_NEWRULE as u8 - ); - assert_eq!(nlmsghdr.nlmsg_seq, 0); - assert_eq!(nlmsghdr.nlmsg_pid, 0); - assert_eq!(nfgenmsg.family, AF_UNIX as u8); - assert_eq!(nfgenmsg.version, NFNETLINK_V0 as u8); - assert_eq!(nfgenmsg.res_id.to_be(), 0); // check the expression content itself assert_eq!( raw_expr, NetlinkExpr::List(vec![ - NetlinkExpr::Final(NFTA_RULE_TABLE, table_name.to_vec()), - NetlinkExpr::Final(NFTA_RULE_CHAIN, chain_name.to_vec()), + NetlinkExpr::Final(NFTA_RULE_TABLE, TABLE_NAME.to_vec()), + NetlinkExpr::Final(NFTA_RULE_CHAIN, CHAIN_NAME.to_vec()), NetlinkExpr::Nested( NFTA_RULE_EXPRESSIONS, vec![NetlinkExpr::Nested( @@ -192,3 +208,109 @@ fn counter_expr_is_valid() { .unwrap() ); } + +#[test] +fn log_expr_is_valid() { + let log = Log { + group: Some(LogGroup(1)), + prefix: Some(LogPrefix::new("mockprefix").unwrap()) + }; + let mut rule = get_test_rule(); + let (nlmsghdr, _nfgenmsg, raw_expr) = get_test_nlmsg_from_expr(&mut rule, &log); + assert_eq!(nlmsghdr.nlmsg_len, 96); + + assert_eq!( + raw_expr, + NetlinkExpr::List(vec![ + NetlinkExpr::Final(NFTA_RULE_TABLE, TABLE_NAME.to_vec()), + NetlinkExpr::Final(NFTA_RULE_CHAIN, CHAIN_NAME.to_vec()), + NetlinkExpr::Nested( + NFTA_RULE_EXPRESSIONS, + vec![NetlinkExpr::Nested( + NFTA_LIST_ELEM, + vec![ + NetlinkExpr::Final(NFTA_EXPR_NAME, b"log\0".to_vec()), + NetlinkExpr::Nested( + NFTA_EXPR_DATA, + vec![ + NetlinkExpr::Final( + NFTA_LOG_PREFIX, + b"mockprefix\0".to_vec() + ), + NetlinkExpr::Final( + NFTA_LOG_GROUP, + 1u16.to_be_bytes().to_vec() + ) + ] + ) + ] + )] + ) + ]) + .to_raw() + .unwrap() + ); +} + +#[test] +fn bitwise_expr_is_valid() { + let netmask = Ipv4Addr::new(255, 255, 255, 0); + let bitwise = Bitwise::new(netmask, 0); + let mut rule = get_test_rule(); + let (nlmsghdr, _nfgenmsg, raw_expr) = get_test_nlmsg_from_expr(&mut rule, &bitwise); + assert_eq!(nlmsghdr.nlmsg_len, 124); + + assert_eq!( + raw_expr, + NetlinkExpr::List(vec![ + NetlinkExpr::Final(NFTA_RULE_TABLE, TABLE_NAME.to_vec()), + NetlinkExpr::Final(NFTA_RULE_CHAIN, CHAIN_NAME.to_vec()), + NetlinkExpr::Nested( + NFTA_RULE_EXPRESSIONS, + vec![NetlinkExpr::Nested( + NFTA_LIST_ELEM, + vec![ + NetlinkExpr::Final(NFTA_EXPR_NAME, b"bitwise\0".to_vec()), + NetlinkExpr::Nested( + NFTA_EXPR_DATA, + vec![ + NetlinkExpr::Final( + NFTA_BITWISE_SREG, + NFT_REG_1.to_be_bytes().to_vec() + ), + NetlinkExpr::Final( + NFTA_BITWISE_DREG, + NFT_REG_1.to_be_bytes().to_vec() + ), + NetlinkExpr::Final( + NFTA_BITWISE_LEN, + 4u32.to_be_bytes().to_vec() + ), + NetlinkExpr::Nested( + NFTA_BITWISE_MASK, + vec![ + NetlinkExpr::Final( + NFTA_DATA_VALUE, + vec![255, 255, 255, 0] + ) + ] + ), + NetlinkExpr::Nested( + NFTA_BITWISE_XOR, + vec![ + NetlinkExpr::Final( + NFTA_DATA_VALUE, + 0u32.to_be_bytes().to_vec() + ) + ] + ) + ] + ) + ] + )] + ) + ]) + .to_raw() + .unwrap() + ); +} |