aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorSimon THOBY <git@nightmared.fr>2022-10-02 16:01:19 +0200
committerSimon THOBY <git@nightmared.fr>2022-10-02 16:01:19 +0200
commit3371865506cad4a795f07bce4495eb00d199f4a6 (patch)
tree7f468905fe7673dbb2d966f04ac0a535704c4db5 /examples
parentac59df84eb292f8e907fdae3436e589df164e826 (diff)
Add some initial support for tests with the full-rust engine
Diffstat (limited to 'examples')
-rw-r--r--examples/add-rules.rs277
-rw-r--r--examples/filter-ethernet.rs185
-rw-r--r--examples/firewall.rs236
3 files changed, 348 insertions, 350 deletions
diff --git a/examples/add-rules.rs b/examples/add-rules.rs
index 0f89601..0dee080 100644
--- a/examples/add-rules.rs
+++ b/examples/add-rules.rs
@@ -37,147 +37,148 @@
//! ```
use ipnetwork::{IpNetwork, Ipv4Network};
-use rustables::{nft_expr, query::send_batch, sys::libc, Batch, Chain, ProtoFamily, Rule, Table};
+//use rustables::{nft_expr, query::send_batch, sys::libc, Batch, Chain, ProtoFamily, Rule, Table};
use std::{ffi::CString, io, net::Ipv4Addr, rc::Rc};
-
-const TABLE_NAME: &str = "example-table";
-const OUT_CHAIN_NAME: &str = "chain-for-outgoing-packets";
-const IN_CHAIN_NAME: &str = "chain-for-incoming-packets";
+//
+//const TABLE_NAME: &str = "example-table";
+//const OUT_CHAIN_NAME: &str = "chain-for-outgoing-packets";
+//const IN_CHAIN_NAME: &str = "chain-for-incoming-packets";
fn main() -> Result<(), Error> {
- // Create a batch. This is used to store all the netlink messages we will later send.
- // Creating a new batch also automatically writes the initial batch begin message needed
- // to tell netlink this is a single transaction that might arrive over multiple netlink packets.
- let mut batch = Batch::new();
-
- // Create a netfilter table operating on both IPv4 and IPv6 (ProtoFamily::Inet)
- let table = Rc::new(Table::new(TABLE_NAME, ProtoFamily::Inet));
- // Add the table to the batch with the `MsgType::Add` type, thus instructing netfilter to add
- // this table under its `ProtoFamily::Inet` ruleset.
- batch.add(&Rc::clone(&table), rustables::MsgType::Add);
-
- // Create input and output chains under the table we created above.
- // Hook the chains to the input and output event hooks, with highest priority (priority zero).
- // See the `Chain::set_hook` documentation for details.
- let mut out_chain = Chain::new(OUT_CHAIN_NAME, Rc::clone(&table));
- let mut in_chain = Chain::new(IN_CHAIN_NAME, Rc::clone(&table));
-
- out_chain.set_hook(rustables::Hook::Out, 0);
- in_chain.set_hook(rustables::Hook::In, 0);
-
- // Set the default policies on the chains. If no rule matches a packet processed by the
- // `out_chain` or the `in_chain` it will accept the packet.
- out_chain.set_policy(rustables::Policy::Accept);
- in_chain.set_policy(rustables::Policy::Accept);
-
- let out_chain = Rc::new(out_chain);
- let in_chain = Rc::new(in_chain);
-
- // Add the two chains to the batch with the `MsgType` to tell netfilter to create the chains
- // under the table.
- batch.add(&Rc::clone(&out_chain), rustables::MsgType::Add);
- batch.add(&Rc::clone(&in_chain), rustables::MsgType::Add);
-
- // === ADD RULE ALLOWING ALL TRAFFIC TO THE LOOPBACK DEVICE ===
-
- // Create a new rule object under the input chain.
- let mut allow_loopback_in_rule = Rule::new(Rc::clone(&in_chain));
- // Lookup the interface index of the loopback interface.
- let lo_iface_index = iface_index("lo")?;
-
- // First expression to be evaluated in this rule is load the meta information "iif"
- // (incoming interface index) into the comparison register of netfilter.
- // When an incoming network packet is processed by this rule it will first be processed by this
- // expression, which will load the interface index of the interface the packet came from into
- // a special "register" in netfilter.
- allow_loopback_in_rule.add_expr(&nft_expr!(meta iif));
- // Next expression in the rule is to compare the value loaded into the register with our desired
- // interface index, and succeed only if it's equal. For any packet processed where the equality
- // does not hold the packet is said to not match this rule, and the packet moves on to be
- // processed by the next rule in the chain instead.
- allow_loopback_in_rule.add_expr(&nft_expr!(cmp == lo_iface_index));
-
- // Add a verdict expression to the rule. Any packet getting this far in the expression
- // processing without failing any expression will be given the verdict added here.
- allow_loopback_in_rule.add_expr(&nft_expr!(verdict accept));
-
- // Add the rule to the batch.
- batch.add(&allow_loopback_in_rule, rustables::MsgType::Add);
-
- // === ADD A RULE ALLOWING (AND COUNTING) ALL PACKETS TO THE 10.1.0.0/24 NETWORK ===
-
- let mut block_out_to_private_net_rule = Rule::new(Rc::clone(&out_chain));
- let private_net_ip = Ipv4Addr::new(10, 1, 0, 0);
- let private_net_prefix = 24;
- let private_net = IpNetwork::V4(Ipv4Network::new(private_net_ip, private_net_prefix)?);
-
- // Load the `nfproto` metadata into the netfilter register. This metadata denotes which layer3
- // protocol the packet being processed is using.
- block_out_to_private_net_rule.add_expr(&nft_expr!(meta nfproto));
- // Check if the currently processed packet is an IPv4 packet. This must be done before payload
- // data assuming the packet uses IPv4 can be loaded in the next expression.
- block_out_to_private_net_rule.add_expr(&nft_expr!(cmp == libc::NFPROTO_IPV4 as u8));
-
- // Load the IPv4 destination address into the netfilter register.
- block_out_to_private_net_rule.add_expr(&nft_expr!(payload ipv4 daddr));
- // Mask out the part of the destination address that is not part of the network bits. The result
- // of this bitwise masking is stored back into the same netfilter register.
- block_out_to_private_net_rule.add_expr(&nft_expr!(bitwise mask private_net.mask(), xor 0));
- // Compare the result of the masking with the IP of the network we are interested in.
- block_out_to_private_net_rule.add_expr(&nft_expr!(cmp == private_net.ip()));
-
- // Add a packet counter to the rule. Shows how many packets have been evaluated against this
- // expression. Since expressions are evaluated from first to last, putting this counter before
- // the above IP net check would make the counter increment on all packets also *not* matching
- // those expressions. Because the counter would then be evaluated before it fails a check.
- // Similarly, if the counter was added after the verdict it would always remain at zero. Since
- // when the packet hits the verdict expression any further processing of expressions stop.
- block_out_to_private_net_rule.add_expr(&nft_expr!(counter));
-
- // Accept all the packets matching the rule so far.
- block_out_to_private_net_rule.add_expr(&nft_expr!(verdict accept));
-
- // Add the rule to the batch. Without this nothing would be sent over netlink and netfilter,
- // and all the work on `block_out_to_private_net_rule` so far would go to waste.
- batch.add(&block_out_to_private_net_rule, rustables::MsgType::Add);
-
- // === ADD A RULE ALLOWING ALL OUTGOING ICMPv6 PACKETS WITH TYPE 133 AND CODE 0 ===
-
- let mut allow_router_solicitation = Rule::new(Rc::clone(&out_chain));
-
- // Check that the packet is IPv6 and ICMPv6
- allow_router_solicitation.add_expr(&nft_expr!(meta nfproto));
- allow_router_solicitation.add_expr(&nft_expr!(cmp == libc::NFPROTO_IPV6 as u8));
- allow_router_solicitation.add_expr(&nft_expr!(meta l4proto));
- allow_router_solicitation.add_expr(&nft_expr!(cmp == libc::IPPROTO_ICMPV6 as u8));
-
- allow_router_solicitation.add_expr(&rustables::expr::Payload::Transport(
- rustables::expr::TransportHeaderField::Icmpv6(rustables::expr::Icmpv6HeaderField::Type),
- ));
- allow_router_solicitation.add_expr(&nft_expr!(cmp == 133u8));
- allow_router_solicitation.add_expr(&rustables::expr::Payload::Transport(
- rustables::expr::TransportHeaderField::Icmpv6(rustables::expr::Icmpv6HeaderField::Code),
- ));
- allow_router_solicitation.add_expr(&nft_expr!(cmp == 0u8));
-
- allow_router_solicitation.add_expr(&nft_expr!(verdict accept));
-
- batch.add(&allow_router_solicitation, rustables::MsgType::Add);
-
- // === FINALIZE THE TRANSACTION AND SEND THE DATA TO NETFILTER ===
-
- // Finalize the batch. This means the batch end message is written into the batch, telling
- // netfilter the we reached the end of the transaction message. It's also converted to a type
- // that implements `IntoIterator<Item = &'a [u8]>`, thus allowing us to get the raw netlink data
- // out so it can be sent over a netlink socket to netfilter.
- match batch.finalize() {
- Some(mut finalized_batch) => {
- // Send the entire batch and process any returned messages.
- send_batch(&mut finalized_batch)?;
- Ok(())
- }
- None => todo!(),
- }
+ // // Create a batch. This is used to store all the netlink messages we will later send.
+ // // Creating a new batch also automatically writes the initial batch begin message needed
+ // // to tell netlink this is a single transaction that might arrive over multiple netlink packets.
+ // let mut batch = Batch::new();
+ //
+ // // Create a netfilter table operating on both IPv4 and IPv6 (ProtoFamily::Inet)
+ // let table = Rc::new(Table::new(TABLE_NAME, ProtoFamily::Inet));
+ // // Add the table to the batch with the `MsgType::Add` type, thus instructing netfilter to add
+ // // this table under its `ProtoFamily::Inet` ruleset.
+ // batch.add(&Rc::clone(&table), rustables::MsgType::Add);
+ //
+ // // Create input and output chains under the table we created above.
+ // // Hook the chains to the input and output event hooks, with highest priority (priority zero).
+ // // See the `Chain::set_hook` documentation for details.
+ // let mut out_chain = Chain::new(OUT_CHAIN_NAME, Rc::clone(&table));
+ // let mut in_chain = Chain::new(IN_CHAIN_NAME, Rc::clone(&table));
+ //
+ // out_chain.set_hook(rustables::Hook::Out, 0);
+ // in_chain.set_hook(rustables::Hook::In, 0);
+ //
+ // // Set the default policies on the chains. If no rule matches a packet processed by the
+ // // `out_chain` or the `in_chain` it will accept the packet.
+ // out_chain.set_policy(rustables::Policy::Accept);
+ // in_chain.set_policy(rustables::Policy::Accept);
+ //
+ // let out_chain = Rc::new(out_chain);
+ // let in_chain = Rc::new(in_chain);
+ //
+ // // Add the two chains to the batch with the `MsgType` to tell netfilter to create the chains
+ // // under the table.
+ // batch.add(&Rc::clone(&out_chain), rustables::MsgType::Add);
+ // batch.add(&Rc::clone(&in_chain), rustables::MsgType::Add);
+ //
+ // // === ADD RULE ALLOWING ALL TRAFFIC TO THE LOOPBACK DEVICE ===
+ //
+ // // Create a new rule object under the input chain.
+ // let mut allow_loopback_in_rule = Rule::new(Rc::clone(&in_chain));
+ // // Lookup the interface index of the loopback interface.
+ // let lo_iface_index = iface_index("lo")?;
+ //
+ // // First expression to be evaluated in this rule is load the meta information "iif"
+ // // (incoming interface index) into the comparison register of netfilter.
+ // // When an incoming network packet is processed by this rule it will first be processed by this
+ // // expression, which will load the interface index of the interface the packet came from into
+ // // a special "register" in netfilter.
+ // allow_loopback_in_rule.add_expr(&nft_expr!(meta iif));
+ // // Next expression in the rule is to compare the value loaded into the register with our desired
+ // // interface index, and succeed only if it's equal. For any packet processed where the equality
+ // // does not hold the packet is said to not match this rule, and the packet moves on to be
+ // // processed by the next rule in the chain instead.
+ // allow_loopback_in_rule.add_expr(&nft_expr!(cmp == lo_iface_index));
+ //
+ // // Add a verdict expression to the rule. Any packet getting this far in the expression
+ // // processing without failing any expression will be given the verdict added here.
+ // allow_loopback_in_rule.add_expr(&nft_expr!(verdict accept));
+ //
+ // // Add the rule to the batch.
+ // batch.add(&allow_loopback_in_rule, rustables::MsgType::Add);
+ //
+ // // === ADD A RULE ALLOWING (AND COUNTING) ALL PACKETS TO THE 10.1.0.0/24 NETWORK ===
+ //
+ // let mut block_out_to_private_net_rule = Rule::new(Rc::clone(&out_chain));
+ // let private_net_ip = Ipv4Addr::new(10, 1, 0, 0);
+ // let private_net_prefix = 24;
+ // let private_net = IpNetwork::V4(Ipv4Network::new(private_net_ip, private_net_prefix)?);
+ //
+ // // Load the `nfproto` metadata into the netfilter register. This metadata denotes which layer3
+ // // protocol the packet being processed is using.
+ // block_out_to_private_net_rule.add_expr(&nft_expr!(meta nfproto));
+ // // Check if the currently processed packet is an IPv4 packet. This must be done before payload
+ // // data assuming the packet uses IPv4 can be loaded in the next expression.
+ // block_out_to_private_net_rule.add_expr(&nft_expr!(cmp == libc::NFPROTO_IPV4 as u8));
+ //
+ // // Load the IPv4 destination address into the netfilter register.
+ // block_out_to_private_net_rule.add_expr(&nft_expr!(payload ipv4 daddr));
+ // // Mask out the part of the destination address that is not part of the network bits. The result
+ // // of this bitwise masking is stored back into the same netfilter register.
+ // block_out_to_private_net_rule.add_expr(&nft_expr!(bitwise mask private_net.mask(), xor 0));
+ // // Compare the result of the masking with the IP of the network we are interested in.
+ // block_out_to_private_net_rule.add_expr(&nft_expr!(cmp == private_net.ip()));
+ //
+ // // Add a packet counter to the rule. Shows how many packets have been evaluated against this
+ // // expression. Since expressions are evaluated from first to last, putting this counter before
+ // // the above IP net check would make the counter increment on all packets also *not* matching
+ // // those expressions. Because the counter would then be evaluated before it fails a check.
+ // // Similarly, if the counter was added after the verdict it would always remain at zero. Since
+ // // when the packet hits the verdict expression any further processing of expressions stop.
+ // block_out_to_private_net_rule.add_expr(&nft_expr!(counter));
+ //
+ // // Accept all the packets matching the rule so far.
+ // block_out_to_private_net_rule.add_expr(&nft_expr!(verdict accept));
+ //
+ // // Add the rule to the batch. Without this nothing would be sent over netlink and netfilter,
+ // // and all the work on `block_out_to_private_net_rule` so far would go to waste.
+ // batch.add(&block_out_to_private_net_rule, rustables::MsgType::Add);
+ //
+ // // === ADD A RULE ALLOWING ALL OUTGOING ICMPv6 PACKETS WITH TYPE 133 AND CODE 0 ===
+ //
+ // let mut allow_router_solicitation = Rule::new(Rc::clone(&out_chain));
+ //
+ // // Check that the packet is IPv6 and ICMPv6
+ // allow_router_solicitation.add_expr(&nft_expr!(meta nfproto));
+ // allow_router_solicitation.add_expr(&nft_expr!(cmp == libc::NFPROTO_IPV6 as u8));
+ // allow_router_solicitation.add_expr(&nft_expr!(meta l4proto));
+ // allow_router_solicitation.add_expr(&nft_expr!(cmp == libc::IPPROTO_ICMPV6 as u8));
+ //
+ // allow_router_solicitation.add_expr(&rustables::expr::Payload::Transport(
+ // rustables::expr::TransportHeaderField::Icmpv6(rustables::expr::Icmpv6HeaderField::Type),
+ // ));
+ // allow_router_solicitation.add_expr(&nft_expr!(cmp == 133u8));
+ // allow_router_solicitation.add_expr(&rustables::expr::Payload::Transport(
+ // rustables::expr::TransportHeaderField::Icmpv6(rustables::expr::Icmpv6HeaderField::Code),
+ // ));
+ // allow_router_solicitation.add_expr(&nft_expr!(cmp == 0u8));
+ //
+ // allow_router_solicitation.add_expr(&nft_expr!(verdict accept));
+ //
+ // batch.add(&allow_router_solicitation, rustables::MsgType::Add);
+ //
+ // // === FINALIZE THE TRANSACTION AND SEND THE DATA TO NETFILTER ===
+ //
+ // // Finalize the batch. This means the batch end message is written into the batch, telling
+ // // netfilter the we reached the end of the transaction message. It's also converted to a type
+ // // that implements `IntoIterator<Item = &'a [u8]>`, thus allowing us to get the raw netlink data
+ // // out so it can be sent over a netlink socket to netfilter.
+ // match batch.finalize() {
+ // Some(mut finalized_batch) => {
+ // // Send the entire batch and process any returned messages.
+ // send_batch(&mut finalized_batch)?;
+ // Ok(())
+ // }
+ // None => todo!(),
+ // }
+ Ok(())
}
// Look up the interface index for a given interface name.
diff --git a/examples/filter-ethernet.rs b/examples/filter-ethernet.rs
index 41454c9..732c8cb 100644
--- a/examples/filter-ethernet.rs
+++ b/examples/filter-ethernet.rs
@@ -1,96 +1,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};
+///! 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];
-
+//
+//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!(),
- }
+ // // 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!(),
+ // }
}
diff --git a/examples/firewall.rs b/examples/firewall.rs
index 46a0a4d..fc25010 100644
--- a/examples/firewall.rs
+++ b/examples/firewall.rs
@@ -1,12 +1,11 @@
-use rustables::{Batch, Chain, ChainMethods, Hook, MatchError, ProtoFamily,
- Protocol, Rule, RuleMethods, Table, MsgType, Policy};
-use rustables::query::{send_batch, Error as QueryError};
-use rustables::expr::{LogGroup, LogPrefix, LogPrefixError};
+//use rustables::{Batch, Chain, ChainMethods, Hook, MatchError, ProtoFamily,
+// Protocol, Rule, RuleMethods, Table, MsgType, Policy};
+//use rustables::query::{send_batch, Error as QueryError};
+//use rustables::expr::{LogGroup, LogPrefix, LogPrefixError};
use ipnetwork::IpNetwork;
use std::ffi::{CString, NulError};
-use std::str::Utf8Error;
use std::rc::Rc;
-
+use std::str::Utf8Error;
#[derive(thiserror::Error, Debug)]
pub enum Error {
@@ -16,127 +15,126 @@ pub enum Error {
AlreadyDone,
#[error("Error converting from a C String")]
NulError(#[from] NulError),
- #[error("Error creating match")]
- MatchError(#[from] MatchError),
+ //#[error("Error creating match")]
+ //MatchError(#[from] MatchError),
#[error("Error converting to utf-8 string")]
Utf8Error(#[from] Utf8Error),
#[error("Error applying batch")]
BatchError(#[from] std::io::Error),
- #[error("Error applying batch")]
- QueryError(#[from] QueryError),
- #[error("Error encoding the prefix")]
- LogPrefixError(#[from] LogPrefixError),
+ //#[error("Error applying batch")]
+ //QueryError(#[from] QueryError),
+ //#[error("Error encoding the prefix")]
+ //LogPrefixError(#[from] LogPrefixError),
}
const TABLE_NAME: &str = "main-table";
-
fn main() -> Result<(), Error> {
- let fw = Firewall::new()?;
- fw.start()?;
+ // let fw = Firewall::new()?;
+ // fw.start()?;
Ok(())
}
-
-
-/// An example firewall. See the source of its `start()` method.
-pub struct Firewall {
- batch: Batch,
- inbound: Rc<Chain>,
- _outbound: Rc<Chain>,
- _forward: Rc<Chain>,
- table: Rc<Table>,
-}
-
-impl Firewall {
- pub fn new() -> Result<Self, Error> {
- let mut batch = Batch::new();
- let table = Rc::new(
- Table::new(&CString::new(TABLE_NAME)?, ProtoFamily::Inet)
- );
- batch.add(&table, MsgType::Add);
-
- // Create base chains. Base chains are hooked into a Direction/Hook.
- let inbound = Rc::new(
- Chain::from_hook(Hook::In, Rc::clone(&table))
- .verdict(Policy::Drop)
- .add_to_batch(&mut batch)
- );
- let _outbound = Rc::new(
- Chain::from_hook(Hook::Out, Rc::clone(&table))
- .verdict(Policy::Accept)
- .add_to_batch(&mut batch)
- );
- let _forward = Rc::new(
- Chain::from_hook(Hook::Forward, Rc::clone(&table))
- .verdict(Policy::Accept)
- .add_to_batch(&mut batch)
- );
-
- Ok(Firewall {
- table,
- batch,
- inbound,
- _outbound,
- _forward
- })
- }
- /// Allow some common-sense exceptions to inbound drop, and accept outbound and forward.
- pub fn start(mut self) -> Result<(), Error> {
- // Allow all established connections to get in.
- Rule::new(Rc::clone(&self.inbound))
- .established()
- .accept()
- .add_to_batch(&mut self.batch);
- // Allow all traffic on the loopback interface.
- Rule::new(Rc::clone(&self.inbound))
- .iface("lo")?
- .accept()
- .add_to_batch(&mut self.batch);
- // Allow ssh from anywhere, and log to dmesg with a prefix.
- Rule::new(Rc::clone(&self.inbound))
- .dport("22", &Protocol::TCP)?
- .accept()
- .log(None, Some(LogPrefix::new("allow ssh connection:")?))
- .add_to_batch(&mut self.batch);
-
- // Allow http from all IPs in 192.168.1.255/24 .
- let local_net = IpNetwork::new([192, 168, 1, 0].into(), 24).unwrap();
- Rule::new(Rc::clone(&self.inbound))
- .dport("80", &Protocol::TCP)?
- .snetwork(local_net)
- .accept()
- .add_to_batch(&mut self.batch);
-
- // Allow ICMP traffic, drop IGMP.
- Rule::new(Rc::clone(&self.inbound))
- .icmp()
- .accept()
- .add_to_batch(&mut self.batch);
- Rule::new(Rc::clone(&self.inbound))
- .igmp()
- .drop()
- .add_to_batch(&mut self.batch);
-
- // Log all traffic not accepted to NF_LOG group 1, accessible with ulogd.
- Rule::new(Rc::clone(&self.inbound))
- .log(Some(LogGroup(1)), None)
- .add_to_batch(&mut self.batch);
-
- let mut finalized_batch = self.batch.finalize().unwrap();
- send_batch(&mut finalized_batch)?;
- println!("table {} commited", TABLE_NAME);
- Ok(())
- }
- /// If there is any table with name TABLE_NAME, remove it.
- pub fn stop(mut self) -> Result<(), Error> {
- self.batch.add(&self.table, MsgType::Add);
- self.batch.add(&self.table, MsgType::Del);
-
- let mut finalized_batch = self.batch.finalize().unwrap();
- send_batch(&mut finalized_batch)?;
- println!("table {} destroyed", TABLE_NAME);
- Ok(())
- }
-}
-
-
+//
+//
+///// An example firewall. See the source of its `start()` method.
+//pub struct Firewall {
+// batch: Batch,
+// inbound: Rc<Chain>,
+// _outbound: Rc<Chain>,
+// _forward: Rc<Chain>,
+// table: Rc<Table>,
+//}
+//
+//impl Firewall {
+// pub fn new() -> Result<Self, Error> {
+// let mut batch = Batch::new();
+// let table = Rc::new(
+// Table::new(&CString::new(TABLE_NAME)?, ProtoFamily::Inet)
+// );
+// batch.add(&table, MsgType::Add);
+//
+// // Create base chains. Base chains are hooked into a Direction/Hook.
+// let inbound = Rc::new(
+// Chain::from_hook(Hook::In, Rc::clone(&table))
+// .verdict(Policy::Drop)
+// .add_to_batch(&mut batch)
+// );
+// let _outbound = Rc::new(
+// Chain::from_hook(Hook::Out, Rc::clone(&table))
+// .verdict(Policy::Accept)
+// .add_to_batch(&mut batch)
+// );
+// let _forward = Rc::new(
+// Chain::from_hook(Hook::Forward, Rc::clone(&table))
+// .verdict(Policy::Accept)
+// .add_to_batch(&mut batch)
+// );
+//
+// Ok(Firewall {
+// table,
+// batch,
+// inbound,
+// _outbound,
+// _forward
+// })
+// }
+// /// Allow some common-sense exceptions to inbound drop, and accept outbound and forward.
+// pub fn start(mut self) -> Result<(), Error> {
+// // Allow all established connections to get in.
+// Rule::new(Rc::clone(&self.inbound))
+// .established()
+// .accept()
+// .add_to_batch(&mut self.batch);
+// // Allow all traffic on the loopback interface.
+// Rule::new(Rc::clone(&self.inbound))
+// .iface("lo")?
+// .accept()
+// .add_to_batch(&mut self.batch);
+// // Allow ssh from anywhere, and log to dmesg with a prefix.
+// Rule::new(Rc::clone(&self.inbound))
+// .dport("22", &Protocol::TCP)?
+// .accept()
+// .log(None, Some(LogPrefix::new("allow ssh connection:")?))
+// .add_to_batch(&mut self.batch);
+//
+// // Allow http from all IPs in 192.168.1.255/24 .
+// let local_net = IpNetwork::new([192, 168, 1, 0].into(), 24).unwrap();
+// Rule::new(Rc::clone(&self.inbound))
+// .dport("80", &Protocol::TCP)?
+// .snetwork(local_net)
+// .accept()
+// .add_to_batch(&mut self.batch);
+//
+// // Allow ICMP traffic, drop IGMP.
+// Rule::new(Rc::clone(&self.inbound))
+// .icmp()
+// .accept()
+// .add_to_batch(&mut self.batch);
+// Rule::new(Rc::clone(&self.inbound))
+// .igmp()
+// .drop()
+// .add_to_batch(&mut self.batch);
+//
+// // Log all traffic not accepted to NF_LOG group 1, accessible with ulogd.
+// Rule::new(Rc::clone(&self.inbound))
+// .log(Some(LogGroup(1)), None)
+// .add_to_batch(&mut self.batch);
+//
+// let mut finalized_batch = self.batch.finalize().unwrap();
+// send_batch(&mut finalized_batch)?;
+// println!("table {} commited", TABLE_NAME);
+// Ok(())
+// }
+// /// If there is any table with name TABLE_NAME, remove it.
+// pub fn stop(mut self) -> Result<(), Error> {
+// self.batch.add(&self.table, MsgType::Add);
+// self.batch.add(&self.table, MsgType::Del);
+//
+// let mut finalized_batch = self.batch.finalize().unwrap();
+// send_batch(&mut finalized_batch)?;
+// println!("table {} destroyed", TABLE_NAME);
+// Ok(())
+// }
+//}
+//
+//