aboutsummaryrefslogtreecommitdiff
path: root/rustables/examples/add-rules.rs
diff options
context:
space:
mode:
authorlafleur <lafleur@boum.org>2021-10-20 16:48:25 +0200
committerlafleur <lafleur@boum.org>2021-10-20 16:48:25 +0200
commitfe4161f2c9717720463783090b88f390a7f67264 (patch)
tree04ee66e4a9cdeca5ddbb6060cf86f5a6ec5009c9 /rustables/examples/add-rules.rs
parent0cea8e9638faf3f92fd9d42e85f543673c84a1c7 (diff)
adapt examples so that they compile
Would require a complete rewrite ; just doing this now so that we can test the CI.
Diffstat (limited to 'rustables/examples/add-rules.rs')
-rw-r--r--rustables/examples/add-rules.rs67
1 files changed, 37 insertions, 30 deletions
diff --git a/rustables/examples/add-rules.rs b/rustables/examples/add-rules.rs
index d114ef1..4fea491 100644
--- a/rustables/examples/add-rules.rs
+++ b/rustables/examples/add-rules.rs
@@ -37,11 +37,12 @@
//! ```
use ipnetwork::{IpNetwork, Ipv4Network};
-use nftnl::{nft_expr, nftnl_sys::libc, Batch, Chain, FinalizedBatch, ProtoFamily, Rule, Table};
+use rustables::{nft_expr, rustables_sys::libc, Batch, Chain, FinalizedBatch, ProtoFamily, Rule, Table};
use std::{
ffi::{self, CString},
io,
net::Ipv4Addr,
+ rc::Rc
};
const TABLE_NAME: &str = "example-table";
@@ -55,34 +56,37 @@ fn main() -> Result<(), Error> {
let mut batch = Batch::new();
// Create a netfilter table operating on both IPv4 and IPv6 (ProtoFamily::Inet)
- let table = Table::new(&CString::new(TABLE_NAME).unwrap(), ProtoFamily::Inet);
+ let table = Rc::new(Table::new(&CString::new(TABLE_NAME).unwrap(), 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(&table, nftnl::MsgType::Add);
+ batch.add(&Rc::clone(&table), rustables::MsgType::Add);
// Create input and output chains under the table we created above.
- let mut out_chain = Chain::new(&CString::new(OUT_CHAIN_NAME).unwrap(), &table);
- let mut in_chain = Chain::new(&CString::new(IN_CHAIN_NAME).unwrap(), &table);
-
// Hook the chains to the input and output event hooks, with highest priority (priority zero).
// See the `Chain::set_hook` documentation for details.
- out_chain.set_hook(nftnl::Hook::Out, 0);
- in_chain.set_hook(nftnl::Hook::In, 0);
+ let mut out_chain = Chain::new(&CString::new(OUT_CHAIN_NAME).unwrap(), Rc::clone(&table));
+ let mut in_chain = Chain::new(&CString::new(IN_CHAIN_NAME).unwrap(), 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(nftnl::Policy::Accept);
- in_chain.set_policy(nftnl::Policy::Accept);
+ 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(&out_chain, nftnl::MsgType::Add);
- batch.add(&in_chain, nftnl::MsgType::Add);
+ 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(&in_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")?;
@@ -103,11 +107,11 @@ fn main() -> Result<(), Error> {
allow_loopback_in_rule.add_expr(&nft_expr!(verdict accept));
// Add the rule to the batch.
- batch.add(&allow_loopback_in_rule, nftnl::MsgType::Add);
+ 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(&out_chain);
+ 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)?);
@@ -140,11 +144,11 @@ fn main() -> Result<(), Error> {
// 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, nftnl::MsgType::Add);
+ 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(&out_chain);
+ 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));
@@ -152,18 +156,18 @@ fn main() -> Result<(), Error> {
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(&nftnl::expr::Payload::Transport(
- nftnl::expr::TransportHeaderField::Icmpv6(nftnl::expr::Icmpv6HeaderField::Type),
+ 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(&nftnl::expr::Payload::Transport(
- nftnl::expr::TransportHeaderField::Icmpv6(nftnl::expr::Icmpv6HeaderField::Code),
+ 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, nftnl::MsgType::Add);
+ batch.add(&allow_router_solicitation, rustables::MsgType::Add);
// === FINALIZE THE TRANSACTION AND SEND THE DATA TO NETFILTER ===
@@ -171,11 +175,14 @@ fn main() -> Result<(), Error> {
// 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.
- let finalized_batch = batch.finalize();
-
- // Send the entire batch and process any returned messages.
- send_and_process(&finalized_batch)?;
- Ok(())
+ match batch.finalize() {
+ Some(mut finalized_batch) => {
+ // Send the entire batch and process any returned messages.
+ send_and_process(&mut finalized_batch)?;
+ Ok(())
+ },
+ None => todo!()
+ }
}
// Look up the interface index for a given interface name.
@@ -189,15 +196,15 @@ fn iface_index(name: &str) -> Result<libc::c_uint, Error> {
}
}
-fn send_and_process(batch: &FinalizedBatch) -> Result<(), Error> {
+fn send_and_process(batch: &mut FinalizedBatch) -> Result<(), Error> {
// Create a netlink socket to netfilter.
let socket = mnl::Socket::new(mnl::Bus::Netfilter)?;
// Send all the bytes in the batch.
- socket.send_all(batch)?;
+ socket.send_all(&mut *batch)?;
// Try to parse the messages coming back from netfilter. This part is still very unclear.
let portid = socket.portid();
- let mut buffer = vec![0; nftnl::nft_nlmsg_maxsize() as usize];
+ let mut buffer = vec![0; rustables::nft_nlmsg_maxsize() as usize];
let very_unclear_what_this_is_for = 2;
while let Some(message) = socket_recv(&socket, &mut buffer[..])? {
match mnl::cb_run(message, very_unclear_what_this_is_for, portid)? {