Skip to content

Commit

Permalink
Unify pcap loading, make times relative to first packet.
Browse files Browse the repository at this point in the history
  • Loading branch information
martinling committed Jun 24, 2024
1 parent 2d4beff commit 6594eec
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 49 deletions.
16 changes: 4 additions & 12 deletions src/capture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1628,8 +1628,8 @@ mod tests {
use std::io::{BufReader, BufWriter, BufRead, Write};
use std::path::PathBuf;
use crate::decoder::Decoder;
use crate::loader::Loader;
use itertools::Itertools;
use pcap_file::{pcap::PcapReader, TsResolution};

fn summarize_item(cap: &mut CaptureReader, item: &TrafficItem, depth: usize)
-> String
Expand Down Expand Up @@ -1683,19 +1683,11 @@ mod tests {
ref_path.push("reference.txt");
out_path.push("output.txt");
{
let pcap_file = File::open(cap_path).unwrap();
let mut pcap_reader = PcapReader::new(pcap_file).unwrap();
let frac_ns = match pcap_reader.header().ts_resolution {
TsResolution::MicroSecond => 1_000,
TsResolution::NanoSecond => 1,
};
let mut loader = Loader::open(cap_path).unwrap();
let (writer, mut reader) = create_capture().unwrap();
let mut decoder = Decoder::new(writer).unwrap();
while let Some(result) = pcap_reader.next_raw_packet() {
let packet = result.unwrap();
let timestamp_ns =
packet.ts_sec as u64 * 1_000_000_000 +
packet.ts_frac as u64 * frac_ns;
while let Some(result) = loader.next() {
let (packet, timestamp_ns) = result.unwrap();
decoder
.handle_raw_packet(&packet.data, timestamp_ns)
.unwrap();
Expand Down
57 changes: 57 additions & 0 deletions src/loader.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use std::fs::File;
use std::io::BufReader;
use std::mem::size_of;
use std::path::PathBuf;

use pcap_file::{
pcap::{PcapReader, PcapHeader, RawPcapPacket},
TsResolution,
};

use anyhow::Error;

pub struct Loader {
pcap: PcapReader<BufReader<File>>,
pub file_size: u64,
pub bytes_read: u64,
frac_ns: u64,
start_time: Option<u64>,
}

impl Loader {
pub fn open(path: PathBuf) -> Result<Loader, Error> {
let file = File::open(path)?;
let file_size = file.metadata()?.len();
let reader = BufReader::new(file);
let pcap = PcapReader::new(reader)?;
let header = pcap.header();
let bytes_read = size_of::<PcapHeader>() as u64;
let frac_ns = match header.ts_resolution {
TsResolution::MicroSecond => 1_000,
TsResolution::NanoSecond => 1,
};
let start_time = None;
Ok(Loader{pcap, file_size, bytes_read, frac_ns, start_time})
}

pub fn next(&mut self) -> Option<Result<(RawPcapPacket, u64), Error>> {
match self.pcap.next_raw_packet() {
None => None,
Some(Err(e)) => Some(Err(Error::from(e))),
Some(Ok(packet)) => {
let raw_timestamp =
packet.ts_sec as u64 * 1_000_000_000 +
packet.ts_frac as u64 * self.frac_ns;
let timestamp = if let Some(start) = self.start_time {
raw_timestamp - start
} else {
self.start_time = Some(raw_timestamp);
0
};
let size = 16 + packet.data.len();
self.bytes_read += size as u64;
Some(Ok((packet, timestamp)))
}
}
}
}
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ mod decoder;
mod expander;
mod id;
mod index_stream;
mod loader;
mod model;
mod rcu;
mod row_data;
Expand Down
21 changes: 5 additions & 16 deletions src/test_replay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ use std::path::PathBuf;
use gtk::prelude::*;

use itertools::assert_equal;
use pcap_file::{pcap::PcapReader, TsResolution};
use serde_json::Deserializer;

use crate::decoder::Decoder;
use crate::loader::Loader;
use crate::model::GenericModel;
use crate::row_data::{GenericRowData, TrafficRowData, DeviceRowData};
use crate::record_ui::UiAction;
Expand Down Expand Up @@ -112,36 +112,25 @@ fn check_replays() {
Ok(())
}).unwrap();
if let Some(capture) = capture {
let file = File::open(path)
let loader = Loader::open(path)
.expect("Failed to open pcap file");
let reader = BufReader::new(file);
let pcap = PcapReader::new(reader)
.expect("Failed to read pcap file");
let decoder = Decoder::new(writer)
.expect("Failed to create decoder");
replay = Some((pcap, decoder, capture));
replay = Some((loader, decoder, capture));
}
},
(Update(count),
Some((pcap, decoder, capture))) => {
Some((loader, decoder, capture))) => {
with_ui(|ui| {
ui.recording
.borrow_mut()
.log_update(count);
Ok(())
}).unwrap();
let frac_ns = match pcap.header().ts_resolution {
TsResolution::MicroSecond => 1_000,
TsResolution::NanoSecond => 1,
};
while capture.packet_index.len() < count {
let packet = pcap
.next_raw_packet()
let (packet, timestamp_ns) = loader.next()
.expect("No next pcap packet")
.expect("Error in pcap reader");
let timestamp_ns =
packet.ts_sec as u64 * 1_000_000_000 +
packet.ts_frac as u64 * frac_ns;
decoder
.handle_raw_packet(&packet.data, timestamp_ns)
.expect("Failed to decode packet");
Expand Down
29 changes: 8 additions & 21 deletions src/ui.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use std::borrow::Cow;
use std::cell::RefCell;
use std::fs::File;
use std::io::{BufReader, BufWriter, Write};
use std::mem::size_of;
use std::io::{BufWriter, Write};
use std::path::PathBuf;
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
use std::time::Duration;
Expand Down Expand Up @@ -50,7 +49,7 @@ use gtk::{
use pcap_file::{
DataLink,
TsResolution,
pcap::{PcapReader, PcapWriter, PcapHeader, RawPcapPacket},
pcap::{PcapWriter, PcapHeader, RawPcapPacket},
};

use crate::backend::cynthion::{
Expand All @@ -71,6 +70,7 @@ use crate::capture::{
};
use crate::decoder::Decoder;
use crate::expander::ExpanderWrapper;
use crate::loader::Loader;
use crate::model::{GenericModel, TrafficModel, DeviceModel};
use crate::row_data::{
GenericRowData,
Expand Down Expand Up @@ -829,37 +829,24 @@ fn start_pcap(action: FileAction, path: PathBuf) -> Result<(), Error> {
let mut capture = ui.capture.clone();
let worker = move || match action {
Load => {
let file = File::open(path)?;
let file_size = file.metadata()?.len();
TOTAL.store(file_size, Ordering::Relaxed);
let reader = BufReader::new(file);
let mut pcap = PcapReader::new(reader)?;
let frac_ns = match pcap.header().ts_resolution {
TsResolution::MicroSecond => 1_000,
TsResolution::NanoSecond => 1,
};
let mut bytes_read = size_of::<PcapHeader>() as u64;
let mut loader = Loader::open(path)?;
TOTAL.store(loader.file_size, Ordering::Relaxed);
let mut decoder = Decoder::new(writer.unwrap())?;
#[cfg(feature="step-decoder")]
let (mut client, _addr) =
TcpListener::bind("127.0.0.1:46563")?.accept()?;
while let Some(result) = pcap.next_raw_packet() {
while let Some(result) = loader.next() {
let (packet, timestamp_ns) = result?;
#[cfg(feature="step-decoder")] {
let mut buf = [0; 1];
client.read(&mut buf).unwrap();
};
let packet = result?;
let timestamp_ns =
packet.ts_sec as u64 * 1_000_000_000 +
packet.ts_frac as u64 * frac_ns;
#[cfg(feature="record-ui-test")]
let guard = UPDATE_LOCK.lock();
decoder.handle_raw_packet(&packet.data, timestamp_ns)?;
#[cfg(feature="record-ui-test")]
drop(guard);
let size = 16 + packet.data.len();
bytes_read += size as u64;
CURRENT.store(bytes_read, Ordering::Relaxed);
CURRENT.store(loader.bytes_read, Ordering::Relaxed);
if STOP.load(Ordering::Relaxed) {
break;
}
Expand Down

0 comments on commit 6594eec

Please sign in to comment.