diff options
author | Aram Drevekenin <aram@poor.dev> | 2019-09-16 21:16:42 +0200 |
---|---|---|
committer | Aram Drevekenin <aram@poor.dev> | 2019-09-16 21:16:42 +0200 |
commit | e3ec9d22f0063d9ce83f87b49fd5dd90d57a9950 (patch) | |
tree | ec6c89abdb959a6d8c46863deb04c9e67311ddca /src | |
parent | 97aa07dfb8b3ab7840b15d4bfb278bb9f1b3c9ae (diff) |
style(all): rustfmt
Diffstat (limited to 'src')
-rw-r--r-- | src/display/ui.rs | 117 | ||||
-rw-r--r-- | src/display/ui_state.rs | 48 | ||||
-rw-r--r-- | src/lib.rs | 38 | ||||
-rw-r--r-- | src/main.rs | 15 | ||||
-rw-r--r-- | src/os/linux.rs | 32 | ||||
-rw-r--r-- | src/store/current_connections.rs | 71 | ||||
-rw-r--r-- | src/store/network_utilization.rs | 30 | ||||
-rw-r--r-- | src/traffic.rs | 135 |
8 files changed, 283 insertions, 203 deletions
diff --git a/src/display/ui.rs b/src/display/ui.rs index dbf4bce..225ab64 100644 --- a/src/display/ui.rs +++ b/src/display/ui.rs @@ -1,13 +1,13 @@ -use ::tui::Terminal; -use ::tui::terminal::Frame; -use ::tui::backend::Backend; -use ::tui::widgets::{Widget, Block, Borders, Table, Row}; -use ::tui::layout::{Layout, Constraint, Direction, Rect}; -use ::tui::style::{Style, Color}; use ::std::fmt; +use ::tui::backend::Backend; +use ::tui::layout::{Constraint, Direction, Layout, Rect}; +use ::tui::style::{Color, Style}; +use ::tui::terminal::Frame; +use ::tui::widgets::{Block, Borders, Row, Table, Widget}; +use ::tui::Terminal; +use crate::display::{Bandwidth, UIState}; use crate::store::{CurrentConnections, NetworkUtilization}; -use crate::display::{UIState, Bandwidth}; struct DisplayBandwidth(f64); @@ -27,14 +27,12 @@ impl fmt::Display for DisplayBandwidth { fn create_table<'a>( title: &'a str, - column_names: &'a[&'a str], + column_names: &'a [&'a str], rows: impl Iterator<Item = Vec<String>> + 'a, - widths: &'a[u16] -) -> impl Widget +'a { - let table_rows = rows.map( - |row| Row::StyledData(row.into_iter(), - Style::default().fg(Color::White)) - ); + widths: &'a [u16], +) -> impl Widget + 'a { + let table_rows = + rows.map(|row| Row::StyledData(row.into_iter(), Style::default().fg(Color::White))); Table::new(column_names.into_iter(), table_rows) .block(Block::default().title(title).borders(Borders::ALL)) .header_style(Style::default().fg(Color::Yellow)) @@ -43,7 +41,11 @@ fn create_table<'a>( .column_spacing(1) } -fn format_row_data(first_cell: String, second_cell: String, bandwidth: &impl Bandwidth) -> Vec<String> { +fn format_row_data( + first_cell: String, + second_cell: String, + bandwidth: &impl Bandwidth, +) -> Vec<String> { vec![ first_cell, second_cell, @@ -51,69 +53,92 @@ fn format_row_data(first_cell: String, second_cell: String, bandwidth: &impl Ban "{}/{}", DisplayBandwidth(bandwidth.get_total_bytes_uploaded() as f64), DisplayBandwidth(bandwidth.get_total_bytes_downloaded() as f64) - ) + ), ] } -fn split (direction: Direction, rect: Rect) -> Vec<Rect> { +fn split(direction: Direction, rect: Rect) -> Vec<Rect> { Layout::default() .direction(direction) .margin(0) - .constraints( - [ - Constraint::Percentage(50), - Constraint::Percentage(50) - ].as_ref() - ) + .constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref()) .split(rect) } -fn render_process_table (state: &UIState, frame: &mut Frame<impl Backend>, rect: Rect) { - let rows = state.processes.iter().map(|(process_name, data_for_process)| { - format_row_data(process_name.to_string(), data_for_process.connection_count.to_string(), data_for_process) - }); +fn render_process_table(state: &UIState, frame: &mut Frame<impl Backend>, rect: Rect) { + let rows = state + .processes + .iter() + .map(|(process_name, data_for_process)| { + format_row_data( + process_name.to_string(), + data_for_process.connection_count.to_string(), + data_for_process, + ) + }); let mut table = create_table( "Utilization by process name", &["Process", "Connection Count", "Total Bytes"], rows, - &[30, 30, 30] + &[30, 30, 30], ); table.render(frame, rect); } -fn render_connections_table (state: &UIState, frame: &mut Frame<impl Backend>, rect: Rect) { - let rows = state.connections.iter().map(|(connection, connection_data)| { - format_row_data(connection.to_string(), connection_data.processes.join(", "), connection_data) - }); +fn render_connections_table(state: &UIState, frame: &mut Frame<impl Backend>, rect: Rect) { + let rows = state + .connections + .iter() + .map(|(connection, connection_data)| { + format_row_data( + connection.to_string(), + connection_data.processes.join(", "), + connection_data, + ) + }); let mut table = create_table( "Utilization by connection", &["Connection", "Processes", "Total Bytes Up/Down"], rows, - &[50, 20, 20] + &[50, 20, 20], ); table.render(frame, rect); } -fn render_remote_ip_table (state: &UIState, frame: &mut Frame<impl Backend>, rect: Rect) { - let rows = state.remote_ips.iter().map(|(remote_ip, data_for_remote_ip)| { - format_row_data(remote_ip.to_string(), data_for_remote_ip.connection_count.to_string(), data_for_remote_ip) - }); +fn render_remote_ip_table(state: &UIState, frame: &mut Frame<impl Backend>, rect: Rect) { + let rows = state + .remote_ips + .iter() + .map(|(remote_ip, data_for_remote_ip)| { + format_row_data( + remote_ip.to_string(), + data_for_remote_ip.connection_count.to_string(), + data_for_remote_ip, + ) + }); let mut table = create_table( "Utilization by remote ip", &["Remote Address", "Connection Count", "Total Bytes"], rows, - &[50, 20, 20] + &[50, 20, 20], ); table.render(frame, rect); } -pub fn display_loop(network_utilization: &NetworkUtilization, terminal: &mut Terminal<impl Backend>, current_connections: CurrentConnections) { +pub fn display_loop( + network_utilization: &NetworkUtilization, + terminal: &mut Terminal<impl Backend>, + current_connections: CurrentConnections, +) { let state = UIState::new(current_connections, &network_utilization); - terminal.draw(|mut f| { - let screen_horizontal_halves = split(Direction::Horizontal, f.size()); - let right_side_vertical_halves = split(Direction::Vertical, screen_horizontal_halves[1]); - render_connections_table(&state, &mut f, screen_horizontal_halves[0]); - render_process_table(&state, &mut f, right_side_vertical_halves[0]); - render_remote_ip_table(&state, &mut f, right_side_vertical_halves[1]); - }).unwrap(); + terminal + .draw(|mut f| { + let screen_horizontal_halves = split(Direction::Horizontal, f.size()); + let right_side_vertical_halves = + split(Direction::Vertical, screen_horizontal_halves[1]); + render_connections_table(&state, &mut f, screen_horizontal_halves[0]); + render_process_table(&state, &mut f, right_side_vertical_halves[0]); + render_remote_ip_table(&state, &mut f, right_side_vertical_halves[1]); + }) + .unwrap(); } diff --git a/src/display/ui_state.rs b/src/display/ui_state.rs index 7b37816..3e30f87 100644 --- a/src/display/ui_state.rs +++ b/src/display/ui_state.rs @@ -1,8 +1,8 @@ use ::std::collections::BTreeMap; use ::std::net::Ipv4Addr; -use crate::traffic::{Connection}; use crate::store::{CurrentConnections, NetworkUtilization}; +use crate::traffic::Connection; pub trait Bandwidth { fn get_total_bytes_downloaded(&self) -> u128; @@ -13,14 +13,14 @@ pub trait Bandwidth { pub struct NetworkData { pub total_bytes_downloaded: u128, pub total_bytes_uploaded: u128, - pub connection_count: u128 + pub connection_count: u128, } #[derive(Default)] pub struct ConnectionData { pub total_bytes_downloaded: u128, pub total_bytes_uploaded: u128, - pub processes: Vec<String> + pub processes: Vec<String>, } impl Bandwidth for ConnectionData { @@ -42,38 +42,52 @@ impl Bandwidth for NetworkData { } pub struct UIState { - pub processes: BTreeMap<String, NetworkData>, - pub remote_ips: BTreeMap<Ipv4Addr, NetworkData>, - pub connections: BTreeMap<Connection, ConnectionData> + pub processes: BTreeMap<String, NetworkData>, + pub remote_ips: BTreeMap<Ipv4Addr, NetworkData>, + pub connections: BTreeMap<Connection, ConnectionData>, } impl UIState { - pub fn new (mut current_connections: CurrentConnections, network_utilization: &NetworkUtilization) -> Self { + pub fn new( + mut current_connections: CurrentConnections, + network_utilization: &NetworkUtilization, + ) -> Self { let mut processes: BTreeMap<String, NetworkData> = BTreeMap::new(); let mut remote_ips: BTreeMap<Ipv4Addr, NetworkData> = BTreeMap::new(); let mut connections: BTreeMap<Connection, ConnectionData> = BTreeMap::new(); for (connection, mut associated_processes) in current_connections.connections.drain() { - if let Some(connection_bandwidth_utilization) = network_utilization.connections.get(&connection) { - let data_for_remote_ip = remote_ips.entry(connection.remote_ip.clone()).or_default(); + if let Some(connection_bandwidth_utilization) = + network_utilization.connections.get(&connection) + { + let data_for_remote_ip = + remote_ips.entry(connection.remote_ip.clone()).or_default(); let connection_data = connections.entry(connection).or_default(); for process in &associated_processes { let data_for_process = processes.entry(process.to_string()).or_default(); - data_for_process.total_bytes_downloaded += &connection_bandwidth_utilization.total_bytes_downloaded; - data_for_process.total_bytes_uploaded += &connection_bandwidth_utilization.total_bytes_uploaded; + data_for_process.total_bytes_downloaded += + &connection_bandwidth_utilization.total_bytes_downloaded; + data_for_process.total_bytes_uploaded += + &connection_bandwidth_utilization.total_bytes_uploaded; data_for_process.connection_count += 1; } - connection_data.processes.append(&mut associated_processes.drain(..).collect()); - connection_data.total_bytes_downloaded += &connection_bandwidth_utilization.total_bytes_downloaded; - connection_data.total_bytes_uploaded += &connection_bandwidth_utilization.total_bytes_uploaded; - data_for_remote_ip.total_bytes_downloaded += connection_bandwidth_utilization.total_bytes_downloaded; - data_for_remote_ip.total_bytes_uploaded += connection_bandwidth_utilization.total_bytes_uploaded; + connection_data + .processes + .append(&mut associated_processes.drain(..).collect()); + connection_data.total_bytes_downloaded += + &connection_bandwidth_utilization.total_bytes_downloaded; + connection_data.total_bytes_uploaded += + &connection_bandwidth_utilization.total_bytes_uploaded; + data_for_remote_ip.total_bytes_downloaded += + connection_bandwidth_utilization.total_bytes_downloaded; + data_for_remote_ip.total_bytes_uploaded += + connection_bandwidth_utilization.total_bytes_uploaded; data_for_remote_ip.connection_count += 1; } } UIState { processes, remote_ips, - connections + connections, } } } @@ -1,30 +1,31 @@ -mod traffic; -mod store; mod display; +mod store; +mod traffic; -use traffic::Sniffer; use display::display_loop; use store::{CurrentConnections, NetworkUtilization}; +use traffic::Sniffer; -use ::std::{thread, time}; -use ::std::sync::{Arc, Mutex}; +use ::netstat::SocketInfo; +use ::pnet::datalink::{DataLinkReceiver, NetworkInterface}; use ::std::sync::atomic::{AtomicBool, Ordering}; -use ::tui::Terminal; +use ::std::sync::{Arc, Mutex}; +use ::std::{thread, time}; +use ::termion::event::{Event, Key}; use ::tui::backend::Backend; -use ::termion::event::{Key, Event}; -use ::pnet::datalink::{DataLinkReceiver, NetworkInterface}; -use ::netstat::SocketInfo; +use ::tui::Terminal; pub struct OsInput { pub network_interface: NetworkInterface, pub network_frames: Box<DataLinkReceiver>, pub get_process_name: fn(i32) -> Option<String>, pub get_open_sockets: fn() -> Vec<SocketInfo>, - pub keyboard_events: Box<Iterator<Item = Event> + Send + Sync + 'static> + pub keyboard_events: Box<Iterator<Item = Event> + Send + Sync + 'static>, } -pub fn start <B> (terminal_backend: B, os_input: OsInput) - where B: Backend + Send + 'static +pub fn start<B>(terminal_backend: B, os_input: OsInput) +where + B: Backend + Send + 'static, { let r = Arc::new(AtomicBool::new(true)); let displaying = r.clone(); @@ -35,16 +36,16 @@ pub fn start <B> (terminal_backend: B, os_input: OsInput) let get_open_sockets = os_input.get_open_sockets; let stdin_handler = thread::spawn(move || { - for evt in keyboard_events{ + for evt in keyboard_events { match evt { Event::Key(Key::Ctrl('c')) | Event::Key(Key::Char('q')) => { // TODO: exit faster r.store(false, Ordering::Relaxed); - break - }, - _ => () + break; + } + _ => (), }; - }; + } }); let mut sniffer = Sniffer::new(os_input.network_interface, os_input.network_frames); @@ -57,7 +58,8 @@ pub fn start <B> (terminal_backend: B, os_input: OsInput) terminal.clear().unwrap(); terminal.hide_cursor().unwrap(); while displaying.load(Ordering::SeqCst) { - let current_connections = CurrentConnections::new(&get_process_name, &get_open_sockets); + let current_connections = + CurrentConnections::new(&get_process_name, &get_open_sockets); { let mut network_utilization = network_utilization.lock().unwrap(); display_loop(&network_utilization, &mut terminal, current_connections); diff --git a/src/main.rs b/src/main.rs index b34a039..87a08a9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,15 +10,18 @@ use structopt::StructOpt; #[structopt(name = "what")] struct Opt { #[structopt(short, long)] - interface: String + interface: String, } -fn main () { - +fn main() { #[cfg(not(target_os = "linux"))] - compile_error!("Sorry, no implementations for platforms other than linux yet :( - PRs welcome!"); + compile_error!( + "Sorry, no implementations for platforms other than linux yet :( - PRs welcome!" + ); - use os::{KeyboardEvents, get_interface, get_datalink_channel, get_process_name, get_open_sockets}; + use os::{ + get_datalink_channel, get_interface, get_open_sockets, get_process_name, KeyboardEvents, + }; let opt = Opt::from_args(); let stdout = io::stdout().into_raw_mode().unwrap(); @@ -33,7 +36,7 @@ fn main () { network_frames, get_process_name, get_open_sockets, - keyboard_events + keyboard_events, }; what::start(terminal_backend, os_input) diff --git a/src/os/linux.rs b/src/os/linux.rs index 4023322..925ef69 100644 --- a/src/os/linux.rs +++ b/src/os/linux.rs @@ -1,11 +1,11 @@ -use ::std::io::stdin; -use ::pnet::datalink::{self, NetworkInterface}; -use ::pnet::datalink::DataLinkReceiver; +use ::netstat::{get_sockets_info, AddressFamilyFlags, ProtocolFlags, SocketInfo}; use ::pnet::datalink::Channel::Ethernet; -use ::termion::event::Event; -use ::termion::input::{TermRead}; -use ::netstat::{SocketInfo, AddressFamilyFlags, ProtocolFlags, get_sockets_info}; +use ::pnet::datalink::DataLinkReceiver; +use ::pnet::datalink::{self, NetworkInterface}; use ::procfs::Process; +use ::std::io::stdin; +use ::termion::event::Event; +use ::termion::input::TermRead; pub struct KeyboardEvents; @@ -14,33 +14,37 @@ impl Iterator for KeyboardEvents { fn next(&mut self) -> Option<Event> { match stdin().events().next() { Some(Ok(ev)) => Some(ev), - _ => None + _ => None, } } } -pub fn get_datalink_channel (interface: &NetworkInterface) -> Box<DataLinkReceiver> { +pub fn get_datalink_channel(interface: &NetworkInterface) -> Box<DataLinkReceiver> { match datalink::channel(interface, Default::default()) { Ok(Ethernet(_tx, rx)) => rx, Ok(_) => panic!("Unhandled channel type"), - Err(e) => panic!("An error occurred when creating the datalink channel: {}", e) + Err(e) => panic!( + "An error occurred when creating the datalink channel: {}", + e + ), } } -pub fn get_interface (interface_name: &str) -> Option<NetworkInterface> { - datalink::interfaces().into_iter() +pub fn get_interface(interface_name: &str) -> Option<NetworkInterface> { + datalink::interfaces() + .into_iter() .filter(|iface| iface.name == interface_name) .next() } -pub fn get_process_name (id: i32) -> Option<String> { +pub fn get_process_name(id: i32) -> Option<String> { match Process::new(id) { Ok(process) => Some(process.stat.comm), - Err(_) => None + Err(_) => None, } } -pub fn get_open_sockets () -> Vec<SocketInfo> { +pub fn get_open_sockets() -> Vec<SocketInfo> { let af_flags = AddressFamilyFlags::IPV4; let proto_flags = ProtocolFlags::TCP | ProtocolFlags::UDP; get_sockets_info(af_flags, proto_flags).unwrap_or_default() diff --git a/src/store/current_connections.rs b/src/store/current_connections.rs index 110a91e..43ed829 100644 --- a/src/store/current_connections.rs +++ b/src/store/current_connections.rs @@ -1,43 +1,44 @@ use crate::traffic::{Connection, Protocol}; +use ::netstat::{ProtocolSocketInfo, SocketInfo}; use ::std::collections::HashMap; use ::std::net::{IpAddr, Ipv4Addr}; -use ::netstat::{SocketInfo, ProtocolSocketInfo}; fn get_ipv4_address(ip: IpAddr) -> Option<Ipv4Addr> { match ip { IpAddr::V4(addr) => Some(addr), - IpAddr::V6(_) => None + IpAddr::V6(_) => None, } } -fn build_ipv4_connection ( +fn build_ipv4_connection( local_ip: Option<Ipv4Addr>, remote_ip: Option<Ipv4Addr>, local_port: u16, remote_port: u16, - protocol: Protocol + protocol: Protocol, ) -> Option<Connection> { match (local_ip, remote_ip) { - (Some(local_ip), Some(remote_ip)) => { - Some(Connection { - local_ip, - remote_ip, - local_port, - remote_port, - protocol - }) - }, - (_, _) => None + (Some(local_ip), Some(remote_ip)) => Some(Connection { + local_ip, + remote_ip, + local_port, + remote_port, + protocol, + }), + (_, _) => None, } } pub struct CurrentConnections { - pub connections: HashMap<Connection, Vec<String>> + pub connections: HashMap<Connection, Vec<String>>, } impl CurrentConnections { - pub fn new(get_process_name: &Fn(i32) -> Option<String>, get_open_sockets: &Fn() -> Vec<SocketInfo>) -> Self { + pub fn new( + get_process_name: &Fn(i32) -> Option<String>, + get_open_sockets: &Fn() -> Vec<SocketInfo>, + ) -> Self { let sockets_info = get_open_sockets(); let mut connections = HashMap::new(); for si in sockets_info { @@ -45,19 +46,43 @@ impl CurrentConnections { ProtocolSocketInfo::Tcp(tcp_si) => { let local_addr = get_ipv4_address(tcp_si.local_addr); let remote_addr = get_ipv4_address(tcp_si.remote_addr); - if let Some(conn) = build_ipv4_connection(local_addr, remote_addr, tcp_si.local_port, tcp_si.remote_port, Protocol::Tcp) { - connections.insert(conn, si.associated_pids.iter().map(|pid| get_process_name(*pid as i32).unwrap()).collect()); // TODO: handle None + if let Some(conn) = build_ipv4_connection( + local_addr, + remote_addr, + tcp_si.local_port, + tcp_si.remote_port, + Protocol::Tcp, + ) { + connections.insert( + conn, + si.associated_pids + .iter() + .map(|pid| get_process_name(*pid as i32).unwrap()) + .collect(), + ); // TODO: handle None } - }, + } ProtocolSocketInfo::Udp(udp_si) => { let local_addr = get_ipv4_address(udp_si.local_addr); let remote_addr = get_ipv4_address(udp_si.remote_addr); - if let Some(conn) = build_ipv4_connection(local_addr, remote_addr, udp_si.local_port, udp_si.remote_port, Protocol::Udp) { - connections.insert(conn, si.associated_pids.iter().map(|pid| get_process_name(*pid as i32).unwrap()).collect()); + if let Some(conn) = build_ipv4_connection( + local_addr, + remote_addr, + udp_si.local_port, + udp_si.remote_port, + Protocol::Udp, + ) { + connections.insert( + conn, + si.associated_pids + .iter() + .map(|pid| get_process_name(*pid as i32).unwrap()) + .collect(), + ); } } } - }; - CurrentConnections {connections} + } + CurrentConnections { connections } } } diff --git a/src/store/network_utilization.rs b/src/store/network_utilization.rs index a92875d..de429aa 100644 --- a/src/store/network_utilization.rs +++ b/src/store/network_utilization.rs @@ -1,4 +1,4 @@ -use crate::traffic::{Segment, Connection, Direction}; +use crate::traffic::{Connection, Direction, Segment}; use ::std::collections::HashMap; @@ -8,16 +8,16 @@ pub struct TotalBandwidth { } impl TotalBandwidth { - pub fn increment_bytes_downloaded (&mut self, ip_length: u128) { + pub fn increment_bytes_downloaded(&mut self, ip_length: u128) { self.total_bytes_downloaded += ip_length; } - pub fn increment_bytes_uploaded (&mut self, ip_length: u128) { + pub fn increment_bytes_uploaded(&mut self, ip_length: u128) { self.total_bytes_uploaded += ip_length; } } pub struct NetworkUtilization { - pub connections: HashMap<Connection, TotalBandwidth> + pub connections: HashMap<Connection, TotalBandwidth>, } impl NetworkUtilization { @@ -25,22 +25,20 @@ impl NetworkUtilization { let connections = HashMap::new(); NetworkUtilization { connections } } - pub fn reset (&mut self) { + pub fn reset(&mut self) { self.connections.clear(); } pub fn update(&mut self, seg: &Segment) { - let total_bandwidth = self.connections.entry(seg.connection.clone()).or_insert(TotalBandwidth { - total_bytes_downloaded: 0, - total_bytes_uploaded: 0 - }); + let total_bandwidth = + self.connections + .entry(seg.connection.clone()) + .or_insert(TotalBandwidth { + total_bytes_downloaded: 0, + total_bytes_uploaded: 0, + }); match seg.direction { - Direction::Download => { - total_bandwidth.increment_bytes_downloaded(seg.ip_length) - }, - Direction::Upload => { - total_bandwidth.increment_bytes_uploaded(seg.ip_length) - } - + Direction::Download => total_bandwidth.increment_bytes_downloaded(seg.ip_length), + Direction::Upload => total_bandwidth.increment_bytes_uploaded(seg.ip_length), } } } diff --git a/src/traffic.rs b/src/traffic.rs index b71e00c..72cff7c 100644 --- a/src/traffic.rs +++ b/src/traffic.rs @@ -1,14 +1,14 @@ +use ::std::boxed::Box; use ::std::fmt; use ::std::net::{Ipv4Addr, SocketAddrV4}; -use ::std::boxed::Box; -use ::pnet::datalink::{NetworkInterface, DataLinkReceiver}; -use ::pnet::packet::Packet; +use ::pnet::datalink::{DataLinkReceiver, NetworkInterface}; use ::pnet::packet::ethernet::{EtherType, EthernetPacket}; -use ::pnet::packet::ipv4::Ipv4Packet; use ::pnet::packet::ip::IpNextHeaderProtocol; +use ::pnet::packet::ipv4::Ipv4Packet; use ::pnet::packet::tcp::TcpPacket; use ::pnet::packet::udp::UdpPacket; +use ::pnet::packet::Packet; use ::ipnetwork::IpNetwork; @@ -31,11 +31,7 @@ impl fmt::Display for Connection { write!( f, "{}:{} => {}:{} ({})", - self.local_ip, - self.local_port, - self.remote_ip, - self.remote_port, - self.protocol + self.local_ip, self.local_port, self.remote_ip, self.remote_port, self.protocol ) } } @@ -43,65 +39,72 @@ impl fmt::Display for Connection { pub struct Segment { pub connection: Connection, pub direction: Direction, - pub ip_length: u128 + pub ip_length: u128, } #[derive(PartialEq, Hash, Eq, Debug, Clone, PartialOrd, Ord)] pub enum Protocol { Tcp, - Udp + Udp, } #[derive(PartialEq, Hash, Eq, Debug, Clone, PartialOrd)] pub enum Direction { Download, - Upload + Upload, } impl fmt::Display for Protocol { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Protocol::Tcp => write!(f, "tcp"), - Protocol::Udp => write!(f, "udp") - } + match *self { + Protocol::Tcp => write!(f, "tcp"), + Protocol::Udp => write!(f, "udp"), + } } } -fn find_direction (network_interface_ips: &Vec<IpNetwork>, ip_packet: &Ipv4Packet) -> Direction { - match network_interface_ips.iter().any(|ip_network| ip_network.ip() == ip_packet.get_source()) { +fn find_direction(network_interface_ips: &Vec<IpNetwork>, ip_packet: &Ipv4Packet) -> Direction { + match network_interface_ips + .iter() + .any(|ip_network| ip_network.ip() == ip_packet.get_source()) + { true => Direction::Upload, - false => Direction::Download + false => Direction::Download, } } impl Direction { - pub fn make_connection (&self, from: SocketAddrV4, to: SocketAddrV4, protocol: Protocol) -> Connection { + pub fn make_connection( + &self, + from: SocketAddrV4, + to: SocketAddrV4, + protocol: Protocol, + ) -> Connection { match self { - Direction::Upload => { - Connection { - local_ip: *from.ip(), - remote_ip: *to.ip(), - local_port: from.port(), - remote_port: to.port(), - protocol - } + Direction::Upload => Connection { + local_ip: *from.ip(), + remote_ip: *to.ip(), + local_port: from.port(), + remote_port: to.port(), + protocol, + }, + Direction::Download => Connection { + local_ip: *to.ip(), + remote_ip: *from.ip(), + local_port: to.port(), + remote_port: from.port(), + protocol, }, - Direction::Download => { - Connection { - local_ip: *to.ip(), - remote_ip: *from.ip(), - local_port: to.port(), - remote_port: from.port(), - protocol - } - } } } } impl Sniffer { - pub fn new (network_interface: NetworkInterface, network_frames: Box<DataLinkReceiver>) -> Self { - Sniffer { network_interface, network_frames } + pub fn new(network_interface: NetworkInterface, network_frames: Box<DataLinkReceiver>) -> Self { + Sniffer { + network_interface, + network_frames, + } } pub fn next(&mut self) -> Option<Segment> { // TODO: https://github.com/libpnet/libpnet/issues/343 @@ -110,38 +113,44 @@ impl Sniffer { panic!("An error occurred while reading: {}", e); }); let packet = EthernetPacket::new(bytes)?; - match packet.get_ethertype() { // TODO: better way through the module? + match packet.get_ethertype() { + // TODO: better way through the module? EtherType(2048) => { let ip_packet = Ipv4Packet::new(packet.payload())?; - let (protocol, source_port, destination_port) = match ip_packet.get_next_level_protocol() { - IpNextHeaderProtocol(6) => { // tcp - let message = TcpPacket::new(ip_packet.payload())?; - ( - Protocol::Tcp, - message.get_source(), - message.get_destination() - ) - }, - IpNextHeaderProtocol(17) => { // udp - let datagram = UdpPacket::new(ip_packet.payload())?; - ( - Protocol::Udp, - datagram.get_source(), - datagram.get_destination() - ) - }, - _ => return None - }; + let (protocol, source_port, destination_port) = + match ip_packet.get_next_level_protocol() { + IpNextHeaderProtocol(6) => { + // tcp + let message = TcpPacket::new(ip_packet.payload())?; + ( + Protocol::Tcp, + message.get_source(), + message.get_destination(), + ) + } + IpNextHeaderProtocol(17) => { + // udp + let datagram = UdpPacket::new(ip_packet.payload())?; + ( + Protocol::Udp, + datagram.get_source(), + datagram.get_destination(), + ) + } + _ => return None, + }; let direction = find_direction(&self.network_interface.ips, &ip_packet); let from = SocketAddrV4::new(ip_packet.get_source(), source_port); let to = SocketAddrV4::new(ip_packet.get_destination(), destination_port); let connection = direction.make_connection(from, to, protocol); let ip_length = ip_packet.get_total_length() as u128; - Some(Segment { connection, ip_length, direction }) - }, - _ => { - None + Some(Segment { + connection, + ip_length, + direction, + }) } + _ => None, } } } |