fix(parsing): mask EARFCN to 14 bits to prevent GSMTAP serialization panic

LTE EARFCNs can exceed the 14-bit GSMTAP ARFCN field maximum (16383),
causing Deku to panic with "bit size of input is larger than bit
requested size: 16 exceeds 14". This broke pcap generation for
international captures (e.g. UK, Switzerland).

Mask the value to 14 bits per the GSMTAP spec instead of panicking.

Fixes #1012, fixes #945

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Deven Ducommun
2026-06-16 14:30:38 -07:00
committed by Will Greenberg
parent b3f63864ad
commit 17a9dfe0ff
+21 -1
View File
@@ -135,7 +135,7 @@ fn log_to_gsmtap(value: LogBody) -> Result<Option<GsmtapMessage>, GsmtapParserEr
}
};
let mut header = GsmtapHeader::new(gsmtap_type);
header.arfcn = packet.get_earfcn().try_into().unwrap_or(0);
header.arfcn = (packet.get_earfcn() as u16) & 0x3FFF;
header.frame_number = packet.get_sfn();
header.subslot = packet.get_subfn();
Ok(Some(GsmtapMessage {
@@ -158,3 +158,23 @@ fn log_to_gsmtap(value: LogBody) -> Result<Option<GsmtapMessage>, GsmtapParserEr
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use deku::DekuContainerWrite;
#[test]
fn test_arfcn_exceeding_14_bits_does_not_panic() {
let mut header = GsmtapHeader::new(GsmtapType::LteRrc(LteRrcSubtype::DlDcch));
// EARFCN 54540 (band 46) exceeds 14-bit max of 16383
let large_earfcn: u32 = 54540;
header.arfcn = (large_earfcn as u16) & 0x3FFF;
let msg = GsmtapMessage {
header,
payload: vec![0x00],
};
// This would panic before the fix with "bit size of input is larger than bit requested size"
assert!(msg.to_bytes().is_ok());
}
}