mirror of
https://github.com/GyulyVGC/sniffnet.git
synced 2026-10-21 14:41:22 +00:00
pause/resume packet captures by applying proper BPF programs
This commit is contained in:
parent
85344cad45
commit
8afd77c94f
3 changed files with 46 additions and 11 deletions
|
|
@ -773,6 +773,7 @@ impl Sniffer {
|
|||
.change_capture_source(matches!(capture_source, CaptureSource::Device(_)));
|
||||
let (tx, rx) = async_channel::unbounded();
|
||||
let (freeze_tx, freeze_rx) = std::sync::mpsc::channel();
|
||||
let filters = self.conf.filters.clone();
|
||||
let _ = thread::Builder::new()
|
||||
.name("thread_parse_packets".to_string())
|
||||
.spawn(move || {
|
||||
|
|
@ -781,8 +782,9 @@ impl Sniffer {
|
|||
capture_source,
|
||||
&mmdb_readers,
|
||||
capture_context,
|
||||
filters,
|
||||
&tx,
|
||||
&freeze_rx,
|
||||
freeze_rx,
|
||||
);
|
||||
})
|
||||
.log_err(location!());
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
//! Module containing functions executed by the thread in charge of parsing sniffed packets
|
||||
|
||||
use crate::gui::types::filters::Filters;
|
||||
use crate::location;
|
||||
use crate::mmdb::asn::get_asn;
|
||||
use crate::mmdb::country::get_country;
|
||||
|
|
@ -29,6 +30,7 @@ use etherparse::{EtherType, LaxPacketHeaders};
|
|||
use pcap::{Address, Packet, PacketHeader};
|
||||
use std::collections::HashMap;
|
||||
use std::net::IpAddr;
|
||||
use std::sync::mpsc::Receiver;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
use std::time::{Duration, Instant};
|
||||
|
|
@ -39,8 +41,9 @@ pub fn parse_packets(
|
|||
mut cs: CaptureSource,
|
||||
mmdb_readers: &MmdbReaders,
|
||||
capture_context: CaptureContext,
|
||||
filters: Filters,
|
||||
tx: &Sender<BackendTrafficMessage>,
|
||||
freeze_rx: &std::sync::mpsc::Receiver<()>,
|
||||
freeze_rx: Receiver<()>,
|
||||
) {
|
||||
let my_link_type = capture_context.my_link_type();
|
||||
let (cap, mut savefile) = capture_context.consume();
|
||||
|
|
@ -53,20 +56,22 @@ pub fn parse_packets(
|
|||
// instant of the first parsed packet plus multiples of 1 second (only used in live captures)
|
||||
let mut first_packet_ticks = None;
|
||||
|
||||
let (pcap_tx, pcap_rx) = std::sync::mpsc::sync_channel(0);
|
||||
let (pcap_tx, pcap_rx) = std::sync::mpsc::sync_channel(10_000);
|
||||
let _ = thread::Builder::new()
|
||||
.name("thread_packet_stream".to_string())
|
||||
.spawn(move || packet_stream(cap, &pcap_tx))
|
||||
.spawn(move || packet_stream(cap, &pcap_tx, &freeze_rx, &filters))
|
||||
.log_err(location!());
|
||||
|
||||
loop {
|
||||
// check if we need to freeze the parsing
|
||||
if freeze_rx.try_recv().is_ok() {
|
||||
// wait until unfreeze
|
||||
let _ = freeze_rx.recv();
|
||||
// reset the first packet ticks
|
||||
first_packet_ticks = Some(Instant::now());
|
||||
}
|
||||
// // check if we need to freeze the parsing
|
||||
// if freeze_rx.try_recv().is_ok() {
|
||||
// // wait until unfreeze
|
||||
// let _ = freeze_rx.recv();
|
||||
// // discard old buffered packets
|
||||
//
|
||||
// // reset the first packet ticks
|
||||
// first_packet_ticks = Some(Instant::now());
|
||||
// }
|
||||
|
||||
let (packet_res, cap_stats) = pcap_rx
|
||||
.recv_timeout(Duration::from_millis(150))
|
||||
|
|
@ -495,8 +500,20 @@ fn maybe_send_tick_run_offline(
|
|||
fn packet_stream(
|
||||
mut cap: CaptureType,
|
||||
tx: &std::sync::mpsc::SyncSender<(Result<PacketOwned, pcap::Error>, Option<pcap::Stat>)>,
|
||||
freeze_rx: &Receiver<()>,
|
||||
filters: &Filters,
|
||||
) {
|
||||
loop {
|
||||
// check if we need to freeze the parsing
|
||||
if freeze_rx.try_recv().is_ok() {
|
||||
// pause the capture
|
||||
cap.pause();
|
||||
// wait until unfreeze
|
||||
let _ = freeze_rx.recv();
|
||||
// resume the capture
|
||||
cap.resume(filters);
|
||||
}
|
||||
|
||||
let packet_res = cap.next_packet();
|
||||
let packet_owned = packet_res.map(|p| PacketOwned {
|
||||
header: *p.header,
|
||||
|
|
|
|||
|
|
@ -150,6 +150,22 @@ impl CaptureType {
|
|||
Self::Offline(cap) => cap.filter(bpf, true),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pause(&mut self) {
|
||||
if let Self::Live(cap) = self {
|
||||
let _ = cap.filter("less 2", true).log_err(location!());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resume(&mut self, filters: &Filters) {
|
||||
if let Self::Live(cap) = self {
|
||||
if filters.is_some_filter_active() {
|
||||
let _ = cap.filter(filters.bpf(), true).log_err(location!());
|
||||
} else if cap.filter("", true).log_err(location!()).is_err() {
|
||||
let _ = cap.filter("greater 0", true).log_err(location!());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue