gstmtap_parser: Add support for NAS messages

This commit is contained in:
Will Greenberg
2023-12-20 08:18:59 -08:00
parent 9fa8284343
commit 73ed01de62
4 changed files with 26 additions and 4 deletions

View File

@@ -119,6 +119,11 @@ pub enum LogBody {
#[deku(ctx = "*ext_header_version")]
packet: LteRrcOtaPacket,
},
// the four NAS command opcodes refer to:
// * 0xb0e2: plain ESM NAS message (incoming)
// * 0xb0e3: plain ESM NAS message (outgoing)
// * 0xb0ec: plain EMM NAS message (incoming)
// * 0xb0ed: plain EMM NAS message (outgoing)
#[deku(id_pat = "0xb0e2 | 0xb0e3 | 0xb0ec | 0xb0ed")]
Nas4GMessage {
ext_header_version: u8,
@@ -132,7 +137,7 @@ pub enum LogBody {
#[deku(id = "0x11eb")]
IpTraffic {
// is this right?? based on https://github.com/P1sec/QCSuper/blob/81dbaeee15ec7747e899daa8e3495e27cdcc1264/src/modules/pcap_dump.py#L378
#[deku(count = "hdr_len - 8")] // is this right???
#[deku(count = "hdr_len - 8")]
msg: Vec<u8>,
},
#[deku(id = "0x713a")]

View File

@@ -21,11 +21,19 @@ pub enum GsmtapType {
LteMacFramed, /* LTE MAC with context hdr */
OsmocoreLog, /* libosmocore logging */
QcDiag, /* Qualcomm DIAG frame */
LteNas, /* LTE Non-Access Stratum */
LteNas(LteNasSubtype), /* LTE Non-Access Stratum */
E1T1, /* E1/T1 Lines */
GsmRlp, /* GSM RLP frames as per 3GPP TS 24.022 */
}
// based on https://github.com/fgsect/scat/blob/97442580e628de414c9f7c2a185f4e28d0ee7523/src/scat/parsers/qualcomm/diagltelogparser.py#L1337
#[repr(u8)]
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum LteNasSubtype {
Plain = 0,
Secure = 1,
}
#[repr(u8)]
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum UmSubtype {
@@ -162,7 +170,7 @@ impl GsmtapType {
GsmtapType::LteMacFramed => 0x0f,
GsmtapType::OsmocoreLog => 0x10,
GsmtapType::QcDiag => 0x11,
GsmtapType::LteNas => 0x12,
GsmtapType::LteNas(_) => 0x12,
GsmtapType::E1T1 => 0x13,
GsmtapType::GsmRlp => 0x14,
}
@@ -173,6 +181,7 @@ impl GsmtapType {
GsmtapType::Um(subtype) => *subtype as u8,
GsmtapType::UmtsRrc(subtype) => *subtype as u8,
GsmtapType::LteRrc(subtype) => *subtype as u8,
GsmtapType::LteNas(subtype) => *subtype as u8,
_ => 0,
}
}

View File

@@ -116,6 +116,14 @@ impl GsmtapParser {
payload: packet.take_payload(),
}))
},
LogBody::Nas4GMessage { msg, .. } => {
// currently we only handle "plain" (i.e. non-secure) NAS messages
let header = GsmtapHeader::new(GsmtapType::LteNas(LteNasSubtype::Plain));
Ok(Some(GsmtapMessage {
header,
payload: msg,
}))
},
_ => {
error!("gsmtap_sink: ignoring unhandled log type: {:?}", value);
Ok(None)

View File

@@ -10,7 +10,7 @@ use deku::prelude::*;
// Tests here are based on https://github.com/fgsect/scat/blob/97442580e628de414c9f7c2a185f4e28d0ee7523/tests/test_diagltelogparser.py
#[test]
fn test_lte_rrc() {
fn test_lte_rrc_ota() {
let mut parser = GsmtapParser::new();
let v26_binary = &[0x10, 0x0, 0x23, 0x0, 0x23, 0x0, 0xc0, 0xb0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1a, 0xf, 0x40, 0xf, 0x40, 0x1, 0xe, 0x1, 0x13, 0x7, 0x0, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x10, 0x15];
let (_, parsed) = Message::from_bytes((v26_binary, 0)).unwrap();