mirror of
https://github.com/EFForg/rayhunter.git
synced 2026-05-27 10:04:47 -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)?;
|
.map_err(WavehunterError::PcapFileWriteError)?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
for msg in dev.read_response().map_err(WavehunterError::DiagReadError)? {
|
for maybe_msg in dev.read_response().map_err(WavehunterError::DiagReadError)? {
|
||||||
debug!("msg: {:?}", msg);
|
match maybe_msg {
|
||||||
if let Some((timestamp, gsmtap_msg)) = gsmtap_parser.recv_message(msg).map_err(WavehunterError::GsmtapParsingError)? {
|
Ok(msg) => {
|
||||||
debug!("gsmtap_msg: {:?}", gsmtap_msg);
|
debug!("msg: {:?}", msg);
|
||||||
pcap_file.write_gsmtap_message(gsmtap_msg, timestamp)
|
let maybe_gsmtap_msg = gsmtap_parser.recv_message(msg)
|
||||||
.map_err(WavehunterError::PcapFileWriteError)?;
|
.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();
|
pcap_file.write_iface_header().unwrap();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match qmdl_reader.read_response() {
|
for maybe_msg in qmdl_reader.read_response().expect("error reading qmdl file") {
|
||||||
Ok(msgs) => {
|
match maybe_msg {
|
||||||
for msg in msgs {
|
Ok(msg) => {
|
||||||
debug!("msg: {:?}", 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);
|
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(e) => {
|
||||||
Err(err) if err.kind() == std::io::ErrorKind::UnexpectedEof => {
|
dbg!("error parsing message: {:?}", e);
|
||||||
println!("Reached end of QMDL file, exiting...");
|
},
|
||||||
std::process::exit(0);
|
}
|
||||||
},
|
|
||||||
Err(err) => panic!("Error reading QMDL file {}", err),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,8 +137,8 @@ impl DiagDevice {
|
|||||||
|
|
||||||
for msg in self.read_response()? {
|
for msg in self.read_response()? {
|
||||||
match msg {
|
match msg {
|
||||||
Message::Log { .. } => info!("skipping log response..."),
|
Ok(Message::Log { .. }) => info!("skipping log response..."),
|
||||||
Message::Response { payload, status, .. } => match payload {
|
Ok(Message::Response { payload, status, .. }) => match payload {
|
||||||
ResponsePayload::LogConfig(LogConfigResponse::RetrieveIdRanges { log_mask_sizes }) => {
|
ResponsePayload::LogConfig(LogConfigResponse::RetrieveIdRanges { log_mask_sizes }) => {
|
||||||
if status != 0 {
|
if status != 0 {
|
||||||
return Err(DiagDeviceError::RequestFailed(status, req));
|
return Err(DiagDeviceError::RequestFailed(status, req));
|
||||||
@@ -147,6 +147,7 @@ impl DiagDevice {
|
|||||||
},
|
},
|
||||||
_ => info!("skipping non-LogConfigResponse response..."),
|
_ => info!("skipping non-LogConfigResponse response..."),
|
||||||
},
|
},
|
||||||
|
Err(e) => error!("error parsing message: {:?}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,8 +160,8 @@ impl DiagDevice {
|
|||||||
|
|
||||||
for msg in self.read_response()? {
|
for msg in self.read_response()? {
|
||||||
match msg {
|
match msg {
|
||||||
Message::Log { .. } => info!("skipping log response..."),
|
Ok(Message::Log { .. }) => info!("skipping log response..."),
|
||||||
Message::Response { payload, status, .. } => {
|
Ok(Message::Response { payload, status, .. }) => {
|
||||||
if let ResponsePayload::LogConfig(LogConfigResponse::SetMask) = payload {
|
if let ResponsePayload::LogConfig(LogConfigResponse::SetMask) = payload {
|
||||||
if status != 0 {
|
if status != 0 {
|
||||||
return Err(DiagDeviceError::RequestFailed(status, req));
|
return Err(DiagDeviceError::RequestFailed(status, req));
|
||||||
@@ -168,6 +169,7 @@ impl DiagDevice {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Err(e) => error!("error parsing message: {:?}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
use crate::diag;
|
use crate::diag;
|
||||||
use crate::{diag::*, hdlc::hdlc_decapsulate};
|
use crate::{diag::*, hdlc::hdlc_decapsulate};
|
||||||
|
use crate::hdlc;
|
||||||
|
|
||||||
use crc::{Crc, Algorithm};
|
use crc::{Crc, Algorithm};
|
||||||
use deku::prelude::*;
|
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
|
// 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
|
// 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);
|
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 {
|
pub trait DiagReader {
|
||||||
type Err;
|
type Err;
|
||||||
|
|
||||||
fn get_next_messages_container(&mut self) -> Result<MessagesContainer, Self::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 {
|
loop {
|
||||||
let container = self.get_next_messages_container()?;
|
let container = self.get_next_messages_container()?;
|
||||||
if container.data_type == DataType::UserSpace {
|
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();
|
let mut result = Vec::new();
|
||||||
for msg in container.messages {
|
for msg in container.messages {
|
||||||
for sub_msg in msg.data.split_inclusive(|&b| b == diag::MESSAGE_TERMINATOR) {
|
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 {
|
if leftover_bytes.len() > 0 {
|
||||||
warn!("warning: {} leftover bytes when parsing Message", leftover_bytes.len());
|
warn!("warning: {} leftover bytes when parsing Message", leftover_bytes.len());
|
||||||
}
|
}
|
||||||
result.push(res);
|
result.push(Ok(res));
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("error parsing response: {:?}", e);
|
result.push(Err(DiagParsingError::MessageParsingError(e, data)));
|
||||||
debug!("{:?}", data);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("error decapsulating response: {:?}", err);
|
result.push(Err(DiagParsingError::HdlcDecapsulationError(err, sub_msg.to_vec())));
|
||||||
debug!("{:?}", &sub_msg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user