diff --git a/lib/src/analysis/analyzer.rs b/lib/src/analysis/analyzer.rs index d2ca26f..46f47b9 100644 --- a/lib/src/analysis/analyzer.rs +++ b/lib/src/analysis/analyzer.rs @@ -1,4 +1,5 @@ use chrono::{DateTime, FixedOffset}; +use log::debug; use pcap_file_tokio::pcapng::blocks::enhanced_packet::EnhancedPacketBlock; use serde::{Deserialize, Serialize}; use std::borrow::Cow; @@ -327,7 +328,7 @@ impl Harness { harness.add_analyzer(Box::new(ConnectionRedirect2GDowngradeAnalyzer {})); } if analyzer_config.lte_sib6_and_7_downgrade { - harness.add_analyzer(Box::new(LteSib6And7DowngradeAnalyzer {})); + harness.add_analyzer(Box::new(LteSib6And7DowngradeAnalyzer::new())); } if analyzer_config.null_cipher { harness.add_analyzer(Box::new(NullCipherAnalyzer {})); @@ -380,6 +381,7 @@ impl Harness { row.events = match InformationElement::try_from(&gsmtap_message) { Ok(element) => self.analyze_information_element(&element), Err(err) => { + debug!("in packet {} failed to convert gsmtap message to IE: {err:?}", self.packet_num); row.skipped_message_reason = Some(format!("failed to convert gsmtap message to IE: {err:?}")); return row; diff --git a/lib/src/analysis/priority_2g_downgrade.rs b/lib/src/analysis/priority_2g_downgrade.rs index e5585ff..f05cd8c 100644 --- a/lib/src/analysis/priority_2g_downgrade.rs +++ b/lib/src/analysis/priority_2g_downgrade.rs @@ -2,18 +2,32 @@ use std::borrow::Cow; use super::analyzer::{Analyzer, Event, EventType}; use super::information_element::{InformationElement, LteInformationElement}; +use log::debug; use telcom_parser::lte_rrc::{ - BCCH_DL_SCH_MessageType, BCCH_DL_SCH_MessageType_c1, CellReselectionPriority, - SystemInformation_r8_IEsSib_TypeAndInfo, SystemInformation_r8_IEsSib_TypeAndInfo_Entry, - SystemInformationBlockType7, SystemInformationCriticalExtensions, + BCCH_DL_SCH_MessageType, BCCH_DL_SCH_MessageType_c1, CellReselectionPriority, SystemInformation_r8_IEsSib_TypeAndInfo, SystemInformation_r8_IEsSib_TypeAndInfo_Entry, SystemInformationBlockType7, SystemInformationCriticalExtensions }; /// Based on heuristic T7 from Shinjo Park's "Why We Cannot Win". -pub struct LteSib6And7DowngradeAnalyzer {} +pub struct LteSib6And7DowngradeAnalyzer { + lte_priority: i16, + legacy_priority: i16, +} +impl Default for LteSib6And7DowngradeAnalyzer{ + fn default() -> Self { + Self::new() + } +} impl LteSib6And7DowngradeAnalyzer { + pub fn new() -> Self { + Self { + lte_priority: 0, + legacy_priority: 0, + } + } + fn unpack_system_information<'a>( - &self, + &mut self, ie: &'a InformationElement, ) -> Option<&'a SystemInformation_r8_IEsSib_TypeAndInfo> { if let InformationElement::LTE(lte_ie) = ie @@ -51,22 +65,67 @@ impl Analyzer for LteSib6And7DowngradeAnalyzer { ie: &InformationElement, _packet_num: usize, ) -> Option { + if let InformationElement::LTE(lte_ie) = ie + && let LteInformationElement::BcchDlSch(sch_msg) = &**lte_ie + && let BCCH_DL_SCH_MessageType::C1(c1) = &sch_msg.message + && let BCCH_DL_SCH_MessageType_c1::SystemInformationBlockType1(_) = c1 + { + let flag; + if self.legacy_priority > self.lte_priority { + flag = Some(Event { + event_type: EventType::High, + message: + format!("LTE cell advertised a 3G cell for priority {} reselection over LTE neighbors at priority {}", self.legacy_priority, self.lte_priority) + .to_string(), + }); + } else { + flag = None; + } + self.lte_priority = 0; + self.legacy_priority = -1; + debug!("reset priority to 0 due to new sib1 at {_packet_num}"); + return flag; + } + let sibs = &self.unpack_system_information(ie)?.0; for sib in sibs { match sib { + SystemInformation_r8_IEsSib_TypeAndInfo_Entry::Sib3(sib3) => { + let res_p: i16 = sib3.cell_reselection_serving_freq_info.cell_reselection_priority.0.into(); + if res_p > self.lte_priority { + self.lte_priority = res_p.into(); + debug!( + "set priority {} due to sib3 (frame {})", + self.lte_priority, _packet_num + ); + } + } , + SystemInformation_r8_IEsSib_TypeAndInfo_Entry::Sib5(sib5) => { + let carrier_freq_list = &sib5.inter_freq_carrier_freq_list; + for carrier_freq in &carrier_freq_list.0 { + if let Some(res_p) = &carrier_freq.cell_reselection_priority { + let pri: i16 = res_p.0.into(); + if pri > self.lte_priority { + self.lte_priority = res_p.0.into(); + debug!( + "set priority {} due to sib5 (frame {})", + self.lte_priority, _packet_num + ); + } + } + } + } , 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 - && p == 0 { - return Some(Event { - event_type: EventType::High, - message: - "LTE cell advertised a 3G cell for priority 0 reselection" - .to_string(), - }); + self.legacy_priority = p.into(); + debug!( + "set legacy priority {} due to sib6 (frame {})", + self.lte_priority, _packet_num + ); } } } @@ -74,14 +133,12 @@ impl Analyzer for LteSib6And7DowngradeAnalyzer { for carrier_info in &carrier_info_list.0 { if let Some(CellReselectionPriority(p)) = carrier_info.cell_reselection_priority - && p == 0 { - return Some(Event { - event_type: EventType::High, - message: - "LTE cell advertised a 3G cell for priority 0 reselection" - .to_string(), - }); + self.legacy_priority = p.into(); + debug!( + "set legacy priority {} due to sib6 (frame {})", + self.lte_priority, _packet_num + ); } } } @@ -95,13 +152,12 @@ impl Analyzer for LteSib6And7DowngradeAnalyzer { for carrier_info in &carrier_info_list.0 { if let Some(CellReselectionPriority(p)) = carrier_info.common_info.cell_reselection_priority - && p == 0 { - return Some(Event { - event_type: EventType::High, - message: "LTE cell advertised a 2G cell for priority 0 reselection" - .to_string(), - }); + self.legacy_priority = p.into(); + debug!( + "set legacy priority {} due to sib7 (frame {})", + self.lte_priority, _packet_num + ); } } }