aboutsummaryrefslogtreecommitdiff
path: root/examples/filter-ethernet.rs
blob: 732c8cb65d6c1aecbbc9def3c4a2596e18c582ac (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
///! Adds a table, chain and a rule that blocks all traffic to a given MAC address
///!
///! Run the following to print out current active tables, chains and rules in netfilter. Must be
///! executed as root:
///! ```bash
///! # nft list ruleset
///! ```
///! After running this example, the output should be the following:
///! ```ignore
///! table inet example-filter-ethernet {
///!         chain chain-for-outgoing-packets {
///!                 type filter hook output priority 3; policy accept;
///!                 ether daddr 00:00:00:00:00:00 drop
///!                 counter packets 0 bytes 0 meta random > 2147483647 counter packets 0 bytes 0
///!         }
///! }
///! ```
///!
///!
///! Everything created by this example can be removed by running
///! ```bash
///! # nft delete table inet example-filter-ethernet
///! ```
//use rustables::{nft_expr, query::send_batch, sys::libc, Batch, Chain, ProtoFamily, Rule, Table};
use std::{ffi::CString, rc::Rc};
//
//const TABLE_NAME: &str = "example-filter-ethernet";
//const OUT_CHAIN_NAME: &str = "chain-for-outgoing-packets";
//
//const BLOCK_THIS_MAC: &[u8] = &[0, 0, 0, 0, 0, 0];
//
fn main() {
    //    // For verbose explanations of what all these lines up until the rule creation does, see the
    //    // `add-rules` example.
    //    let mut batch = Batch::new();
    //    let table = Rc::new(Table::new(
    //        &CString::new(TABLE_NAME).unwrap(),
    //        ProtoFamily::Inet,
    //    ));
    //    batch.add(&Rc::clone(&table), rustables::MsgType::Add);
    //
    //    let mut out_chain = Chain::new(&CString::new(OUT_CHAIN_NAME).unwrap(), Rc::clone(&table));
    //    out_chain.set_hook(rustables::Hook::Out, 3);
    //    out_chain.set_policy(rustables::Policy::Accept);
    //    let out_chain = Rc::new(out_chain);
    //    batch.add(&Rc::clone(&out_chain), rustables::MsgType::Add);
    //
    //    // === ADD RULE DROPPING ALL TRAFFIC TO THE MAC ADDRESS IN `BLOCK_THIS_MAC` ===
    //
    //    let mut block_ethernet_rule = Rule::new(Rc::clone(&out_chain));
    //
    //    // Check that the interface type is an ethernet interface. Must be done before we can check
    //    // payload values in the ethernet header.
    //    block_ethernet_rule.add_expr(&nft_expr!(meta iiftype));
    //    block_ethernet_rule.add_expr(&nft_expr!(cmp == libc::ARPHRD_ETHER));
    //
    //    // Compare the ethernet destination address against the MAC address we want to drop
    //    block_ethernet_rule.add_expr(&nft_expr!(payload ethernet daddr));
    //    block_ethernet_rule.add_expr(&nft_expr!(cmp == BLOCK_THIS_MAC));
    //
    //    // Drop the matching packets.
    //    block_ethernet_rule.add_expr(&nft_expr!(verdict drop));
    //
    //    batch.add(&block_ethernet_rule, rustables::MsgType::Add);
    //
    //    // === FOR FUN, ADD A PACKET THAT MATCHES 50% OF ALL PACKETS ===
    //
    //    // This packet has a counter before and after the check that has 50% chance of matching.
    //    // So after a number of packets has passed through this rule, the first counter should have a
    //    // value approximately double that of the second counter. This rule has no verdict, so it never
    //    // does anything with the matching packets.
    //    let mut random_rule = Rule::new(Rc::clone(&out_chain));
    //    // This counter expression will be evaluated (and increment the counter) for all packets coming
    //    // through.
    //    random_rule.add_expr(&nft_expr!(counter));
    //
    //    // Load a pseudo-random 32 bit unsigned integer into the netfilter register.
    //    random_rule.add_expr(&nft_expr!(meta random));
    //    // Check if the random integer is larger than `u32::MAX/2`, thus having 50% chance of success.
    //    random_rule.add_expr(&nft_expr!(cmp > (::std::u32::MAX / 2).to_be()));
    //
    //    // Add a second counter. This will only be incremented for the packets passing the random check.
    //    random_rule.add_expr(&nft_expr!(counter));
    //
    //    batch.add(&random_rule, rustables::MsgType::Add);
    //
    //    // === FINALIZE THE TRANSACTION AND SEND THE DATA TO NETFILTER ===
    //
    //    match batch.finalize() {
    //        Some(mut finalized_batch) => {
    //            send_batch(&mut finalized_batch).expect("Couldn't process the batch");
    //        }
    //        None => todo!(),
    //    }
}