use rustables::{
expr::{
Cmp, CmpOp, Counter, ExpressionList, HighLevelPayload, Immediate, LLHeaderField, Meta,
MetaType, VerdictKind,
},
Batch, Chain, ChainPolicy, Hook, HookClass, ProtocolFamily, Rule, Table,
};
const TABLE_NAME: &str = "example-filter-ethernet";
const OUT_CHAIN_NAME: &str = "chain-for-outgoing-packets";
const BLOCK_THIS_MAC: &[u8] = &[1, 2, 3, 4, 5, 6];
fn main() {
let mut batch = Batch::new();
let table = Table::new(ProtocolFamily::Inet).with_name(TABLE_NAME);
batch.add(&table, rustables::MsgType::Add);
let mut out_chain = Chain::new(&table).with_name(OUT_CHAIN_NAME);
out_chain.set_hook(Hook::new(HookClass::Out, 3));
out_chain.set_policy(ChainPolicy::Accept);
batch.add(&out_chain, rustables::MsgType::Add);
let mut block_ethernet_rule = Rule::new(&out_chain).unwrap();
block_ethernet_rule.set_expressions(
ExpressionList::default()
.with_value(Meta::new(MetaType::IifType))
.with_value(Cmp::new(CmpOp::Eq, (libc::ARPHRD_ETHER as u16).to_le_bytes()))
.with_value(HighLevelPayload::LinkLayer(LLHeaderField::Daddr).build())
.with_value(Cmp::new(CmpOp::Eq, BLOCK_THIS_MAC))
.with_value(Immediate::new_verdict(VerdictKind::Drop)),
);
batch.add(&block_ethernet_rule, rustables::MsgType::Add);
let mut random_rule = Rule::new(&out_chain).unwrap();
random_rule.set_expressions(
ExpressionList::default()
.with_value(Counter::default())
.with_value(Meta::new(MetaType::PRandom))
.with_value(Cmp::new(CmpOp::Gt, (::std::u32::MAX / 2).to_be_bytes()))
.with_value(Counter::default()),
);
batch.add(&random_rule, rustables::MsgType::Add);
batch.send().unwrap();
}