mirror of
https://github.com/EFForg/rayhunter.git
synced 2026-05-29 02:54:46 -07:00
Merge branch 'main' into notifications
This commit is contained in:
1
.github/workflows/main.yml
vendored
1
.github/workflows/main.yml
vendored
@@ -13,6 +13,7 @@ env:
|
|||||||
FILE_RAYHUNTER_DAEMON_ORBIC: ../../rayhunter-daemon-orbic/rayhunter-daemon
|
FILE_RAYHUNTER_DAEMON_ORBIC: ../../rayhunter-daemon-orbic/rayhunter-daemon
|
||||||
FILE_RAYHUNTER_DAEMON_TPLINK: ../../rayhunter-daemon-tplink/rayhunter-daemon
|
FILE_RAYHUNTER_DAEMON_TPLINK: ../../rayhunter-daemon-tplink/rayhunter-daemon
|
||||||
FILE_RAYHUNTER_DAEMON_WINGTECH: ../../rayhunter-daemon-wingtech/rayhunter-daemon
|
FILE_RAYHUNTER_DAEMON_WINGTECH: ../../rayhunter-daemon-wingtech/rayhunter-daemon
|
||||||
|
RUSTFLAGS: "-Dwarnings"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
files_changed:
|
files_changed:
|
||||||
|
|||||||
@@ -137,20 +137,20 @@ async fn perform_analysis(
|
|||||||
enable_dummy_analyzer: bool,
|
enable_dummy_analyzer: bool,
|
||||||
analyzer_config: &AnalyzerConfig,
|
analyzer_config: &AnalyzerConfig,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
info!("Opening QMDL and analysis file for {}...", name);
|
info!("Opening QMDL and analysis file for {name}...");
|
||||||
let (analysis_file, qmdl_file, entry_index) = {
|
let (analysis_file, qmdl_file, entry_index) = {
|
||||||
let mut qmdl_store = qmdl_store_lock.write().await;
|
let mut qmdl_store = qmdl_store_lock.write().await;
|
||||||
let (entry_index, _) = qmdl_store
|
let (entry_index, _) = qmdl_store
|
||||||
.entry_for_name(name)
|
.entry_for_name(name)
|
||||||
.ok_or(format!("failed to find QMDL store entry for {}", name))?;
|
.ok_or(format!("failed to find QMDL store entry for {name}"))?;
|
||||||
let analysis_file = qmdl_store
|
let analysis_file = qmdl_store
|
||||||
.clear_and_open_entry_analysis(entry_index)
|
.clear_and_open_entry_analysis(entry_index)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| format!("{:?}", e))?;
|
.map_err(|e| format!("{e:?}"))?;
|
||||||
let qmdl_file = qmdl_store
|
let qmdl_file = qmdl_store
|
||||||
.open_entry_qmdl(entry_index)
|
.open_entry_qmdl(entry_index)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| format!("{:?}", e))?;
|
.map_err(|e| format!("{e:?}"))?;
|
||||||
|
|
||||||
(analysis_file, qmdl_file, entry_index)
|
(analysis_file, qmdl_file, entry_index)
|
||||||
};
|
};
|
||||||
@@ -158,7 +158,7 @@ async fn perform_analysis(
|
|||||||
let mut analysis_writer =
|
let mut analysis_writer =
|
||||||
AnalysisWriter::new(analysis_file, enable_dummy_analyzer, analyzer_config)
|
AnalysisWriter::new(analysis_file, enable_dummy_analyzer, analyzer_config)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| format!("{:?}", e))?;
|
.map_err(|e| format!("{e:?}"))?;
|
||||||
let file_size = qmdl_file
|
let file_size = qmdl_file
|
||||||
.metadata()
|
.metadata()
|
||||||
.await
|
.await
|
||||||
@@ -169,7 +169,7 @@ async fn perform_analysis(
|
|||||||
.as_stream()
|
.as_stream()
|
||||||
.try_filter(|container| future::ready(container.data_type == DataType::UserSpace)));
|
.try_filter(|container| future::ready(container.data_type == DataType::UserSpace)));
|
||||||
|
|
||||||
info!("Starting analysis for {}...", name);
|
info!("Starting analysis for {name}...");
|
||||||
while let Some(container) = qmdl_stream
|
while let Some(container) = qmdl_stream
|
||||||
.try_next()
|
.try_next()
|
||||||
.await
|
.await
|
||||||
@@ -178,20 +178,20 @@ async fn perform_analysis(
|
|||||||
let (size_bytes, _) = analysis_writer
|
let (size_bytes, _) = analysis_writer
|
||||||
.analyze(container)
|
.analyze(container)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| format!("{:?}", e))?;
|
.map_err(|e| format!("{e:?}"))?;
|
||||||
debug!("{} analysis: {} bytes written", name, size_bytes);
|
debug!("{name} analysis: {size_bytes} bytes written");
|
||||||
let mut qmdl_store = qmdl_store_lock.write().await;
|
let mut qmdl_store = qmdl_store_lock.write().await;
|
||||||
qmdl_store
|
qmdl_store
|
||||||
.update_entry_analysis_size(entry_index, size_bytes)
|
.update_entry_analysis_size(entry_index, size_bytes)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| format!("{:?}", e))?;
|
.map_err(|e| format!("{e:?}"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
analysis_writer
|
analysis_writer
|
||||||
.close()
|
.close()
|
||||||
.await
|
.await
|
||||||
.map_err(|e| format!("{:?}", e))?;
|
.map_err(|e| format!("{e:?}"))?;
|
||||||
info!("Analysis for {} complete!", name);
|
info!("Analysis for {name} complete!");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -219,7 +219,7 @@ pub fn run_analysis_thread(
|
|||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
error!("failed to analyze {}: {}", name, err);
|
error!("failed to analyze {name}: {err}");
|
||||||
}
|
}
|
||||||
finish_running_analysis(analysis_status_lock.clone()).await;
|
finish_running_analysis(analysis_status_lock.clone()).await;
|
||||||
}
|
}
|
||||||
@@ -280,7 +280,7 @@ pub async fn start_analysis(
|
|||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
(
|
(
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
format!("failed to queue new analysis files: {:?}", e),
|
format!("failed to queue new analysis files: {e:?}"),
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,14 +84,13 @@ async fn analyze_file(enable_dummy_analyzer: bool, qmdl_path: &str, show_skipped
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if show_skipped && skipped > 0 {
|
if show_skipped && skipped > 0 {
|
||||||
info!("{}: messages skipped:", qmdl_path);
|
info!("{qmdl_path}: messages skipped:");
|
||||||
for (reason, count) in skipped_reasons.iter() {
|
for (reason, count) in skipped_reasons.iter() {
|
||||||
info!(" - {}: \"{}\"", count, reason);
|
info!(" - {count}: \"{reason}\"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
info!(
|
info!(
|
||||||
"{}: {} messages analyzed, {} warnings, {} messages skipped",
|
"{qmdl_path}: {total_messages} messages analyzed, {warnings} warnings, {skipped} messages skipped"
|
||||||
qmdl_path, total_messages, warnings, skipped
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ async fn init_qmdl_store(config: &config::Config) -> Result<RecordingStore, Rayh
|
|||||||
match RecordingStore::load(&config.qmdl_store_path).await {
|
match RecordingStore::load(&config.qmdl_store_path).await {
|
||||||
Ok(store) => Ok(store),
|
Ok(store) => Ok(store),
|
||||||
Err(RecordingStoreError::ParseManifestError(err)) => {
|
Err(RecordingStoreError::ParseManifestError(err)) => {
|
||||||
error!("failed to parse QMDL manifest: {}", err);
|
error!("failed to parse QMDL manifest: {err}");
|
||||||
info!("creating new empty manifest...");
|
info!("creating new empty manifest...");
|
||||||
Ok(RecordingStore::create(&config.qmdl_store_path).await?)
|
Ok(RecordingStore::create(&config.qmdl_store_path).await?)
|
||||||
}
|
}
|
||||||
@@ -124,6 +124,7 @@ async fn init_qmdl_store(config: &config::Config) -> Result<RecordingStore, Rayh
|
|||||||
// Start a thread that'll track when user hits ctrl+c. When that happens,
|
// Start a thread that'll track when user hits ctrl+c. When that happens,
|
||||||
// trigger various cleanup tasks, including sending signals to other threads to
|
// trigger various cleanup tasks, including sending signals to other threads to
|
||||||
// shutdown
|
// shutdown
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn run_shutdown_thread(
|
fn run_shutdown_thread(
|
||||||
task_tracker: &TaskTracker,
|
task_tracker: &TaskTracker,
|
||||||
diag_device_sender: Sender<DiagDeviceCtrlMessage>,
|
diag_device_sender: Sender<DiagDeviceCtrlMessage>,
|
||||||
@@ -141,14 +142,14 @@ fn run_shutdown_thread(
|
|||||||
select! {
|
select! {
|
||||||
res = tokio::signal::ctrl_c() => {
|
res = tokio::signal::ctrl_c() => {
|
||||||
if let Err(err) = res {
|
if let Err(err) = res {
|
||||||
error!("Unable to listen for shutdown signal: {}", err);
|
error!("Unable to listen for shutdown signal: {err}");
|
||||||
}
|
}
|
||||||
|
|
||||||
should_restart_flag.store(false, Ordering::Relaxed);
|
should_restart_flag.store(false, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
res = daemon_restart_rx => {
|
res = daemon_restart_rx => {
|
||||||
if let Err(err) = res {
|
if let Err(err) = res {
|
||||||
error!("Unable to listen for shutdown signal: {}", err);
|
error!("Unable to listen for shutdown signal: {err}");
|
||||||
}
|
}
|
||||||
|
|
||||||
should_restart_flag.store(true, Ordering::Relaxed);
|
should_restart_flag.store(true, Ordering::Relaxed);
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ pub enum DiagDeviceCtrlMessage {
|
|||||||
Exit,
|
Exit,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn run_diag_read_thread(
|
pub fn run_diag_read_thread(
|
||||||
task_tracker: &TaskTracker,
|
task_tracker: &TaskTracker,
|
||||||
mut dev: DiagDevice,
|
mut dev: DiagDevice,
|
||||||
@@ -58,7 +59,7 @@ pub fn run_diag_read_thread(
|
|||||||
let (qmdl_file, new_analysis_file) = match qmdl_store.new_entry().await {
|
let (qmdl_file, new_analysis_file) = match qmdl_store.new_entry().await {
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("couldn't create new qmdl entry: {}", e);
|
error!("couldn't create new qmdl entry: {e}");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -73,7 +74,7 @@ pub fn run_diag_read_thread(
|
|||||||
.expect("failed to write to analysis file"));
|
.expect("failed to write to analysis file"));
|
||||||
|
|
||||||
if let Err(e) = ui_update_sender.send(display::DisplayState::Recording).await {
|
if let Err(e) = ui_update_sender.send(display::DisplayState::Recording).await {
|
||||||
warn!("couldn't send ui update message: {}", e);
|
warn!("couldn't send ui update message: {e}");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Some(DiagDeviceCtrlMessage::StopRecording) => {
|
Some(DiagDeviceCtrlMessage::StopRecording) => {
|
||||||
@@ -84,11 +85,11 @@ pub fn run_diag_read_thread(
|
|||||||
entry.name.to_string(),
|
entry.name.to_string(),
|
||||||
))
|
))
|
||||||
.await {
|
.await {
|
||||||
warn!("couldn't send analysis message: {}", e);
|
warn!("couldn't send analysis message: {e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Err(e) = qmdl_store.close_current_entry().await {
|
if let Err(e) = qmdl_store.close_current_entry().await {
|
||||||
error!("couldn't close current entry: {}", e);
|
error!("couldn't close current entry: {e}");
|
||||||
}
|
}
|
||||||
|
|
||||||
maybe_qmdl_writer = None;
|
maybe_qmdl_writer = None;
|
||||||
@@ -98,7 +99,7 @@ pub fn run_diag_read_thread(
|
|||||||
maybe_analysis_writer = None;
|
maybe_analysis_writer = None;
|
||||||
|
|
||||||
if let Err(e) = ui_update_sender.send(display::DisplayState::Paused).await {
|
if let Err(e) = ui_update_sender.send(display::DisplayState::Paused).await {
|
||||||
warn!("couldn't send ui update message: {}", e);
|
warn!("couldn't send ui update message: {e}");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// None means all the Senders have been dropped, so it's
|
// None means all the Senders have been dropped, so it's
|
||||||
@@ -154,7 +155,7 @@ pub fn run_diag_read_thread(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("error reading diag device: {}", err);
|
error!("error reading diag device: {err}");
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,7 +179,7 @@ pub async fn start_recording(
|
|||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
(
|
(
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
format!("couldn't send start recording message: {}", e),
|
format!("couldn't send start recording message: {e}"),
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@@ -198,7 +199,7 @@ pub async fn stop_recording(
|
|||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
(
|
(
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
format!("couldn't send stop recording message: {}", e),
|
format!("couldn't send stop recording message: {e}"),
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
Ok((StatusCode::ACCEPTED, "ok".to_string()))
|
Ok((StatusCode::ACCEPTED, "ok".to_string()))
|
||||||
@@ -234,7 +235,7 @@ pub async fn delete_recording(
|
|||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
(
|
(
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
format!("couldn't send stop recording message: {}", e),
|
format!("couldn't send stop recording message: {e}"),
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
state
|
state
|
||||||
@@ -244,7 +245,7 @@ pub async fn delete_recording(
|
|||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
(
|
(
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
format!("couldn't send ui update message: {}", e),
|
format!("couldn't send ui update message: {e}"),
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
Ok((StatusCode::ACCEPTED, "ok".to_string()))
|
Ok((StatusCode::ACCEPTED, "ok".to_string()))
|
||||||
@@ -263,14 +264,14 @@ pub async fn delete_all_recordings(
|
|||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
(
|
(
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
format!("couldn't send stop recording message: {}", e),
|
format!("couldn't send stop recording message: {e}"),
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
let mut qmdl_store = state.qmdl_store_lock.write().await;
|
let mut qmdl_store = state.qmdl_store_lock.write().await;
|
||||||
qmdl_store.delete_all_entries().await.map_err(|e| {
|
qmdl_store.delete_all_entries().await.map_err(|e| {
|
||||||
(
|
(
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
format!("couldn't delete all recordings: {}", e),
|
format!("couldn't delete all recordings: {e}"),
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
state
|
state
|
||||||
@@ -280,7 +281,7 @@ pub async fn delete_all_recordings(
|
|||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
(
|
(
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
format!("couldn't send ui update message: {}", e),
|
format!("couldn't send ui update message: {e}"),
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
Ok((StatusCode::ACCEPTED, "ok".to_string()))
|
Ok((StatusCode::ACCEPTED, "ok".to_string()))
|
||||||
@@ -299,13 +300,13 @@ pub async fn get_analysis_report(
|
|||||||
} else {
|
} else {
|
||||||
qmdl_store.entry_for_name(&qmdl_name).ok_or((
|
qmdl_store.entry_for_name(&qmdl_name).ok_or((
|
||||||
StatusCode::NOT_FOUND,
|
StatusCode::NOT_FOUND,
|
||||||
format!("Couldn't find QMDL entry with name \"{}\"", qmdl_name),
|
format!("Couldn't find QMDL entry with name \"{qmdl_name}\""),
|
||||||
))?
|
))?
|
||||||
};
|
};
|
||||||
let analysis_file = qmdl_store
|
let analysis_file = qmdl_store
|
||||||
.open_entry_analysis(entry_index)
|
.open_entry_analysis(entry_index)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, format!("{:?}", e)))?;
|
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, format!("{e:?}")))?;
|
||||||
let analysis_stream = ReaderStream::new(analysis_file);
|
let analysis_stream = ReaderStream::new(analysis_file);
|
||||||
|
|
||||||
let headers = [(CONTENT_TYPE, "application/x-ndjson")];
|
let headers = [(CONTENT_TYPE, "application/x-ndjson")];
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ impl GenericFramebuffer for Framebuffer {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if res < 0 {
|
if res < 0 {
|
||||||
panic!("failed to send FBIORECT_DISPLAY ioctl, {}", res);
|
panic!("failed to send FBIORECT_DISPLAY ioctl, {res}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ pub fn update_ui(
|
|||||||
// we write the status every second because it may have been overwritten through menu
|
// we write the status every second because it may have been overwritten through menu
|
||||||
// navigation.
|
// navigation.
|
||||||
if display_level != 0 {
|
if display_level != 0 {
|
||||||
if let Err(e) = fs::write(OLED_PATH, &pixels) {
|
if let Err(e) = fs::write(OLED_PATH, pixels) {
|
||||||
error!("failed to write to display: {e}");
|
error!("failed to write to display: {e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ pub fn run_key_input_thread(
|
|||||||
let mut file = match File::open("/dev/input/event0").await {
|
let mut file = match File::open("/dev/input/event0").await {
|
||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Failed to open /dev/input/event0: {}", e);
|
error!("Failed to open /dev/input/event0: {e}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -49,7 +49,7 @@ pub fn run_key_input_thread(
|
|||||||
}
|
}
|
||||||
result = file.read_exact(&mut buffer) => {
|
result = file.read_exact(&mut buffer) => {
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
error!("failed to read key input: {}", e);
|
error!("failed to read key input: {e}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,12 +79,12 @@ pub fn run_key_input_thread(
|
|||||||
{
|
{
|
||||||
if let Err(e) = diag_tx.send(DiagDeviceCtrlMessage::StopRecording).await
|
if let Err(e) = diag_tx.send(DiagDeviceCtrlMessage::StopRecording).await
|
||||||
{
|
{
|
||||||
error!("Failed to send StopRecording: {}", e);
|
error!("Failed to send StopRecording: {e}");
|
||||||
}
|
}
|
||||||
if let Err(e) =
|
if let Err(e) =
|
||||||
diag_tx.send(DiagDeviceCtrlMessage::StartRecording).await
|
diag_tx.send(DiagDeviceCtrlMessage::StartRecording).await
|
||||||
{
|
{
|
||||||
error!("Failed to send StartRecording: {}", e);
|
error!("Failed to send StartRecording: {e}");
|
||||||
}
|
}
|
||||||
last_keyup = None;
|
last_keyup = None;
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ pub async fn get_pcap(
|
|||||||
}
|
}
|
||||||
let (entry_index, entry) = qmdl_store.entry_for_name(&qmdl_name).ok_or((
|
let (entry_index, entry) = qmdl_store.entry_for_name(&qmdl_name).ok_or((
|
||||||
StatusCode::NOT_FOUND,
|
StatusCode::NOT_FOUND,
|
||||||
format!("couldn't find manifest entry with name {}", qmdl_name),
|
format!("couldn't find manifest entry with name {qmdl_name}"),
|
||||||
))?;
|
))?;
|
||||||
if entry.qmdl_size_bytes == 0 {
|
if entry.qmdl_size_bytes == 0 {
|
||||||
return Err((
|
return Err((
|
||||||
@@ -40,14 +40,14 @@ pub async fn get_pcap(
|
|||||||
let qmdl_file = qmdl_store
|
let qmdl_file = qmdl_store
|
||||||
.open_entry_qmdl(entry_index)
|
.open_entry_qmdl(entry_index)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, format!("{:?}", e)))?;
|
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, format!("{e:?}")))?;
|
||||||
// the QMDL reader should stop at the last successfully written data chunk
|
// the QMDL reader should stop at the last successfully written data chunk
|
||||||
// (entry.size_bytes)
|
// (entry.size_bytes)
|
||||||
let (reader, writer) = duplex(1024);
|
let (reader, writer) = duplex(1024);
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
if let Err(e) = generate_pcap_data(writer, qmdl_file, qmdl_size_bytes).await {
|
if let Err(e) = generate_pcap_data(writer, qmdl_file, qmdl_size_bytes).await {
|
||||||
error!("failed to generate PCAP: {:?}", e);
|
error!("failed to generate PCAP: {e:?}");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ where
|
|||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => error!("error parsing message: {:?}", e),
|
Err(e) => error!("error parsing message: {e:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ pub async fn get_qmdl(
|
|||||||
let qmdl_store = state.qmdl_store_lock.read().await;
|
let qmdl_store = state.qmdl_store_lock.read().await;
|
||||||
let (entry_index, entry) = qmdl_store.entry_for_name(qmdl_idx).ok_or((
|
let (entry_index, entry) = qmdl_store.entry_for_name(qmdl_idx).ok_or((
|
||||||
StatusCode::NOT_FOUND,
|
StatusCode::NOT_FOUND,
|
||||||
format!("couldn't find qmdl file with name {}", qmdl_idx),
|
format!("couldn't find qmdl file with name {qmdl_idx}"),
|
||||||
))?;
|
))?;
|
||||||
let qmdl_file = qmdl_store
|
let qmdl_file = qmdl_store
|
||||||
.open_entry_qmdl(entry_index)
|
.open_entry_qmdl(entry_index)
|
||||||
@@ -52,7 +52,7 @@ pub async fn get_qmdl(
|
|||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
(
|
(
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
format!("error opening QMDL file: {}", err),
|
format!("error opening QMDL file: {err}"),
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
let limited_qmdl_file = qmdl_file.take(entry.qmdl_size_bytes as u64);
|
let limited_qmdl_file = qmdl_file.take(entry.qmdl_size_bytes as u64);
|
||||||
@@ -105,14 +105,14 @@ pub async fn set_config(
|
|||||||
let config_str = toml::to_string_pretty(&config).map_err(|err| {
|
let config_str = toml::to_string_pretty(&config).map_err(|err| {
|
||||||
(
|
(
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
format!("failed to serialize config as TOML: {}", err),
|
format!("failed to serialize config as TOML: {err}"),
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
write(&state.config_path, config_str).await.map_err(|err| {
|
write(&state.config_path, config_str).await.map_err(|err| {
|
||||||
(
|
(
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
format!("failed to write config file: {}", err),
|
format!("failed to write config file: {err}"),
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ pub async fn get_zip(
|
|||||||
let qmdl_store = state.qmdl_store_lock.read().await;
|
let qmdl_store = state.qmdl_store_lock.read().await;
|
||||||
let (entry_index, entry) = qmdl_store.entry_for_name(&qmdl_idx).ok_or((
|
let (entry_index, entry) = qmdl_store.entry_for_name(&qmdl_idx).ok_or((
|
||||||
StatusCode::NOT_FOUND,
|
StatusCode::NOT_FOUND,
|
||||||
format!("couldn't find entry with name {}", qmdl_idx),
|
format!("couldn't find entry with name {qmdl_idx}"),
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
if entry.qmdl_size_bytes == 0 {
|
if entry.qmdl_size_bytes == 0 {
|
||||||
@@ -207,7 +207,7 @@ pub async fn get_zip(
|
|||||||
{
|
{
|
||||||
// if we fail to generate the PCAP file, we should still continue and give the
|
// if we fail to generate the PCAP file, we should still continue and give the
|
||||||
// user the QMDL.
|
// user the QMDL.
|
||||||
error!("Failed to generate PCAP: {:?}", e);
|
error!("Failed to generate PCAP: {e:?}");
|
||||||
}
|
}
|
||||||
|
|
||||||
entry_writer.into_inner().close().await?;
|
entry_writer.into_inner().close().await?;
|
||||||
@@ -219,7 +219,7 @@ pub async fn get_zip(
|
|||||||
.await;
|
.await;
|
||||||
|
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
error!("Error generating ZIP file: {:?}", e);
|
error!("Error generating ZIP file: {e:?}");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -283,7 +283,7 @@ mod tests {
|
|||||||
|
|
||||||
let analysis_status = {
|
let analysis_status = {
|
||||||
let store = store_lock.try_read().unwrap();
|
let store = store_lock.try_read().unwrap();
|
||||||
crate::analysis::AnalysisStatus::new(&*store)
|
crate::analysis::AnalysisStatus::new(&store)
|
||||||
};
|
};
|
||||||
|
|
||||||
Arc::new(ServerState {
|
Arc::new(ServerState {
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ impl MemoryStats {
|
|||||||
// turns a number of kilobytes (like 28293) into a human-readable string (like "28.3M")
|
// turns a number of kilobytes (like 28293) into a human-readable string (like "28.3M")
|
||||||
fn humanize_kb(kb: usize) -> String {
|
fn humanize_kb(kb: usize) -> String {
|
||||||
if kb < 1000 {
|
if kb < 1000 {
|
||||||
return format!("{}K", kb);
|
return format!("{kb}K");
|
||||||
}
|
}
|
||||||
format!("{:.1}M", kb as f64 / 1024.0)
|
format!("{:.1}M", kb as f64 / 1024.0)
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@ pub async fn get_system_stats(
|
|||||||
match SystemStats::new(qmdl_store.path.to_str().unwrap()).await {
|
match SystemStats::new(qmdl_store.path.to_str().unwrap()).await {
|
||||||
Ok(stats) => Ok(Json(stats)),
|
Ok(stats) => Ok(Json(stats)),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("error getting system stats: {}", err);
|
error!("error getting system stats: {err}");
|
||||||
Err((
|
Err((
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
"error getting system stats".to_string(),
|
"error getting system stats".to_string(),
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ impl Harness {
|
|||||||
let qmdl_message = match maybe_qmdl_message {
|
let qmdl_message = match maybe_qmdl_message {
|
||||||
Ok(msg) => msg,
|
Ok(msg) => msg,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
row.skipped_message_reasons.push(format!("{:?}", err));
|
row.skipped_message_reasons.push(format!("{err:?}"));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -183,7 +183,7 @@ impl Harness {
|
|||||||
let gsmtap_message = match gsmtap_parser::parse(qmdl_message) {
|
let gsmtap_message = match gsmtap_parser::parse(qmdl_message) {
|
||||||
Ok(msg) => msg,
|
Ok(msg) => msg,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
row.skipped_message_reasons.push(format!("{:?}", err));
|
row.skipped_message_reasons.push(format!("{err:?}"));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -195,7 +195,7 @@ impl Harness {
|
|||||||
let element = match InformationElement::try_from(&gsmtap_msg) {
|
let element = match InformationElement::try_from(&gsmtap_msg) {
|
||||||
Ok(element) => element,
|
Ok(element) => element,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
row.skipped_message_reasons.push(format!("{:?}", err));
|
row.skipped_message_reasons.push(format!("{err:?}"));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ impl Analyzer for ConnectionRedirect2GDowngradeAnalyzer {
|
|||||||
}),
|
}),
|
||||||
_ => Some(Event {
|
_ => Some(Event {
|
||||||
event_type: EventType::Informational,
|
event_type: EventType::Informational,
|
||||||
message: format!("RRCConnectionRelease CarrierInfo: {:?}", carrier_info),
|
message: format!("RRCConnectionRelease CarrierInfo: {carrier_info:?}"),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
use std::any::Any;
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use pycrate_rs::nas::emm::EMMMessage;
|
use pycrate_rs::nas::emm::EMMMessage;
|
||||||
use pycrate_rs::nas::generated::emm::emm_identity_request::{EMMIdentityRequest, IDTypeV};
|
use pycrate_rs::nas::generated::emm::emm_identity_request::IDTypeV;
|
||||||
use pycrate_rs::nas::NASMessage;
|
use pycrate_rs::nas::NASMessage;
|
||||||
|
|
||||||
use super::analyzer::{Analyzer, Event, EventType, Severity};
|
use super::analyzer::{Analyzer, Event, EventType, Severity};
|
||||||
@@ -54,10 +53,9 @@ impl Analyzer for ImsiRequestedAnalyzer {
|
|||||||
},
|
},
|
||||||
message: format!(
|
message: format!(
|
||||||
"NAS IMSI identity request detected, however it was within \
|
"NAS IMSI identity request detected, however it was within \
|
||||||
the first {} packets of this analysis. If you just \
|
the first {PACKET_THRESHHOLD} packets of this analysis. If you just \
|
||||||
turned your device on, this is likely a \
|
turned your device on, this is likely a \
|
||||||
false-positive.",
|
false-positive."
|
||||||
PACKET_THRESHHOLD
|
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -103,25 +103,18 @@ impl DiagDevice {
|
|||||||
loop {
|
loop {
|
||||||
match Self::try_new().await {
|
match Self::try_new().await {
|
||||||
Ok(device) => {
|
Ok(device) => {
|
||||||
info!(
|
info!("Diag device initialization succeeded after {num_retries} retries");
|
||||||
"Diag device initialization succeeded after {} retries",
|
|
||||||
num_retries
|
|
||||||
);
|
|
||||||
return Ok(device);
|
return Ok(device);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
num_retries += 1;
|
num_retries += 1;
|
||||||
if start_time.elapsed() >= max_duration {
|
if start_time.elapsed() >= max_duration {
|
||||||
error!(
|
error!("Failed to initialize diag device after {max_duration:?}: {e}");
|
||||||
"Failed to initialize diag device after {:?}: {}",
|
|
||||||
max_duration, e
|
|
||||||
);
|
|
||||||
return Err(e);
|
return Err(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
"Diag device initialization failed {} times, retrying in {:?}: {}",
|
"Diag device initialization failed {num_retries} times, retrying in {delay:?}: {e}"
|
||||||
num_retries, delay, e
|
|
||||||
);
|
);
|
||||||
sleep(delay).await;
|
sleep(delay).await;
|
||||||
|
|
||||||
@@ -240,7 +233,7 @@ impl DiagDevice {
|
|||||||
}
|
}
|
||||||
_ => info!("skipping non-LogConfigResponse response..."),
|
_ => info!("skipping non-LogConfigResponse response..."),
|
||||||
},
|
},
|
||||||
Err(e) => error!("error parsing message: {:?}", e),
|
Err(e) => error!("error parsing message: {e:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,7 +261,7 @@ impl DiagDevice {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => error!("error parsing message: {:?}", e),
|
Err(e) => error!("error parsing message: {e:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +275,7 @@ impl DiagDevice {
|
|||||||
for (log_type, &log_mask_bitsize) in log_mask_sizes.iter().enumerate() {
|
for (log_type, &log_mask_bitsize) in log_mask_sizes.iter().enumerate() {
|
||||||
if log_mask_bitsize > 0 {
|
if log_mask_bitsize > 0 {
|
||||||
self.set_log_mask(log_type as u32, log_mask_bitsize).await?;
|
self.set_log_mask(log_type as u32, log_mask_bitsize).await?;
|
||||||
info!("enabled logging for log type {}", log_type);
|
info!("enabled logging for log type {log_type}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,10 +339,7 @@ fn enable_frame_readwrite(fd: i32, mode: u32) -> DiagResult<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ret < 0 {
|
if ret < 0 {
|
||||||
let msg = format!(
|
let msg = format!("DIAG_IOCTL_SWITCH_LOGGING ioctl failed with error code {ret}");
|
||||||
"DIAG_IOCTL_SWITCH_LOGGING ioctl failed with error code {}",
|
|
||||||
ret
|
|
||||||
);
|
|
||||||
return Err(DiagDeviceError::InitializationFailed(msg));
|
return Err(DiagDeviceError::InitializationFailed(msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ fn log_to_gsmtap(value: LogBody) -> Result<Option<GsmtapMessage>, GsmtapParserEr
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
error!("gsmtap_sink: ignoring unhandled log type: {:?}", value);
|
error!("gsmtap_sink: ignoring unhandled log type: {value:?}");
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user