aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib.rs2
-rw-r--r--src/rule_match.rs25
2 files changed, 20 insertions, 7 deletions
diff --git a/src/lib.rs b/src/lib.rs
index c42c5a2..984eec7 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -117,7 +117,7 @@ pub use rule::Rule;
pub use rule::{get_rules_cb, list_rules_for_chain};
mod rule_match;
-pub use rule_match::{Match, Protocol, Error as MatchError};
+pub use rule_match::{iface_index, Match, Protocol, Error as MatchError};
pub mod set;
diff --git a/src/rule_match.rs b/src/rule_match.rs
index 35c71b6..f60f8c0 100644
--- a/src/rule_match.rs
+++ b/src/rule_match.rs
@@ -18,6 +18,8 @@ pub enum Error {
NoSuchIface,
#[error("Error converting from a string to an integer")]
ParseError(#[from] ParseIntError),
+ #[error("the interface name is too long")]
+ NameTooLong,
}
@@ -62,9 +64,12 @@ pub trait Match {
where Self: std::marker::Sized;
/// Match packets in an already established connections.
fn established(self) -> Self where Self: std::marker::Sized;
- /// Match packets going through `interface`. `iface_name` is an interface name, as in
- /// "wlan0" or "lo".
- fn iface(self, ifacename: &str) -> Result<Self, Error>
+ /// Match packets going through `iface_index`. Interface indexes can be queried with
+ /// `iface_index()`.
+ fn iface_id(self, iface_index: libc::c_uint) -> Result<Self, Error>
+ where Self: std::marker::Sized;
+ /// Match packets going through `iface_name`, an interface name, as in "wlan0" or "lo".
+ fn iface(self, iface_name: &str) -> Result<Self, Error>
where Self: std::marker::Sized;
/// Add a log instruction to the rule. `group` is the NFLog group, `prefix` is a prefix
/// appended to each log line.
@@ -130,12 +135,20 @@ impl Match for Rule {
self.add_expr(&nft_expr!(cmp != 0u32));
self
}
- fn iface(mut self, iface_name: &str) -> Result<Self, Error> {
- let iface_index = iface_index(iface_name)?;
+ fn iface_id(mut self, iface_index: libc::c_uint) -> Result<Self, Error> {
self.add_expr(&nft_expr!(meta iif));
self.add_expr(&nft_expr!(cmp == iface_index));
Ok(self)
}
+ fn iface(mut self, iface_name: &str) -> Result<Self, Error> {
+ if iface_name.len() > libc::IFNAMSIZ {
+ return Err(Error::NameTooLong);
+ }
+
+ self.add_expr(&nft_expr!(meta iifname));
+ self.add_expr(&nft_expr!(cmp == CString::new(iface_name)?.as_bytes()));
+ Ok(self)
+ }
fn saddr(mut self, ip: IpAddr) -> Self {
self.add_expr(&nft_expr!(meta nfproto));
match ip {
@@ -202,7 +215,7 @@ impl Match for Rule {
}
/// Look up the interface index for a given interface name.
-fn iface_index(name: &str) -> Result<libc::c_uint, Error> {
+pub fn iface_index(name: &str) -> Result<libc::c_uint, Error> {
let c_name = CString::new(name)?;
let index = unsafe { libc::if_nametoindex(c_name.as_ptr()) };
match index {