From 9a9853bb7cfd9bb448d54f2198f64773972e0cc3 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Thu, 25 Apr 2024 08:26:45 -0700 Subject: [PATCH] [dataset] relocate `IsTlvValid()` to `Dataset` (#10060) This commit relocates `IsTlvValid()` to the `Dataset` class, emphasizing its specificity for validating Dataset TLVs and not other MeshCop TLVs. --- src/core/meshcop/dataset.cpp | 54 +++++++++++++++++++++++- src/core/meshcop/dataset.hpp | 14 ++++++ src/core/meshcop/dataset_manager_ftd.cpp | 2 +- src/core/meshcop/meshcop_tlvs.cpp | 51 ---------------------- src/core/meshcop/meshcop_tlvs.hpp | 10 ----- 5 files changed, 67 insertions(+), 64 deletions(-) diff --git a/src/core/meshcop/dataset.cpp b/src/core/meshcop/dataset.cpp index 35844bddc..f757392b3 100644 --- a/src/core/meshcop/dataset.cpp +++ b/src/core/meshcop/dataset.cpp @@ -172,14 +172,64 @@ bool Dataset::IsValid(void) const for (const Tlv *cur = GetTlvsStart(); cur < end; cur = cur->GetNext()) { - VerifyOrExit(!cur->IsExtended() && (cur + 1) <= end && cur->GetNext() <= end && Tlv::IsValid(*cur), - rval = false); + VerifyOrExit(!cur->IsExtended() && (cur + 1) <= end && cur->GetNext() <= end && IsTlvValid(*cur), rval = false); } exit: return rval; } +bool Dataset::IsTlvValid(const Tlv &aTlv) +{ + bool isValid = true; + uint8_t minLength = 0; + + switch (aTlv.GetType()) + { + case Tlv::kPanId: + minLength = sizeof(PanIdTlv::UintValueType); + break; + case Tlv::kExtendedPanId: + minLength = sizeof(ExtendedPanIdTlv::ValueType); + break; + case Tlv::kPskc: + minLength = sizeof(PskcTlv::ValueType); + break; + case Tlv::kNetworkKey: + minLength = sizeof(NetworkKeyTlv::ValueType); + break; + case Tlv::kMeshLocalPrefix: + minLength = sizeof(MeshLocalPrefixTlv::ValueType); + break; + case Tlv::kChannel: + VerifyOrExit(aTlv.GetLength() >= sizeof(ChannelTlvValue), isValid = false); + isValid = aTlv.ReadValueAs().IsValid(); + break; + case Tlv::kNetworkName: + isValid = As(aTlv).IsValid(); + break; + + case Tlv::kSecurityPolicy: + isValid = As(aTlv).IsValid(); + break; + + case Tlv::kChannelMask: + isValid = As(aTlv).IsValid(); + break; + + default: + break; + } + + if (minLength > 0) + { + isValid = (aTlv.GetLength() >= minLength); + } + +exit: + return isValid; +} + const Tlv *Dataset::FindTlv(Tlv::Type aType) const { return As(Tlv::FindTlv(mTlvs, mLength, aType)); } void Dataset::ConvertTo(Info &aDatasetInfo) const diff --git a/src/core/meshcop/dataset.hpp b/src/core/meshcop/dataset.hpp index 32f74e331..af03896db 100644 --- a/src/core/meshcop/dataset.hpp +++ b/src/core/meshcop/dataset.hpp @@ -252,6 +252,20 @@ public: */ bool IsValid(void) const; + /** + * Validates the format and value of a given MeshCoP TLV used in Dataset. + * + * TLV types that can appear in an Active or Pending Operational Dataset are validated. Other TLV types including + * unknown TLV types are considered as valid. + * + * @param[in] aTlv The TLV to validate. + * + * @retval TRUE The TLV format and value is valid, or TLV type is unknown (not supported in Dataset). + * @retval FALSE The TLV format or value is invalid. + * + */ + static bool IsTlvValid(const Tlv &aTlv); + /** * Indicates whether or not a given TLV type is present in the Dataset. * diff --git a/src/core/meshcop/dataset_manager_ftd.cpp b/src/core/meshcop/dataset_manager_ftd.cpp index 16be30c3f..f845408aa 100644 --- a/src/core/meshcop/dataset_manager_ftd.cpp +++ b/src/core/meshcop/dataset_manager_ftd.cpp @@ -291,7 +291,7 @@ Error DatasetManager::DatasetTlv::ReadFromMessage(const Message &aMessage, uint1 SuccessOrExit(error = aMessage.Read(aOffset, this, sizeof(Tlv))); VerifyOrExit(GetLength() <= Dataset::kMaxValueSize, error = kErrorParse); SuccessOrExit(error = aMessage.Read(aOffset + sizeof(Tlv), mValue, GetLength())); - VerifyOrExit(Tlv::IsValid(*this), error = kErrorParse); + VerifyOrExit(Dataset::IsTlvValid(*this), error = kErrorParse); exit: return error; diff --git a/src/core/meshcop/meshcop_tlvs.cpp b/src/core/meshcop/meshcop_tlvs.cpp index a7f84eaa3..c4ea22d3b 100644 --- a/src/core/meshcop/meshcop_tlvs.cpp +++ b/src/core/meshcop/meshcop_tlvs.cpp @@ -43,57 +43,6 @@ namespace ot { namespace MeshCoP { -bool Tlv::IsValid(const Tlv &aTlv) -{ - bool isValid = true; - uint8_t minLength = 0; - - switch (aTlv.GetType()) - { - case Tlv::kPanId: - minLength = sizeof(PanIdTlv::UintValueType); - break; - case Tlv::kExtendedPanId: - minLength = sizeof(ExtendedPanIdTlv::ValueType); - break; - case Tlv::kPskc: - minLength = sizeof(PskcTlv::ValueType); - break; - case Tlv::kNetworkKey: - minLength = sizeof(NetworkKeyTlv::ValueType); - break; - case Tlv::kMeshLocalPrefix: - minLength = sizeof(MeshLocalPrefixTlv::ValueType); - break; - case Tlv::kChannel: - VerifyOrExit(aTlv.GetLength() >= sizeof(ChannelTlvValue), isValid = false); - isValid = aTlv.ReadValueAs().IsValid(); - break; - case Tlv::kNetworkName: - isValid = As(aTlv).IsValid(); - break; - - case Tlv::kSecurityPolicy: - isValid = As(aTlv).IsValid(); - break; - - case Tlv::kChannelMask: - isValid = As(aTlv).IsValid(); - break; - - default: - break; - } - - if (minLength > 0) - { - isValid = (aTlv.GetLength() >= minLength); - } - -exit: - return isValid; -} - NameData NetworkNameTlv::GetNetworkName(void) const { uint8_t len = GetLength(); diff --git a/src/core/meshcop/meshcop_tlvs.hpp b/src/core/meshcop/meshcop_tlvs.hpp index 7605392dc..084f84d8b 100644 --- a/src/core/meshcop/meshcop_tlvs.hpp +++ b/src/core/meshcop/meshcop_tlvs.hpp @@ -160,16 +160,6 @@ public: */ const Tlv *GetNext(void) const { return As(ot::Tlv::GetNext()); } - /** - * Indicates whether a TLV appears to be well-formed. - * - * @param[in] aTlv A reference to the TLV. - * - * @returns TRUE if the TLV appears to be well-formed, FALSE otherwise. - * - */ - static bool IsValid(const Tlv &aTlv); - } OT_TOOL_PACKED_END; /**