From 77b8f20bc98ce1aadd0580d140c8365a3dcf79d5 Mon Sep 17 00:00:00 2001 From: Marcin Siodelski Date: Wed, 7 Feb 2024 19:01:44 +0100 Subject: [PATCH] [#13] Allow specifying multiple interfaces --- src/cli.rs | 12 +++++++----- src/dispatcher.rs | 8 ++++---- src/listener.rs | 14 +++++++------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 581b1da..6bc67b6 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -37,7 +37,7 @@ enum Commands { Collect { /// Interface name. #[arg(short, long)] - interface_name: String, + interface_name: Vec, }, } @@ -57,13 +57,15 @@ impl Cli { let args = Cli::parse(); if let Some(commands) = args.commands { match commands { - Commands::Collect { interface_name } => { + Commands::Collect { interface_name: interface_names } => { Cli::install_signal_handler(); let mut dispatcher = dispatcher::Dispatcher::new(); let filter = Filter::new().bootp_server_relay(); - dispatcher - .add_listener(interface_name.as_str(), filter) - .expect("listener already added"); + for interface_name in interface_names.iter() { + dispatcher + .add_listener(interface_name.as_str(), &filter) + .expect("listener already added"); + }; dispatcher .add_timer(timer::Type::DataScrape, 3000) .expect("timer already added"); diff --git a/src/dispatcher.rs b/src/dispatcher.rs index 48896ef..6205648 100644 --- a/src/dispatcher.rs +++ b/src/dispatcher.rs @@ -93,7 +93,7 @@ impl Dispatcher { /// The [Filter] applies filtering rules for packets capturing. For example, /// it can be used to filter only BOOTP packets, only UDP packets, select /// port number etc. - pub fn add_listener(&mut self, interface_name: &str, filter: Filter) -> Result<(), Error> { + pub fn add_listener(&mut self, interface_name: &str, filter: &Filter) -> Result<(), Error> { if self.listeners.contains_key(interface_name) { return Err(Error::AddListenerExists); } @@ -168,12 +168,12 @@ mod tests { fn add_listener() { let mut dispatcher = Dispatcher::new(); let filter = Filter::new().udp(); - assert_eq!(dispatcher.add_listener("lo", filter), Ok(())); + assert_eq!(dispatcher.add_listener("lo", &filter), Ok(())); assert_eq!( - dispatcher.add_listener("lo", Filter::new()), + dispatcher.add_listener("lo", &Filter::new()), Err(AddListenerExists) ); - assert_eq!(dispatcher.add_listener("lo0", Filter::new()), Ok(())); + assert_eq!(dispatcher.add_listener("lo0", &Filter::new()), Ok(())); assert_eq!(dispatcher.listeners.len(), 2); assert!(dispatcher.listeners.contains_key("lo")); assert!(dispatcher.listeners.contains_key("lo0")); diff --git a/src/listener.rs b/src/listener.rs index 9e3526f..62a7e35 100644 --- a/src/listener.rs +++ b/src/listener.rs @@ -60,7 +60,7 @@ trait State { /// /// A filter is only applied when the listener is in the [Inactive] /// state. - fn filter(self: Box, packet_filter: Filter) -> Box; + fn filter(self: Box, packet_filter: &Filter) -> Box; /// Starts the listener thread if not started yet. /// @@ -88,7 +88,7 @@ struct Inactive { struct Active {} /// An enum of protocols used for filtering. -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum Proto { /// Filtering by BOOTP or DHCPv4 messages. Bootp, @@ -107,7 +107,7 @@ pub enum Proto { /// ```rust /// let filter = Filter::new().udp().port(10067); /// ``` -#[derive(Debug)] +#[derive(Copy, Debug)] pub struct Filter { proto: Option, port: Option, @@ -135,7 +135,7 @@ impl Listener { /// /// - `packet_filter` - a packet filter instance used for capturing /// a specific type of the packets. - pub fn filter(&mut self, packet_filter: Filter) { + pub fn filter(&mut self, packet_filter: &Filter) { if let Some(s) = self.state.take() { self.state = Some(s.filter(packet_filter)) } @@ -161,10 +161,10 @@ impl Listener { } impl State for Inactive { - fn filter(self: Box, packet_filter: Filter) -> Box { + fn filter(self: Box, packet_filter: &Filter) -> Box { Box::new(Inactive { interface_name: self.interface_name.to_string(), - filter: Some(packet_filter), + filter: Some(packet_filter.clone()), }) } @@ -201,7 +201,7 @@ impl State for Inactive { } impl State for Active { - fn filter(self: Box, _packet_filter: Filter) -> Box { + fn filter(self: Box, _packet_filter: &Filter) -> Box { self }