mirror of
https://github.com/EFForg/rayhunter.git
synced 2026-05-27 01:54:46 -07:00
diag_reader: raise parsing/hdlc error handling to caller
This'll let us unit test the reader more easily
This commit is contained in:
@@ -75,12 +75,21 @@ fn main() -> Result<(), WavehunterError> {
|
||||
.map_err(WavehunterError::PcapFileWriteError)?;
|
||||
|
||||
loop {
|
||||
for msg in dev.read_response().map_err(WavehunterError::DiagReadError)? {
|
||||
debug!("msg: {:?}", msg);
|
||||
if let Some((timestamp, gsmtap_msg)) = gsmtap_parser.recv_message(msg).map_err(WavehunterError::GsmtapParsingError)? {
|
||||
debug!("gsmtap_msg: {:?}", gsmtap_msg);
|
||||
pcap_file.write_gsmtap_message(gsmtap_msg, timestamp)
|
||||
.map_err(WavehunterError::PcapFileWriteError)?;
|
||||
for maybe_msg in dev.read_response().map_err(WavehunterError::DiagReadError)? {
|
||||
match maybe_msg {
|
||||
Ok(msg) => {
|
||||
debug!("msg: {:?}", msg);
|
||||
let maybe_gsmtap_msg = gsmtap_parser.recv_message(msg)
|
||||
.map_err(WavehunterError::GsmtapParsingError)?;
|
||||
if let Some((timestamp, gsmtap_msg)) = maybe_gsmtap_msg {
|
||||
debug!("gsmtap_msg: {:?}", gsmtap_msg);
|
||||
pcap_file.write_gsmtap_message(gsmtap_msg, timestamp)
|
||||
.map_err(WavehunterError::PcapFileWriteError)?;
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
dbg!("error parsing message: {:?}", e);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,21 +20,21 @@ fn main() {
|
||||
pcap_file.write_iface_header().unwrap();
|
||||
|
||||
loop {
|
||||
match qmdl_reader.read_response() {
|
||||
Ok(msgs) => {
|
||||
for msg in msgs {
|
||||
for maybe_msg in qmdl_reader.read_response().expect("error reading qmdl file") {
|
||||
match maybe_msg {
|
||||
Ok(msg) => {
|
||||
debug!("msg: {:?}", msg);
|
||||
if let Some((timestamp, gsmtap_msg)) = gsmtap_parser.recv_message(msg).unwrap() {
|
||||
let maybe_gsmtap_msg = gsmtap_parser.recv_message(msg).expect("error parsing gsmtap message");
|
||||
if let Some((timestamp, gsmtap_msg)) = maybe_gsmtap_msg {
|
||||
debug!("gsmtap_msg: {:?}", gsmtap_msg);
|
||||
pcap_file.write_gsmtap_message(gsmtap_msg, timestamp).unwrap();
|
||||
pcap_file.write_gsmtap_message(gsmtap_msg, timestamp)
|
||||
.expect("error writing pcap packet");
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(err) if err.kind() == std::io::ErrorKind::UnexpectedEof => {
|
||||
println!("Reached end of QMDL file, exiting...");
|
||||
std::process::exit(0);
|
||||
},
|
||||
Err(err) => panic!("Error reading QMDL file {}", err),
|
||||
},
|
||||
Err(e) => {
|
||||
dbg!("error parsing message: {:?}", e);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,8 +137,8 @@ impl DiagDevice {
|
||||
|
||||
for msg in self.read_response()? {
|
||||
match msg {
|
||||
Message::Log { .. } => info!("skipping log response..."),
|
||||
Message::Response { payload, status, .. } => match payload {
|
||||
Ok(Message::Log { .. }) => info!("skipping log response..."),
|
||||
Ok(Message::Response { payload, status, .. }) => match payload {
|
||||
ResponsePayload::LogConfig(LogConfigResponse::RetrieveIdRanges { log_mask_sizes }) => {
|
||||
if status != 0 {
|
||||
return Err(DiagDeviceError::RequestFailed(status, req));
|
||||
@@ -147,6 +147,7 @@ impl DiagDevice {
|
||||
},
|
||||
_ => info!("skipping non-LogConfigResponse response..."),
|
||||
},
|
||||
Err(e) => error!("error parsing message: {:?}", e),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,8 +160,8 @@ impl DiagDevice {
|
||||
|
||||
for msg in self.read_response()? {
|
||||
match msg {
|
||||
Message::Log { .. } => info!("skipping log response..."),
|
||||
Message::Response { payload, status, .. } => {
|
||||
Ok(Message::Log { .. }) => info!("skipping log response..."),
|
||||
Ok(Message::Response { payload, status, .. }) => {
|
||||
if let ResponsePayload::LogConfig(LogConfigResponse::SetMask) = payload {
|
||||
if status != 0 {
|
||||
return Err(DiagDeviceError::RequestFailed(status, req));
|
||||
@@ -168,6 +169,7 @@ impl DiagDevice {
|
||||
return Ok(());
|
||||
}
|
||||
},
|
||||
Err(e) => error!("error parsing message: {:?}", e),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
use crate::diag;
|
||||
use crate::{diag::*, hdlc::hdlc_decapsulate};
|
||||
use crate::hdlc;
|
||||
|
||||
use crc::{Crc, Algorithm};
|
||||
use deku::prelude::*;
|
||||
use log::{debug, info, warn, error};
|
||||
use log::{info, warn, error};
|
||||
use thiserror::Error;
|
||||
|
||||
// this is sorta based on the params qcsuper uses, plus what seems to be used in
|
||||
// https://github.com/fgsect/scat/blob/f1538b397721df3ab8ba12acd26716abcf21f78b/util.py#L47
|
||||
@@ -19,12 +21,22 @@ pub const CRC_CCITT_ALG: Algorithm<u16> = Algorithm {
|
||||
};
|
||||
pub const CRC_CCITT: Crc<u16> = Crc::<u16>::new(&CRC_CCITT_ALG);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum DiagParsingError {
|
||||
#[error("Failed to parse Message: {0}, data: {1:?}")]
|
||||
MessageParsingError(deku::DekuError, Vec<u8>),
|
||||
#[error("HDLC decapsulation of message failed: {0}, data: {1:?}")]
|
||||
HdlcDecapsulationError(hdlc::HdlcError, Vec<u8>),
|
||||
}
|
||||
|
||||
type MaybeMessage = Result<Message, DiagParsingError>;
|
||||
|
||||
pub trait DiagReader {
|
||||
type Err;
|
||||
|
||||
fn get_next_messages_container(&mut self) -> Result<MessagesContainer, Self::Err>;
|
||||
|
||||
fn read_response(&mut self) -> Result<Vec<Message>, Self::Err> {
|
||||
fn read_response(&mut self) -> Result<Vec<MaybeMessage>, Self::Err> {
|
||||
loop {
|
||||
let container = self.get_next_messages_container()?;
|
||||
if container.data_type == DataType::UserSpace {
|
||||
@@ -35,7 +47,7 @@ pub trait DiagReader {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_response_container(&self, container: MessagesContainer) -> Result<Vec<Message>, Self::Err> {
|
||||
fn parse_response_container(&self, container: MessagesContainer) -> Result<Vec<MaybeMessage>, Self::Err> {
|
||||
let mut result = Vec::new();
|
||||
for msg in container.messages {
|
||||
for sub_msg in msg.data.split_inclusive(|&b| b == diag::MESSAGE_TERMINATOR) {
|
||||
@@ -45,16 +57,14 @@ pub trait DiagReader {
|
||||
if leftover_bytes.len() > 0 {
|
||||
warn!("warning: {} leftover bytes when parsing Message", leftover_bytes.len());
|
||||
}
|
||||
result.push(res);
|
||||
result.push(Ok(res));
|
||||
},
|
||||
Err(e) => {
|
||||
error!("error parsing response: {:?}", e);
|
||||
debug!("{:?}", data);
|
||||
result.push(Err(DiagParsingError::MessageParsingError(e, data)));
|
||||
},
|
||||
},
|
||||
Err(err) => {
|
||||
error!("error decapsulating response: {:?}", err);
|
||||
debug!("{:?}", &sub_msg);
|
||||
result.push(Err(DiagParsingError::HdlcDecapsulationError(err, sub_msg.to_vec())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user