From 81bc53a9ce548b70d46c7b17dc37c7a87707f4a5 Mon Sep 17 00:00:00 2001 From: rtulip Date: Sat, 30 Nov 2019 09:04:57 -0800 Subject: refactor(os): shared behaviour (#19) * Moved KeyboardEvents to shared * Moved get_datalink_channel, get_interface, lookup_addr, sigwinch, and create_write_to_stdout * Make shared only visible within os module * Moved get_input into shared * Changed functions to private --- src/os/linux.rs | 101 +---------------------------------------------------- src/os/macos.rs | 98 +-------------------------------------------------- src/os/mod.rs | 14 ++++---- src/os/shared.rs | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 112 insertions(+), 205 deletions(-) create mode 100644 src/os/shared.rs diff --git a/src/os/linux.rs b/src/os/linux.rs index f72f613..783e5de 100644 --- a/src/os/linux.rs +++ b/src/os/linux.rs @@ -1,51 +1,9 @@ -use ::pnet::datalink::Channel::Ethernet; -use ::pnet::datalink::DataLinkReceiver; -use ::pnet::datalink::{self, Config, NetworkInterface}; -use ::std::io::{self, stdin, Write}; -use ::termion::event::Event; -use ::termion::input::TermRead; - use ::std::collections::HashMap; -use ::std::net::IpAddr; -use ::std::time; - use ::procfs::FDTarget; -use signal_hook::iterator::Signals; use crate::network::{Connection, Protocol}; -use crate::OsInputOutput; - -struct KeyboardEvents; - -impl Iterator for KeyboardEvents { - type Item = Event; - fn next(&mut self) -> Option { - match stdin().events().next() { - Some(Ok(ev)) => Some(ev), - _ => None, - } - } -} -fn get_datalink_channel( - interface: &NetworkInterface, -) -> Result, failure::Error> { - let mut config = Config::default(); - config.read_timeout = Some(time::Duration::new(0, 1)); - match datalink::channel(interface, config) { - Ok(Ethernet(_tx, rx)) => Ok(rx), - Ok(_) => failure::bail!("Unknown interface type"), - Err(e) => failure::bail!("Failed to listen to network interface: {}", e), - } -} - -fn get_interface(interface_name: &str) -> Option { - datalink::interfaces() - .into_iter() - .find(|iface| iface.name == interface_name) -} - -fn get_open_sockets() -> HashMap { +pub(crate) fn get_open_sockets() -> HashMap { let mut open_sockets = HashMap::new(); let all_procs = procfs::all_processes(); @@ -84,60 +42,3 @@ fn get_open_sockets() -> HashMap { } open_sockets } - -fn lookup_addr(ip: &IpAddr) -> Option { - ::dns_lookup::lookup_addr(ip).ok() -} - -fn sigwinch() -> (Box) + Send>, Box) { - let signals = Signals::new(&[signal_hook::SIGWINCH]).unwrap(); - let on_winch = { - let signals = signals.clone(); - move |cb: Box| { - for signal in signals.forever() { - match signal { - signal_hook::SIGWINCH => cb(), - _ => unreachable!(), - } - } - } - }; - let cleanup = move || { - signals.close(); - }; - (Box::new(on_winch), Box::new(cleanup)) -} - -pub fn create_write_to_stdout() -> Box { - Box::new({ - let mut stdout = io::stdout(); - move |output: String| { - writeln!(stdout, "{}", output).unwrap(); - } - }) -} - -pub fn get_input(interface_name: &str) -> Result { - let keyboard_events = Box::new(KeyboardEvents); - let network_interface = match get_interface(interface_name) { - Some(interface) => interface, - None => { - failure::bail!("Cannot find interface {}", interface_name); - } - }; - let network_frames = get_datalink_channel(&network_interface)?; - let lookup_addr = Box::new(lookup_addr); - let write_to_stdout = create_write_to_stdout(); - let (on_winch, cleanup) = sigwinch(); - - Ok(OsInputOutput { - network_interface, - network_frames, - get_open_sockets, - keyboard_events, - lookup_addr, - on_winch, - cleanup, - write_to_stdout, - }) -} diff --git a/src/os/macos.rs b/src/os/macos.rs index 47248d0..cf68d04 100644 --- a/src/os/macos.rs +++ b/src/os/macos.rs @@ -1,49 +1,10 @@ -use ::pnet::datalink::Channel::Ethernet; -use ::pnet::datalink::DataLinkReceiver; -use ::pnet::datalink::{self, Config, NetworkInterface}; -use ::std::io::{self, stdin, Write}; -use ::termion::event::Event; -use ::termion::input::TermRead; - use ::std::collections::HashMap; -use ::std::net::IpAddr; - -use signal_hook::iterator::Signals; use crate::network::Connection; -use crate::OsInputOutput; use super::lsof_utils; use std::net::SocketAddr; -struct KeyboardEvents; - -impl Iterator for KeyboardEvents { - type Item = Event; - fn next(&mut self) -> Option { - match stdin().events().next() { - Some(Ok(ev)) => Some(ev), - _ => None, - } - } -} - -fn get_datalink_channel( - interface: &NetworkInterface, -) -> Result, failure::Error> { - match datalink::channel(interface, Config::default()) { - Ok(Ethernet(_tx, rx)) => Ok(rx), - Ok(_) => failure::bail!("Unknown interface type"), - Err(e) => failure::bail!("Failed to listen to network interface: {}", e), - } -} - -fn get_interface(interface_name: &str) -> Option { - datalink::interfaces() - .into_iter() - .find(|iface| iface.name == interface_name) -} - #[derive(Debug)] struct RawConnection { ip: String, @@ -53,7 +14,7 @@ struct RawConnection { process_name: String, } -fn get_open_sockets() -> HashMap { +pub(crate) fn get_open_sockets() -> HashMap { let mut open_sockets = HashMap::new(); let connections = lsof_utils::get_connections(); @@ -72,60 +33,3 @@ fn get_open_sockets() -> HashMap { return open_sockets; } - -fn lookup_addr(ip: &IpAddr) -> Option { - ::dns_lookup::lookup_addr(ip).ok() -} - -fn sigwinch() -> (Box) + Send>, Box) { - let signals = Signals::new(&[signal_hook::SIGWINCH]).unwrap(); - let on_winch = { - let signals = signals.clone(); - move |cb: Box| { - for signal in signals.forever() { - match signal { - signal_hook::SIGWINCH => cb(), - _ => unreachable!(), - } - } - } - }; - let cleanup = move || { - signals.close(); - }; - (Box::new(on_winch), Box::new(cleanup)) -} - -pub fn create_write_to_stdout() -> Box { - Box::new({ - let mut stdout = io::stdout(); - move |output: String| { - writeln!(stdout, "{}", output).unwrap(); - } - }) -} - -pub fn get_input(interface_name: &str) -> Result { - let keyboard_events = Box::new(KeyboardEvents); - let network_interface = match get_interface(interface_name) { - Some(interface) => interface, - None => { - failure::bail!("Cannot find interface {}", interface_name); - } - }; - let network_frames = get_datalink_channel(&network_interface)?; - let lookup_addr = Box::new(lookup_addr); - let write_to_stdout = create_write_to_stdout(); - let (on_winch, cleanup) = sigwinch(); - - Ok(OsInputOutput { - network_interface, - network_frames, - get_open_sockets, - keyboard_events, - lookup_addr, - on_winch, - cleanup, - write_to_stdout, - }) -} diff --git a/src/os/mod.rs b/src/os/mod.rs index 0a8cbdf..b45afff 100644 --- a/src/os/mod.rs +++ b/src/os/mod.rs @@ -1,14 +1,12 @@ #[cfg(target_os = "linux")] -mod linux; - -#[cfg(target_os = "linux")] -pub use linux::*; - -#[cfg(target_os = "macos")] -mod macos; +pub (self) mod linux; #[cfg(target_os = "macos")] -pub use macos::*; +pub (self) mod macos; #[cfg(target_os = "macos")] mod lsof_utils; + +mod shared; + +pub use shared::*; diff --git a/src/os/shared.rs b/src/os/shared.rs new file mode 100644 index 0000000..bef7604 --- /dev/null +++ b/src/os/shared.rs @@ -0,0 +1,104 @@ +use ::pnet::datalink::Channel::Ethernet; +use ::pnet::datalink::DataLinkReceiver; +use ::pnet::datalink::{self, Config, NetworkInterface}; +use ::std::io::{self, stdin, Write}; +use ::termion::event::Event; +use ::termion::input::TermRead; + +use ::std::net::IpAddr; +use ::std::time; + +use signal_hook::iterator::Signals; + +use crate::OsInputOutput; +#[cfg(target_os = "linux")] +use crate::os::linux::get_open_sockets; +#[cfg(target_os = "macos")] +use crate::os::macos::get_open_sockets; + +pub struct KeyboardEvents; + +impl Iterator for KeyboardEvents { + type Item = Event; + fn next(&mut self) -> Option { + match stdin().events().next() { + Some(Ok(ev)) => Some(ev), + _ => None, + } + } +} + +fn get_datalink_channel( + interface: &NetworkInterface, +) -> Result, failure::Error> { + let mut config = Config::default(); + config.read_timeout = Some(time::Duration::new(0, 1)); + match datalink::channel(interface, config) { + Ok(Ethernet(_tx, rx)) => Ok(rx), + Ok(_) => failure::bail!("Unknown interface type"), + Err(e) => failure::bail!("Failed to listen to network interface: {}", e), + } +} + +fn get_interface(interface_name: &str) -> Option { + datalink::interfaces() + .into_iter() + .find(|iface| iface.name == interface_name) +} + +fn lookup_addr(ip: &IpAddr) -> Option { + ::dns_lookup::lookup_addr(ip).ok() +} + +fn sigwinch() -> (Box) + Send>, Box) { + let signals = Signals::new(&[signal_hook::SIGWINCH]).unwrap(); + let on_winch = { + let signals = signals.clone(); + move |cb: Box| { + for signal in signals.forever() { + match signal { + signal_hook::SIGWINCH => cb(), + _ => unreachable!(), + } + } + } + }; + let cleanup = move || { + signals.close(); + }; + (Box::new(on_winch), Box::new(cleanup)) +} + +fn create_write_to_stdout() -> Box { + Box::new({ + let mut stdout = io::stdout(); + move |output: String| { + writeln!(stdout, "{}", output).unwrap(); + } + }) +} + +pub fn get_input(interface_name: &str) -> Result { + let keyboard_events = Box::new(KeyboardEvents); + let network_interface = match get_interface(interface_name) { + Some(interface) => interface, + None => { + failure::bail!("Cannot find interface {}", interface_name); + } + }; + let network_frames = get_datalink_channel(&network_interface)?; + let lookup_addr = Box::new(lookup_addr); + let write_to_stdout = create_write_to_stdout(); + let (on_winch, cleanup) = sigwinch(); + + Ok(OsInputOutput { + network_interface, + network_frames, + get_open_sockets, + keyboard_events, + lookup_addr, + on_winch, + cleanup, + write_to_stdout, + }) +} -- cgit v1.2.3