diff --git a/lib/src/analysis/analyzer.rs b/lib/src/analysis/analyzer.rs index 03958d5..47fa5aa 100644 --- a/lib/src/analysis/analyzer.rs +++ b/lib/src/analysis/analyzer.rs @@ -7,7 +7,7 @@ use crate::{diag::MessagesContainer, gsmtap_parser}; use super::{ imsi_requested::ImsiRequestedAnalyzer, information_element::InformationElement, - lte_downgrade::LteSib6And7DowngradeAnalyzer, + lte_downgrade::ConnectionRedirect2GDowngradeAnalyzer, null_cipher::NullCipherAnalyzer, }; @@ -117,7 +117,7 @@ impl Harness { pub fn new_with_all_analyzers() -> Self { let mut harness = Harness::new(); - harness.add_analyzer(Box::new(LteSib6And7DowngradeAnalyzer{})); + harness.add_analyzer(Box::new(ConnectionRedirect2GDowngradeAnalyzer{})); harness.add_analyzer(Box::new(ImsiRequestedAnalyzer::new())); harness.add_analyzer(Box::new(NullCipherAnalyzer{})); diff --git a/lib/src/analysis/lte_downgrade.rs b/lib/src/analysis/lte_downgrade.rs index 44003fd..101cbef 100644 --- a/lib/src/analysis/lte_downgrade.rs +++ b/lib/src/analysis/lte_downgrade.rs @@ -2,80 +2,40 @@ use std::borrow::Cow; use super::analyzer::{Analyzer, Event, EventType, Severity}; use super::information_element::{InformationElement, LteInformationElement}; -use telcom_parser::lte_rrc::{BCCH_DL_SCH_MessageType, BCCH_DL_SCH_MessageType_c1, CellReselectionPriority, SystemInformationBlockType7, SystemInformationCriticalExtensions, SystemInformation_r8_IEsSib_TypeAndInfo, SystemInformation_r8_IEsSib_TypeAndInfo_Entry}; +use telcom_parser::lte_rrc::{DL_DCCH_Message, DL_DCCH_MessageType, DL_DCCH_MessageType_c1, RRCConnectionReleaseCriticalExtensions, RRCConnectionReleaseCriticalExtensions_c1, RedirectedCarrierInfo}; +use super::util::unpack; /// Based on heuristic T7 from Shinjo Park's "Why We Cannot Win". -pub struct LteSib6And7DowngradeAnalyzer { -} - -impl LteSib6And7DowngradeAnalyzer { - fn unpack_system_information<'a>(&self, ie: &'a InformationElement) -> Option<&'a SystemInformation_r8_IEsSib_TypeAndInfo> { - if let InformationElement::LTE(LteInformationElement::BcchDlSch(bcch_dl_sch_message)) = ie { - if let BCCH_DL_SCH_MessageType::C1(BCCH_DL_SCH_MessageType_c1::SystemInformation(system_information)) = &bcch_dl_sch_message.message { - if let SystemInformationCriticalExtensions::SystemInformation_r8(sib) = &system_information.critical_extensions { - return Some(&sib.sib_type_and_info); - } - } - } - None - } +pub struct ConnectionRedirect2GDowngradeAnalyzer { } // TODO: keep track of SIB state to compare LTE reselection blocks w/ 2g/3g ones -impl Analyzer for LteSib6And7DowngradeAnalyzer { +impl Analyzer for ConnectionRedirect2GDowngradeAnalyzer { fn get_name(&self) -> Cow { - Cow::from("LTE SIB 6/7 Downgrade") + Cow::from("Connection Release/Redirected Carrier 2G Downgrade") } fn get_description(&self) -> Cow { - Cow::from("Tests for LTE cells broadcasting a SIB type 6 and 7 which include 2G/3G frequencies with higher priorities.") + Cow::from("Tests if a cell releases our connection and redirects us to a 2G cell.") } - fn analyze_information_element(&mut self, ie: &InformationElement) -> Option { - let sibs = &self.unpack_system_information(ie)?.0; - for sib in sibs { - match sib { - SystemInformation_r8_IEsSib_TypeAndInfo_Entry::Sib6(sib6) => { - if let Some(carrier_info_list) = sib6.carrier_freq_list_utra_fdd.as_ref() { - for carrier_info in &carrier_info_list.0 { - if let Some(CellReselectionPriority(p)) = carrier_info.cell_reselection_priority { - if p == 0 { - return Some(Event { - event_type: EventType::QualitativeWarning { severity: Severity::High }, - message: "LTE cell advertised a 3G cell for priority 0 reselection".to_string(), - }); - } - } - } - } - if let Some(carrier_info_list) = sib6.carrier_freq_list_utra_tdd.as_ref() { - for carrier_info in &carrier_info_list.0 { - if let Some(CellReselectionPriority(p)) = carrier_info.cell_reselection_priority { - if p == 0 { - return Some(Event { - event_type: EventType::QualitativeWarning { severity: Severity::High }, - message: "LTE cell advertised a 3G cell for priority 0 reselection".to_string(), - }); - } - } - } - } - }, - SystemInformation_r8_IEsSib_TypeAndInfo_Entry::Sib7(SystemInformationBlockType7 { carrier_freqs_info_list: Some(carrier_info_list), .. }) => { - for carrier_info in &carrier_info_list.0 { - if let Some(CellReselectionPriority(p)) = carrier_info.common_info.cell_reselection_priority { - if p == 0 { - return Some(Event { - event_type: EventType::QualitativeWarning { severity: Severity::High }, - message: "LTE cell advertised a 2G cell for priority 0 reselection".to_string(), - }); - } - } - } - }, - _ => {}, - } + fn analyze_information_element(&mut self, ie: &InformationElement) -> Option { + unpack!(InformationElement::LTE(lte_ie) = ie); + unpack!(LteInformationElement::DlDcch(DL_DCCH_Message { message }) = lte_ie); + unpack!(DL_DCCH_MessageType::C1(c1) = message); + unpack!(DL_DCCH_MessageType_c1::RrcConnectionRelease(release) = c1); + unpack!(RRCConnectionReleaseCriticalExtensions::C1(c1) = &release.critical_extensions); + unpack!(RRCConnectionReleaseCriticalExtensions_c1::RrcConnectionRelease_r8(r8_ies) = c1); + unpack!(Some(carrier_info) = &r8_ies.redirected_carrier_info); + match carrier_info { + RedirectedCarrierInfo::Geran(_carrier_freqs_geran) => Some(Event { + event_type: EventType::QualitativeWarning { severity: Severity::High }, + message: format!("Detected 2G downgrade"), + }), + _ => Some(Event { + event_type: EventType::Informational, + message: format!("RRCConnectionRelease CarrierInfo: {:?}", carrier_info), + }), } - None } } diff --git a/lib/src/analysis/mod.rs b/lib/src/analysis/mod.rs index d777f98..5b70ed5 100644 --- a/lib/src/analysis/mod.rs +++ b/lib/src/analysis/mod.rs @@ -4,3 +4,4 @@ pub mod lte_downgrade; pub mod imsi_provided; pub mod imsi_requested; pub mod null_cipher; +pub mod util; diff --git a/lib/src/analysis/util.rs b/lib/src/analysis/util.rs new file mode 100644 index 0000000..a011dfb --- /dev/null +++ b/lib/src/analysis/util.rs @@ -0,0 +1,7 @@ +macro_rules! unpack { + ($pat:pat = $val:expr) => { + let $pat = $val else { return None; }; + }; +} + +pub(crate) use unpack;