From 51f9d2cb9db58bd4af9ed5d0a0f6c8af48a43e06 Mon Sep 17 00:00:00 2001 From: Simon Lin Date: Wed, 15 Jul 2020 11:40:34 +0800 Subject: [PATCH] [tests] ignore unknown TLV (#5232) This commit ignores unknown TLVs when parsing a message and continues to parse the rest parts of the message. An unknown TLV can cause the simulator to drop the whole packet, which could lead to packet parsing issues. For example, if a Child ID Response message is dropped, the dissector will fail to add the Short Address and Extended Address to the Device Descriptors, causing subsequent secure packets unable to be decrypted. --- tests/scripts/thread-cert/mesh_cop.py | 7 ++++-- tests/scripts/thread-cert/mle.py | 23 ++++++++++---------- tests/scripts/thread-cert/tlvs_parsing.py | 26 +++++++++++++++++++++-- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/tests/scripts/thread-cert/mesh_cop.py b/tests/scripts/thread-cert/mesh_cop.py index 36544f351..3f2d1dfa9 100644 --- a/tests/scripts/thread-cert/mesh_cop.py +++ b/tests/scripts/thread-cert/mesh_cop.py @@ -30,9 +30,11 @@ from binascii import hexlify from enum import IntEnum import io +import logging import struct from network_data import SubTlvsFactory +from tlvs_parsing import UnknownTlvFactory import common @@ -931,9 +933,10 @@ class MeshCopCommandFactory: try: return self._tlvs_factories[_type] except KeyError: - raise KeyError( - "Could not find TLV factory. Unsupported TLV type: {}".format( + logging.error( + 'Could not find TLV factory. Unsupported TLV type: {}'.format( _type)) + return UnknownTlvFactory(_type) def _parse_tlv(self, data): _type = TlvType(ord(data.read(1))) diff --git a/tests/scripts/thread-cert/mle.py b/tests/scripts/thread-cert/mle.py index e075be141..c47f19056 100644 --- a/tests/scripts/thread-cert/mle.py +++ b/tests/scripts/thread-cert/mle.py @@ -28,6 +28,7 @@ # import io +import logging import struct from binascii import hexlify @@ -35,6 +36,7 @@ from binascii import hexlify import common from enum import IntEnum +from tlvs_parsing import UnknownTlvFactory class CommandType(IntEnum): @@ -452,15 +454,13 @@ class LeaderData(object): self.leader_router_id == other.leader_router_id) def __repr__(self): - return ( - "LeaderData(partition_id={}, weighting={}, data_version={}, stable_data_version={},", - "leader_router_id={})").format( - self.partition_id, - self.weighting, - self.data_version, - self.stable_data_version, - self.leader_router_id, - ) + return 'LeaderData(partition_id={}, weighting={}, data_version={}, stable_data_version={},leader_router_id={}'.format( + self.partition_id, + self.weighting, + self.data_version, + self.stable_data_version, + self.leader_router_id, + ) class LeaderDataFactory: @@ -1138,9 +1138,10 @@ class MleCommandFactory: try: return self._tlvs_factories[_type] except KeyError: - raise KeyError( - "Could not find TLV factory. Unsupported TLV type: {}".format( + logging.error( + 'Could not find TLV factory. Unsupported TLV type: {}'.format( _type)) + return UnknownTlvFactory(_type) def _parse_tlv(self, data, message_info): _type = TlvType(ord(data.read(1))) diff --git a/tests/scripts/thread-cert/tlvs_parsing.py b/tests/scripts/thread-cert/tlvs_parsing.py index 5c9920d53..5ca8f7c5c 100644 --- a/tests/scripts/thread-cert/tlvs_parsing.py +++ b/tests/scripts/thread-cert/tlvs_parsing.py @@ -27,6 +27,26 @@ # POSSIBILITY OF SUCH DAMAGE. import io +import logging + + +class UnknownTlv(object): + + def __init__(self, type, data): + self.type = type + self.data = data + + def __repr__(self): + return 'UnknownTlv(%d, %s)' % (self.type, self.data) + + +class UnknownTlvFactory(object): + + def __init__(self, type): + self._type = type + + def parse(self, data, message_info): + return UnknownTlv(self._type, data) class SubTlvsFactory(object): @@ -38,8 +58,10 @@ class SubTlvsFactory(object): try: return self._sub_tlvs_factories[_type] except KeyError: - raise RuntimeError( - "Could not find factory. Factory type = {}.".format(_type)) + logging.error( + 'Could not find TLV factory. Unsupported TLV type: {}'.format( + _type)) + return UnknownTlvFactory(_type) def parse(self, data, message_info): sub_tlvs = []