diff options
author | lafleur <lafleur@boum.org> | 2021-11-04 17:46:27 +0100 |
---|---|---|
committer | lafleur <lafleur@boum.org> | 2021-11-05 11:37:16 +0100 |
commit | ba5908d8846faa1687fd3a09ffa872832c8ce334 (patch) | |
tree | 888d590ad65fec2329f6aadef09acaf346f6898d /rustables | |
parent | 838b33889e37a960df2accaaa15b1b3135d73b8b (diff) |
add most expr tests - needs fixes, see TODO
Diffstat (limited to 'rustables')
-rw-r--r-- | rustables/src/expr/payload.rs | 2 | ||||
-rw-r--r-- | rustables/src/tests/mod.rs | 509 |
2 files changed, 484 insertions, 27 deletions
diff --git a/rustables/src/expr/payload.rs b/rustables/src/expr/payload.rs index 25a71ad..334c939 100644 --- a/rustables/src/expr/payload.rs +++ b/rustables/src/expr/payload.rs @@ -2,7 +2,7 @@ use super::{DeserializationError, Expression, Rule}; use rustables_sys::{self as sys, libc}; use std::os::raw::c_char; -trait HeaderField { +pub trait HeaderField { fn offset(&self) -> u32; fn len(&self) -> u32; } diff --git a/rustables/src/tests/mod.rs b/rustables/src/tests/mod.rs index d0bf1cc..508b482 100644 --- a/rustables/src/tests/mod.rs +++ b/rustables/src/tests/mod.rs @@ -1,11 +1,11 @@ -use crate::expr::{Bitwise, Counter, Expression, Log, LogGroup, LogPrefix}; use crate::{nft_nlmsg_maxsize, Chain, NlMsg, ProtoFamily, MsgType, Rule, Table}; +use crate::expr::{Bitwise, Cmp, CmpOp, Conntrack, Counter, Expression, IcmpCode, Immediate, Log, LogGroup, LogPrefix, Lookup, Meta, Nat, NatType, Payload, Reject, Register, TcpHeaderField, TransportHeaderField, HeaderField}; +use crate::set::Set; 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; @@ -164,6 +164,118 @@ fn get_test_nlmsg_from_expr(rule: &mut Rule, expr: &impl Expression) -> (nlmsghd } #[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() + ); +} + +#[test] +fn cmp_expr_is_valid() { + let cmp = Cmp::new(CmpOp::Eq, 0); + let mut rule = get_test_rule(); + let (nlmsghdr, _nfgenmsg, raw_expr) = get_test_nlmsg_from_expr(&mut rule, &cmp); + assert_eq!(nlmsghdr.nlmsg_len, 100); + + 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"cmp\0".to_vec()), + NetlinkExpr::Nested( + NFTA_EXPR_DATA, + vec![ + NetlinkExpr::Final( + NFTA_CMP_SREG, + NFT_REG_1.to_be_bytes().to_vec() + ), + NetlinkExpr::Final( + NFTA_CMP_OP, + NFT_CMP_EQ.to_be_bytes().to_vec() + ), + NetlinkExpr::Nested( + NFTA_CMP_DATA, + vec![ + NetlinkExpr::Final( + 1u16, + 0u32.to_be_bytes().to_vec() + ) + ] + ) + ] + ) + ] + )] + ) + ]) + .to_raw() + .unwrap() + ); +} + +#[test] fn counter_expr_is_valid() { let nb_bytes = 123456u64; let nb_packets = 987u64; @@ -175,7 +287,6 @@ fn counter_expr_is_valid() { let (nlmsghdr, _nfgenmsg, raw_expr) = get_test_nlmsg_from_expr(&mut rule, &counter); assert_eq!(nlmsghdr.nlmsg_len, 100); - // check the expression content itself assert_eq!( raw_expr, NetlinkExpr::List(vec![ @@ -210,6 +321,91 @@ fn counter_expr_is_valid() { } #[test] +fn ct_expr_is_valid() { + let ct = Conntrack::State; + let mut rule = get_test_rule(); + let (nlmsghdr, _nfgenmsg, raw_expr) = get_test_nlmsg_from_expr(&mut rule, &ct); + assert_eq!(nlmsghdr.nlmsg_len, 88); + + 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"ct\0".to_vec()), + NetlinkExpr::Nested( + NFTA_EXPR_DATA, + vec![ + NetlinkExpr::Final( + NFTA_CT_KEY, + NFT_CT_STATE.to_be_bytes().to_vec() + ), + NetlinkExpr::Final( + NFTA_CT_DREG, + NFT_REG_1.to_be_bytes().to_vec() + ) + ] + ) + ] + )] + ) + ]) + .to_raw() + .unwrap() + ) +} + +#[test] +fn immediate_expr_is_valid() { + let immediate = Immediate::new(42u8, Register::Reg1); + let mut rule = get_test_rule(); + let (nlmsghdr, _nfgenmsg, raw_expr) = get_test_nlmsg_from_expr(&mut rule, &immediate); + assert_eq!(nlmsghdr.nlmsg_len, 100); + + 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"immediate\0".to_vec()), + NetlinkExpr::Nested( + NFTA_EXPR_DATA, + vec![ + NetlinkExpr::Final( + NFTA_IMMEDIATE_DREG, + NFT_REG_1.to_be_bytes().to_vec() + ), + NetlinkExpr::Nested( + NFTA_IMMEDIATE_DATA, + vec![ + NetlinkExpr::Final( + 1u16, + 42u8.to_be_bytes().to_vec() + ) + ] + ) + ] + ) + ] + )] + ) + ]) + .to_raw() + .unwrap() + ); +} + +#[test] fn log_expr_is_valid() { let log = Log { group: Some(LogGroup(1)), @@ -253,12 +449,16 @@ fn log_expr_is_valid() { } #[test] -fn bitwise_expr_is_valid() { - let netmask = Ipv4Addr::new(255, 255, 255, 0); - let bitwise = Bitwise::new(netmask, 0); +fn lookup_expr_is_valid() { + let set_name = &CStr::from_bytes_with_nul(b"mockset\0").unwrap(); 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); + let table = rule.get_chain().get_table(); + let mut set = Set::new(set_name, 0, &table, ProtoFamily::Inet); + let address: Ipv4Addr = [8, 8, 8, 8].into(); + set.add(&address); + let lookup = Lookup::new(&set).unwrap(); + let (nlmsghdr, _nfgenmsg, raw_expr) = get_test_nlmsg_from_expr(&mut rule, &lookup); + assert_eq!(nlmsghdr.nlmsg_len, 104); assert_eq!( raw_expr, @@ -270,40 +470,295 @@ fn bitwise_expr_is_valid() { vec![NetlinkExpr::Nested( NFTA_LIST_ELEM, vec![ - NetlinkExpr::Final(NFTA_EXPR_NAME, b"bitwise\0".to_vec()), + NetlinkExpr::Final(NFTA_EXPR_NAME, b"lookup\0".to_vec()), NetlinkExpr::Nested( NFTA_EXPR_DATA, vec![ NetlinkExpr::Final( - NFTA_BITWISE_SREG, + NFTA_LOOKUP_SREG, NFT_REG_1.to_be_bytes().to_vec() ), NetlinkExpr::Final( - NFTA_BITWISE_DREG, + NFTA_LOOKUP_SET, + b"mockset\0".to_vec() + ), + NetlinkExpr::Final( + NFTA_LOOKUP_SET_ID, + 0u32.to_be_bytes().to_vec() + ), + ] + ) + ] + )] + ) + ]) + .to_raw() + .unwrap() + ); +} + +/* +use crate::expr::Masquerade; +#[test] +fn masquerade_expr_is_valid() { + let masquerade = Masquerade; + let mut rule = get_test_rule(); + let (nlmsghdr, _nfgenmsg, raw_expr) = get_test_nlmsg_from_expr(&mut rule, &masquerade); + assert_eq!(nlmsghdr.nlmsg_len, 76); + + 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"masq\0".to_vec()), + // TODO find the right value to substitute here. + NetlinkExpr::Final(32770u16, vec![]), + ] + )] + ) + ]) + .to_raw() + .unwrap() + ); +} +*/ + +#[test] +fn meta_expr_is_valid() { + let meta = Meta::Protocol; + let mut rule = get_test_rule(); + let (nlmsghdr, _nfgenmsg, raw_expr) = get_test_nlmsg_from_expr(&mut rule, &meta); + assert_eq!(nlmsghdr.nlmsg_len, 92); + + 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"meta\0".to_vec()), + NetlinkExpr::Nested( + NFTA_EXPR_DATA, + vec![ + NetlinkExpr::Final( + NFTA_META_KEY, + NFT_META_PROTOCOL.to_be_bytes().to_vec() + ), + NetlinkExpr::Final( + NFTA_META_DREG, NFT_REG_1.to_be_bytes().to_vec() + ) + ] + ) + ] + )] + ) + ]) + .to_raw() + .unwrap() + ); +} + +#[test] +fn nat_expr_is_valid() { + let nat = Nat { + nat_type: NatType::SNat, + family: ProtoFamily::Ipv4, + ip_register: Register::Reg1, + port_register: None + }; + let mut rule = get_test_rule(); + let (nlmsghdr, _nfgenmsg, raw_expr) = get_test_nlmsg_from_expr(&mut rule, &nat); + 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"nat\0".to_vec()), + NetlinkExpr::Nested( + NFTA_EXPR_DATA, + vec![ + NetlinkExpr::Final( + NFTA_NAT_TYPE, + NFT_NAT_SNAT.to_be_bytes().to_vec() ), NetlinkExpr::Final( - NFTA_BITWISE_LEN, - 4u32.to_be_bytes().to_vec() + NFTA_NAT_FAMILY, + // TODO find the right value to substitute here. + //(ProtoFamily::Ipv4 as u16).to_le_bytes().to_vec() + 2u32.to_be_bytes().to_vec() ), - NetlinkExpr::Nested( - NFTA_BITWISE_MASK, - vec![ - NetlinkExpr::Final( - NFTA_DATA_VALUE, - vec![255, 255, 255, 0] - ) - ] + NetlinkExpr::Final( + NFTA_NAT_REG_ADDR_MIN, + NFT_REG_1.to_be_bytes().to_vec() + ) + ] + ) + ] + )] + ) + ]) + .to_raw() + .unwrap() + ); +} + +#[test] +fn payload_expr_is_valid() { + // TODO test loaded payload ? + let tcp_header_field = TcpHeaderField::Sport; + let transport_header_field = TransportHeaderField::Tcp(tcp_header_field); + let payload = Payload::Transport(transport_header_field); + let mut rule = get_test_rule(); + let (nlmsghdr, _nfgenmsg, raw_expr) = get_test_nlmsg_from_expr(&mut rule, &payload); + assert_eq!(nlmsghdr.nlmsg_len, 108); + + 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"payload\0".to_vec()), + NetlinkExpr::Nested( + NFTA_EXPR_DATA, + vec![ + NetlinkExpr::Final( + NFTA_PAYLOAD_DREG, + NFT_REG_1.to_be_bytes().to_vec() + ), + NetlinkExpr::Final( + NFTA_PAYLOAD_BASE, + NFT_PAYLOAD_TRANSPORT_HEADER.to_be_bytes().to_vec() + ), + NetlinkExpr::Final( + NFTA_PAYLOAD_OFFSET, + tcp_header_field.offset().to_be_bytes().to_vec() + ), + NetlinkExpr::Final( + NFTA_PAYLOAD_LEN, + //tcp_header_field.len().to_be_bytes().to_vec() + 0u32.to_be_bytes().to_vec() + ), + ] + ) + ] + )] + ) + ]) + .to_raw() + .unwrap() + ); +} + +#[test] +fn reject_expr_is_valid() { + let code = IcmpCode::NoRoute; + let reject = Reject::Icmp(code); + let mut rule = get_test_rule(); + let (nlmsghdr, _nfgenmsg, raw_expr) = get_test_nlmsg_from_expr(&mut rule, &reject); + assert_eq!(nlmsghdr.nlmsg_len, 92); + + 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"reject\0".to_vec()), + NetlinkExpr::Nested( + NFTA_EXPR_DATA, + vec![ + NetlinkExpr::Final( + NFTA_REJECT_TYPE, + NFT_REJECT_ICMPX_UNREACH.to_be_bytes().to_vec() + ), + NetlinkExpr::Final( + NFTA_REJECT_ICMP_CODE, + (code as u8).to_be_bytes().to_vec() + ), + ] + ) + ] + )] + ) + ]) + .to_raw() + .unwrap() + ); +} + +/* +use rustables_sys::libc::NF_DROP; +use crate::expr::Verdict; +#[test] +fn verdict_expr_is_valid() { + let verdict = Verdict::Drop; + let mut rule = get_test_rule(); + let chain = rule.get_chain().get_name().to_owned(); + let (nlmsghdr, _nfgenmsg, raw_expr) = get_test_nlmsg_from_expr(&mut rule, &verdict); + assert_eq!(nlmsghdr.nlmsg_len, 104); + + 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"immediate\0".to_vec()), + // TODO find the right arrangement for Verdict's data. + NetlinkExpr::Nested( + NFTA_EXPR_DATA, + vec![ + NetlinkExpr::Final( + NFTA_IMMEDIATE_DREG, + NFT_REG_VERDICT.to_be_bytes().to_vec() ), NetlinkExpr::Nested( - NFTA_BITWISE_XOR, + NFTA_IMMEDIATE_DATA, vec![ NetlinkExpr::Final( - NFTA_DATA_VALUE, - 0u32.to_be_bytes().to_vec() - ) + NFTA_VERDICT_CHAIN_ID, + //rustables_sys::NFTNL_EXPR_IMM_CHAIN as u16, + (chain.as_ptr() as u8).to_be_bytes().to_vec() + ), + NetlinkExpr::Final( + NFTA_VERDICT_CODE, + //rustables_sys::NFTNL_EXPR_IMM_VERDICT as u16, + NF_DROP.to_be_bytes().to_vec() + //0u32.to_be_bytes().to_vec() + ), ] - ) + ), ] ) ] @@ -314,3 +769,5 @@ fn bitwise_expr_is_valid() { .unwrap() ); } +*/ + |