mirror of
https://github.com/EFForg/rayhunter.git
synced 2026-07-22 07:28:11 -07:00
Refactor and simplify QmdlReader
In the past, QmdlReader was written to share a trait with DiagDevice, so it had to pretend to be reading MessagesContainers. This needlessly complicated both its code as well as that of consumers'. Instead, QmdlReader now returns a stream of diag Messages. QmdlReader also automatically detects if it's reading a compressed QMDL stream or not. Additionally, QmdlReader no longer can be bounded by a filesize limit, and instead relies on HDLC message framing to detect file truncation. This works for both compressed and uncompressed QMDL files.
This commit is contained in:
+11
-23
@@ -1,15 +1,13 @@
|
||||
use clap::Parser;
|
||||
use futures::TryStreamExt;
|
||||
use log::{debug, error, info, warn};
|
||||
use pcap_file_tokio::pcapng::{Block, PcapNgReader};
|
||||
use rayhunter::{
|
||||
analysis::analyzer::{AnalysisRow, AnalyzerConfig, EventType, Harness},
|
||||
diag::DataType,
|
||||
gsmtap_parser,
|
||||
pcap::GsmtapPcapWriter,
|
||||
qmdl::QmdlReader,
|
||||
};
|
||||
use std::{collections::HashMap, future, path::PathBuf, pin::pin};
|
||||
use std::{collections::HashMap, path::PathBuf};
|
||||
use tokio::fs::File;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
@@ -113,22 +111,14 @@ async fn analyze_pcap(pcap_path: &str, show_skipped: bool) {
|
||||
async fn analyze_qmdl(qmdl_path: &str, show_skipped: bool) {
|
||||
let mut harness = Harness::new_with_config(&AnalyzerConfig::default());
|
||||
let qmdl_file = &mut File::open(&qmdl_path).await.expect("failed to open file");
|
||||
let compressed = qmdl_path.ends_with(".gz");
|
||||
let qmdl_reader = QmdlReader::new(qmdl_file, compressed, None);
|
||||
let mut qmdl_stream = pin!(
|
||||
qmdl_reader
|
||||
.as_stream()
|
||||
.try_filter(|container| future::ready(container.data_type == DataType::UserSpace))
|
||||
);
|
||||
let mut qmdl_reader = QmdlReader::new(qmdl_file).await.expect("failed to open QmdlReader");
|
||||
let mut report = Report::new(qmdl_path);
|
||||
while let Some(container) = qmdl_stream
|
||||
.try_next()
|
||||
while let Some(maybe_message) = qmdl_reader
|
||||
.get_next_message()
|
||||
.await
|
||||
.expect("failed getting QMDL container")
|
||||
.expect("failed to get message")
|
||||
{
|
||||
for row in harness.analyze_qmdl_messages(container) {
|
||||
report.process_row(row);
|
||||
}
|
||||
report.process_row(harness.analyze_qmdl_message(maybe_message));
|
||||
}
|
||||
report.print_summary(show_skipped);
|
||||
}
|
||||
@@ -137,9 +127,7 @@ async fn pcapify(qmdl_path: &PathBuf) {
|
||||
let qmdl_file = &mut File::open(&qmdl_path)
|
||||
.await
|
||||
.expect("failed to open qmdl file");
|
||||
let compressed = qmdl_path.ends_with(".gz");
|
||||
let qmdl_file_size = qmdl_file.metadata().await.unwrap().len();
|
||||
let mut qmdl_reader = QmdlReader::new(qmdl_file, compressed, Some(qmdl_file_size as usize));
|
||||
let mut qmdl_reader = QmdlReader::new(qmdl_file).await.expect("failed to open QmdlReader");
|
||||
let mut pcap_path = qmdl_path.clone();
|
||||
pcap_path.set_extension("pcapng");
|
||||
let pcap_file = &mut File::create(&pcap_path)
|
||||
@@ -147,12 +135,12 @@ async fn pcapify(qmdl_path: &PathBuf) {
|
||||
.expect("failed to open pcap file");
|
||||
let mut pcap_writer = GsmtapPcapWriter::new(pcap_file).await.unwrap();
|
||||
pcap_writer.write_iface_header().await.unwrap();
|
||||
while let Some(container) = qmdl_reader
|
||||
.get_next_messages_container()
|
||||
while let Some(maybe_message) = qmdl_reader
|
||||
.get_next_message()
|
||||
.await
|
||||
.expect("failed to get container")
|
||||
.expect("failed to get message")
|
||||
{
|
||||
for msg in container.into_messages().into_iter().flatten() {
|
||||
if let Ok(msg) = maybe_message {
|
||||
if let Ok(Some((timestamp, parsed))) = gsmtap_parser::parse(msg) {
|
||||
pcap_writer
|
||||
.write_gsmtap_message(parsed, timestamp)
|
||||
|
||||
Reference in New Issue
Block a user