summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorebroto <ebroto@tutanota.com>2020-01-14 21:44:50 +0100
committerGitHub <noreply@github.com>2020-01-14 21:44:50 +0100
commitc6f7ac469e9509832b2885f4d7c73f9f9b15b868 (patch)
treec02cc40cbf7345c10c4b0b7dc6a4865e03d9b230
parentbafff57b01f98526ba9d4ad707d554e3e2617c4e (diff)
parenta16d1e4fea64b61e2b477bab08bd5d136f2ec0d8 (diff)
Merge pull request #70 from zhangxp1998/ipv6
Support Ipv6
-rw-r--r--src/display/components/table.rs9
-rw-r--r--src/display/ui.rs6
-rw-r--r--src/display/ui_state.rs4
-rw-r--r--src/network/connection.rs33
-rw-r--r--src/network/dns/client.rs10
-rw-r--r--src/network/dns/mod.rs4
-rw-r--r--src/network/dns/resolver.rs8
-rw-r--r--src/network/sniffer.rs113
-rw-r--r--src/os/linux.rs14
-rw-r--r--src/os/lsof.rs2
-rw-r--r--src/os/lsof_utils.rs83
-rw-r--r--src/tests/fakes/fake_input.rs23
12 files changed, 193 insertions, 116 deletions
diff --git a/src/display/components/table.rs b/src/display/components/table.rs
index 2b823d7..ff5a148 100644
--- a/src/display/components/table.rs
+++ b/src/display/components/table.rs
@@ -9,7 +9,7 @@ use ::tui::widgets::{Block, Borders, Row, Widget};
use crate::display::{Bandwidth, DisplayBandwidth, UIState};
use crate::network::{display_connection_string, display_ip_or_host};
-use ::std::net::Ipv4Addr;
+use ::std::net::IpAddr;
use std::iter::FromIterator;
const FIRST_WIDTH_BREAKPOINT: u16 = 50;
@@ -54,10 +54,7 @@ pub struct Table<'a> {
}
impl<'a> Table<'a> {
- pub fn create_connections_table(
- state: &UIState,
- ip_to_host: &HashMap<Ipv4Addr, String>,
- ) -> Self {
+ pub fn create_connections_table(state: &UIState, ip_to_host: &HashMap<IpAddr, String>) -> Self {
let mut connections_list = Vec::from_iter(&state.connections);
sort_by_bandwidth(&mut connections_list);
let connections_rows = connections_list
@@ -105,7 +102,7 @@ impl<'a> Table<'a> {
}
pub fn create_remote_addresses_table(
state: &UIState,
- ip_to_host: &HashMap<Ipv4Addr, String>,
+ ip_to_host: &HashMap<IpAddr, String>,
) -> Self {
let mut remote_addresses_list = Vec::from_iter(&state.remote_addresses);
sort_by_bandwidth(&mut remote_addresses_list);
diff --git a/src/display/ui.rs b/src/display/ui.rs
index 0c4d36a..2c44d23 100644
--- a/src/display/ui.rs
+++ b/src/display/ui.rs
@@ -7,7 +7,7 @@ use crate::display::components::{HelpText, Layout, Table, TotalBandwidth};
use crate::display::UIState;
use crate::network::{display_connection_string, display_ip_or_host, LocalSocket, Utilization};
-use ::std::net::Ipv4Addr;
+use ::std::net::IpAddr;
use chrono::prelude::*;
@@ -17,7 +17,7 @@ where
{
terminal: Terminal<B>,
state: UIState,
- ip_to_host: HashMap<Ipv4Addr, String>,
+ ip_to_host: HashMap<IpAddr, String>,
}
impl<B> Ui<B>
@@ -101,7 +101,7 @@ where
&mut self,
connections_to_procs: HashMap<LocalSocket, String>,
utilization: Utilization,
- ip_to_host: HashMap<Ipv4Addr, String>,
+ ip_to_host: HashMap<IpAddr, String>,
) {
self.state.update(connections_to_procs, utilization);
self.ip_to_host.extend(ip_to_host);
diff --git a/src/display/ui_state.rs b/src/display/ui_state.rs
index cddc622..de5fd9a 100644
--- a/src/display/ui_state.rs
+++ b/src/display/ui_state.rs
@@ -65,7 +65,7 @@ pub struct UtilizationData {
#[derive(Default)]
pub struct UIState {
pub processes: BTreeMap<String, NetworkData>,
- pub remote_addresses: BTreeMap<Ipv4Addr, NetworkData>,
+ pub remote_addresses: BTreeMap<IpAddr, NetworkData>,
pub connections: BTreeMap<Connection, ConnectionData>,
pub total_bytes_downloaded: u128,
pub total_bytes_uploaded: u128,
@@ -106,7 +106,7 @@ impl UIState {
self.utilization_data.pop_front();
}
let mut processes: BTreeMap<String, NetworkData> = BTreeMap::new();
- let mut remote_addresses: BTreeMap<Ipv4Addr, NetworkData> = BTreeMap::new();
+ let mut remote_addresses: BTreeMap<IpAddr, NetworkData> = BTreeMap::new();
let mut connections: BTreeMap<Connection, ConnectionData> = BTreeMap::new();
let mut total_bytes_downloaded: u128 = 0;
let mut total_bytes_uploaded: u128 = 0;
diff --git a/src/network/connection.rs b/src/network/connection.rs
index bdbf448..c0c35ea 100644
--- a/src/network/connection.rs
+++ b/src/network/connection.rs
@@ -1,6 +1,6 @@
use ::std::collections::HashMap;
use ::std::fmt;
-use ::std::net::{IpAddr, Ipv4Addr};
+use ::std::net::IpAddr;
use ::std::net::SocketAddr;
@@ -35,7 +35,7 @@ impl fmt::Display for Protocol {
#[derive(Clone, Ord, PartialOrd, PartialEq, Eq, Hash, Debug, Copy)]
pub struct Socket {
- pub ip: Ipv4Addr,
+ pub ip: IpAddr,
pub port: u16,
}
@@ -52,7 +52,7 @@ pub struct Connection {
pub local_socket: LocalSocket,
}
-pub fn display_ip_or_host(ip: Ipv4Addr, ip_to_host: &HashMap<Ipv4Addr, String>) -> String {
+pub fn display_ip_or_host(ip: IpAddr, ip_to_host: &HashMap<IpAddr, String>) -> String {
match ip_to_host.get(&ip) {
Some(host) => host.clone(),
None => ip.to_string(),
@@ -61,7 +61,7 @@ pub fn display_ip_or_host(ip: Ipv4Addr, ip_to_host: &HashMap<Ipv4Addr, String>)
pub fn display_connection_string(
connection: &Connection,
- ip_to_host: &HashMap<Ipv4Addr, String>,
+ ip_to_host: &HashMap<IpAddr, String>,
interface_name: &str,
) -> String {
format!(
@@ -80,20 +80,17 @@ impl Connection {
local_ip: IpAddr,
local_port: u16,
protocol: Protocol,
- ) -> Option<Self> {
- match remote_socket {
- SocketAddr::V4(remote_socket) => Some(Connection {
- remote_socket: Socket {
- ip: *remote_socket.ip(),
- port: remote_socket.port(),
- },
- local_socket: LocalSocket {
- ip: local_ip,
- port: local_port,
- protocol,
- },
- }),
- _ => None,
+ ) -> Self {
+ Connection {
+ remote_socket: Socket {
+ ip: remote_socket.ip(),
+ port: remote_socket.port(),
+ },
+ local_socket: LocalSocket {
+ ip: local_ip,
+ port: local_port,
+ protocol,
+ },
}
}
}
diff --git a/src/network/dns/client.rs b/src/network/dns/client.rs
index f9d12ed..9e13604 100644
--- a/src/network/dns/client.rs
+++ b/src/network/dns/client.rs
@@ -1,7 +1,7 @@
use crate::network::dns::{resolver::Lookup, IpTable};
use std::{
collections::HashSet,
- net::Ipv4Addr,
+ net::IpAddr,
sync::{Arc, Mutex},
thread::{Builder, JoinHandle},
};
@@ -10,14 +10,14 @@ use tokio::{
sync::mpsc::{self, Sender},
};
-type PendingAddrs = HashSet<Ipv4Addr>;
+type PendingAddrs = HashSet<IpAddr>;
const CHANNEL_SIZE: usize = 1_000;
pub struct Client {
cache: Arc<Mutex<IpTable>>,
pending: Arc<Mutex<PendingAddrs>>,
- tx: Option<Sender<Vec<Ipv4Addr>>>,
+ tx: Option<Sender<Vec<IpAddr>>>,
handle: Option<JoinHandle<()>>,
}
@@ -28,7 +28,7 @@ impl Client {
{
let cache = Arc::new(Mutex::new(IpTable::new()));
let pending = Arc::new(Mutex::new(PendingAddrs::new()));
- let (tx, mut rx) = mpsc::channel::<Vec<Ipv4Addr>>(CHANNEL_SIZE);
+ let (tx, mut rx) = mpsc::channel::<Vec<IpAddr>>(CHANNEL_SIZE);
let handle = Builder::new().name("resolver".into()).spawn({
let cache = cache.clone();
@@ -65,7 +65,7 @@ impl Client {
})
}
- pub fn resolve(&mut self, ips: Vec<Ipv4Addr>) {
+ pub fn resolve(&mut self, ips: Vec<IpAddr>) {
// Remove ips that are already being resolved
let ips = ips
.into_iter()
diff --git a/src/network/dns/mod.rs b/src/network/dns/mod.rs
index be1464e..2c911b0 100644
--- a/src/network/dns/mod.rs
+++ b/src/network/dns/mod.rs
@@ -1,4 +1,4 @@
-use std::{collections::HashMap, net::Ipv4Addr};
+use std::{collections::HashMap, net::IpAddr};
mod client;
mod resolver;
@@ -6,4 +6,4 @@ mod resolver;
pub use client::*;
pub use resolver::*;
-pub type IpTable = HashMap<Ipv4Addr, String>;
+pub type IpTable = HashMap<IpAddr, String>;
diff --git a/src/network/dns/resolver.rs b/src/network/dns/resolver.rs
index 007c485..074f46e 100644
--- a/src/network/dns/resolver.rs
+++ b/src/network/dns/resolver.rs
@@ -1,11 +1,11 @@
use async_trait::async_trait;
-use std::net::Ipv4Addr;
+use std::net::IpAddr;
use tokio::runtime::Handle;
use trust_dns_resolver::{error::ResolveErrorKind, TokioAsyncResolver};
#[async_trait]
pub trait Lookup {
- async fn lookup(&self, ip: Ipv4Addr) -> Option<String>;
+ async fn lookup(&self, ip: IpAddr) -> Option<String>;
}
pub struct Resolver(TokioAsyncResolver);
@@ -19,8 +19,8 @@ impl Resolver {
#[async_trait]
impl Lookup for Resolver {
- async fn lookup(&self, ip: Ipv4Addr) -> Option<String> {
- let lookup_future = self.0.reverse_lookup(ip.into());
+ async fn lookup(&self, ip: IpAddr) -> Option<String> {
+ let lookup_future = self.0.reverse_lookup(ip);
match lookup_future.await {
Ok(names) => {
// Take the first result and convert it to a string
diff --git a/src/network/sniffer.rs b/src/network/sniffer.rs
index ae73714..4426438 100644
--- a/src/network/sniffer.rs
+++ b/src/network/sniffer.rs
@@ -2,8 +2,9 @@ use ::std::boxed::Box;
use ::pnet_bandwhich_fork::datalink::{DataLinkReceiver, NetworkInterface};
use ::pnet_bandwhich_fork::packet::ethernet::{EtherTypes, EthernetPacket};
-use ::pnet_bandwhich_fork::packet::ip::IpNextHeaderProtocols;
+use ::pnet_bandwhich_fork::packet::ip::{IpNextHeaderProtocol, IpNextHeaderProtocols};
use ::pnet_bandwhich_fork::packet::ipv4::Ipv4Packet;
+use ::pnet_bandwhich_fork::packet::ipv6::Ipv6Packet;
use ::pnet_bandwhich_fork::packet::tcp::TcpPacket;
use ::pnet_bandwhich_fork::packet::udp::UdpPacket;
use ::pnet_bandwhich_fork::packet::Packet;
@@ -13,6 +14,7 @@ use ::std::net::{IpAddr, SocketAddr};
use crate::network::{Connection, Protocol};
+#[derive(Debug)]
pub struct Segment {
pub interface_name: String,
pub connection: Connection,
@@ -27,10 +29,10 @@ pub enum Direction {
}
impl Direction {
- pub fn new(network_interface_ips: &[IpNetwork], ip_packet: &Ipv4Packet) -> Self {
+ pub fn new(network_interface_ips: &[IpNetwork], source: IpAddr) -> Self {
if network_interface_ips
.iter()
- .any(|ip_network| ip_network.ip() == ip_packet.get_source())
+ .any(|ip_network| ip_network.ip() == source)
{
Direction::Upload
} else {
@@ -39,6 +41,42 @@ impl Direction {
}
}
+trait NextLevelProtocol {
+ fn get_next_level_protocol(&self) -> IpNextHeaderProtocol;
+}
+
+impl NextLevelProtocol for Ipv6Packet<'_> {
+ fn get_next_level_protocol(&self) -> IpNextHeaderProtocol {
+ self.get_next_header()
+ }
+}
+
+macro_rules! extract_transport_protocol {
+ ( $ip_packet: ident ) => {{
+ match $ip_packet.get_next_level_protocol() {
+ IpNextHeaderProtocols::Tcp => {
+ let message = TcpPacket::new($ip_packet.payload())?;
+ (
+ Protocol::Tcp,
+ message.get_source(),
+ message.get_destination(),
+ $ip_packet.payload().len() as u128,
+ )
+ }
+ IpNextHeaderProtocols::Udp => {
+ let datagram = UdpPacket::new($ip_packet.payload())?;
+ (
+ Protocol::Udp,
+ datagram.get_source(),
+ datagram.get_destination(),
+ $ip_packet.payload().len() as u128,
+ )
+ }
+ _ => return None,
+ }
+ }};
+}
+
pub struct Sniffer {
network_interface: NetworkInterface,
network_frames: Box<dyn DataLinkReceiver>,
@@ -56,55 +94,68 @@ impl Sniffer {
}
pub fn next(&mut self) -> Option<Segment> {
let bytes = self.network_frames.next().ok()?;
- let ip_packet = Ipv4Packet::new(&bytes)?;
+ // See https://github.com/libpnet/libpnet/blob/master/examples/packetdump.rs
+ let payload_offset = if self.network_interface.is_loopback() && cfg!(target_os = "macos") {
+ // The pnet code for BPF loopback adds a zero'd out Ethernet header
+ 14
+ } else {
+ 0
+ };
+ let ip_packet = Ipv4Packet::new(&bytes[payload_offset..])?;
let version = ip_packet.get_version();
match version {
4 => Self::handle_v4(ip_packet, &self.network_interface),
- 6 => None, // FIXME v6 support!
+ 6 => Self::handle_v6(
+ Ipv6Packet::new(&bytes[payload_offset..])?,
+ &self.network_interface,
+ ),
_ => {
let pkg = EthernetPacket::new(bytes)?;
match pkg.get_ethertype() {
EtherTypes::Ipv4 => {
Self::handle_v4(Ipv4Packet::new(pkg.payload())?, &self.network_interface)
}
+ EtherTypes::Ipv6 => {
+ Self::handle_v6(Ipv6Packet::new(pkg.payload())?, &self.network_interface)
+ }
_ => None,
}
}
}
}
+ fn handle_v6(ip_packet: Ipv6Packet, network_interface: &NetworkInterface) -> Option<Segment> {
+ let (protocol, source_port, destination_port, data_length) =
+ extract_transport_protocol!(ip_packet);
+
+ let interface_name = network_interface.name.clone();
+ let direction = Direction::new(&network_interface.ips, ip_packet.get_source().into());
+ let from = SocketAddr::new(ip_packet.get_source().into(), source_port);
+ let to = SocketAddr::new(ip_packet.get_destination().into(), destination_port);
+
+ let connection = match direction {
+ Direction::Download => Connection::new(from, to.ip(), destination_port, protocol),
+ Direction::Upload => Connection::new(to, from.ip(), source_port, protocol),
+ };
+ Some(Segment {
+ interface_name,
+ connection,
+ data_length,
+ direction,
+ })
+ }
fn handle_v4(ip_packet: Ipv4Packet, network_interface: &NetworkInterface) -> Option<Segment> {
let (protocol, source_port, destination_port, data_length) =
- match ip_packet.get_next_level_protocol() {
- IpNextHeaderProtocols::Tcp => {
- let message = TcpPacket::new(ip_packet.payload())?;
- (
- Protocol::Tcp,
- message.get_source(),
- message.get_destination(),
- ip_packet.payload().len() as u128,
- )
- }
- IpNextHeaderProtocols::Udp => {
- let datagram = UdpPacket::new(ip_packet.payload())?;
- (
- Protocol::Udp,
- datagram.get_source(),
- datagram.get_destination(),
- ip_packet.payload().len() as u128,
- )
- }
- _ => return None,
- };
+ extract_transport_protocol!(ip_packet);
let interface_name = network_interface.name.clone();
- let direction = Direction::new(&network_interface.ips, &ip_packet);
- let from = SocketAddr::new(IpAddr::V4(ip_packet.get_source()), source_port);
- let to = SocketAddr::new(IpAddr::V4(ip_packet.get_destination()), destination_port);
+ let direction = Direction::new(&network_interface.ips, ip_packet.get_source().into());
+ let from = SocketAddr::new(ip_packet.get_source().into(), source_port);
+ let to = SocketAddr::new(ip_packet.get_destination().into(), destination_port);
let connection = match direction {
- Direction::Download => Connection::new(from, to.ip(), destination_port, protocol)?,
- Direction::Upload => Connection::new(to, from.ip(), source_port, protocol)?,
+ Direction::Download => Connection::new(from, to.ip(), destination_port, protocol),
+ Direction::Upload => Connection::new(to, from.ip(), source_port, protocol),
};
Some(Segment {
interface_name,
diff --git a/src/os/linux.rs b/src/os/linux.rs
index e863e4f..ada04fb 100644
--- a/src/os/linux.rs
+++ b/src/os/linux.rs
@@ -23,11 +23,14 @@ pub(crate) fn get_open_sockets() -> OpenSockets {
}
}
- if let Ok(tcp) = ::procfs::net::tcp() {
+ if let Ok(mut tcp) = ::procfs::net::tcp() {
+ if let Ok(mut tcp6) = ::procfs::net::tcp6() {
+ tcp.append(&mut tcp6);
+ }
for entry in tcp.into_iter() {
let local_port = entry.local_address.port();
let local_ip = entry.local_address.ip();
- if let (Some(connection), Some(procname)) = (
+ if let (connection, Some(procname)) = (
Connection::new(entry.remote_address, local_ip, local_port, Protocol::Tcp),
inode_to_procname.get(&entry.inode),
) {
@@ -37,11 +40,14 @@ pub(crate) fn get_open_sockets() -> OpenSockets {
}
}
- if let Ok(udp) = ::procfs::net::udp() {
+ if let Ok(mut udp) = ::procfs::net::udp() {
+ if let Ok(mut udp6) = ::procfs::net::udp6() {
+ udp.append(&mut udp6);
+ }
for entry in udp.into_iter() {
let local_port = entry.local_address.port();
let local_ip = entry.local_address.ip();
- if let (Some(connection), Some(procname)) = (
+ if let (connection, Some(procname)) = (
Connection::new(entry.remote_address, local_ip, local_port, Protocol::Udp),
inode_to_procname.get(&entry.inode),
) {
diff --git a/src/os/lsof.rs b/src/os/lsof.rs
index 68b4bad..31e3266 100644
--- a/src/os/lsof.rs
+++ b/src/os/lsof.rs
@@ -29,7 +29,7 @@ pub(crate) fn get_open_sockets() -> OpenSockets {
let local_port = raw_connection.get_local_port();
let socket_addr = SocketAddr::new(remote_ip, remote_port);
- let connection = Connection::new(socket_addr, local_ip, local_port, protocol).unwrap();
+ let connection = Connection::new(socket_addr, local_ip, local_port, protocol);
open_sockets.insert(connection.local_socket, raw_connection.process_name.clone());
connections_vec.push(connection);
diff --git a/src/os/lsof_utils.rs b/src/os/lsof_utils.rs
index 17b9781..fa51fa1 100644
--- a/src/os/lsof_utils.rs
+++ b/src/os/lsof_utils.rs
@@ -18,7 +18,7 @@ pub struct RawConnection {
lazy_static! {
static ref CONNECTION_REGEX: Regex =
Regex::new(r"\[?([^\s\]]*)\]?:(\d+)->\[?([^\s\]]*)\]?:(\d+)").unwrap();
- static ref LISTEN_REGEX: Regex = Regex::new(r"(.*):(.*)").unwrap();
+ static ref LISTEN_REGEX: Regex = Regex::new(r"\[?([^\s\[\]]*)\]?:(.*)").unwrap();
}
fn get_null_addr(ip_type: &str) -> &str {
@@ -124,7 +124,7 @@ impl RawConnection {
}
pub fn get_connections() -> RawConnections {
- let content = run(&["-n", "-P", "-i4", "+c", "0"]);
+ let content = run(&["-n", "-P", "-i4", "-i6", "+c", "0"]);
RawConnections::new(content)
}
@@ -168,6 +168,7 @@ impl Iterator for RawConnections {
mod tests {
use super::*;
+ const IPV6_LINE_RAW_OUTPUT: &str = "ProcessName 29266 user 9u IPv6 0x5d53dfe5445cee01 0t0 UDP [fe80:4::aede:48ff:fe00:1122]:1111->[fe80:4::aede:48ff:fe33:4455]:2222";
const LINE_RAW_OUTPUT: &str = "ProcessName 29266 user 39u IPv4 0x28ffb9c0021196bf 0t0 UDP 192.168.0.1:1111->198.252.206.25:2222";
const FULL_RAW_OUTPUT: &str = r#"
com.apple 590 etoledom 193u IPv4 0x28ffb9c041115627 0t0 TCP 192.168.1.37:60298->31.13.83.36:443 (ESTABLISHED)
@@ -184,19 +185,15 @@ com.apple 590 etoledom 204u IPv4 0x28ffb9c04111253f 0t0 TCP 192.168.1.
}
#[test]
- fn test_iterator() {
- let iterator = RawConnections::new(String::from(LINE_RAW_OUTPUT));
- let mut worked = false;
- for raw_connection in iterator {
- worked = true;
- assert_eq!(raw_connection.process_name, String::from("ProcessName"));
- }
- assert!(worked);
+ fn test_raw_connection_is_created_from_raw_output_ipv4() {
+ test_raw_connection_is_created_from_raw_output(LINE_RAW_OUTPUT);
}
-
#[test]
- fn test_raw_connection_is_created_from_raw_output() {
- let connection = RawConnection::new(LINE_RAW_OUTPUT);
+ fn test_raw_connection_is_created_from_raw_output_ipv6() {
+ test_raw_connection_is_created_from_raw_output(IPV6_LINE_RAW_OUTPUT);
+ }
+ fn test_raw_connection_is_created_from_raw_output(raw_output: &str) {
+ let connection = RawConnection::new(raw_output);
assert!(connection.is_some());
}
@@ -207,35 +204,67 @@ com.apple 590 etoledom 204u IPv4 0x28ffb9c04111253f 0t0 TCP 192.168.1.
}
#[test]
- fn test_raw_connection_parse_remote_port() {
- let connection = RawConnection::new(LINE_RAW_OUTPUT).unwrap();
+ fn test_raw_connection_parse_remote_port_ipv4() {
+ test_raw_connection_parse_remote_port(LINE_RAW_OUTPUT);
+ }
+ #[test]
+ fn test_raw_connection_parse_remote_port_ipv6() {
+ test_raw_connection_parse_remote_port(IPV6_LINE_RAW_OUTPUT);
+ }
+ fn test_raw_connection_parse_remote_port(raw_output: &str) {
+ let connection = RawConnection::new(raw_output).unwrap();
assert_eq!(connection.get_remote_port(), 2222);
}
#[test]
- fn test_raw_connection_parse_local_port() {
- let connection = RawConnection::new(LINE_RAW_OUTPUT).unwrap();
+ fn test_raw_connection_parse_local_port_ipv4() {
+ test_raw_connection_parse_local_port(LINE_RAW_OUTPUT);
+ }
+ #[test]
+ fn test_raw_connection_parse_local_port_ipv6() {
+ test_raw_connection_parse_local_port(IPV6_LINE_RAW_OUTPUT);
+ }
+ fn test_raw_connection_parse_local_port(raw_output: &str) {
+ let connection = RawConnection::new(raw_output).unwrap();
assert_eq!(connection.get_local_port(), 1111);
}
#[test]
- fn test_raw_connection_parse_ip_address() {
- let connection = RawConnection::new(LINE_RAW_OUTPUT).unwrap();
- assert_eq!(
- connection.get_remote_ip().to_string(),
- String::from("198.252.206.25")
- );
+ fn test_raw_connection_parse_ip_address_ipv4() {
+ test_raw_connection_parse_ip_address(LINE_RAW_OUTPUT, "198.252.206.25");
+ }
+ #[test]
+ fn test_raw_connection_parse_ip_address_ipv6() {
+ test_raw_connection_parse_ip_address(IPV6_LINE_RAW_OUTPUT, "fe80:4::aede:48ff:fe33:4455");
+ }
+ fn test_raw_connection_parse_ip_address(raw_output: &str, ip: &str) {
+ let connection = RawConnection::new(raw_output).unwrap();
+ assert_eq!(connection.get_remote_ip().to_string(), String::from(ip));
}
#[test]
- fn test_raw_connection_parse_protocol() {
- let connection = RawConnection::new(LINE_RAW_OUTPUT).unwrap();
+ fn test_raw_connection_parse_protocol_ipv4() {
+ test_raw_connection_parse_protocol(LINE_RAW_OUTPUT);
+ }
+ #[test]
+ fn test_raw_connection_parse_protocol_ipv6() {
+ test_raw_connection_parse_protocol(IPV6_LINE_RAW_OUTPUT);
+ }
+ fn test_raw_connection_parse_protocol(raw_line: &str) {
+ let connection = RawConnection::new(raw_line).unwrap();
assert_eq!(connection.get_protocol(), Protocol::Udp);
}
#[test]
- fn test_raw_connection_parse_process_name() {
- let connection = RawConnection::new(LINE_RAW_OUTPUT).unwrap();
+ fn test_raw_connection_parse_process_name_ipv4() {
+ test_raw_connection_parse_process_name(LINE_RAW_OUTPUT);
+ }
+ #[test]
+ fn test_raw_connection_parse_process_name_ipv6() {
+ test_raw_connection_parse_process_name(IPV6_LINE_RAW_OUTPUT);
+ }
+ fn test_raw_connection_parse_process_name(raw_line: &str) {
+ let connection = RawConnection::new(raw_line).unwrap();
assert_eq!(connection.process_name, String::from("ProcessName"));
}
}
diff --git a/src/tests/fakes/fake_input.rs b/src/tests/fakes/fake_input.rs
index 253082e..3290ac2 100644
--- a/src/tests/fakes/fake_input.rs
+++ b/src/tests/fakes/fake_input.rs
@@ -93,8 +93,7 @@ pub fn get_open_sockets() -> OpenSockets {
local_ip,
443,
Protocol::Tcp,
- )
- .unwrap(),
+ ),
String::from("1"),
);
open_sockets.insert(
@@ -103,8 +102,7 @@ pub fn get_open_sockets() -> OpenSockets {
local_ip,
4434,
Protocol::Tcp,
- )
- .unwrap(),
+ ),
String::from("4"),
);
open_sockets.insert(
@@ -113,8 +111,7 @@ pub fn get_open_sockets() -> OpenSockets {
local_ip,
4435,
Protocol::Tcp,
- )
- .unwrap(),
+ ),
String::from("5"),
);
open_sockets.insert(
@@ -123,8 +120,7 @@ pub fn get_open_sockets() -> OpenSockets {
local_ip,
4432,
Protocol::Tcp,
- )
- .unwrap(),
+ ),
String::from("2"),
);
open_sockets.insert(
@@ -133,8 +129,7 @@ pub fn get_open_sockets() -> OpenSockets {
local_ip,
443,
Protocol::Tcp,
- )
- .unwrap(),
+ ),
String::from("1"),
);
let mut local_socket_to_procs = HashMap::new();
@@ -156,7 +151,10 @@ pub fn get_interfaces() -> Vec<NetworkInterface> {
index: 42,
mac: None,
ips: vec![IpNetwork::V4("10.0.0.2".parse().unwrap())],
- flags: 42,
+ // It's important that the IFF_LOOPBACK bit is set to 0.
+ // Otherwise sniffer will attempt to start parse packets
+ // at offset 14
+ flags: 0,
}]
}
@@ -179,8 +177,7 @@ struct FakeResolver(HashMap<IpAddr, String>);
#[async_trait]
impl Lookup for FakeResolver {
- async fn lookup(&self, ip: Ipv4Addr) -> Option<String> {
- let ip = IpAddr::from(ip);
+ async fn lookup(&self, ip: IpAddr) -> Option<String> {
self.0.get(&ip).cloned()
}
}