associate unassigned recent connections on port with the looked up program

This commit is contained in:
GyulyVGC 2026-02-21 14:23:44 +01:00
parent 10ddbaa38f
commit aa89be9971
5 changed files with 55 additions and 4 deletions

View file

@ -28,6 +28,7 @@ use crate::gui::types::timing_events::TimingEvents;
use crate::mmdb::asn::ASN_MMDB;
use crate::mmdb::country::COUNTRY_MMDB;
use crate::mmdb::types::mmdb_reader::{MmdbReader, MmdbReaders};
use crate::networking::manage_packets::get_local_port;
use crate::networking::parse_packets::BackendTrafficMessage;
use crate::networking::parse_packets::parse_packets;
use crate::networking::traffic_preview::{TrafficPreview, traffic_preview};
@ -40,7 +41,10 @@ use crate::networking::types::host::{Host, HostMessage};
use crate::networking::types::info_traffic::InfoTraffic;
use crate::networking::types::ip_blacklist::IpBlacklist;
use crate::networking::types::my_device::MyDevice;
use crate::networking::types::program_lookup::{ProgramLookup, lookup_program};
use crate::networking::types::program::Program;
use crate::networking::types::program_lookup::{
ProgramLookup, VALID_PROGRAM_TIMEOUT, lookup_program,
};
use crate::notifications::notify_and_log::notify_and_log;
use crate::notifications::types::logged_notification::LoggedNotifications;
use crate::notifications::types::notifications::{DataNotification, Notification};
@ -872,9 +876,25 @@ impl Sniffer {
self.combobox_data_states
.data
.update_program(lookup_res.2.as_ref());
// associate unassigned recent connections on port with the program
if lookup_res.2.is_some() {
self.info_traffic
.map
.iter_mut()
.filter(|(k, v)| {
v.program.is_unknown()
&& v.final_instant.elapsed().as_millis() < VALID_PROGRAM_TIMEOUT
&& get_local_port(k, v.traffic_direction)
== Some((lookup_res.0, lookup_res.1))
})
.for_each(|(_, v)| {
v.program = Program::from_proc(lookup_res.2.clone());
});
}
// update program lookup state with the new lookup result
program_lookup.update(lookup_res);
// TODO: associate past unassigned connections on port with the program
}
}

View file

@ -21,6 +21,7 @@ use crate::networking::types::service_query::ServiceQuery;
use crate::networking::types::traffic_direction::TrafficDirection;
use crate::networking::types::traffic_type::TrafficType;
use std::fmt::Write;
use std::time::Instant;
include!(concat!(env!("OUT_DIR"), "/services.rs"));
@ -299,6 +300,7 @@ pub fn modify_or_insert_in_map(
info.transmitted_bytes += exchanged_bytes;
info.transmitted_packets += 1;
info.final_timestamp = timestamp;
info.final_instant = Instant::now();
if key.protocol.eq(&Protocol::ICMP) {
info.icmp_types
.entry(icmp_type)
@ -319,6 +321,7 @@ pub fn modify_or_insert_in_map(
transmitted_packets: 1,
initial_timestamp: timestamp,
final_timestamp: timestamp,
final_instant: Instant::now(),
service,
traffic_direction,
icmp_types: if key.protocol.eq(&Protocol::ICMP) {

View file

@ -12,11 +12,12 @@ use crate::report::types::sort_type::SortType;
use crate::utils::types::timestamp::Timestamp;
use std::cmp::Ordering;
use std::collections::HashMap;
use std::time::Instant;
/// Struct useful to format the output report file and to keep track of statistics about the sniffed traffic.
///
/// Each `InfoAddressPortPair` struct is associated to a single address:port pair.
#[derive(Clone, Default, Debug)]
#[derive(Clone, Debug)]
pub struct InfoAddressPortPair {
/// Source MAC address
pub mac_address1: Option<String>,
@ -30,6 +31,8 @@ pub struct InfoAddressPortPair {
pub initial_timestamp: Timestamp,
/// Last occurrence of information exchange featuring the associate address:port pair as a source or destination.
pub final_timestamp: Timestamp,
/// Final instance of information exchange featuring the associate address:port pair as a source or destination (used for Program).
pub final_instant: Instant,
/// Upper layer service carried by the associated address:port pair.
pub service: Service,
/// Determines if the connection is incoming or outgoing
@ -50,6 +53,7 @@ impl InfoAddressPortPair {
self.transmitted_bytes += other.transmitted_bytes;
self.transmitted_packets += other.transmitted_packets;
self.final_timestamp = other.final_timestamp;
self.final_instant = other.final_instant;
self.service = other.service;
self.is_blacklisted = other.is_blacklisted;
self.traffic_direction = other.traffic_direction;
@ -98,6 +102,26 @@ impl InfoAddressPortPair {
}
}
impl Default for InfoAddressPortPair {
fn default() -> Self {
Self {
mac_address1: None,
mac_address2: None,
transmitted_bytes: 0,
transmitted_packets: 0,
initial_timestamp: Timestamp::default(),
final_timestamp: Timestamp::default(),
final_instant: Instant::now(),
service: Service::default(),
traffic_direction: TrafficDirection::default(),
icmp_types: HashMap::new(),
arp_types: HashMap::new(),
is_blacklisted: false,
program: Program::default(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

View file

@ -24,6 +24,10 @@ impl Program {
matches!(self, Program::Name(_))
}
pub fn is_unknown(&self) -> bool {
matches!(self, Program::Unknown)
}
pub fn from_proc(proc: Option<Process>) -> Self {
proc.map_or(Program::Unknown, |proc| Program::Name(proc.name))
}

View file

@ -4,7 +4,7 @@ use std::collections::HashMap;
use std::time::Instant;
const RETRY_TIMEOUT: u128 = 1500; // milliseconds
const VALID_PROGRAM_TIMEOUT: u128 = 60_000; // milliseconds
pub const VALID_PROGRAM_TIMEOUT: u128 = 60_000; // milliseconds
pub struct ProgramLookup {
map: HashMap<(u16, Protocol), LookedUpProgram>,