mirror of
https://github.com/EFForg/rayhunter.git
synced 2026-06-30 06:02:06 -07:00
linting and polishing for PR
This commit is contained in:
committed by
Will Greenberg
parent
8f03ad8f4a
commit
c424902560
@@ -77,23 +77,31 @@ mod test {
|
||||
// Constructed as: opcode(1) + pending(1) + outer_len(2) + inner_len(2) +
|
||||
// log_type(2=0xb17f LE) + timestamp(8) + body(40) = 56 bytes total
|
||||
let mut msg_bytes: Vec<u8> = vec![
|
||||
0x10, 0x00, // opcode=Log, pending=0
|
||||
56, 0, 56, 0, // outer_length=56, inner_length=56
|
||||
0x7f, 0xb1, // log_type = 0xb17f (LE)
|
||||
0x10, 0x00, // opcode=Log, pending=0
|
||||
56, 0, 56, 0, // outer_length=56, inner_length=56
|
||||
0x7f, 0xb1, // log_type = 0xb17f (LE)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // timestamp
|
||||
];
|
||||
msg_bytes.extend_from_slice(&[
|
||||
0x05, // version=5
|
||||
0x01, 0x00, 0x00, 0x39, 0x07, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00,
|
||||
0xab, 0xb5, 0x5a, 0x00, 0xab, 0xb5, 0x5a, 0x00,
|
||||
0x1a, 0x69, 0xa4, 0x11, 0x1a, 0x45, 0x0d, 0x00, 0x86, 0xa7, 0xae, 0x02,
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x1c, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x39, 0x07, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0xab, 0xb5, 0x5a,
|
||||
0x00, 0xab, 0xb5, 0x5a, 0x00, 0x1a, 0x69, 0xa4, 0x11, 0x1a, 0x45, 0x0d, 0x00, 0x86,
|
||||
0xa7, 0xae, 0x02, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1c, 0x00, 0x00,
|
||||
]);
|
||||
let msg = Message::from_bytes((&msg_bytes, 0)).expect("Message parse failed").1;
|
||||
if let Message::Log { body: LogBody::LteMl1ServingCellMeas { packet, .. }, .. } = msg {
|
||||
let msg = Message::from_bytes((&msg_bytes, 0))
|
||||
.expect("Message parse failed")
|
||||
.1;
|
||||
if let Message::Log {
|
||||
body: LogBody::LteMl1ServingCellMeas { packet, .. },
|
||||
..
|
||||
} = msg
|
||||
{
|
||||
assert_eq!(packet.get_earfcn(), 1849);
|
||||
let rsrp = packet.get_rsrp_dbm();
|
||||
assert!(rsrp <= -44 && rsrp >= -120, "RSRP {rsrp} dBm outside valid LTE range");
|
||||
assert!(
|
||||
rsrp <= -44 && rsrp >= -120,
|
||||
"RSRP {rsrp} dBm outside valid LTE range"
|
||||
);
|
||||
} else {
|
||||
panic!("unexpected message variant");
|
||||
}
|
||||
|
||||
@@ -201,7 +201,8 @@ fn parse_rach_response(payload: &[u8]) -> Option<GsmtapMessage> {
|
||||
|
||||
if sp_id == 0x06 {
|
||||
// RACH Attempt subpacket
|
||||
if let Some(msg) = extract_rach_attempt_gsmtap(&payload[offset + 4..sp_end], sp_version) {
|
||||
if let Some(msg) = extract_rach_attempt_gsmtap(&payload[offset + 4..sp_end], sp_version)
|
||||
{
|
||||
return Some(msg);
|
||||
}
|
||||
}
|
||||
@@ -258,7 +259,10 @@ fn extract_rach_attempt_gsmtap(body: &[u8], version: u8) -> Option<GsmtapMessage
|
||||
// RA-RNTI (type=2) and applies the RAR PDU format. The 4-byte framing prefix is:
|
||||
// [RadioType=1(FDD)][Direction=1(DL)][RNTIType=2(RA-RNTI)][0x01=payload-marker]
|
||||
let payload = vec![
|
||||
0x01u8, 0x01, 0x02, 0x01, // framing: FDD, DL, RA-RNTI, payload-marker
|
||||
0x01u8,
|
||||
0x01,
|
||||
0x02,
|
||||
0x01, // framing: FDD, DL, RA-RNTI, payload-marker
|
||||
rapid & 0x3F,
|
||||
((ta >> 3) & 0xFF) as u8,
|
||||
((ta & 0x07) as u8) << 5,
|
||||
@@ -278,6 +282,7 @@ fn extract_rach_attempt_gsmtap(body: &[u8], version: u8) -> Option<GsmtapMessage
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::gsmtap::GsmtapType;
|
||||
use deku::DekuContainerWrite;
|
||||
|
||||
#[test]
|
||||
@@ -293,4 +298,49 @@ mod tests {
|
||||
// This would panic before the fix with "bit size of input is larger than bit requested size"
|
||||
assert!(msg.to_bytes().is_ok());
|
||||
}
|
||||
|
||||
// Builds a minimal 0xb062 payload: outer header + one RACH Attempt subpacket (version 0x03).
|
||||
// v0x03 body layout: hdr=6B [_, _, rapid, _, _, bitmask], then MSG2=7B [backoff(2), result(1), tc_rnti(2), ta(2)]
|
||||
fn make_rach_v03_payload(ta_raw: u16, bitmask: u8) -> Vec<u8> {
|
||||
let rapid: u8 = 43;
|
||||
let tc_rnti: u16 = 0x1234;
|
||||
let [ta_lo, ta_hi] = ta_raw.to_le_bytes();
|
||||
let [rnti_lo, rnti_hi] = tc_rnti.to_le_bytes();
|
||||
// sp_size covers the 4-byte subpacket header + 6-byte body header + 7-byte MSG2 = 17
|
||||
vec![
|
||||
0x01, 0x01, 0x00, 0x00, // outer: version=1, num_subpackets=1, reserved
|
||||
0x06, 0x03, 17, 0x00, // subpacket: id=0x06, version=0x03, size=17 LE
|
||||
0x00, 0x00, rapid, 0x00, 0x00, bitmask, // body header (6 bytes)
|
||||
0x00, 0x00, 0x01, rnti_lo, rnti_hi, ta_lo, ta_hi, // MSG2 (7 bytes)
|
||||
]
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rach_response_valid_ta() {
|
||||
let payload = make_rach_v03_payload(42, 0x02); // 0x02 = msg2 present, msg1 absent
|
||||
let msg = parse_rach_response(&payload).expect("expected a GsmtapMessage for valid TA");
|
||||
assert_eq!(msg.header.gsmtap_type, GsmtapType::LteMacFramed);
|
||||
// TA stored in frame_number for Wireshark compatibility (gsmtap.frame_nr)
|
||||
assert_eq!(msg.header.frame_number, 42);
|
||||
// MAC RAR PDU: 4-byte framing prefix + 7-byte RAR PDU = 11 bytes
|
||||
assert_eq!(msg.payload.len(), 11);
|
||||
// Verify TA encoding in RAR PDU bytes 5–6 (TA[10:3] and TA[2:0])
|
||||
// ta=42: ta>>3=5 in byte[5], (ta&7)<<5 = 2<<5 = 0x40 in byte[6]
|
||||
assert_eq!(msg.payload[5], 5);
|
||||
assert_eq!(msg.payload[6], 0x40);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rach_response_ffff_sentinel_returns_none() {
|
||||
// 0xFFFF means RAR was received but TA was not valid; must be dropped
|
||||
let payload = make_rach_v03_payload(0xFFFF, 0x02);
|
||||
assert!(parse_rach_response(&payload).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rach_response_no_msg2_returns_none() {
|
||||
// bitmask=0x01 means only MSG1 present; no TA available
|
||||
let payload = make_rach_v03_payload(42, 0x01);
|
||||
assert!(parse_rach_response(&payload).is_none());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user