mirror of
https://github.com/EFForg/rayhunter.git
synced 2026-04-26 23:49:59 -07:00
chore: cargo fmt
This commit is contained in:
committed by
Will Greenberg
parent
151e186ef9
commit
9fe75ac961
@@ -1,14 +1,13 @@
|
||||
use std::borrow::Cow;
|
||||
use chrono::{DateTime, FixedOffset};
|
||||
use serde::Serialize;
|
||||
use std::borrow::Cow;
|
||||
|
||||
use crate::{diag::MessagesContainer, gsmtap_parser};
|
||||
use crate::util::RuntimeMetadata;
|
||||
use crate::{diag::MessagesContainer, gsmtap_parser};
|
||||
|
||||
use super::{
|
||||
imsi_requested::ImsiRequestedAnalyzer,
|
||||
information_element::InformationElement,
|
||||
connection_redirect_downgrade::ConnectionRedirect2GDowngradeAnalyzer,
|
||||
imsi_requested::ImsiRequestedAnalyzer, information_element::InformationElement,
|
||||
priority_2g_downgrade::LteSib6And7DowngradeAnalyzer,
|
||||
};
|
||||
|
||||
@@ -118,14 +117,16 @@ impl Default for Harness {
|
||||
|
||||
impl Harness {
|
||||
pub fn new() -> Self {
|
||||
Self { analyzers: Vec::new() }
|
||||
Self {
|
||||
analyzers: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_with_all_analyzers() -> Self {
|
||||
let mut harness = Harness::new();
|
||||
harness.add_analyzer(Box::new(ImsiRequestedAnalyzer::new()));
|
||||
harness.add_analyzer(Box::new(ConnectionRedirect2GDowngradeAnalyzer{}));
|
||||
harness.add_analyzer(Box::new(LteSib6And7DowngradeAnalyzer{}));
|
||||
harness.add_analyzer(Box::new(ConnectionRedirect2GDowngradeAnalyzer {}));
|
||||
harness.add_analyzer(Box::new(LteSib6And7DowngradeAnalyzer {}));
|
||||
|
||||
// FIXME: our RRC parser is reporting false positives for this due to an
|
||||
// upstream hampi bug (https://github.com/ystero-dev/hampi/issues/133).
|
||||
@@ -186,19 +187,22 @@ impl Harness {
|
||||
}
|
||||
|
||||
fn analyze_information_element(&mut self, ie: &InformationElement) -> Vec<Option<Event>> {
|
||||
self.analyzers.iter_mut()
|
||||
self.analyzers
|
||||
.iter_mut()
|
||||
.map(|analyzer| analyzer.analyze_information_element(ie))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn get_names(&self) -> Vec<Cow<'_, str>> {
|
||||
self.analyzers.iter()
|
||||
self.analyzers
|
||||
.iter()
|
||||
.map(|analyzer| analyzer.get_name())
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn get_descriptions(&self) -> Vec<Cow<'_, str>> {
|
||||
self.analyzers.iter()
|
||||
self.analyzers
|
||||
.iter()
|
||||
.map(|analyzer| analyzer.get_description())
|
||||
.collect()
|
||||
}
|
||||
|
||||
@@ -2,13 +2,15 @@ use std::borrow::Cow;
|
||||
|
||||
use super::analyzer::{Analyzer, Event, EventType, Severity};
|
||||
use super::information_element::{InformationElement, LteInformationElement};
|
||||
use telcom_parser::lte_rrc::{DL_DCCH_MessageType, DL_DCCH_MessageType_c1, RRCConnectionReleaseCriticalExtensions, RRCConnectionReleaseCriticalExtensions_c1, RedirectedCarrierInfo};
|
||||
use super::util::unpack;
|
||||
use telcom_parser::lte_rrc::{
|
||||
DL_DCCH_MessageType, DL_DCCH_MessageType_c1, RRCConnectionReleaseCriticalExtensions,
|
||||
RRCConnectionReleaseCriticalExtensions_c1, RedirectedCarrierInfo,
|
||||
};
|
||||
|
||||
// Based on HITBSecConf presentation "Forcing a targeted LTE cellphone into an
|
||||
// eavesdropping network" by Lin Huang
|
||||
pub struct ConnectionRedirect2GDowngradeAnalyzer {
|
||||
}
|
||||
pub struct ConnectionRedirect2GDowngradeAnalyzer {}
|
||||
|
||||
// TODO: keep track of SIB state to compare LTE reselection blocks w/ 2g/3g ones
|
||||
impl Analyzer for ConnectionRedirect2GDowngradeAnalyzer {
|
||||
@@ -33,7 +35,9 @@ impl Analyzer for ConnectionRedirect2GDowngradeAnalyzer {
|
||||
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 },
|
||||
event_type: EventType::QualitativeWarning {
|
||||
severity: Severity::High,
|
||||
},
|
||||
message: "Detected 2G downgrade".to_owned(),
|
||||
}),
|
||||
_ => Some(Event {
|
||||
|
||||
@@ -5,8 +5,7 @@ use telcom_parser::lte_rrc::{PCCH_MessageType, PCCH_MessageType_c1, PagingUE_Ide
|
||||
use super::analyzer::{Analyzer, Event, EventType, Severity};
|
||||
use super::information_element::{InformationElement, LteInformationElement};
|
||||
|
||||
pub struct ImsiProvidedAnalyzer {
|
||||
}
|
||||
pub struct ImsiProvidedAnalyzer {}
|
||||
|
||||
impl Analyzer for ImsiProvidedAnalyzer {
|
||||
fn get_name(&self) -> Cow<str> {
|
||||
@@ -19,10 +18,10 @@ impl Analyzer for ImsiProvidedAnalyzer {
|
||||
|
||||
fn analyze_information_element(&mut self, ie: &InformationElement) -> Option<Event> {
|
||||
let pcch_msg = match ie {
|
||||
InformationElement::LTE(lte_ie) => match &** lte_ie {
|
||||
InformationElement::LTE(lte_ie) => match &**lte_ie {
|
||||
LteInformationElement::PCCH(pcch_msg) => pcch_msg,
|
||||
_ => return None,
|
||||
}
|
||||
},
|
||||
_ => return None,
|
||||
};
|
||||
let PCCH_MessageType::C1(PCCH_MessageType_c1::Paging(paging)) = &pcch_msg.message else {
|
||||
@@ -31,9 +30,11 @@ impl Analyzer for ImsiProvidedAnalyzer {
|
||||
for record in &paging.paging_record_list.as_ref()?.0 {
|
||||
if let PagingUE_Identity::Imsi(_) = record.ue_identity {
|
||||
return Some(Event {
|
||||
event_type: EventType::QualitativeWarning { severity: Severity::High },
|
||||
event_type: EventType::QualitativeWarning {
|
||||
severity: Severity::High,
|
||||
},
|
||||
message: "IMSI was provided to cell".to_string(),
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
None
|
||||
|
||||
@@ -36,7 +36,7 @@ impl Analyzer for ImsiRequestedAnalyzer {
|
||||
InformationElement::LTE(inner) => match &**inner {
|
||||
LteInformationElement::NAS(payload) => payload,
|
||||
_ => return None,
|
||||
}
|
||||
},
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
@@ -45,7 +45,7 @@ impl Analyzer for ImsiRequestedAnalyzer {
|
||||
if self.packet_num < PACKET_THRESHHOLD {
|
||||
return Some(Event {
|
||||
event_type: EventType::QualitativeWarning {
|
||||
severity: Severity::Medium
|
||||
severity: Severity::Medium,
|
||||
},
|
||||
message: format!(
|
||||
"NAS IMSI identity request detected, however it was within \
|
||||
@@ -53,15 +53,15 @@ impl Analyzer for ImsiRequestedAnalyzer {
|
||||
turned your device on, this is likely a \
|
||||
false-positive.",
|
||||
PACKET_THRESHHOLD
|
||||
)
|
||||
})
|
||||
),
|
||||
});
|
||||
} else {
|
||||
return Some(Event {
|
||||
event_type: EventType::QualitativeWarning {
|
||||
severity: Severity::High
|
||||
severity: Severity::High,
|
||||
},
|
||||
message: "NAS IMSI identity request detected".to_owned(),
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
None
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
//! the term to refer to a structured, fully parsed message in any telcom
|
||||
//! standard.
|
||||
|
||||
use crate::gsmtap::{GsmtapMessage, GsmtapType, LteNasSubtype, LteRrcSubtype};
|
||||
use telcom_parser::{decode, lte_rrc};
|
||||
use thiserror::Error;
|
||||
use crate::gsmtap::{GsmtapMessage, GsmtapType, LteNasSubtype, LteRrcSubtype};
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum InformationElementError {
|
||||
@@ -46,7 +46,6 @@ pub enum LteInformationElement {
|
||||
|
||||
// FIXME: actually parse NAS messages
|
||||
NAS(Vec<u8>),
|
||||
|
||||
// FIXME: unclear which message these "NB" types map to
|
||||
//DlCcchNb(),
|
||||
//DlDcchNb(),
|
||||
@@ -65,8 +64,8 @@ impl TryFrom<&GsmtapMessage> for InformationElement {
|
||||
fn try_from(gsmtap_msg: &GsmtapMessage) -> Result<Self, Self::Error> {
|
||||
match gsmtap_msg.header.gsmtap_type {
|
||||
GsmtapType::LteRrc(lte_rrc_subtype) => {
|
||||
use LteRrcSubtype as L;
|
||||
use LteInformationElement as R;
|
||||
use LteRrcSubtype as L;
|
||||
let lte = match lte_rrc_subtype {
|
||||
L::DlCcch => R::DlCcch(decode(&gsmtap_msg.payload)?),
|
||||
L::DlDcch => R::DlDcch(Box::new(decode(&gsmtap_msg.payload)?)),
|
||||
@@ -82,14 +81,20 @@ impl TryFrom<&GsmtapMessage> for InformationElement {
|
||||
L::BcchDlSchMbms => R::BcchDlSchMbms(decode(&gsmtap_msg.payload)?),
|
||||
L::SbcchSlBch => R::SbcchSlBch(decode(&gsmtap_msg.payload)?),
|
||||
L::SbcchSlBchV2x => R::SbcchSlBchV2x(decode(&gsmtap_msg.payload)?),
|
||||
_ => return Err(InformationElementError::UnsupportedGsmtapType(gsmtap_msg.header.gsmtap_type)),
|
||||
_ => {
|
||||
return Err(InformationElementError::UnsupportedGsmtapType(
|
||||
gsmtap_msg.header.gsmtap_type,
|
||||
))
|
||||
}
|
||||
};
|
||||
Ok(InformationElement::LTE(Box::new(lte)))
|
||||
},
|
||||
GsmtapType::LteNas(LteNasSubtype::Plain) => {
|
||||
Ok(InformationElement::LTE(Box::new(LteInformationElement::NAS(gsmtap_msg.payload.clone()))))
|
||||
},
|
||||
_ => Err(InformationElementError::UnsupportedGsmtapType(gsmtap_msg.header.gsmtap_type)),
|
||||
}
|
||||
GsmtapType::LteNas(LteNasSubtype::Plain) => Ok(InformationElement::LTE(Box::new(
|
||||
LteInformationElement::NAS(gsmtap_msg.payload.clone()),
|
||||
))),
|
||||
_ => Err(InformationElementError::UnsupportedGsmtapType(
|
||||
gsmtap_msg.header.gsmtap_type,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
pub mod analyzer;
|
||||
pub mod information_element;
|
||||
pub mod priority_2g_downgrade;
|
||||
pub mod connection_redirect_downgrade;
|
||||
pub mod imsi_provided;
|
||||
pub mod imsi_requested;
|
||||
pub mod information_element;
|
||||
pub mod null_cipher;
|
||||
pub mod priority_2g_downgrade;
|
||||
pub mod util;
|
||||
|
||||
@@ -1,25 +1,41 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use telcom_parser::lte_rrc::{CipheringAlgorithm_r12, DL_DCCH_MessageType, DL_DCCH_MessageType_c1, RRCConnectionReconfiguration, RRCConnectionReconfigurationCriticalExtensions, RRCConnectionReconfigurationCriticalExtensions_c1, SCG_Configuration_r12, SecurityConfigHO_v1530HandoverType_v1530, SecurityModeCommand, SecurityModeCommandCriticalExtensions, SecurityModeCommandCriticalExtensions_c1};
|
||||
use telcom_parser::lte_rrc::{
|
||||
CipheringAlgorithm_r12, DL_DCCH_MessageType, DL_DCCH_MessageType_c1,
|
||||
RRCConnectionReconfiguration, RRCConnectionReconfigurationCriticalExtensions,
|
||||
RRCConnectionReconfigurationCriticalExtensions_c1, SCG_Configuration_r12,
|
||||
SecurityConfigHO_v1530HandoverType_v1530, SecurityModeCommand,
|
||||
SecurityModeCommandCriticalExtensions, SecurityModeCommandCriticalExtensions_c1,
|
||||
};
|
||||
|
||||
use super::analyzer::{Analyzer, Event, EventType, Severity};
|
||||
use super::information_element::{InformationElement, LteInformationElement};
|
||||
|
||||
pub struct NullCipherAnalyzer {
|
||||
}
|
||||
pub struct NullCipherAnalyzer {}
|
||||
|
||||
impl NullCipherAnalyzer {
|
||||
fn check_rrc_connection_reconfiguration_cipher(&self, reconfiguration: &RRCConnectionReconfiguration) -> bool {
|
||||
let RRCConnectionReconfigurationCriticalExtensions::C1(c1) = &reconfiguration.critical_extensions else {
|
||||
fn check_rrc_connection_reconfiguration_cipher(
|
||||
&self,
|
||||
reconfiguration: &RRCConnectionReconfiguration,
|
||||
) -> bool {
|
||||
let RRCConnectionReconfigurationCriticalExtensions::C1(c1) =
|
||||
&reconfiguration.critical_extensions
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
let RRCConnectionReconfigurationCriticalExtensions_c1::RrcConnectionReconfiguration_r8(c1) = c1 else {
|
||||
let RRCConnectionReconfigurationCriticalExtensions_c1::RrcConnectionReconfiguration_r8(c1) =
|
||||
c1
|
||||
else {
|
||||
return false;
|
||||
};
|
||||
if let Some(handover) = &c1.security_config_ho {
|
||||
let maybe_security_config = match &handover.handover_type {
|
||||
telcom_parser::lte_rrc::SecurityConfigHOHandoverType::IntraLTE(lte) => lte.security_algorithm_config.as_ref(),
|
||||
telcom_parser::lte_rrc::SecurityConfigHOHandoverType::InterRAT(rat) => Some(&rat.security_algorithm_config),
|
||||
telcom_parser::lte_rrc::SecurityConfigHOHandoverType::IntraLTE(lte) => {
|
||||
lte.security_algorithm_config.as_ref()
|
||||
}
|
||||
telcom_parser::lte_rrc::SecurityConfigHOHandoverType::InterRAT(rat) => {
|
||||
Some(&rat.security_algorithm_config)
|
||||
}
|
||||
};
|
||||
if let Some(security_config) = maybe_security_config {
|
||||
if security_config.ciphering_algorithm.0 == CipheringAlgorithm_r12::EEA0 {
|
||||
@@ -28,7 +44,9 @@ impl NullCipherAnalyzer {
|
||||
}
|
||||
}
|
||||
// Use map/flatten to dig into a long chain of nested Option types
|
||||
let maybe_v1250 = c1.non_critical_extension.as_ref()
|
||||
let maybe_v1250 = c1
|
||||
.non_critical_extension
|
||||
.as_ref()
|
||||
.and_then(|v890| v890.non_critical_extension.as_ref())
|
||||
.and_then(|v920| v920.non_critical_extension.as_ref())
|
||||
.and_then(|v1020| v1020.non_critical_extension.as_ref())
|
||||
@@ -37,8 +55,11 @@ impl NullCipherAnalyzer {
|
||||
return false;
|
||||
};
|
||||
|
||||
if let Some(SCG_Configuration_r12::Setup(scg_setup)) = v1250.scg_configuration_r12.as_ref() {
|
||||
let maybe_cipher = scg_setup.scg_config_part_scg_r12.as_ref()
|
||||
if let Some(SCG_Configuration_r12::Setup(scg_setup)) = v1250.scg_configuration_r12.as_ref()
|
||||
{
|
||||
let maybe_cipher = scg_setup
|
||||
.scg_config_part_scg_r12
|
||||
.as_ref()
|
||||
.and_then(|scg| scg.mobility_control_info_scg_r12.as_ref())
|
||||
.and_then(|mci| mci.ciphering_algorithm_scg_r12.as_ref());
|
||||
if let Some(cipher) = maybe_cipher {
|
||||
@@ -48,7 +69,9 @@ impl NullCipherAnalyzer {
|
||||
}
|
||||
}
|
||||
|
||||
let maybe_v1530_security_config = v1250.non_critical_extension.as_ref()
|
||||
let maybe_v1530_security_config = v1250
|
||||
.non_critical_extension
|
||||
.as_ref()
|
||||
.and_then(|v1310| v1310.non_critical_extension.as_ref())
|
||||
.and_then(|v1430| v1430.non_critical_extension.as_ref())
|
||||
.and_then(|v1510| v1510.non_critical_extension.as_ref())
|
||||
@@ -57,9 +80,15 @@ impl NullCipherAnalyzer {
|
||||
return false;
|
||||
};
|
||||
let maybe_security_algorithm = match &v1530_security_config.handover_type_v1530 {
|
||||
SecurityConfigHO_v1530HandoverType_v1530::Intra5GC(intra_5gc) => intra_5gc.security_algorithm_config_r15.as_ref(),
|
||||
SecurityConfigHO_v1530HandoverType_v1530::Fivegc_ToEPC(to_epc) => Some(&to_epc.security_algorithm_config_r15),
|
||||
SecurityConfigHO_v1530HandoverType_v1530::Epc_To5GC(to_5gc) => Some(&to_5gc.security_algorithm_config_r15),
|
||||
SecurityConfigHO_v1530HandoverType_v1530::Intra5GC(intra_5gc) => {
|
||||
intra_5gc.security_algorithm_config_r15.as_ref()
|
||||
}
|
||||
SecurityConfigHO_v1530HandoverType_v1530::Fivegc_ToEPC(to_epc) => {
|
||||
Some(&to_epc.security_algorithm_config_r15)
|
||||
}
|
||||
SecurityConfigHO_v1530HandoverType_v1530::Epc_To5GC(to_5gc) => {
|
||||
Some(&to_5gc.security_algorithm_config_r15)
|
||||
}
|
||||
};
|
||||
if let Some(security_algorithm) = maybe_security_algorithm {
|
||||
if security_algorithm.ciphering_algorithm.0 == CipheringAlgorithm_r12::EEA0 {
|
||||
@@ -76,7 +105,13 @@ impl NullCipherAnalyzer {
|
||||
let SecurityModeCommandCriticalExtensions_c1::SecurityModeCommand_r8(r8) = &c1 else {
|
||||
return false;
|
||||
};
|
||||
if r8.security_config_smc.security_algorithm_config.ciphering_algorithm.0 == CipheringAlgorithm_r12::EEA0 {
|
||||
if r8
|
||||
.security_config_smc
|
||||
.security_algorithm_config
|
||||
.ciphering_algorithm
|
||||
.0
|
||||
== CipheringAlgorithm_r12::EEA0
|
||||
{
|
||||
return true;
|
||||
}
|
||||
false
|
||||
@@ -94,23 +129,29 @@ impl Analyzer for NullCipherAnalyzer {
|
||||
|
||||
fn analyze_information_element(&mut self, ie: &InformationElement) -> Option<Event> {
|
||||
let dcch_msg = match ie {
|
||||
InformationElement::LTE(lte_ie) => match &** lte_ie {
|
||||
InformationElement::LTE(lte_ie) => match &**lte_ie {
|
||||
LteInformationElement::DlDcch(dcch_msg) => dcch_msg,
|
||||
_ => return None,
|
||||
}
|
||||
},
|
||||
_ => return None,
|
||||
};
|
||||
let DL_DCCH_MessageType::C1(c1) = &dcch_msg.message else {
|
||||
return None;
|
||||
};
|
||||
let null_cipher_detected = match c1 {
|
||||
DL_DCCH_MessageType_c1::RrcConnectionReconfiguration(reconfiguration) => self.check_rrc_connection_reconfiguration_cipher(reconfiguration),
|
||||
DL_DCCH_MessageType_c1::SecurityModeCommand(command) => self.check_security_mode_command_cipher(command),
|
||||
DL_DCCH_MessageType_c1::RrcConnectionReconfiguration(reconfiguration) => {
|
||||
self.check_rrc_connection_reconfiguration_cipher(reconfiguration)
|
||||
}
|
||||
DL_DCCH_MessageType_c1::SecurityModeCommand(command) => {
|
||||
self.check_security_mode_command_cipher(command)
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
if null_cipher_detected {
|
||||
return Some(Event {
|
||||
event_type: EventType::QualitativeWarning { severity: Severity::High },
|
||||
event_type: EventType::QualitativeWarning {
|
||||
severity: Severity::High,
|
||||
},
|
||||
message: "Cell suggested use of null cipher".to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,18 +2,29 @@ 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::{
|
||||
BCCH_DL_SCH_MessageType, BCCH_DL_SCH_MessageType_c1, CellReselectionPriority,
|
||||
SystemInformationBlockType7, SystemInformationCriticalExtensions,
|
||||
SystemInformation_r8_IEsSib_TypeAndInfo, SystemInformation_r8_IEsSib_TypeAndInfo_Entry,
|
||||
};
|
||||
|
||||
/// Based on heuristic T7 from Shinjo Park's "Why We Cannot Win".
|
||||
pub struct LteSib6And7DowngradeAnalyzer {
|
||||
}
|
||||
pub struct LteSib6And7DowngradeAnalyzer {}
|
||||
|
||||
impl LteSib6And7DowngradeAnalyzer {
|
||||
fn unpack_system_information<'a>(&self, ie: &'a InformationElement) -> Option<&'a SystemInformation_r8_IEsSib_TypeAndInfo> {
|
||||
fn unpack_system_information<'a>(
|
||||
&self,
|
||||
ie: &'a InformationElement,
|
||||
) -> Option<&'a SystemInformation_r8_IEsSib_TypeAndInfo> {
|
||||
if let InformationElement::LTE(lte_ie) = ie {
|
||||
if let LteInformationElement::BcchDlSch(bcch_dl_sch_message) = &**lte_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 {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -33,14 +44,19 @@ impl Analyzer for LteSib6And7DowngradeAnalyzer {
|
||||
Cow::from("Tests for LTE cells broadcasting a SIB type 6 and 7 which include 2G/3G frequencies with higher priorities.")
|
||||
}
|
||||
|
||||
fn analyze_information_element(&mut self, ie: &InformationElement) -> Option<super::analyzer::Event> {
|
||||
fn analyze_information_element(
|
||||
&mut self,
|
||||
ie: &InformationElement,
|
||||
) -> Option<super::analyzer::Event> {
|
||||
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 let Some(CellReselectionPriority(p)) =
|
||||
carrier_info.cell_reselection_priority
|
||||
{
|
||||
if p == 0 {
|
||||
return Some(Event {
|
||||
event_type: EventType::QualitativeWarning { severity: Severity::High },
|
||||
@@ -52,7 +68,9 @@ impl Analyzer for LteSib6And7DowngradeAnalyzer {
|
||||
}
|
||||
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 let Some(CellReselectionPriority(p)) =
|
||||
carrier_info.cell_reselection_priority
|
||||
{
|
||||
if p == 0 {
|
||||
return Some(Event {
|
||||
event_type: EventType::QualitativeWarning { severity: Severity::High },
|
||||
@@ -62,20 +80,31 @@ impl Analyzer for LteSib6And7DowngradeAnalyzer {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
SystemInformation_r8_IEsSib_TypeAndInfo_Entry::Sib7(SystemInformationBlockType7 { carrier_freqs_info_list: Some(carrier_info_list), .. }) => {
|
||||
}
|
||||
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 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(),
|
||||
event_type: EventType::QualitativeWarning {
|
||||
severity: Severity::High,
|
||||
},
|
||||
message:
|
||||
"LTE cell advertised a 2G cell for priority 0 reselection"
|
||||
.to_string(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
None
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
// Unpacks a pattern, or returns None.
|
||||
//
|
||||
// # Examples
|
||||
@@ -24,7 +23,9 @@
|
||||
//
|
||||
macro_rules! unpack {
|
||||
($pat:pat = $val:expr) => {
|
||||
let $pat = $val else { return None; };
|
||||
let $pat = $val else {
|
||||
return None;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user