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
+6 -1
View File
@@ -119,6 +119,11 @@ pub enum LogBody {
#[deku(ctx = "*ext_header_version")] #[deku(ctx = "*ext_header_version")]
packet: LteRrcOtaPacket, 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")] #[deku(id_pat = "0xb0e2 | 0xb0e3 | 0xb0ec | 0xb0ed")]
Nas4GMessage { Nas4GMessage {
ext_header_version: u8, ext_header_version: u8,
@@ -132,7 +137,7 @@ pub enum LogBody {
#[deku(id = "0x11eb")] #[deku(id = "0x11eb")]
IpTraffic { IpTraffic {
// is this right?? based on https://github.com/P1sec/QCSuper/blob/81dbaeee15ec7747e899daa8e3495e27cdcc1264/src/modules/pcap_dump.py#L378 // 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>, msg: Vec<u8>,
}, },
#[deku(id = "0x713a")] #[deku(id = "0x713a")]
+11 -2
View File
@@ -21,11 +21,19 @@ pub enum GsmtapType {
LteMacFramed, /* LTE MAC with context hdr */ LteMacFramed, /* LTE MAC with context hdr */
OsmocoreLog, /* libosmocore logging */ OsmocoreLog, /* libosmocore logging */
QcDiag, /* Qualcomm DIAG frame */ QcDiag, /* Qualcomm DIAG frame */
LteNas, /* LTE Non-Access Stratum */ LteNas(LteNasSubtype), /* LTE Non-Access Stratum */
E1T1, /* E1/T1 Lines */ E1T1, /* E1/T1 Lines */
GsmRlp, /* GSM RLP frames as per 3GPP TS 24.022 */ 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)] #[repr(u8)]
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
pub enum UmSubtype { pub enum UmSubtype {
@@ -162,7 +170,7 @@ impl GsmtapType {
GsmtapType::LteMacFramed => 0x0f, GsmtapType::LteMacFramed => 0x0f,
GsmtapType::OsmocoreLog => 0x10, GsmtapType::OsmocoreLog => 0x10,
GsmtapType::QcDiag => 0x11, GsmtapType::QcDiag => 0x11,
GsmtapType::LteNas => 0x12, GsmtapType::LteNas(_) => 0x12,
GsmtapType::E1T1 => 0x13, GsmtapType::E1T1 => 0x13,
GsmtapType::GsmRlp => 0x14, GsmtapType::GsmRlp => 0x14,
} }
@@ -173,6 +181,7 @@ impl GsmtapType {
GsmtapType::Um(subtype) => *subtype as u8, GsmtapType::Um(subtype) => *subtype as u8,
GsmtapType::UmtsRrc(subtype) => *subtype as u8, GsmtapType::UmtsRrc(subtype) => *subtype as u8,
GsmtapType::LteRrc(subtype) => *subtype as u8, GsmtapType::LteRrc(subtype) => *subtype as u8,
GsmtapType::LteNas(subtype) => *subtype as u8,
_ => 0, _ => 0,
} }
} }
+8
View File
@@ -116,6 +116,14 @@ impl GsmtapParser {
payload: packet.take_payload(), 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); error!("gsmtap_sink: ignoring unhandled log type: {:?}", value);
Ok(None) Ok(None)
+1 -1
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 // Tests here are based on https://github.com/fgsect/scat/blob/97442580e628de414c9f7c2a185f4e28d0ee7523/tests/test_diagltelogparser.py
#[test] #[test]
fn test_lte_rrc() { fn test_lte_rrc_ota() {
let mut parser = GsmtapParser::new(); 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 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(); let (_, parsed) = Message::from_bytes((v26_binary, 0)).unwrap();