aboutsummaryrefslogtreecommitdiff
path: root/rustables
diff options
context:
space:
mode:
authorlafleur <lafleur@boum.org>2021-11-04 17:46:27 +0100
committerlafleur <lafleur@boum.org>2021-11-05 11:37:16 +0100
commitba5908d8846faa1687fd3a09ffa872832c8ce334 (patch)
tree888d590ad65fec2329f6aadef09acaf346f6898d /rustables
parent838b33889e37a960df2accaaa15b1b3135d73b8b (diff)
add most expr tests - needs fixes, see TODO
Diffstat (limited to 'rustables')
-rw-r--r--rustables/src/expr/payload.rs2
-rw-r--r--rustables/src/tests/mod.rs509
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()
);
}
+*/
+