#[macro_use]
#[allow(dead_code)]
mod helper;
use crate::helper::pfcli;
use assert_matches::assert_matches;
use std::net::{Ipv4Addr, Ipv6Addr};
static ANCHOR_NAME: &str = "pfctl-rs.integration.testing.nat-rules";
fn nat_rule(dest: pfctl::Ip, nat_to: pfctl::Ip) -> pfctl::NatRule {
pfctl::NatRuleBuilder::default()
.action(pfctl::NatRuleAction::Nat {
nat_to: nat_to.into(),
})
.to(pfctl::Endpoint::new(dest, 1234))
.build()
.unwrap()
}
fn nat_rule_ipv4() -> pfctl::NatRule {
nat_rule(
pfctl::Ip::from(Ipv4Addr::new(127, 0, 0, 1)),
pfctl::Ip::from(Ipv4Addr::new(127, 0, 0, 2)),
)
}
fn nat_rule_ipv6() -> pfctl::NatRule {
nat_rule(
pfctl::Ip::from(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)),
pfctl::Ip::from(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 2)),
)
}
fn nonat_rule(dest: pfctl::Ip) -> pfctl::NatRule {
pfctl::NatRuleBuilder::default()
.action(pfctl::NatRuleAction::NoNat)
.to(pfctl::Endpoint::new(dest, 1234))
.build()
.unwrap()
}
fn nonat_rule_ipv4() -> pfctl::NatRule {
nonat_rule(pfctl::Ip::from(Ipv4Addr::new(127, 0, 0, 1)))
}
fn nonat_rule_ipv6() -> pfctl::NatRule {
nonat_rule(pfctl::Ip::from(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)))
}
fn before_each() {
pfctl::PfCtl::new()
.unwrap()
.try_add_anchor(ANCHOR_NAME, pfctl::AnchorKind::Nat)
.unwrap();
}
fn after_each() {
pfcli::flush_rules(ANCHOR_NAME, pfcli::FlushOptions::Nat);
pfctl::PfCtl::new()
.unwrap()
.try_remove_anchor(ANCHOR_NAME, pfctl::AnchorKind::Nat)
.unwrap();
}
test!(add_nat_rule_ipv4 {
let mut pf = pfctl::PfCtl::new().unwrap();
let rule = nat_rule_ipv4();
assert_matches!(pf.add_nat_rule(ANCHOR_NAME, &rule), Ok(()));
assert_eq!(
pfcli::get_nat_rules(ANCHOR_NAME),
&["nat inet from any to 127.0.0.1 port = 1234 -> 127.0.0.2"]
);
});
test!(add_nat_rule_ipv6 {
let mut pf = pfctl::PfCtl::new().unwrap();
let rule = nat_rule_ipv6();
assert_matches!(pf.add_nat_rule(ANCHOR_NAME, &rule), Ok(()));
assert_eq!(
pfcli::get_nat_rules(ANCHOR_NAME),
&["nat inet6 from any to ::1 port = 1234 -> ::2"]
);
});
test!(add_nonat_rule_ipv4 {
let mut pf = pfctl::PfCtl::new().unwrap();
let rule = nonat_rule_ipv4();
assert_matches!(pf.add_nat_rule(ANCHOR_NAME, &rule), Ok(()));
assert_eq!(
pfcli::get_nat_rules(ANCHOR_NAME),
&["no nat inet from any to 127.0.0.1 port = 1234"]
);
});
test!(add_nonat_rule_ipv6 {
let mut pf = pfctl::PfCtl::new().unwrap();
let rule = nonat_rule_ipv6();
assert_matches!(pf.add_nat_rule(ANCHOR_NAME, &rule), Ok(()));
assert_eq!(
pfcli::get_nat_rules(ANCHOR_NAME),
&["no nat inet6 from any to ::1 port = 1234"]
);
});