mirror of
https://github.com/EFForg/rayhunter.git
synced 2026-05-24 08:44:45 -07:00
some renaming, reorganization
This commit is contained in:
50
src/debug_file.rs
Normal file
50
src/debug_file.rs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
use crate::diag_reader::DiagReader;
|
||||||
|
use crate::diag_device::DiagResult;
|
||||||
|
use crate::diag::*;
|
||||||
|
|
||||||
|
use deku::prelude::*;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Read;
|
||||||
|
|
||||||
|
#[derive(Debug, DekuRead, DekuWrite)]
|
||||||
|
#[deku(endian = "little")]
|
||||||
|
pub struct DebugFileBlock<'a> {
|
||||||
|
pub size: u32,
|
||||||
|
#[deku(count = "size")]
|
||||||
|
pub data: &'a [u8],
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct DebugFileReader {
|
||||||
|
file: File,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DebugFileReader {
|
||||||
|
pub fn new<P>(path: P) -> DiagResult<Self> where P: AsRef<std::path::Path> {
|
||||||
|
let file = std::fs::File::options()
|
||||||
|
.read(true)
|
||||||
|
.open(path)?;
|
||||||
|
Ok(DebugFileReader { file })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl DiagReader for DebugFileReader {
|
||||||
|
fn get_next_messages_container(&mut self) -> DiagResult<MessagesContainer> {
|
||||||
|
let mut bytes_read_buf = [0; 4];
|
||||||
|
if let Err(e) = self.file.read_exact(&mut bytes_read_buf) {
|
||||||
|
if e.kind() == std::io::ErrorKind::UnexpectedEof {
|
||||||
|
println!("reached end of debug file, exiting...");
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
return Err(e.into());
|
||||||
|
}
|
||||||
|
let bytes_read = u32::from_le_bytes(bytes_read_buf) as usize;
|
||||||
|
let mut data = vec![0; bytes_read as usize];
|
||||||
|
self.file.read_exact(&mut data)?;
|
||||||
|
let ((leftover_bytes, _), container) = MessagesContainer::from_bytes((&data, 0))?;
|
||||||
|
if leftover_bytes.len() > 0 {
|
||||||
|
println!("warning: {} leftover bytes when parsing MessagesContainer", leftover_bytes.len());
|
||||||
|
}
|
||||||
|
Ok(container)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
mod hdlc;
|
mod hdlc;
|
||||||
mod diag;
|
mod diag;
|
||||||
mod diag_device;
|
mod diag_device;
|
||||||
|
mod diag_reader;
|
||||||
|
mod debug_file;
|
||||||
mod log_codes;
|
mod log_codes;
|
||||||
|
|
||||||
use crate::diag_device::{DebugFileReader, DiagReader};
|
use crate::debug_file::DebugFileReader;
|
||||||
|
use crate::diag_reader::DiagReader;
|
||||||
|
|
||||||
fn main() -> diag_device::DiagResult<()> {
|
fn main() -> diag_device::DiagResult<()> {
|
||||||
// this should eventually be removed for prod
|
// this should eventually be removed for prod
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
use crate::hdlc::{hdlc_encapsulate, hdlc_decapsulate, HdlcError};
|
use crate::hdlc::{hdlc_encapsulate, HdlcError};
|
||||||
use crate::diag::{Message, ResponsePayload, Request, LogConfigRequest, LogConfigResponse, build_log_mask_request, RequestContainer, DataType, MessagesContainer};
|
use crate::diag::{Message, ResponsePayload, Request, LogConfigRequest, LogConfigResponse, build_log_mask_request, RequestContainer, DataType, MessagesContainer};
|
||||||
|
use crate::diag_reader::{DiagReader, CRC_CCITT};
|
||||||
|
use crate::debug_file::DebugFileBlock;
|
||||||
use crate::log_codes;
|
use crate::log_codes;
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{Read, Write, Seek};
|
use std::io::{Read, Write};
|
||||||
use std::os::fd::AsRawFd;
|
use std::os::fd::AsRawFd;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use crc::{Crc, Algorithm};
|
|
||||||
use deku::prelude::*;
|
use deku::prelude::*;
|
||||||
|
|
||||||
pub type DiagResult<T> = Result<T, DiagDeviceError>;
|
pub type DiagResult<T> = Result<T, DiagDeviceError>;
|
||||||
@@ -29,20 +30,6 @@ pub enum DiagDeviceError {
|
|||||||
DekuError(#[from] DekuError),
|
DekuError(#[from] DekuError),
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
|
||||||
pub const CRC_CCITT_ALG: Algorithm<u16> = Algorithm {
|
|
||||||
poly: 0x1021,
|
|
||||||
init: 0xffff,
|
|
||||||
refin: true,
|
|
||||||
refout: true,
|
|
||||||
width: 16,
|
|
||||||
xorout: 0xffff,
|
|
||||||
check: 0x2189,
|
|
||||||
residue: 0x0000,
|
|
||||||
};
|
|
||||||
pub const CRC_CCITT: Crc<u16> = Crc::<u16>::new(&CRC_CCITT_ALG);
|
|
||||||
|
|
||||||
pub const LOG_CODES_FOR_RAW_PACKET_LOGGING: [u32; 11] = [
|
pub const LOG_CODES_FOR_RAW_PACKET_LOGGING: [u32; 11] = [
|
||||||
// Layer 2:
|
// Layer 2:
|
||||||
log_codes::LOG_GPRS_MAC_SIGNALLING_MESSAGE_C, // 0x5226
|
log_codes::LOG_GPRS_MAC_SIGNALLING_MESSAGE_C, // 0x5226
|
||||||
@@ -76,100 +63,13 @@ pub struct DiagDevice<'a> {
|
|||||||
use_mdm: i32,
|
use_mdm: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, DekuRead, DekuWrite)]
|
|
||||||
#[deku(endian = "little")]
|
|
||||||
struct DebugReadBlock<'a> {
|
|
||||||
size: u32,
|
|
||||||
#[deku(count = "size")]
|
|
||||||
data: &'a [u8],
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct DebugFileReader {
|
|
||||||
file: File,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DebugFileReader {
|
|
||||||
pub fn new<P>(path: P) -> DiagResult<Self> where P: AsRef<std::path::Path> {
|
|
||||||
let file = std::fs::File::options()
|
|
||||||
.read(true)
|
|
||||||
.open(path)?;
|
|
||||||
Ok(DebugFileReader { file })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait DiagReader {
|
|
||||||
fn get_next_messages_container(&mut self) -> DiagResult<MessagesContainer>;
|
|
||||||
|
|
||||||
fn read_response(&mut self) -> DiagResult<Vec<Message>> {
|
|
||||||
loop {
|
|
||||||
let container = self.get_next_messages_container()?;
|
|
||||||
if container.data_type == DataType::UserSpace {
|
|
||||||
return self.parse_response_container(container);
|
|
||||||
} else {
|
|
||||||
println!("skipping non-userspace message...")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_response_container(&self, container: MessagesContainer) -> DiagResult<Vec<Message>> {
|
|
||||||
let mut result = Vec::new();
|
|
||||||
for msg in container.messages {
|
|
||||||
for sub_msg in msg.data.split_inclusive(|&b| b == 0x7e) {
|
|
||||||
match hdlc_decapsulate(&sub_msg, &CRC_CCITT) {
|
|
||||||
Ok(data) => match Message::from_bytes((&data, 0)) {
|
|
||||||
Ok(((leftover_bytes, _), res)) => {
|
|
||||||
if leftover_bytes.len() > 0 {
|
|
||||||
println!("warning: {} leftover bytes when parsing Message", leftover_bytes.len());
|
|
||||||
}
|
|
||||||
result.push(res);
|
|
||||||
},
|
|
||||||
Err(e) => {
|
|
||||||
println!("error parsing response: {:?}", e);
|
|
||||||
println!("{:?}", data);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Err(err) => {
|
|
||||||
println!("error decapsulating response: {:?}", err);
|
|
||||||
println!("{:?}", &sub_msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
impl DiagReader for DebugFileReader {
|
|
||||||
fn get_next_messages_container(&mut self) -> DiagResult<MessagesContainer> {
|
|
||||||
let mut bytes_read_buf = [0; 4];
|
|
||||||
match self.file.read_exact(&mut bytes_read_buf) {
|
|
||||||
Ok(_) => {},
|
|
||||||
Err(e) => {
|
|
||||||
dbg!(e.kind());
|
|
||||||
if e.kind() == std::io::ErrorKind::UnexpectedEof {
|
|
||||||
println!("reached end of debug file, exiting...");
|
|
||||||
std::process::exit(0);
|
|
||||||
}
|
|
||||||
return Err(e.into());
|
|
||||||
},
|
|
||||||
}
|
|
||||||
let bytes_read = u32::from_le_bytes(bytes_read_buf) as usize;
|
|
||||||
let mut data = vec![0; bytes_read as usize];
|
|
||||||
self.file.read_exact(&mut data)?;
|
|
||||||
let ((leftover_bytes, _), container) = MessagesContainer::from_bytes((&data, 0))?;
|
|
||||||
if leftover_bytes.len() > 0 {
|
|
||||||
println!("warning: {} leftover bytes when parsing MessagesContainer", leftover_bytes.len());
|
|
||||||
}
|
|
||||||
Ok(container)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> DiagReader for DiagDevice<'a> {
|
impl<'a> DiagReader for DiagDevice<'a> {
|
||||||
fn get_next_messages_container(&mut self) -> DiagResult<MessagesContainer> {
|
fn get_next_messages_container(&mut self) -> DiagResult<MessagesContainer> {
|
||||||
let bytes_read = self.file.read(&mut self.read_buf).unwrap();
|
let bytes_read = self.file.read(&mut self.read_buf).unwrap();
|
||||||
if let Some(debug_file) = self.debug_file.as_mut() {
|
if let Some(debug_file) = self.debug_file.as_mut() {
|
||||||
let debug_block = DebugReadBlock {
|
let debug_block = DebugFileBlock {
|
||||||
size: bytes_read as u32,
|
size: bytes_read as u32,
|
||||||
data: &self.read_buf[0..bytes_read],
|
data: &self.read_buf[0..bytes_read],
|
||||||
};
|
};
|
||||||
|
|||||||
61
src/diag_reader.rs
Normal file
61
src/diag_reader.rs
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
use crate::{diag::*, hdlc::hdlc_decapsulate};
|
||||||
|
use crate::diag_device::DiagResult;
|
||||||
|
|
||||||
|
use crc::{Crc, Algorithm};
|
||||||
|
use deku::prelude::*;
|
||||||
|
|
||||||
|
// 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
|
||||||
|
pub const CRC_CCITT_ALG: Algorithm<u16> = Algorithm {
|
||||||
|
poly: 0x1021,
|
||||||
|
init: 0xffff,
|
||||||
|
refin: true,
|
||||||
|
refout: true,
|
||||||
|
width: 16,
|
||||||
|
xorout: 0xffff,
|
||||||
|
check: 0x2189,
|
||||||
|
residue: 0x0000,
|
||||||
|
};
|
||||||
|
pub const CRC_CCITT: Crc<u16> = Crc::<u16>::new(&CRC_CCITT_ALG);
|
||||||
|
|
||||||
|
pub trait DiagReader {
|
||||||
|
fn get_next_messages_container(&mut self) -> DiagResult<MessagesContainer>;
|
||||||
|
|
||||||
|
fn read_response(&mut self) -> DiagResult<Vec<Message>> {
|
||||||
|
loop {
|
||||||
|
let container = self.get_next_messages_container()?;
|
||||||
|
if container.data_type == DataType::UserSpace {
|
||||||
|
return self.parse_response_container(container);
|
||||||
|
} else {
|
||||||
|
println!("skipping non-userspace message...")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_response_container(&self, container: MessagesContainer) -> DiagResult<Vec<Message>> {
|
||||||
|
let mut result = Vec::new();
|
||||||
|
for msg in container.messages {
|
||||||
|
for sub_msg in msg.data.split_inclusive(|&b| b == 0x7e) {
|
||||||
|
match hdlc_decapsulate(&sub_msg, &CRC_CCITT) {
|
||||||
|
Ok(data) => match Message::from_bytes((&data, 0)) {
|
||||||
|
Ok(((leftover_bytes, _), res)) => {
|
||||||
|
if leftover_bytes.len() > 0 {
|
||||||
|
println!("warning: {} leftover bytes when parsing Message", leftover_bytes.len());
|
||||||
|
}
|
||||||
|
result.push(res);
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
println!("error parsing response: {:?}", e);
|
||||||
|
println!("{:?}", data);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Err(err) => {
|
||||||
|
println!("error decapsulating response: {:?}", err);
|
||||||
|
println!("{:?}", &sub_msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -87,7 +87,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_hdlc_encapsulate() {
|
fn test_hdlc_encapsulate() {
|
||||||
let crc = Crc::<u16>::new(&crate::diag_device::CRC_CCITT_ALG);
|
let crc = Crc::<u16>::new(&crate::diag_reader::CRC_CCITT_ALG);
|
||||||
let data = vec![0x01, 0x02, 0x03, 0x04];
|
let data = vec![0x01, 0x02, 0x03, 0x04];
|
||||||
let expected = vec![1, 2, 3, 4, 145, 57, 126];
|
let expected = vec![1, 2, 3, 4, 145, 57, 126];
|
||||||
let encapsulated = hdlc_encapsulate(&data, &crc);
|
let encapsulated = hdlc_encapsulate(&data, &crc);
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
mod hdlc;
|
mod hdlc;
|
||||||
mod diag;
|
mod diag;
|
||||||
mod diag_device;
|
mod diag_device;
|
||||||
|
mod diag_reader;
|
||||||
|
mod debug_file;
|
||||||
mod log_codes;
|
mod log_codes;
|
||||||
|
|
||||||
use crate::diag_device::{DiagDevice, DiagReader};
|
use crate::diag_device::DiagDevice;
|
||||||
|
use crate::diag_reader::DiagReader;
|
||||||
|
|
||||||
fn main() -> diag_device::DiagResult<()> {
|
fn main() -> diag_device::DiagResult<()> {
|
||||||
// this should eventually be removed for prod
|
// this should eventually be removed for prod
|
||||||
|
|||||||
Reference in New Issue
Block a user