From 86a207a41724a7b9698c678d0b5de7498f68281e Mon Sep 17 00:00:00 2001 From: HimbeerserverDE Date: Fri, 14 Apr 2023 17:52:13 +0200 Subject: add dnat support --- Cargo.toml | 2 +- src/rule_methods.rs | 24 +++++++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8ca640a..371e1a7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rustables" -version = "0.9.0" +version = "0.10.0" authors = ["lafleur@boum.org", "Simon Thoby", "Mullvad VPN", "HimbeerserverDE"] license = "GPL-3.0-or-later" description = "Safe abstraction for libnftnl. Provides low-level userspace access to the in-kernel nf_tables subsystem" diff --git a/src/rule_methods.rs b/src/rule_methods.rs index ded8594..03d1c35 100644 --- a/src/rule_methods.rs +++ b/src/rule_methods.rs @@ -8,10 +8,10 @@ use crate::error::BuilderError; use crate::expr::ct::{ConnTrackState, Conntrack, ConntrackKey}; use crate::expr::{ Bitwise, Cmp, CmpOp, HighLevelPayload, IPv4HeaderField, IPv6HeaderField, Immediate, Masquerade, - Meta, MetaType, NetworkHeaderField, TCPHeaderField, TransportHeaderField, UDPHeaderField, - VerdictKind, + Meta, MetaType, Nat, NatType, NetworkHeaderField, Register, TCPHeaderField, + TransportHeaderField, UDPHeaderField, VerdictKind, }; -use crate::Rule; +use crate::{ProtocolFamily, Rule}; /// Simple protocol description. Note that it does not implement other layer 4 protocols as /// IGMP et al. See [`Rule::igmp`] for a workaround. @@ -229,6 +229,24 @@ impl Rule { self.add_expr(Masquerade {}); self } + /// Adds the `Nat` verdict to the rule, with type `DNat`. The packet + /// will have its destination address and optionally port rewritten. + pub fn dnat(mut self, dst: IpAddr, port: Option) -> Self { + self.add_expr(Immediate::new_data(ip_to_vec(dst), Register::Reg1)); + if let Some(port) = port { + self.add_expr(Immediate::new_data( + port.to_be_bytes().to_vec(), + Register::Reg2, + )); + } + self.add_expr(Nat { + nat_type: Some(NatType::DNat), + family: Some(ProtocolFamily::Inet), + ip_register: Some(Register::Reg1), + port_register: port.map(|_| Register::Reg2), + }); + self + } } /// Looks up the interface index for a given interface name. -- cgit v1.2.3