summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/log.rs29
-rw-r--r--src/main.rs217
-rw-r--r--src/opt.rs165
-rw-r--r--src/pkt.rs112
-rw-r--r--src/platform/linux.rs29
5 files changed, 283 insertions, 269 deletions
diff --git a/src/log.rs b/src/log.rs
index d4cd1e7..639a0e0 100644
--- a/src/log.rs
+++ b/src/log.rs
@@ -1,4 +1,4 @@
-// Copyright 2025 Dillution <[email protected]>.
+// Copyright 2025-2026 Dillution <[email protected]>.
//
// This file is part of DPIBreak.
//
@@ -16,7 +16,6 @@
// along with DPIBreak. If not, see <https://www.gnu.org/licenses/>.
use std::fmt;
-use std::sync::OnceLock;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum LogLevel {
@@ -26,18 +25,6 @@ pub enum LogLevel {
Error, // Unrecoverable
}
-const DEFAULT_LOG_LEVEL: LogLevel = LogLevel::Warning;
-
-static LOG_LEVEL_OVERRIDE: OnceLock<LogLevel> = OnceLock::new();
-
-pub fn set_log_level(level: LogLevel) -> Result<(), &'static str> {
- LOG_LEVEL_OVERRIDE.set(level).map_err(|_| "LOG_LEVEL already initialized")
-}
-
-pub fn current_log_level() -> LogLevel {
- *LOG_LEVEL_OVERRIDE.get().unwrap_or(&DEFAULT_LOG_LEVEL)
-}
-
impl fmt::Display for LogLevel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let p = match self {
@@ -74,20 +61,10 @@ impl std::str::FromStr for LogLevel {
}
}
-static NO_SPLASH: OnceLock<bool> = OnceLock::new();
-
-pub fn set_no_splash(no_splash: bool) -> Result<(), &'static str> {
- NO_SPLASH.set(no_splash).map_err(|_| "NO_SPLASH already initialized")
-}
-
-pub fn no_splash() -> bool {
- *NO_SPLASH.get().unwrap_or(&false)
-}
-
#[macro_export]
macro_rules! log_println {
($level:expr, $($arg:tt)*) => {{
- if $level >= crate::log::current_log_level() {
+ if $level >= crate::opt::log_level() {
println!("{} {}", $level, format_args!($($arg)*));
}
}};
@@ -96,7 +73,7 @@ macro_rules! log_println {
#[macro_export]
macro_rules! splash {
($($arg:tt)*) => {{
- if !crate::log::no_splash() {
+ if !crate::opt::no_splash() {
println!($($arg)*);
}
}};
diff --git a/src/main.rs b/src/main.rs
index ab7becc..a36bd48 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -15,16 +15,16 @@
// You should have received a copy of the GNU General Public License
// along with DPIBreak. If not, see <https://www.gnu.org/licenses/>.
-use anyhow::{Result, anyhow, Context};
+use anyhow::{Result, Context};
use std::sync::{
atomic::{Ordering, AtomicBool},
- OnceLock,
};
mod platform;
mod pkt;
mod tls;
mod log;
+mod opt;
use log::LogLevel;
@@ -36,211 +36,6 @@ const MESSAGE_AT_RUN: &str = r#"DPIBreak is now running.
Press Ctrl+C or close this window to stop.
"#;
static RUNNING: AtomicBool = AtomicBool::new(true);
-static OPT_DELAY_MS: OnceLock<u64> = OnceLock::new();
-
-static OPT_FAKE: OnceLock<bool> = OnceLock::new();
-
-fn opt_fake() -> bool {
- *crate::OPT_FAKE.get().expect("OPT_FAKE not initialized")
-}
-
-fn delay_ms() -> u64 {
- *OPT_DELAY_MS.get().expect("OPT_DELAY_MS not initialized")
-}
-
-fn split_packet(
- view: &pkt::PktView,
- start: u32,
- end: Option<u32>,
- out_buf: &mut Vec<u8>
-) -> Result<()> {
- pkt::split_packet_0(view, start, end, out_buf, None, None, None)
-}
-
-fn send_segment(
- view: &pkt::PktView,
- start: u32,
- end: Option<u32>,
- buf: &mut Vec<u8>
-) -> Result<()> {
- use platform::send_to_raw;
-
- if opt_fake() {
- pkt::fake_clienthello(view, start, end, buf)?;
- send_to_raw(buf)?;
- }
- split_packet(view, start, end, buf)?;
- send_to_raw(buf)?;
-
- Ok(())
-}
-
-fn split_packet_1(view: &pkt::PktView, order: &[u32], buf: &mut Vec<u8>) -> Result<()> {
- let mut it = order.iter().copied();
-
- let Some(mut first) = it.next() else {
- return Err(anyhow!("split_packet_1: invalid order array"));
- };
-
- for next in it {
- send_segment(view, first, Some(next), buf)?;
- std::thread::sleep(std::time::Duration::from_millis(delay_ms()));
- first = next;
- }
-
- send_segment(view, first, None, buf)?;
-
- Ok(())
-}
-
-/// Return Ok(true) if packet is handled
-fn handle_packet(pkt: &[u8], buf: &mut Vec::<u8>) -> Result<bool> {
- #[cfg(target_os = "linux")]
- let is_filtered = platform::IS_U32_SUPPORTED.load(Ordering::Relaxed);
-
- #[cfg(windows)]
- let is_filtered = true;
-
- let view = pkt::PktView::from_raw(pkt)?;
-
- if !is_filtered && !tls::is_client_hello(view.tcp.payload()) {
- return Ok(false);
- }
-
- // TODO: if clienthello packet has been (unlikely) fragmented,
- // we should find the second part and drop, reassemble it here.
-
- split_packet_1(&view, &[0, 1], buf)?;
-
- #[cfg(debug_assertions)]
- log_println!(LogLevel::Debug, "packet is handled, len={}", pkt.len());
-
- Ok(true)
-}
-
-#[macro_export]
-macro_rules! handle_packet {
- ($bytes:expr, $buf:expr, handled => $on_handled:expr, rejected => $on_rejected:expr $(,)?) => {{
- match handle_packet($bytes, $buf) {
- Ok(true) => { $on_handled }
- Ok(false) => { $on_rejected }
- Err(e) => {
- log_println!(LogLevel::Warning, "handle_packet: {e}");
- $on_rejected
- }
- }
- }};
-}
-
-fn take_value<T, I>(args: &mut I, arg_name: &str) -> Result<T>
-where
- T: std::str::FromStr,
- T::Err: std::error::Error + Send + Sync + 'static,
- I: Iterator<Item = String>,
-{
- let raw = args
- .next()
- .ok_or_else(|| anyhow!("argument: missing value after {}", arg_name))?;
- raw.parse::<T>()
- .with_context(|| format!("argument {}: invalid value '{}'", arg_name, raw))
-}
-
-fn usage() {
- println!(
- r#"Usage: dpibreak [OPTIONS]
-
-Options:
- --delay-ms <u64> (default: 0)
- --queue-num <u16> (linux only, default: 1)
- --nft-command <string> (linux only, default: nft)
- --loglevel <debug|info|warning|error> (default: warning)
- --no-splash Do not print splash messages
-
- --fake Enable fake clienthello injection
- --fake-ttl <u8> Override ttl of fake clienthello (default: 8)
- --fake-badsum Modifies the TCP checksum of the fake packet to an invalid value.
-
- -h, --help Show this help"#
- );
-}
-
-fn set_opt<T: std::fmt::Display>(
- name: &str,
- cell: &OnceLock<T>,
- value: T,
-) -> Result<()> {
- log_println!(LogLevel::Info, "{name}: {value}");
- cell.set(value).map_err(|_| anyhow!("{name} already initialized"))
-}
-
-fn splash_banner() {
- splash!("{PROJECT_NAME} v{PKG_VERSION} - {PKG_DESCRIPTION}");
- splash!("{PKG_HOMEPAGE}");
- splash!("");
-}
-
-fn parse_args_1() -> Result<()> {
- let mut delay_ms: u64 = 0;
- let mut no_splash: bool = false;
- let mut fake: bool = false;
- let mut fake_ttl: u8 = 8;
- let mut fake_badsum: bool = false;
-
- #[cfg(debug_assertions)]
- let mut log_level: log::LogLevel = LogLevel::Debug;
- #[cfg(not(debug_assertions))]
- let mut log_level: log::LogLevel = LogLevel::Warning;
- #[cfg(target_os = "linux")]
- let mut queue_num: u16 = 1;
- #[cfg(target_os = "linux")]
- let mut nft_command = String::from("nft");
-
- let mut args = std::env::args().skip(1); // program name
-
- while let Some(arg) = args.next() {
- let argv = arg.as_str();
-
- match argv {
- "-h" | "--help" => { usage(); std::process::exit(0); }
- "--delay-ms" => { delay_ms = take_value(&mut args, argv)?; }
- "--loglevel" => { log_level = take_value(&mut args, argv)?; }
- "--no-splash" => { no_splash = true; }
-
- "--fake" => { fake = true; }
- "--fake-ttl" => { fake_ttl = take_value(&mut args, argv)?; }
- "--fake-badsum" => { fake_badsum = true }
-
- #[cfg(target_os = "linux")]
- "--queue-num" => { queue_num = take_value(&mut args, argv)?; }
-
- #[cfg(target_os = "linux")]
- "--nft-command" => { nft_command = take_value(&mut args, argv)?; }
-
- _ => { return Err(anyhow!("argument: unknown: {}", arg)); }
- }
- }
-
- log::set_no_splash(no_splash).map_err(|e| anyhow!("{e}"))?;
- log::set_log_level(log_level).map_err(|e| anyhow!("{e}"))?;
-
- set_opt("OPT_DELAY_MS", &OPT_DELAY_MS, delay_ms)?;
- set_opt("OPT_FAKE", &OPT_FAKE, fake)?;
- set_opt("OPT_FAKE_TTL", &pkt::OPT_FAKE_TTL, fake_ttl)?;
- set_opt("OPT_FAKE_BADSUM", &pkt::OPT_FAKE_BADSUM, fake_badsum)?;
-
- #[cfg(target_os = "linux")] set_opt("OPT_QUEUE_NUM", &platform::OPT_QUEUE_NUM, queue_num)?;
- #[cfg(target_os = "linux")] set_opt("OPT_NFT_COMMAND", &platform::OPT_NFT_COMMAND, nft_command)?;
-
- Ok(())
-}
-
-fn parse_args() {
- if let Err(e) = parse_args_1() {
- log_println!(LogLevel::Error, "{e}");
- usage();
- std::process::exit(1);
- }
-}
fn trap_exit() -> Result<()> {
ctrlc::set_handler(|| {
@@ -261,9 +56,15 @@ impl Drop for EnsureCleanup {
}
}
+fn splash_banner() {
+ splash!("{PROJECT_NAME} v{PKG_VERSION} - {PKG_DESCRIPTION}");
+ splash!("{PKG_HOMEPAGE}");
+ splash!("");
+}
+
fn main_0() -> Result<()> {
trap_exit()?;
- parse_args();
+ opt::parse_args();
splash_banner();
let _guard = EnsureCleanup;
diff --git a/src/opt.rs b/src/opt.rs
new file mode 100644
index 0000000..287f1d7
--- /dev/null
+++ b/src/opt.rs
@@ -0,0 +1,165 @@
+// SPDX-FileCopyrightText: 2026 Dilluti0n <[email protected]>
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+use anyhow::{Result, anyhow, Context};
+use std::sync::OnceLock;
+
+use crate::log_println;
+
+use crate::log;
+
+use log::LogLevel;
+
+static OPT_NO_SPLASH: OnceLock<bool> = OnceLock::new();
+static OPT_LOG_LEVEL: OnceLock<LogLevel> = OnceLock::new();
+
+static OPT_FAKE_TTL: OnceLock<u8> = OnceLock::new();
+static OPT_FAKE_BADSUM: OnceLock<bool> = OnceLock::new();
+static OPT_FAKE: OnceLock<bool> = OnceLock::new();
+
+static OPT_DELAY_MS: OnceLock<u64> = OnceLock::new();
+
+#[cfg(target_os = "linux")] static OPT_QUEUE_NUM: OnceLock<u16> = OnceLock::new();
+#[cfg(target_os = "linux")] static OPT_NFT_COMMAND: OnceLock<String> = OnceLock::new();
+
+pub fn no_splash() -> bool {
+ *OPT_NO_SPLASH.get().expect("OPT_NO_SPLASH not initialized")
+}
+
+pub fn log_level() -> LogLevel {
+ *OPT_LOG_LEVEL.get().expect("OPT_LOG_LEVEL not initialized")
+}
+
+pub fn fake() -> bool {
+ *OPT_FAKE.get().expect("OPT_FAKE not initialized")
+}
+
+pub fn fake_ttl() -> u8 {
+ *OPT_FAKE_TTL.get().expect("OPT_FAKE_TTL not initialized")
+}
+
+pub fn fake_badsum() -> bool {
+ *OPT_FAKE_BADSUM.get().expect("OPT_FAKE_BADSUM not initialized")
+}
+
+pub fn delay_ms() -> u64 {
+ *OPT_DELAY_MS.get().expect("OPT_DELAY_MS not initialized")
+}
+
+#[cfg(target_os = "linux")]
+pub fn queue_num() -> u16 {
+ *OPT_QUEUE_NUM.get().expect("OPT_QUEUE_NUM not initialized")
+}
+
+#[cfg(target_os = "linux")]
+pub fn nft_command() -> &'static str {
+ OPT_NFT_COMMAND.get().expect("OPT_NFT_COMMAND not initialized").as_str()
+}
+
+fn take_value<T, I>(args: &mut I, arg_name: &str) -> Result<T>
+where
+ T: std::str::FromStr,
+ T::Err: std::error::Error + Send + Sync + 'static,
+ I: Iterator<Item = String>,
+{
+ let raw = args
+ .next()
+ .ok_or_else(|| anyhow!("argument: missing value after {}", arg_name))?;
+ raw.parse::<T>()
+ .with_context(|| format!("argument {}: invalid value '{}'", arg_name, raw))
+}
+
+fn usage() {
+ println!(
+ r#"Usage: dpibreak [OPTIONS]
+
+Options:
+ --delay-ms <u64> (default: 0)
+ --queue-num <u16> (linux only, default: 1)
+ --nft-command <string> (linux only, default: nft)
+ --loglevel <debug|info|warning|error> (default: warning)
+ --no-splash Do not print splash messages
+
+ --fake Enable fake clienthello injection
+ --fake-ttl <u8> Override ttl of fake clienthello (default: 8)
+ --fake-badsum Modifies the TCP checksum of the fake packet to an invalid value.
+
+ -h, --help Show this help"#
+ );
+}
+
+fn set_opt<T: std::fmt::Display>(
+ name: &str,
+ cell: &OnceLock<T>,
+ value: T,
+) -> Result<()> {
+ cell.set(value).map_err(|_| anyhow!("{name} already initialized"))?;
+
+ let v = cell.get().expect("just set; qed");
+ log_println!(LogLevel::Info, "{name}: {v}");
+
+ Ok(())
+}
+
+fn parse_args_1() -> Result<()> {
+ let mut delay_ms: u64 = 0;
+ let mut no_splash: bool = false;
+ let mut fake: bool = false;
+ let mut fake_ttl: u8 = 8;
+ let mut fake_badsum: bool = false;
+
+ #[cfg(debug_assertions)]
+ let mut log_level: log::LogLevel = LogLevel::Debug;
+ #[cfg(not(debug_assertions))]
+ let mut log_level: log::LogLevel = LogLevel::Warning;
+ #[cfg(target_os = "linux")]
+ let mut queue_num: u16 = 1;
+ #[cfg(target_os = "linux")]
+ let mut nft_command = String::from("nft");
+
+ let mut args = std::env::args().skip(1); // program name
+
+ while let Some(arg) = args.next() {
+ let argv = arg.as_str();
+
+ match argv {
+ "-h" | "--help" => { usage(); std::process::exit(0); }
+ "--delay-ms" => { delay_ms = take_value(&mut args, argv)?; }
+ "--loglevel" => { log_level = take_value(&mut args, argv)?; }
+ "--no-splash" => { no_splash = true; }
+
+ "--fake" => { fake = true; }
+ "--fake-ttl" => { fake_ttl = take_value(&mut args, argv)?; }
+ "--fake-badsum" => { fake_badsum = true }
+
+ #[cfg(target_os = "linux")]
+ "--queue-num" => { queue_num = take_value(&mut args, argv)?; }
+
+ #[cfg(target_os = "linux")]
+ "--nft-command" => { nft_command = take_value(&mut args, argv)?; }
+
+ _ => { return Err(anyhow!("argument: unknown: {}", arg)); }
+ }
+ }
+
+ set_opt("OPT_LOG_LEVEL", &OPT_LOG_LEVEL, log_level)?;
+ set_opt("OPT_NO_SPLASH", &OPT_NO_SPLASH, no_splash)?;
+
+ set_opt("OPT_DELAY_MS", &OPT_DELAY_MS, delay_ms)?;
+ set_opt("OPT_FAKE", &OPT_FAKE, fake)?;
+ set_opt("OPT_FAKE_TTL", &OPT_FAKE_TTL, fake_ttl)?;
+ set_opt("OPT_FAKE_BADSUM", &OPT_FAKE_BADSUM, fake_badsum)?;
+
+ #[cfg(target_os = "linux")] set_opt("OPT_QUEUE_NUM", &OPT_QUEUE_NUM, queue_num)?;
+ #[cfg(target_os = "linux")] set_opt("OPT_NFT_COMMAND", &OPT_NFT_COMMAND, nft_command)?;
+
+ Ok(())
+}
+
+pub fn parse_args() {
+ if let Err(e) = parse_args_1() {
+ log_println!(LogLevel::Error, "{e}");
+ usage();
+ std::process::exit(1);
+ }
+}
diff --git a/src/pkt.rs b/src/pkt.rs
index 69450dc..caabe12 100644
--- a/src/pkt.rs
+++ b/src/pkt.rs
@@ -18,7 +18,16 @@
use anyhow::Result;
use etherparse::{IpSlice, TcpSlice};
use anyhow::anyhow;
-use std::sync::OnceLock;
+use std::sync::atomic::Ordering;
+
+use crate::log_println;
+
+use crate::log;
+use crate::opt;
+use crate::platform;
+use crate::tls;
+
+use log::LogLevel;
/// www.microsoft.com
/// Stolen from github.com/bol-van/zapret/blob/master/nfq/desync.c
@@ -82,17 +91,6 @@ const DEFAULT_FAKE_TLS_CLIENTHELLO: &'static [u8] = &[
0x84, 0x4f, 0x78, 0x64, 0x30, 0x69, 0xe2, 0x1b
];
-pub static OPT_FAKE_TTL: OnceLock<u8> = OnceLock::new();
-pub static OPT_FAKE_BADSUM: OnceLock<bool> = OnceLock::new();
-
-fn fake_ttl() -> u8 {
- *OPT_FAKE_TTL.get().expect("OPT_FAKE_TTL not initialized")
-}
-
-fn fake_badsum() -> bool {
- *OPT_FAKE_BADSUM.get().expect("OPT_FAKE_BADSUM not initialized")
-}
-
pub struct PktView<'a> {
pub ip: IpSlice<'a>,
pub tcp: TcpSlice<'a>
@@ -183,14 +181,14 @@ pub fn split_packet_0(
Ok(())
}
-pub fn fake_clienthello(
+fn fake_clienthello(
view: &PktView,
start: u32,
end: Option<u32>,
out_buf: &mut Vec<u8>
) -> Result<()> {
- let tcp_checksum = if fake_badsum() {
+ let tcp_checksum = if opt::fake_badsum() {
Some(0)
} else {
None
@@ -198,6 +196,90 @@ pub fn fake_clienthello(
split_packet_0(view, start, end, out_buf,
Some(DEFAULT_FAKE_TLS_CLIENTHELLO),
- Some(fake_ttl()),
+ Some(opt::fake_ttl()),
tcp_checksum)
}
+
+fn split_packet(
+ view: &PktView,
+ start: u32,
+ end: Option<u32>,
+ out_buf: &mut Vec<u8>
+) -> Result<()> {
+ split_packet_0(view, start, end, out_buf, None, None, None)
+}
+
+fn send_segment(
+ view: &PktView,
+ start: u32,
+ end: Option<u32>,
+ buf: &mut Vec<u8>
+) -> Result<()> {
+ use platform::send_to_raw;
+
+ if opt::fake() {
+ fake_clienthello(view, start, end, buf)?;
+ send_to_raw(buf)?;
+ }
+ split_packet(view, start, end, buf)?;
+ send_to_raw(buf)?;
+
+ Ok(())
+}
+
+fn split_packet_1(view: &PktView, order: &[u32], buf: &mut Vec<u8>) -> Result<()> {
+ let mut it = order.iter().copied();
+
+ let Some(mut first) = it.next() else {
+ return Err(anyhow!("split_packet_1: invalid order array"));
+ };
+
+ for next in it {
+ send_segment(view, first, Some(next), buf)?;
+ std::thread::sleep(std::time::Duration::from_millis(opt::delay_ms()));
+ first = next;
+ }
+
+ send_segment(view, first, None, buf)?;
+
+ Ok(())
+}
+
+/// Return Ok(true) if packet is handled
+pub fn handle_packet(pkt: &[u8], buf: &mut Vec::<u8>) -> Result<bool> {
+ #[cfg(target_os = "linux")]
+ let is_filtered = platform::IS_U32_SUPPORTED.load(Ordering::Relaxed);
+
+ #[cfg(windows)]
+ let is_filtered = true;
+
+ let view = PktView::from_raw(pkt)?;
+
+ if !is_filtered && !tls::is_client_hello(view.tcp.payload()) {
+ return Ok(false);
+ }
+
+ // TODO: if clienthello packet has been (unlikely) fragmented,
+ // we should find the second part and drop, reassemble it here.
+
+ split_packet_1(&view, &[0, 1], buf)?;
+
+ #[cfg(debug_assertions)]
+ log_println!(LogLevel::Debug, "packet is handled, len={}", pkt.len());
+
+ Ok(true)
+}
+
+#[macro_export]
+macro_rules! handle_packet {
+ ($bytes:expr, $buf:expr, handled => $on_handled:expr, rejected => $on_rejected:expr $(,)?) => {{
+ match crate::pkt::handle_packet($bytes, $buf) {
+ Ok(true) => { $on_handled }
+ Ok(false) => { $on_rejected }
+ Err(e) => {
+ log_println!(LogLevel::Warning, "handle_packet: {e}");
+ $on_rejected
+ }
+ }
+ }};
+}
diff --git a/src/platform/linux.rs b/src/platform/linux.rs
index a86daaa..5b413b4 100644
--- a/src/platform/linux.rs
+++ b/src/platform/linux.rs
@@ -1,4 +1,4 @@
-// Copyright 2025 Dillution <[email protected]>.
+// Copyright 2025-2026 Dillution <[email protected]>.
//
// This file is part of DPIBreak.
//
@@ -19,7 +19,6 @@ use iptables::IPTables;
use std::sync::{
atomic::{AtomicBool, Ordering},
Mutex,
- OnceLock,
LazyLock
};
use std::process::{Command, Stdio};
@@ -32,20 +31,8 @@ pub static IS_XT_U32_LOADED_BY_US: AtomicBool = AtomicBool::new(false);
static IS_NFT_NOT_SUPPORTED: AtomicBool = AtomicBool::new(false);
const DPIBREAK_CHAIN: &str = "DPIBREAK";
-
-pub static OPT_QUEUE_NUM: OnceLock<u16> = OnceLock::new();
-pub static OPT_NFT_COMMAND: OnceLock<String> = OnceLock::new();
-
const INJECT_MARK: u32 = 0xD001;
-fn queue_num() -> u16 {
- *OPT_QUEUE_NUM.get().expect("OPT_QUEUE_NUM not initialized")
-}
-
-fn nft_command() -> &'static str {
- OPT_NFT_COMMAND.get().expect("OPT_NFT_COMMAND not initialized").as_str()
-}
-
fn exec_process(args: &[&str], input: Option<&str>) -> Result<()> {
if args.is_empty() {
return Err(anyhow!("command args cannot be empty"));
@@ -82,7 +69,7 @@ fn exec_process(args: &[&str], input: Option<&str>) -> Result<()> {
/// Apply json format nft rules with `nft_command() -j -f -`.
fn apply_nft_rules(rule: &str) -> Result<()> {
- exec_process(&[nft_command(), "-j", "-f", "-"], Some(rule))
+ exec_process(&[crate::opt::nft_command(), "-j", "-f", "-"], Some(rule))
}
fn is_xt_u32_loaded() -> bool {
@@ -132,7 +119,8 @@ fn iptables_err(e: impl ToString) -> Error {
}
fn install_iptables_rules(ipt: &IPTables) -> Result<()> {
- let base = format!("-p tcp --dport 443 -j NFQUEUE --queue-num {} --queue-bypass", queue_num());
+ let base = format!("-p tcp --dport 443 -j NFQUEUE --queue-num {} --queue-bypass",
+ crate::opt::queue_num());
let rule = if is_u32_supported(ipt) {
const U32: &str = "-m u32 --u32 \
@@ -272,7 +260,7 @@ fn install_nft_rules() -> Result<()> {
},
{
"queue": {
- "num": queue_num(),
+ "num": crate::opt::queue_num(),
"flags": [ "bypass" ]
}
}
@@ -421,8 +409,9 @@ pub fn run() -> Result<()> {
use super::PACKET_SIZE_CAP;
let mut q = Queue::open()?;
- q.bind(queue_num())?;
- log_println!(LogLevel::Info, "nfqueue: bound to queue number {}", queue_num());
+ q.bind(crate::opt::queue_num())?;
+ log_println!(LogLevel::Info, "nfqueue: bound to queue number {}",
+ crate::opt::queue_num());
{ // to check inturrupts
let raw_fd = q.as_raw_fd();
@@ -463,7 +452,7 @@ pub fn run() -> Result<()> {
q.verdict(msg)?;
}
}
- q.unbind(queue_num())?;
+ q.unbind(crate::opt::queue_num())?;
Ok(())
}