diff --git a/tests/scripts/thread-cert/Cert_5_1_01_RouterAttach.py b/tests/scripts/thread-cert/Cert_5_1_01_RouterAttach.py deleted file mode 100755 index d0ca9b67d..000000000 --- a/tests/scripts/thread-cert/Cert_5_1_01_RouterAttach.py +++ /dev/null @@ -1,318 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import mle -import network_layer -import thread_cert -from pktverify.consts import MLE_ADVERTISEMENT, MLE_PARENT_REQUEST, MLE_PARENT_RESPONSE, MLE_CHILD_UPDATE_RESPONSE, MLE_CHILD_ID_REQUEST, MLE_CHILD_ID_RESPONSE, MLE_LINK_REQUEST, MLE_LINK_ACCEPT_AND_REQUEST, ADDR_SOL_URI, SOURCE_ADDRESS_TLV, MODE_TLV, TIMEOUT_TLV, CHALLENGE_TLV, RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, MLE_FRAME_COUNTER_TLV, ROUTE64_TLV, ADDRESS16_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, TLV_REQUEST_TLV, SCAN_MASK_TLV, CONNECTIVITY_TLV, LINK_MARGIN_TLV, VERSION_TLV, ADDRESS_REGISTRATION_TLV, NL_MAC_EXTENDED_ADDRESS_TLV, NL_RLOC16_TLV, NL_STATUS_TLV, NL_ROUTER_MASK_TLV, COAP_CODE_ACK -from pktverify.packet_verifier import PacketVerifier -from pktverify.null_field import nullField - -LEADER = 1 -ROUTER = 2 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to show that the Leader is able to form -# a network and the Router attaches to it with proper steps. -# -# Test Topology: -# ------------- -# Leader -# | -# Router -# -# DUT Types: -# ---------- -# Leader -# Router - - -class Cert_5_1_01_RouterAttach(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [ROUTER] - }, - ROUTER: { - 'name': 'ROUTER', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[ROUTER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER].get_state(), 'router') - - self.collect_rloc16s() - - leader_addr = self.nodes[LEADER].get_ip6_address(config.ADDRESS_TYPE.LINK_LOCAL) - self.assertTrue(self.nodes[ROUTER].ping(leader_addr)) - self.simulator.go(5) - - router_addr = self.nodes[ROUTER].get_ip6_address(config.ADDRESS_TYPE.LINK_LOCAL) - self.assertTrue(self.nodes[LEADER].ping(router_addr)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_RLOC16 = pv.vars['LEADER_RLOC16'] - ROUTER = pv.vars['ROUTER'] - - # Step 1: Leader is sending properly formatted MLE Advertisements. - # Advertisements MUST be sent with an IP hop limit of 255 to - # the Link-Local All Nodes multicast address (FF02::1). - # The following TLVs MUST be present in the MLE Advertisements: - # - Leader Data TLV - # - Route64 TLV - # - Source Address TLV - - pkts.filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - filter(lambda p: { - LEADER_DATA_TLV, - ROUTE64_TLV, - SOURCE_ADDRESS_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255).\ - must_next() - - # Step 2: Router sends a MLE Parent Request with an IP hop limit of - # 255 to the Link-Local All Routers multicast address (FF02::2). - # The following TLVs MUST be present in the MLE Parent Request: - # - Challenge TLV - # - Mode TLV - # - Scan Mask TLV - # If the DUT sends multiple MLE Parent Requests - # - The first one MUST be sent only to all Routers - # - Subsequent ones MAY be sent to all Routers and REEDS - # - Version TLV - # If the first MLE Parent Request was sent to all Routers and - # REEDS, the test fails. - - pkts.filter_wpan_src64(ROUTER).\ - filter_LLARMA().\ - filter_mle_cmd(MLE_PARENT_REQUEST).\ - filter(lambda p: { - CHALLENGE_TLV, - MODE_TLV, - SCAN_MASK_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255 and\ - p.mle.tlv.scan_mask.r == 1 and\ - p.mle.tlv.scan_mask.e == 0).\ - must_next() - - # Step 3: Leader responds with a MLE Parent Response. - # The following TLVs MUST be present in the MLE Parent Response: - # - Challenge TLV - # - Connectivity TLV - # - Leader Data TLV - # - Link-layer Frame Counter TLV - # - Link Margin TLV - # - Response TLV - # - Source Address - # - Version TLV - # - MLE Frame Counter TLV (optional) - - pkts.filter_wpan_src64(LEADER).\ - filter_wpan_dst64(ROUTER).\ - filter_mle_cmd(MLE_PARENT_RESPONSE).\ - filter(lambda p: { - CHALLENGE_TLV, - CONNECTIVITY_TLV, - LEADER_DATA_TLV, - LINK_LAYER_FRAME_COUNTER_TLV, - LINK_MARGIN_TLV, - RESPONSE_TLV, - SOURCE_ADDRESS_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type)).\ - must_next() - - # Step 4: Router sends a MLE Child ID Request. - # The following TLVs MUST be present in the MLE Child ID Request: - # - Link-layer Frame Counter TLV - # - Mode TLV - # - Response TLV - # - Timeout TLV - # - TLV Request TLV - # - Address16 TLV - # - Network Data TLV - # - Route64 TLV (optional) - # - Version TLV - # - MLE Frame Counter TLV (optional) - # The following TLV MUST NOT be present in the MLE Child ID Request: - # - Address Registration TLV - - _pkt = pkts.filter_wpan_src64(ROUTER).\ - filter_wpan_dst64(LEADER).\ - filter_mle_cmd(MLE_CHILD_ID_REQUEST).\ - filter(lambda p: { - LINK_LAYER_FRAME_COUNTER_TLV, - MODE_TLV, - RESPONSE_TLV, - TIMEOUT_TLV, - TLV_REQUEST_TLV, - ADDRESS16_TLV, - NETWORK_DATA_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.mle.tlv.addr16 is nullField and\ - p.thread_nwd.tlv.type is nullField).\ - must_next() - _pkt.must_not_verify(lambda p: (ADDRESS_REGISTRATION_TLV) in p.mle.tlv.type) - - # Step 5: Leader responds with a Child ID Response. - # The following TLVs MUST be present in the Child ID Response: - # - Address16 TLV - # - Leader Data TLV - # - Network Data TLV - # - Source Address TLV - # - Route64 TLV (if requested) - - pkts.filter_wpan_src64(LEADER).\ - filter_wpan_dst64(ROUTER).\ - filter_mle_cmd(MLE_CHILD_ID_RESPONSE).\ - filter(lambda p: { - ADDRESS16_TLV, - LEADER_DATA_TLV, - NETWORK_DATA_TLV, - SOURCE_ADDRESS_TLV, - ROUTE64_TLV - } <= set(p.mle.tlv.type) or\ - { - ADDRESS16_TLV, - LEADER_DATA_TLV, - NETWORK_DATA_TLV, - SOURCE_ADDRESS_TLV - } <= set(p.mle.tlv.type)).\ - must_next() - - # Step 6: Router sends an Address Solicit Request. - # Ensure the Address Solicit Request is properly formatted: - # CoAP Request URI - # coap://:MM/a/as - # CoAP Payload - # - MAC Extended Address TLV - # - Status TLV - - _pkt = pkts.filter_wpan_src64(ROUTER).\ - filter_wpan_dst16(LEADER_RLOC16).\ - filter_coap_request(ADDR_SOL_URI).\ - filter(lambda p: { - NL_MAC_EXTENDED_ADDRESS_TLV, - NL_STATUS_TLV - } <= set(p.coap.tlv.type)\ - ).\ - must_next() - - # Step 7: Leader sends an Address Solicit Response. - # Ensure the Address Solicit Response is properly formatted: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # - Status TLV (value = Success) - # - RLOC16 TLV - # - Router Mask TLV - - pkts.filter_wpan_src64(LEADER).\ - filter_wpan_dst16(_pkt.wpan.src16).\ - filter_coap_ack(ADDR_SOL_URI).\ - filter(lambda p: { - NL_STATUS_TLV, - NL_RLOC16_TLV, - NL_ROUTER_MASK_TLV - } <= set(p.coap.tlv.type) and\ - p.coap.code == COAP_CODE_ACK and\ - p.thread_address.tlv.status == 0\ - ).\ - must_next() - - # Steps 8 and 9 are skipped due to change the Link establishment - # process (no multicast MLE Link Request by new router). - - # Step 10: Router is sending properly formatted MLE Advertisements. - # MLE Advertisements MUST be sent with an IP Hop Limit of - # 255 to the Link-Local All Nodes multicast address (FF02::1). - # The following TLVs MUST be present in the MLE Advertisements: - # - Leader Data TLV - # - Route64 TLV - # - Source Address TLV - - pkts.filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - filter(lambda p: { - LEADER_DATA_TLV, - ROUTE64_TLV, - SOURCE_ADDRESS_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255).\ - must_next() - - # Step 11: DUT responds with ICMPv6 Echo Reply - - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(ROUTER).\ - filter_wpan_dst64(LEADER).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(LEADER).\ - filter_wpan_dst64(ROUTER).\ - must_next() - - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(LEADER).\ - filter_wpan_dst64(ROUTER).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER).\ - filter_wpan_dst64(LEADER).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_1_02_ChildAddressTimeout.py b/tests/scripts/thread-cert/Cert_5_1_02_ChildAddressTimeout.py deleted file mode 100755 index abb9e8cdd..000000000 --- a/tests/scripts/thread-cert/Cert_5_1_02_ChildAddressTimeout.py +++ /dev/null @@ -1,183 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import mle -import thread_cert -from pktverify.consts import MLE_CHILD_ID_RESPONSE, ADDR_QRY_URI, ADDR_NTF_URI, NL_TARGET_EID_TLV -from pktverify.packet_verifier import PacketVerifier - -LEADER = 1 -ROUTER = 2 -MED = 3 -SED = 4 - -MTDS = [MED, SED] - -# Test Purpose and Description: -# ----------------------------- -# The purpose of the test case is to verify that when the timer reaches -# the value of the Timeout TLV sent by the Child, the Parent stops -# responding to Address Query on the Child's behalf -# -# Test Topology: -# -------------- -# Leader -# | -# Router -# / \ -# MED SED -# -# DUT Types: -# ---------- -# Router - - -class Cert_5_1_02_ChildAddressTimeout(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [ROUTER] - }, - ROUTER: { - 'name': 'ROUTER', - 'mode': 'rdn', - 'allowlist': [LEADER, MED, SED] - }, - MED: { - 'name': 'MED', - 'is_mtd': True, - 'mode': 'rn', - 'timeout': config.DEFAULT_CHILD_TIMEOUT, - 'allowlist': [ROUTER] - }, - SED: { - 'name': 'SED', - 'is_mtd': True, - 'mode': 'n', - 'timeout': config.DEFAULT_CHILD_TIMEOUT, - 'allowlist': [ROUTER] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[ROUTER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER].get_state(), 'router') - - self.nodes[MED].start() - self.simulator.go(5) - self.assertEqual(self.nodes[MED].get_state(), 'child') - - self.nodes[SED].start() - self.simulator.go(5) - self.assertEqual(self.nodes[SED].get_state(), 'child') - - self.collect_ipaddrs() - - med_mleid = self.nodes[MED].get_ip6_address(config.ADDRESS_TYPE.ML_EID) - sed_mleid = self.nodes[SED].get_ip6_address(config.ADDRESS_TYPE.ML_EID) - - self.nodes[MED].stop() - self.nodes[SED].stop() - self.simulator.go(config.DEFAULT_CHILD_TIMEOUT + 5) - self.assertFalse(self.nodes[LEADER].ping(med_mleid)) - self.assertFalse(self.nodes[LEADER].ping(sed_mleid)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - ROUTER = pv.vars['ROUTER'] - MED = pv.vars['MED'] - MED_MLEID = pv.vars['MED_MLEID'] - SED = pv.vars['SED'] - SED_MLEID = pv.vars['SED_MLEID'] - MM = pv.vars['MM_PORT'] - - # Step 1: Verify topology is formed correctly - - pv.verify_attached('ROUTER') - - pkts.filter_wpan_src64(ROUTER).\ - filter_wpan_dst64(MED).\ - filter_mle_cmd(MLE_CHILD_ID_RESPONSE).\ - must_next() - - pkts.filter_wpan_src64(ROUTER).\ - filter_wpan_dst64(SED).\ - filter_mle_cmd(MLE_CHILD_ID_RESPONSE).\ - must_next() - - # Step 2: Power off both devices and allow for the keep-alive timeout to expire - # Step 3: The Leader sends an ICMPv6 Echo Request to MED and attempts to perform - # address resolution by sending an Address Query Request - - pkts.filter_wpan_src64(LEADER).\ - filter_RLARMA().\ - filter_coap_request(ADDR_QRY_URI, port=MM).\ - filter(lambda p: p.thread_address.tlv.type == [NL_TARGET_EID_TLV] and\ - p.thread_address.tlv.target_eid == MED_MLEID).\ - must_next() - - # Step 4: Router MUST NOT respond with an Address Notification Message - - pkts.filter_wpan_src64(ROUTER).\ - filter_coap_request(ADDR_NTF_URI).\ - must_not_next() - - # Step 5: The Leader sends an ICMPv6 Echo Request to SED and attempts to perform - # address resolution by sending an Address Query Request - - pkts.filter_wpan_src64(LEADER).\ - filter_RLARMA().\ - filter(lambda p: p.thread_address.tlv.type == [NL_TARGET_EID_TLV] and\ - p.thread_address.tlv.target_eid == SED_MLEID).\ - filter_coap_request(ADDR_QRY_URI, port=MM).\ - must_next() - - # Step 6: Router MUST NOT respond with an Address Notification Message - - pkts.filter_wpan_src64(ROUTER).\ - filter_coap_request(ADDR_NTF_URI).\ - must_not_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_1_03_RouterAddressReallocation.py b/tests/scripts/thread-cert/Cert_5_1_03_RouterAddressReallocation.py deleted file mode 100755 index e7c443ed4..000000000 --- a/tests/scripts/thread-cert/Cert_5_1_03_RouterAddressReallocation.py +++ /dev/null @@ -1,241 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import mle -import network_layer -import thread_cert -from pktverify.consts import MLE_ADVERTISEMENT, MLE_PARENT_REQUEST, MLE_CHILD_ID_REQUEST, ADDR_SOL_URI, MODE_TLV, TIMEOUT_TLV, CHALLENGE_TLV, RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, ROUTE64_TLV, ADDRESS16_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, TLV_REQUEST_TLV, SCAN_MASK_TLV, VERSION_TLV, ADDRESS_REGISTRATION_TLV, NL_MAC_EXTENDED_ADDRESS_TLV, NL_STATUS_TLV, NL_RLOC16_TLV -from pktverify.packet_verifier import PacketVerifier - -LEADER = 1 -ROUTER1 = 2 -ROUTER2 = 3 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to verify that after the removal of the -# Leader from the network, the DUT will first attempt to reattach to the -# original partition, then attach to a new partition and request its -# original short address. -# -# Test Topology: -# ------------- -# Leader Router_2 -# / \ -> | -# Router_1 - Router_2 Router_1[DUT] -# -# DUT Types: -# ---------- -# Router - - -class Cert_5_1_03_RouterAddressReallocation(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [ROUTER1, ROUTER2] - }, - ROUTER1: { - 'name': 'ROUTER_1', - 'mode': 'rdn', - 'allowlist': [LEADER, ROUTER2] - }, - ROUTER2: { - 'name': 'ROUTER_2', - 'mode': 'rdn', - 'allowlist': [LEADER, ROUTER1] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - - self.nodes[ROUTER2].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER2].get_state(), 'router') - - self.nodes[ROUTER2].set_network_id_timeout(110) - self.nodes[LEADER].stop() - self.simulator.go(140) - - self.assertEqual(self.nodes[ROUTER2].get_state(), 'leader') - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - self.collect_rloc16s() - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_RLOC16 = pv.vars['LEADER_RLOC16'] - ROUTER_1 = pv.vars['ROUTER_1'] - ROUTER_2 = pv.vars['ROUTER_2'] - ROUTER_2_RLOC16 = pv.vars['ROUTER_2_RLOC16'] - - # Step 2: Verify topology is formed correctly. - pv.verify_attached('ROUTER_1') - _pkt_as = pkts.filter_wpan_src64(LEADER).\ - filter_coap_ack(ADDR_SOL_URI).\ - must_next() - - pv.verify_attached('ROUTER_2') - _pkt_pt = pkts.filter_wpan_src64(ROUTER_2).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - must_next() - - # Step 5: Router_1 MUST attempt to reattach to its original partition - # by sending a MLE Parent Request with a hop limit of 255 to - # the All-Routers multicast address (FF02::2). - # The following TLVs MUST be present in the MLE Parent Request: - # - Challenge TLV - # - Mode TLV - # - Scan Mask TLV (MUST have E and R flags set) - # - Version TLV - # The DUT MUST make two separate attempts to reconnect to its - # original partition in this manner - - with pkts.save_index(): - for i in range(2): - pkts.filter_wpan_src64(ROUTER_1).\ - filter_LLARMA().\ - filter_mle_cmd(MLE_PARENT_REQUEST).\ - filter(lambda p: { - CHALLENGE_TLV, - MODE_TLV, - SCAN_MASK_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255 and\ - p.mle.tlv.scan_mask.r == 1 and\ - p.mle.tlv.scan_mask.e == 1).\ - must_next() - - # Step 6: Router_1 MUST attempt to attach to any other partition - # within range by sending a MLE Parent Request. - # The following TLVs MUST be present in the MLE Parent Request: - # - Challenge TLV - # - Mode TLV - # - Scan Mask TLV - # - Version TLV - - pkts.filter_wpan_src64(ROUTER_2).\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - filter_LLANMA().\ - filter(lambda p:\ - p.mle.tlv.leader_data.partition_id != - _pkt_pt.mle.tlv.leader_data.partition_id).\ - must_next() - - pkts.filter_wpan_src64(ROUTER_1).\ - filter_LLARMA().\ - filter_mle_cmd(MLE_PARENT_REQUEST).\ - filter(lambda p: { - CHALLENGE_TLV, - MODE_TLV, - SCAN_MASK_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.mle.tlv.scan_mask.r == 1 and\ - p.mle.tlv.scan_mask.e == 0 and\ - p.ipv6.hlim == 255).\ - must_next() - - # Step 7: Router_1 sends a MLE Child ID Request to Router_2. - # The following TLVs MUST be present in the MLE Child ID Request: - # - Link-layer Frame Counter TLV - # - Mode TLV - # - Response TLV - # - Timeout TLV - # - TLV Request TLV - # - Version TLV - # - MLE Frame Counter TLV (optional) - # The following TLV MUST NOT be present in the MLE Child ID Request: - # - Address Registration TLV - - _pkt = pkts.filter_wpan_src64(ROUTER_1).\ - filter_wpan_dst64(ROUTER_2).\ - filter_mle_cmd(MLE_CHILD_ID_REQUEST).\ - filter(lambda p: { - LINK_LAYER_FRAME_COUNTER_TLV, - MODE_TLV, - RESPONSE_TLV, - TIMEOUT_TLV, - TLV_REQUEST_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type)).\ - must_next() - _pkt.must_not_verify(lambda p: (ADDRESS_REGISTRATION_TLV) in p.mle.tlv.type) - - # Step 8: Router_1 sends an Address Solicit Request. - # Ensure the Address Solicit Request is properly formatted: - # CoAP Request URI - # coap://:MM/a/as - # CoAP Payload - # - MAC Extended Address TLV - # - Status TLV - # - RLOC16 TLV - - _pkt = pkts.filter_wpan_src64(ROUTER_1).\ - filter_wpan_dst16(ROUTER_2_RLOC16).\ - filter_coap_request(ADDR_SOL_URI).\ - filter(lambda p: { - NL_MAC_EXTENDED_ADDRESS_TLV, - NL_STATUS_TLV, - NL_RLOC16_TLV - } <= set(p.coap.tlv.type) and\ - p.thread_address.tlv.rloc16 == - _pkt_as.thread_address.tlv.rloc16).\ - must_next() - - # Step 9: Router_2 automatically sends an Address Solicit Response. - - pkts.filter_wpan_src64(ROUTER_2).\ - filter_wpan_dst16(_pkt.wpan.src16).\ - filter_coap_ack(ADDR_SOL_URI).\ - filter(lambda p: p.thread_address.tlv.rloc16 == - _pkt_as.thread_address.tlv.rloc16 and\ - p.thread_address.tlv.status == 0).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_1_04_RouterAddressReallocation.py b/tests/scripts/thread-cert/Cert_5_1_04_RouterAddressReallocation.py deleted file mode 100755 index c0cc2bbc0..000000000 --- a/tests/scripts/thread-cert/Cert_5_1_04_RouterAddressReallocation.py +++ /dev/null @@ -1,269 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import mle -import network_layer -import thread_cert -from pktverify.consts import MLE_ADVERTISEMENT, MLE_PARENT_REQUEST, MLE_PARENT_RESPONSE, MLE_CHILD_ID_RESPONSE, ADDR_SOL_URI, MODE_TLV, CHALLENGE_TLV, RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, CONNECTIVITY_TLV, ROUTE64_TLV, ADDRESS16_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, SCAN_MASK_TLV, VERSION_TLV, LINK_MARGIN_TLV, SOURCE_ADDRESS_TLV, COAP_CODE_ACK, NL_STATUS_TLV, NL_RLOC16_TLV, NL_ROUTER_MASK_TLV -from pktverify.packet_verifier import PacketVerifier - -LEADER = 1 -ROUTER1 = 2 -ROUTER2 = 3 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to verify that when the original Leader is -# removed from the network, the DUT will create a new partition as Leader and -# will assign a router ID if a specific ID is requested. -# -# Test Topology: -# ------------- -# Leader -# / \ -# Router_1 - Router_2 -# [DUT] -# -# DUT Types: -# ---------- -# Router - - -class Cert_5_1_04_RouterAddressReallocation(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - SUPPORT_NCP = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'partition_id': 1, - 'allowlist': [ROUTER1, ROUTER2] - }, - ROUTER1: { - 'name': 'ROUTER_1', - 'mode': 'rdn', - 'allowlist': [LEADER, ROUTER2] - }, - ROUTER2: { - 'name': 'ROUTER_2', - 'mode': 'rdn', - 'allowlist': [LEADER, ROUTER1] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - - self.nodes[ROUTER2].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER2].get_state(), 'router') - - self.nodes[ROUTER2].set_network_id_timeout(200) - self.nodes[LEADER].stop() - self.simulator.go(220) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'leader') - self.assertEqual(self.nodes[ROUTER2].get_state(), 'router') - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - ROUTER_1 = pv.vars['ROUTER_1'] - ROUTER_2 = pv.vars['ROUTER_2'] - MM = pv.vars['MM_PORT'] - - # Step 3: Verify topology is formed correctly. - - pv.verify_attached('ROUTER_1') - _pkt_pt = pkts.filter_wpan_src64(ROUTER_1).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - must_next() - with pkts.save_index(): - _pkt_id = pkts.filter_wpan_src64(ROUTER_1).\ - filter_wpan_dst64(ROUTER_2).\ - filter_mle_cmd(MLE_PARENT_RESPONSE).\ - must_next() - - pv.verify_attached('ROUTER_2') - _pkt_as = pkts.filter_wpan_src64(LEADER).\ - filter_coap_ack(ADDR_SOL_URI, port=MM).\ - must_next() - - # Step 5: Router_1 MUST attempt to reattach to its original partition - # by sending a MLE Parent Request with a hop limit of 255 to - # the All-Routers multicast address (FF02::2). - # The following TLVs MUST be present in the MLE Parent Request: - # - Challenge TLV - # - Mode TLV - # - Scan Mask TLV (MUST have E and R flags set) - # - Version TLV - # The DUT MUST make two separate attempts to reconnect to its - # original partition in this manner - - with pkts.save_index(): - for i in range(1, 3): - pkts.filter_wpan_src64(ROUTER_1).\ - filter_LLARMA().\ - filter_mle_cmd(MLE_PARENT_REQUEST).\ - filter(lambda p: { - CHALLENGE_TLV, - MODE_TLV, - SCAN_MASK_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255 and\ - p.mle.tlv.scan_mask.r == 1 and\ - p.mle.tlv.scan_mask.e == 1 - ).\ - must_next() - - # Step 6: Router_1 MUST attempt to attach to any other partition - # within range by sending a MLE Parent Request. - # The following TLVs MUST be present in the MLE Parent Request: - # - Challenge TLV - # - Mode TLV - # - Scan Mask TLV - # - Version TLV - - pkts.filter_wpan_src64(ROUTER_1).\ - filter_LLARMA().\ - filter_mle_cmd(MLE_PARENT_REQUEST).\ - filter(lambda p: { - CHALLENGE_TLV, - MODE_TLV, - SCAN_MASK_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255 and\ - p.mle.tlv.scan_mask.r == 1 and\ - p.mle.tlv.scan_mask.e == 0 - ).\ - must_next() - - # Step 7: Router_1 MUST create a new partition and update the following - # values randomly: - # - Partition ID - # - Initial VN_version & VN_stable_version - # - Initial ID sequence number - # Notes: Considerring the randomly created VN_version & VN_stable_version - # could equal the previous versions, checking one of them to - # reduce case failures - - pkts.filter_wpan_src64(ROUTER_1).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - filter(lambda p:\ - p.mle.tlv.leader_data.partition_id != - _pkt_pt.mle.tlv.leader_data.partition_id and\ - (p.mle.tlv.leader_data.data_version != - _pkt_pt.mle.tlv.leader_data.data_version or\ - p.mle.tlv.leader_data.stable_data_version != - _pkt_pt.mle.tlv.leader_data.stable_data_version) - ).\ - must_next() - - # Step 9: Router_1 MUST send a properly formatted Parent Response and - # Child ID Response to Router_2. - - pkts.filter_wpan_src64(ROUTER_1).\ - filter_wpan_dst64(ROUTER_2).\ - filter_mle_cmd(MLE_PARENT_RESPONSE).\ - filter(lambda p: { - CHALLENGE_TLV, - CONNECTIVITY_TLV, - LEADER_DATA_TLV, - LINK_LAYER_FRAME_COUNTER_TLV, - LINK_MARGIN_TLV, - RESPONSE_TLV, - SOURCE_ADDRESS_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.mle.tlv.conn.id_seq != _pkt_id.mle.tlv.conn.id_seq - ).\ - must_next() - - pkts.filter_wpan_src64(ROUTER_1).\ - filter_wpan_dst64(ROUTER_2).\ - filter_mle_cmd(MLE_CHILD_ID_RESPONSE).\ - filter(lambda p: { - ADDRESS16_TLV, - LEADER_DATA_TLV, - NETWORK_DATA_TLV, - SOURCE_ADDRESS_TLV, - ROUTE64_TLV - } <= set(p.mle.tlv.type) or\ - { - ADDRESS16_TLV, - LEADER_DATA_TLV, - NETWORK_DATA_TLV, - SOURCE_ADDRESS_TLV - } <= set(p.mle.tlv.type)\ - ).\ - must_next() - - # Step 10: Router_1 MUST send a properly-formatted Address Solicit - # Response Message to Router_2. - # If a specific router ID is requested, the DUT MUST provide this - # router ID: - # CoAP Response Code - # - 2.04 Changed - # CoAP Payload - # - Status TLV (value = Success) - # - RLOC16 TLV - # - Router Mask TLV - - pkts.filter_wpan_src64(ROUTER_1).\ - filter_coap_ack(ADDR_SOL_URI, port=MM).\ - filter(lambda p: { - NL_STATUS_TLV, - NL_RLOC16_TLV, - NL_ROUTER_MASK_TLV - } <= set(p.coap.tlv.type) and\ - p.coap.code == COAP_CODE_ACK and\ - p.thread_address.tlv.rloc16 == - _pkt_as.thread_address.tlv.rloc16 and\ - p.thread_address.tlv.status == 0 - ).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_1_05_RouterAddressTimeout.py b/tests/scripts/thread-cert/Cert_5_1_05_RouterAddressTimeout.py deleted file mode 100755 index debf50f40..000000000 --- a/tests/scripts/thread-cert/Cert_5_1_05_RouterAddressTimeout.py +++ /dev/null @@ -1,314 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import mle -import network_layer -import thread_cert -from pktverify.consts import MLE_PARENT_RESPONSE, MLE_CHILD_ID_RESPONSE, MLE_LINK_REQUEST, ADDR_SOL_URI, CHALLENGE_TLV, RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, CONNECTIVITY_TLV, ROUTE64_TLV, ADDRESS16_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, VERSION_TLV, TLV_REQUEST_TLV, LINK_MARGIN_TLV, SOURCE_ADDRESS_TLV, COAP_CODE_ACK, COAP_CODE_POST, NL_MAC_EXTENDED_ADDRESS_TLV, NL_STATUS_TLV, NL_RLOC16_TLV, NL_ROUTER_MASK_TLV -from pktverify.packet_verifier import PacketVerifier - -LEADER = 1 -ROUTER1 = 2 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to verify that after deallocating a Router ID, -# Leader as a DUT doesn't reassign the Router ID for at least ID_REUSE_DELAY -# seconds -# -# Test Topology: -# ------------- -# Leader -# | -# Router -# -# DUT Types: -# ---------- -# Leader - - -class Cert_5_1_05_RouterAddressTimeout(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [ROUTER1] - }, - ROUTER1: { - 'name': 'ROUTER', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - } - - def _setUpRouter1(self): - self.nodes[ROUTER1].add_allowlist(self.nodes[LEADER].get_addr64()) - self.nodes[ROUTER1].enable_allowlist() - self.nodes[ROUTER1].set_router_selection_jitter(1) - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - - self.nodes[ROUTER1].reset() - self._setUpRouter1() - self.simulator.go(200) - self.nodes[ROUTER1].start() - self.simulator.go(config.ROUTER_RESTORE_DELAY) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - - self.nodes[ROUTER1].reset() - self._setUpRouter1() - self.simulator.go(300) - self.nodes[ROUTER1].start() - self.simulator.go(config.ROUTER_RESTORE_DELAY) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - ROUTER = pv.vars['ROUTER'] - MM = pv.vars['MM_PORT'] - - # Step 1: Verify topology is formed correctly. - - pv.verify_attached('ROUTER') - _pkt_as = pkts.filter_wpan_src64(LEADER).\ - filter_coap_ack(ADDR_SOL_URI, port=MM).\ - filter(lambda p: { - NL_STATUS_TLV, - NL_RLOC16_TLV, - NL_ROUTER_MASK_TLV - } <= set(p.coap.tlv.type) and\ - p.coap.code == COAP_CODE_ACK and\ - p.thread_address.tlv.status == 0 - ).\ - must_next() - - # Step 3: Router automatically sends a link request, reattaches and - # requests its original Router ID after reset within the - # ID_REUSE_DELAY interval - - pkts.filter_wpan_src64(ROUTER).\ - filter_LLARMA().\ - filter_mle_cmd(MLE_LINK_REQUEST).\ - filter(lambda p: { - CHALLENGE_TLV, - VERSION_TLV, - TLV_REQUEST_TLV, - ADDRESS16_TLV, - ROUTE64_TLV - } <= set(p.mle.tlv.type)\ - ).\ - must_next() - - # Step 4: Leader MUST send a properly formatted Parent Response and - # Child ID Response to Router. - # And send Address Solicit Response Message to Router. - # The RLOC16 TLV in the Address Solicit Response message MUST - # contain a different Router ID then the one allocated in the - # original attach because ID_REUSE_DELAY interval has not - # timed out. - # - # CoAP Response Code - # - 2.04 Changed - # CoAP Payload - # - Status TLV (value = Success) - # - RLOC16 TLV - # - Router Mask TLV - - pkts.filter_wpan_src64(LEADER).\ - filter_wpan_dst64(ROUTER).\ - filter_mle_cmd(MLE_PARENT_RESPONSE).\ - filter(lambda p: { - CHALLENGE_TLV, - CONNECTIVITY_TLV, - LEADER_DATA_TLV, - LINK_LAYER_FRAME_COUNTER_TLV, - LINK_MARGIN_TLV, - RESPONSE_TLV, - SOURCE_ADDRESS_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) - ).\ - must_next() - - pkts.filter_wpan_src64(LEADER).\ - filter_wpan_dst64(ROUTER).\ - filter_mle_cmd(MLE_CHILD_ID_RESPONSE).\ - filter(lambda p: { - ADDRESS16_TLV, - LEADER_DATA_TLV, - NETWORK_DATA_TLV, - SOURCE_ADDRESS_TLV, - ROUTE64_TLV - } <= set(p.mle.tlv.type) or\ - { - ADDRESS16_TLV, - LEADER_DATA_TLV, - NETWORK_DATA_TLV, - SOURCE_ADDRESS_TLV - } <= set(p.mle.tlv.type)\ - ).\ - must_next() - - _pkt_as2 = pkts.filter_wpan_src64(ROUTER).\ - filter_coap_request(ADDR_SOL_URI, port=MM).\ - filter(lambda p: { - NL_MAC_EXTENDED_ADDRESS_TLV, - NL_RLOC16_TLV, - NL_STATUS_TLV - } <= set(p.coap.tlv.type) and\ - p.coap.code == COAP_CODE_POST and\ - p.thread_address.tlv.rloc16 == - _pkt_as.thread_address.tlv.rloc16 - ).\ - must_next() - - _pkt_as3 = pkts.filter_wpan_src64(LEADER).\ - filter_coap_ack(ADDR_SOL_URI, port=MM).\ - filter(lambda p: { - NL_STATUS_TLV, - NL_RLOC16_TLV, - NL_ROUTER_MASK_TLV - } <= set(p.coap.tlv.type) and\ - p.coap.code == COAP_CODE_ACK and\ - p.thread_address.tlv.rloc16 != - _pkt_as2.thread_address.tlv.rloc16 and\ - p.thread_address.tlv.status == 0 - ).\ - must_next() - - # Step 6: Router automatically sends a link request, reattaches and - # requests its most recent Router ID after reset after the - # ID_REUSE_DELAY interval - - pkts.filter_wpan_src64(ROUTER).\ - filter_LLARMA().\ - filter_mle_cmd(MLE_LINK_REQUEST).\ - filter(lambda p: { - CHALLENGE_TLV, - VERSION_TLV, - TLV_REQUEST_TLV, - ADDRESS16_TLV, - ROUTE64_TLV - } <= set(p.mle.tlv.type)\ - ).\ - must_next() - - # Step 7: Leader MUST send a properly formatted Parent Response and - # Child ID Response to Router. - # And send Address Solicit Response Message to Router. - # The RLOC16 TLV in the Address Solicit Response message MUST - # contain the requested Router ID - # - # CoAP Response Code - # - 2.04 Changed - # CoAP Payload - # - Status TLV (value = Success) - # - RLOC16 TLV - # - Router Mask TLV - - pkts.filter_wpan_src64(LEADER).\ - filter_wpan_dst64(ROUTER).\ - filter_mle_cmd(MLE_PARENT_RESPONSE).\ - filter(lambda p: { - CHALLENGE_TLV, - CONNECTIVITY_TLV, - LEADER_DATA_TLV, - LINK_LAYER_FRAME_COUNTER_TLV, - LINK_MARGIN_TLV, - RESPONSE_TLV, - SOURCE_ADDRESS_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) - ).\ - must_next() - - pkts.filter_wpan_src64(LEADER).\ - filter_wpan_dst64(ROUTER).\ - filter_mle_cmd(MLE_CHILD_ID_RESPONSE).\ - filter(lambda p: { - ADDRESS16_TLV, - LEADER_DATA_TLV, - NETWORK_DATA_TLV, - SOURCE_ADDRESS_TLV, - ROUTE64_TLV - } <= set(p.mle.tlv.type) or\ - { - ADDRESS16_TLV, - LEADER_DATA_TLV, - NETWORK_DATA_TLV, - SOURCE_ADDRESS_TLV - } <= set(p.mle.tlv.type)\ - ).\ - must_next() - - pkts.filter_wpan_src64(ROUTER).\ - filter_coap_request(ADDR_SOL_URI, port=MM).\ - filter(lambda p: { - NL_MAC_EXTENDED_ADDRESS_TLV, - NL_RLOC16_TLV, - NL_STATUS_TLV - } <= set(p.coap.tlv.type) and\ - p.coap.code == COAP_CODE_POST and\ - p.thread_address.tlv.rloc16 == - _pkt_as3.thread_address.tlv.rloc16 - ).\ - must_next() - - pkts.filter_wpan_src64(LEADER).\ - filter_coap_ack(ADDR_SOL_URI, port=MM).\ - filter(lambda p: { - NL_STATUS_TLV, - NL_RLOC16_TLV, - NL_ROUTER_MASK_TLV - } <= set(p.coap.tlv.type) and\ - p.coap.code == COAP_CODE_ACK and\ - p.thread_address.tlv.rloc16 == - _pkt_as3.thread_address.tlv.rloc16 and\ - p.thread_address.tlv.status == 0 - ).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_1_06_RemoveRouterId.py b/tests/scripts/thread-cert/Cert_5_1_06_RemoveRouterId.py deleted file mode 100755 index 738bc2b97..000000000 --- a/tests/scripts/thread-cert/Cert_5_1_06_RemoveRouterId.py +++ /dev/null @@ -1,199 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import command -import config -import mle -import thread_cert -from command import CheckType -from pktverify.consts import MLE_PARENT_REQUEST, MLE_CHILD_ID_REQUEST, ADDR_SOL_URI, MODE_TLV, TIMEOUT_TLV, CHALLENGE_TLV, RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, ADDRESS16_TLV, NETWORK_DATA_TLV, TLV_REQUEST_TLV, SCAN_MASK_TLV, VERSION_TLV, ADDRESS_REGISTRATION_TLV, NL_MAC_EXTENDED_ADDRESS_TLV, NL_RLOC16_TLV, NL_STATUS_TLV, NL_ROUTER_MASK_TLV, COAP_CODE_POST, COAP_CODE_ACK -from pktverify.packet_verifier import PacketVerifier -from pktverify.null_field import nullField - -LEADER = 1 -ROUTER1 = 2 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to verify that when the Leader -# de-allocates a router ID, the DUT, as a router, re-attaches. -# -# Test Topology: -# ------------- -# Leader -# | -# Router -# -# DUT Types: -# ---------- -# Router - - -class Cert_5_1_06_RemoveRouterId(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [ROUTER1] - }, - ROUTER1: { - 'name': 'ROUTER', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - rloc16 = self.nodes[ROUTER1].get_addr16() - self.collect_rloc16s() - - router_lladdr = self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.LINK_LOCAL) - self.assertTrue(self.nodes[LEADER].ping(router_lladdr)) - - self.nodes[LEADER].release_router_id(rloc16 >> 10) - self.simulator.go(5) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - - self.assertTrue(self.nodes[LEADER].ping(router_lladdr)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_RLOC16 = pv.vars['LEADER_RLOC16'] - ROUTER = pv.vars['ROUTER'] - MM = pv.vars['MM_PORT'] - - # Step 1: Verify topology is formed correctly. - - pv.verify_attached('ROUTER') - _pkt_as = pkts.filter_wpan_src64(LEADER).\ - filter_coap_ack(ADDR_SOL_URI, port=MM).\ - filter(lambda p: { - NL_STATUS_TLV, - NL_RLOC16_TLV, - NL_ROUTER_MASK_TLV - } <= set(p.coap.tlv.type) and\ - p.coap.code == COAP_CODE_ACK and\ - p.thread_address.tlv.status == 0 - ).\ - must_next() - - # Step 3: Router send a properly formatted - # MLE Parent Request, - # MLE Child ID Request, - # and Address Solicit Request - # messages to the Leader. - - pkts.filter_wpan_src64(ROUTER).\ - filter_LLARMA().\ - filter_mle_cmd(MLE_PARENT_REQUEST).\ - filter(lambda p: { - CHALLENGE_TLV, - MODE_TLV, - SCAN_MASK_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255 and\ - p.mle.tlv.scan_mask.r == 1 and\ - p.mle.tlv.scan_mask.e == 0).\ - must_next() - - _pkt = pkts.filter_wpan_src64(ROUTER).\ - filter_wpan_dst64(LEADER).\ - filter_mle_cmd(MLE_CHILD_ID_REQUEST).\ - filter(lambda p: { - LINK_LAYER_FRAME_COUNTER_TLV, - MODE_TLV, - RESPONSE_TLV, - TIMEOUT_TLV, - TLV_REQUEST_TLV, - ADDRESS16_TLV, - NETWORK_DATA_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.mle.tlv.addr16 is nullField and\ - p.thread_nwd.tlv.type is nullField).\ - must_next() - _pkt.must_not_verify(lambda p: (ADDRESS_REGISTRATION_TLV) in p.mle.tlv.type) - - pkts.filter_wpan_src64(ROUTER).\ - filter_wpan_dst16(LEADER_RLOC16).\ - filter_coap_request(ADDR_SOL_URI, port=MM).\ - filter(lambda p: { - NL_MAC_EXTENDED_ADDRESS_TLV, - NL_RLOC16_TLV, - NL_STATUS_TLV - } <= set(p.coap.tlv.type) and\ - p.coap.code == COAP_CODE_POST and\ - p.thread_address.tlv.rloc16 == - _pkt_as.thread_address.tlv.rloc16 - ).\ - must_next() - - pkts.filter_wpan_src64(LEADER).\ - filter_coap_ack(ADDR_SOL_URI, port=MM).\ - filter(lambda p: { - NL_STATUS_TLV, - NL_RLOC16_TLV, - NL_ROUTER_MASK_TLV - } <= set(p.coap.tlv.type) and\ - p.coap.code == COAP_CODE_ACK and\ - p.thread_address.tlv.rloc16 != - _pkt_as.thread_address.tlv.rloc16 and\ - p.thread_address.tlv.status == 0 - ).\ - must_next() - - # Step 4: DUT responds with ICMPv6 Echo Reply - - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(LEADER).\ - filter_wpan_dst64(ROUTER).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER).\ - filter_wpan_dst64(LEADER).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_1_07_MaxChildCount.py b/tests/scripts/thread-cert/Cert_5_1_07_MaxChildCount.py deleted file mode 100755 index d65e17685..000000000 --- a/tests/scripts/thread-cert/Cert_5_1_07_MaxChildCount.py +++ /dev/null @@ -1,279 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import thread_cert -from pktverify.consts import MLE_PARENT_RESPONSE, MLE_CHILD_ID_RESPONSE, SOURCE_ADDRESS_TLV, CHALLENGE_TLV, RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, ADDRESS16_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, CONNECTIVITY_TLV, LINK_MARGIN_TLV, VERSION_TLV, ADDRESS_REGISTRATION_TLV -from pktverify.packet_verifier import PacketVerifier -from pktverify.null_field import nullField - -LEADER = 1 -ROUTER = 2 -SED1 = 7 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to validate the minimum -# conformance requirements for router-capable devices: -# a)Minimum number of supported children. -# b)Minimum MTU requirement when sending/forwarding an -# IPv6 datagram to a SED. -# c)Minimum number of sent/forwarded IPv6 datagrams to -# SED children. -# -# Test Topology: -# ------------- -# -# Leader -# | -# Router[DUT] -# / \ -# MED1 - MED4 SED1 - SED6 -# -# DUT Types: -# ---------- -# Router - - -class Cert_5_1_07_MaxChildCount(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [ROUTER] - }, - ROUTER: { - 'name': 'ROUTER', - 'max_children': 10, - 'mode': 'rdn', - 'allowlist': [LEADER, 3, 4, 5, 6, SED1, 8, 9, 10, 11, 12] - }, - 3: { - 'name': 'MED1', - 'is_mtd': True, - 'mode': 'rn', - 'timeout': config.DEFAULT_CHILD_TIMEOUT, - 'allowlist': [ROUTER] - }, - 4: { - 'name': 'MED2', - 'is_mtd': True, - 'mode': 'rn', - 'timeout': config.DEFAULT_CHILD_TIMEOUT, - 'allowlist': [ROUTER] - }, - 5: { - 'name': 'MED3', - 'is_mtd': True, - 'mode': 'rn', - 'timeout': config.DEFAULT_CHILD_TIMEOUT, - 'allowlist': [ROUTER] - }, - 6: { - 'name': 'MED4', - 'is_mtd': True, - 'mode': 'rn', - 'timeout': config.DEFAULT_CHILD_TIMEOUT, - 'allowlist': [ROUTER] - }, - SED1: { - 'name': 'SED1', - 'is_mtd': True, - 'mode': '-', - 'timeout': config.DEFAULT_CHILD_TIMEOUT, - 'allowlist': [ROUTER] - }, - 8: { - 'name': 'SED2', - 'is_mtd': True, - 'mode': '-', - 'timeout': config.DEFAULT_CHILD_TIMEOUT, - 'allowlist': [ROUTER] - }, - 9: { - 'name': 'SED3', - 'is_mtd': True, - 'mode': '-', - 'timeout': config.DEFAULT_CHILD_TIMEOUT, - 'allowlist': [ROUTER] - }, - 10: { - 'name': 'SED4', - 'is_mtd': True, - 'mode': '-', - 'timeout': config.DEFAULT_CHILD_TIMEOUT, - 'allowlist': [ROUTER] - }, - 11: { - 'name': 'SED5', - 'is_mtd': True, - 'mode': '-', - 'timeout': config.DEFAULT_CHILD_TIMEOUT, - 'allowlist': [ROUTER] - }, - 12: { - 'name': 'SED6', - 'is_mtd': True, - 'mode': '-', - 'timeout': config.DEFAULT_CHILD_TIMEOUT, - 'allowlist': [ROUTER] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[ROUTER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER].get_state(), 'router') - - for i in range(3, 13): - self.nodes[i].start() - self.simulator.go(7) - self.assertEqual(self.nodes[i].get_state(), 'child') - - self.collect_rloc16s() - self.collect_ipaddrs() - - ipaddrs = self.nodes[SED1].get_addrs() - for addr in ipaddrs: - if addr[0:4] != 'fe80' and 'ff:fe00' not in addr: - self.assertTrue(self.nodes[LEADER].ping(addr, size=1232)) - break - - for i in range(3, 13): - ipaddrs = self.nodes[i].get_addrs() - for addr in ipaddrs: - if addr[0:4] != 'fe80' and 'ff:fe00' not in addr: - self.assertTrue(self.nodes[LEADER].ping(addr, size=106)) - break - - def verify(self, pv: PacketVerifier): - pkts = pv.pkts - pv.summary.show() - - ROUTER = pv.vars['ROUTER'] - router_pkts = pkts.filter_wpan_src64(ROUTER) - - # Step 1: The DUT MUST send properly formatted MLE Parent Response - # and MLE Child ID Response to each child. - for i in range(1, 7): - _pkts = router_pkts.copy().filter_wpan_dst64(pv.vars['SED%d' % i]) - _pkts.filter_mle_cmd(MLE_PARENT_RESPONSE).\ - filter(lambda p: { - CHALLENGE_TLV, - CONNECTIVITY_TLV, - LEADER_DATA_TLV, - LINK_LAYER_FRAME_COUNTER_TLV, - LINK_MARGIN_TLV, - RESPONSE_TLV, - SOURCE_ADDRESS_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) - ).\ - must_next() - _pkts.filter_mle_cmd(MLE_CHILD_ID_RESPONSE).\ - filter(lambda p: { - SOURCE_ADDRESS_TLV, - LEADER_DATA_TLV, - ADDRESS16_TLV, - NETWORK_DATA_TLV, - ADDRESS_REGISTRATION_TLV - } <= set(p.mle.tlv.type) and\ - p.mle.tlv.addr16 is not nullField and\ - p.thread_nwd.tlv.type is not None and\ - p.thread_meshcop.tlv.type is not None - ).\ - must_next() - - for i in range(1, 5): - _pkts = router_pkts.copy().filter_wpan_dst64(pv.vars['MED%d' % i]) - _pkts.filter_mle_cmd(MLE_PARENT_RESPONSE).\ - filter(lambda p: { - CHALLENGE_TLV, - CONNECTIVITY_TLV, - LEADER_DATA_TLV, - LINK_LAYER_FRAME_COUNTER_TLV, - LINK_MARGIN_TLV, - RESPONSE_TLV, - SOURCE_ADDRESS_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) - ).\ - must_next() - - _pkts.filter_mle_cmd(MLE_CHILD_ID_RESPONSE).\ - filter(lambda p: { - SOURCE_ADDRESS_TLV, - LEADER_DATA_TLV, - ADDRESS16_TLV, - NETWORK_DATA_TLV, - ADDRESS_REGISTRATION_TLV - } <= set(p.mle.tlv.type) and\ - p.mle.tlv.addr16 is not nullField and\ - p.thread_meshcop.tlv.type is not None - ).\ - must_next() - - # Step 2: The DUT MUST properly forward ICMPv6 Echo Requests to all MED children - # The DUT MUST properly forward ICMPv6 Echo Replies to the Leader - leader_rloc16 = pv.vars['LEADER_RLOC16'] - for i in range(1, 5): - rloc16 = pv.vars['MED%d_RLOC16' % i] - _pkts = router_pkts.copy() - p = _pkts.filter('wpan.dst16 == {rloc16}', rloc16=rloc16).\ - filter_ping_request().\ - must_next() - _pkts.filter('wpan.dst16 == {rloc16}', - rloc16=leader_rloc16).\ - filter_ping_reply(identifier=p.icmpv6.echo.identifier).\ - must_next() - - # Step 3: The DUT MUST properly forward ICMPv6 Echo Requests to all SED children - # The DUT MUST properly forward ICMPv6 Echo Replies to the Leader - for i in range(1, 7): - rloc16 = pv.vars['SED%d_RLOC16' % i] - _pkts = router_pkts.copy() - p = _pkts.filter('wpan.dst16 == {rloc16}', rloc16=rloc16).\ - filter_ping_request().\ - must_next() - _pkts.filter('wpan.dst16 == {rloc16}', - rloc16=leader_rloc16).\ - filter_ping_reply(identifier=p.icmpv6.echo.identifier).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_1_08_RouterAttachConnectivity.py b/tests/scripts/thread-cert/Cert_5_1_08_RouterAttachConnectivity.py deleted file mode 100755 index 3aac58c7d..000000000 --- a/tests/scripts/thread-cert/Cert_5_1_08_RouterAttachConnectivity.py +++ /dev/null @@ -1,220 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import mle -import thread_cert -from pktverify.consts import MLE_PARENT_REQUEST, MLE_PARENT_RESPONSE, MLE_CHILD_ID_REQUEST, SOURCE_ADDRESS_TLV, MODE_TLV, TIMEOUT_TLV, CHALLENGE_TLV, RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, ADDRESS16_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, TLV_REQUEST_TLV, SCAN_MASK_TLV, CONNECTIVITY_TLV, LINK_MARGIN_TLV, VERSION_TLV, ADDRESS_REGISTRATION_TLV -from pktverify.packet_verifier import PacketVerifier -from pktverify.null_field import nullField - -LEADER = 1 -ROUTER1 = 2 -ROUTER2 = 3 -ROUTER3 = 4 -ROUTER4 = 5 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to verify that the DUT chooses -# to attach to a router with better connectivity -# -# Test Topology: -# ------------- -# Leader--Router1 -# / \ / -# Router2 Router3 -# \ / -# Router4[DUT] -# -# DUT Types: -# ---------- -# Router - - -class Cert_5_1_08_RouterAttachConnectivity(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [ROUTER1, ROUTER2, ROUTER3] - }, - ROUTER1: { - 'name': 'ROUTER_1', - 'mode': 'rdn', - 'allowlist': [LEADER, ROUTER3] - }, - ROUTER2: { - 'name': 'ROUTER_2', - 'mode': 'rdn', - 'allowlist': [LEADER, ROUTER4] - }, - ROUTER3: { - 'name': 'ROUTER_3', - 'mode': 'rdn', - 'allowlist': [LEADER, ROUTER1, ROUTER4] - }, - ROUTER4: { - 'name': 'ROUTER_4', - 'mode': 'rdn', - 'allowlist': [ROUTER2, ROUTER3] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - for i in range(2, 5): - self.nodes[i].start() - - self.simulator.go(config.ROUTER_STARTUP_DELAY) - - for i in range(2, 5): - self.assertEqual(self.nodes[i].get_state(), 'router') - - self.simulator.go(config.MAX_ADVERTISEMENT_INTERVAL) - - self.nodes[ROUTER4].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER4].get_state(), 'router') - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - ROUTER_2 = pv.vars['ROUTER_2'] - ROUTER_3 = pv.vars['ROUTER_3'] - ROUTER_4 = pv.vars['ROUTER_4'] - - # Step 1: Verify all routers and Leader are sending MLE advertisements. - for i in (1, 2, 3): - with pkts.save_index(): - pv.verify_attached('ROUTER_%d' % i) - - # Step 3: DUT sends a MLE Parent Request with an IP hop limit of - # 255 to the Link-Local All Routers multicast address (FF02::2). - # The following TLVs MUST be present in the MLE Parent Request: - # - Challenge TLV - # - Mode TLV - # - Scan Mask TLV - # If the DUT sends multiple MLE Parent Requests - # - The first one MUST be sent only to all Routers - # - Subsequent ones MAY be sent to all Routers and REEDS - # - Version TLV - # If the first MLE Parent Request was sent to all Routers and - # REEDS, the test fails. - - pkts.filter_wpan_src64(ROUTER_4).\ - filter_LLARMA().\ - filter_mle_cmd(MLE_PARENT_REQUEST).\ - filter(lambda p: { - CHALLENGE_TLV, - MODE_TLV, - SCAN_MASK_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255 and\ - p.mle.tlv.scan_mask.r == 1 and\ - p.mle.tlv.scan_mask.e == 0 - ).\ - must_next() - - # Step 4: Router2 and Router3 respond with a MLE Parent Response. - # The following TLVs MUST be present in the MLE Parent Response: - # - Challenge TLV - # - Connectivity TLV - # - Leader Data TLV - # - Link-layer Frame Counter TLV - # - Link Margin TLV - # - Response TLV - # - Source Address - # - Version TLV - # - MLE Frame Counter TLV (optional) - - for i in (2, 3): - with pkts.save_index(): - pkts.filter_wpan_src64(pv.vars['ROUTER_%d' % i]).\ - filter_wpan_dst64(ROUTER_4).\ - filter_mle_cmd(MLE_PARENT_RESPONSE).\ - filter(lambda p: { - CHALLENGE_TLV, - CONNECTIVITY_TLV, - LEADER_DATA_TLV, - LINK_LAYER_FRAME_COUNTER_TLV, - LINK_MARGIN_TLV, - RESPONSE_TLV, - SOURCE_ADDRESS_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) - ).\ - must_next() - - # Step 5: DUT sends a MLE Child ID Request to Router3. - # The following TLVs MUST be present in the MLE Child ID Request: - # - Link-layer Frame Counter TLV - # - Mode TLV - # - Response TLV - # - Timeout TLV - # - TLV Request TLV - # - Address16 TLV - # - Network Data TLV - # - Route64 TLV (optional) - # - Version TLV - # - MLE Frame Counter TLV (optional) - # The following TLV MUST NOT be present in the MLE Child ID Request: - # - Address Registration TLV - - _pkt = pkts.filter_wpan_src64(ROUTER_4).\ - filter_wpan_dst64(ROUTER_3).\ - filter_mle_cmd(MLE_CHILD_ID_REQUEST).\ - filter(lambda p: { - LINK_LAYER_FRAME_COUNTER_TLV, - MODE_TLV, - RESPONSE_TLV, - TIMEOUT_TLV, - TLV_REQUEST_TLV, - ADDRESS16_TLV, - NETWORK_DATA_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.mle.tlv.addr16 is nullField and\ - p.thread_nwd.tlv.type is nullField - ).\ - must_next() - _pkt.must_not_verify(lambda p: (ADDRESS_REGISTRATION_TLV) in p.mle.tlv.type) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_1_09_REEDAttachConnectivity.py b/tests/scripts/thread-cert/Cert_5_1_09_REEDAttachConnectivity.py deleted file mode 100755 index ba18b3147..000000000 --- a/tests/scripts/thread-cert/Cert_5_1_09_REEDAttachConnectivity.py +++ /dev/null @@ -1,274 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import mle -import thread_cert -from pktverify.consts import MLE_ADVERTISEMENT, MLE_PARENT_REQUEST, MLE_PARENT_RESPONSE, MLE_CHILD_ID_REQUEST, SOURCE_ADDRESS_TLV, MODE_TLV, TIMEOUT_TLV, CHALLENGE_TLV, RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, ADDRESS16_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, TLV_REQUEST_TLV, SCAN_MASK_TLV, CONNECTIVITY_TLV, LINK_MARGIN_TLV, VERSION_TLV, ADDRESS_REGISTRATION_TLV -from pktverify.packet_verifier import PacketVerifier -from pktverify.null_field import nullField - -LEADER = 1 -ROUTER1 = 2 -REED1 = 3 -REED2 = 4 -ROUTER2 = 5 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to verify that the DUT will -# pick REED_1 as its parent because of its better connectivity -# -# Test Topology: -# ------------- -# Leader--Router1 -# / \ / -# REED2 REED1 -# \ / -# Router2[DUT] -# -# DUT Types: -# ---------- -# Router - - -class Cert_5_1_09_REEDAttachConnectivity(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [ROUTER1, REED1, REED2] - }, - ROUTER1: { - 'name': 'ROUTER_1', - 'mode': 'rdn', - 'allowlist': [LEADER, REED1] - }, - REED1: { - 'name': 'REED_1', - 'mode': 'rdn', - 'router_upgrade_threshold': 0, - 'allowlist': [LEADER, ROUTER1, ROUTER2] - }, - REED2: { - 'name': 'REED_2', - 'mode': 'rdn', - 'router_upgrade_threshold': 0, - 'allowlist': [LEADER, ROUTER2] - }, - ROUTER2: { - 'name': 'ROUTER_2', - 'mode': 'rdn', - 'allowlist': [REED1, REED2] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - for i in range(2, 5): - self.nodes[i].start() - - self.simulator.go(config.ROUTER_STARTUP_DELAY) - - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - self.assertEqual(self.nodes[REED1].get_state(), 'child') - self.assertEqual(self.nodes[REED2].get_state(), 'child') - - self.simulator.go(config.MAX_ADVERTISEMENT_INTERVAL) - - self.nodes[ROUTER2].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER2].get_state(), 'router') - self.assertEqual(self.nodes[REED1].get_state(), 'router') - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - REED_1 = pv.vars['REED_1'] - ROUTER_1 = pv.vars['ROUTER_1'] - ROUTER_2 = pv.vars['ROUTER_2'] - - # Step 1: Verify ROUTER_1 and Leader are sending MLE advertisements. - pkts.filter_wpan_src64(LEADER).\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - must_next() - pv.verify_attached('ROUTER_1') - - # Step 3: The DUT sends a MLE Parent Request with an IP hop limit of - # 255 to the Link-Local All Routers multicast address (FF02::2). - # The following TLVs MUST be present in the MLE Parent Request: - # - Challenge TLV - # - Mode TLV - # - Scan Mask TLV - # If the DUT sends multiple MLE Parent Requests - # - The first one MUST be sent only to all Routers - # - Subsequent ones MAY be sent to all Routers and REEDS - # - Version TLV - # If the first MLE Parent Request was sent to all Routers and - # REEDS, the test fails. - - pkts.filter_wpan_src64(ROUTER_2).\ - filter_LLARMA().\ - filter_mle_cmd(MLE_PARENT_REQUEST).\ - filter(lambda p: { - CHALLENGE_TLV, - MODE_TLV, - SCAN_MASK_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255 and\ - p.mle.tlv.scan_mask.r == 1 and\ - p.mle.tlv.scan_mask.e == 0 - ).\ - must_next() - lstart = pkts.index - - # Step 5: The DUT MUST send a MLE Parent Request with an IP hop limit of - # 255 to the Link-Local All Routers multicast address (FF02::2). - # The following TLVs MUST be present in the MLE Parent Request: - # - Challenge TLV - # - Mode TLV - # - Scan Mask TLV - # - The Scan Mask TLV MUST be sent to Routers And REEDs - # - Version TLV - # - # In securing the first three messages of the attaching process, - # the full four-byte key sequence number MUST be included in - # the Auxiliary Security Header used for MLE security. - # - # To send the full four-byte key sequence number, the Key - # Identifier Mode of the Security Control Field SHALL be set to - # ‘0x02’, indicating the presence of a four-byte Key Source, - # which SHALL contain the four-byte key sequence number in - # network byte order. - - pkts.filter_wpan_src64(ROUTER_2).\ - filter_LLARMA().\ - filter_mle_cmd(MLE_PARENT_REQUEST).\ - filter(lambda p: { - CHALLENGE_TLV, - MODE_TLV, - SCAN_MASK_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255 and\ - p.mle.tlv.scan_mask.r == 1 and\ - p.mle.tlv.scan_mask.e == 1 and\ - p.wpan.aux_sec.key_id_mode == 0x2 - ).\ - must_next() - lend = pkts.index - - # Step 4: REED_1 and REED_2 no response to Parent Request meant for all routers. - - for i in (1, 2): - pkts.range(lstart, lend).\ - filter_wpan_src64(pv.vars['REED_%d' % i]).\ - filter_wpan_dst64(ROUTER_2).\ - filter_mle_cmd(MLE_PARENT_RESPONSE).\ - must_not_next() - - # Step 6: REED_1 and REED_2 respond with a MLE Parent Response. - # The following TLVs MUST be present in the MLE Parent Response: - # - Challenge TLV - # - Connectivity TLV - # - Leader Data TLV - # - Link-layer Frame Counter TLV - # - Link Margin TLV - # - Response TLV - # - Source Address - # - Version TLV - # - MLE Frame Counter TLV (optional) - - for i in (1, 2): - with pkts.save_index(): - pkts.filter_wpan_src64(pv.vars['REED_%d' % i]).\ - filter_wpan_dst64(ROUTER_2).\ - filter_mle_cmd(MLE_PARENT_RESPONSE).\ - filter(lambda p: { - CHALLENGE_TLV, - CONNECTIVITY_TLV, - LEADER_DATA_TLV, - LINK_LAYER_FRAME_COUNTER_TLV, - LINK_MARGIN_TLV, - RESPONSE_TLV, - SOURCE_ADDRESS_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.wpan.aux_sec.key_id_mode == 0x2 - ).\ - must_next() - - # Step 7: DUT sends a MLE Child ID Request to REED_1. - # The following TLVs MUST be present in the MLE Child ID Request: - # - Link-layer Frame Counter TLV - # - Mode TLV - # - Response TLV - # - Timeout TLV - # - TLV Request TLV - # - Address16 TLV - # - Network Data TLV - # - Route64 TLV (optional) - # - Version TLV - # - MLE Frame Counter TLV (optional) - # The following TLV MUST NOT be present in the MLE Child ID Request: - # - Address Registration TLV - - _pkt = pkts.filter_wpan_src64(ROUTER_2).\ - filter_wpan_dst64(REED_1).\ - filter_mle_cmd(MLE_CHILD_ID_REQUEST).\ - filter(lambda p: { - LINK_LAYER_FRAME_COUNTER_TLV, - MODE_TLV, - RESPONSE_TLV, - TIMEOUT_TLV, - TLV_REQUEST_TLV, - ADDRESS16_TLV, - NETWORK_DATA_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.mle.tlv.addr16 is nullField and\ - p.thread_nwd.tlv.type is nullField and\ - p.wpan.aux_sec.key_id_mode == 0x2 - ).\ - must_next() - _pkt.must_not_verify(lambda p: (ADDRESS_REGISTRATION_TLV) in p.mle.tlv.type) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_1_10_RouterAttachLinkQuality.py b/tests/scripts/thread-cert/Cert_5_1_10_RouterAttachLinkQuality.py deleted file mode 100755 index af5076ea0..000000000 --- a/tests/scripts/thread-cert/Cert_5_1_10_RouterAttachLinkQuality.py +++ /dev/null @@ -1,214 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import mle -import thread_cert -from pktverify.consts import MLE_ADVERTISEMENT, MLE_PARENT_REQUEST, MLE_PARENT_RESPONSE, MLE_CHILD_ID_REQUEST, SOURCE_ADDRESS_TLV, MODE_TLV, TIMEOUT_TLV, CHALLENGE_TLV, RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, ADDRESS16_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, TLV_REQUEST_TLV, SCAN_MASK_TLV, CONNECTIVITY_TLV, LINK_MARGIN_TLV, VERSION_TLV, ADDRESS_REGISTRATION_TLV -from pktverify.packet_verifier import PacketVerifier -from pktverify.null_field import nullField - -LEADER = 1 -ROUTER1 = 2 -ROUTER2 = 3 -ROUTER3 = 4 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to validate that the DUT -# will choose a router with better link quality as its parent. -# -# Test Topology: -# ------------- -# Leader -# / \ -# ROUTER2 ROUTER1 -# \ /(better link_quality) -# Router3[DUT] -# -# DUT Types: -# ---------- -# Router - - -class Cert_5_1_10_RouterAttachLinkQuality(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [ROUTER1, ROUTER2] - }, - ROUTER1: { - 'name': 'ROUTER_1', - 'mode': 'rdn', - 'allowlist': [LEADER, ROUTER3] - }, - ROUTER2: { - 'name': 'ROUTER_2', - 'mode': 'rdn', - 'allowlist': [LEADER, (ROUTER3, -85)] - }, - ROUTER3: { - 'name': 'ROUTER_3', - 'mode': 'rdn', - 'allowlist': [ROUTER1, ROUTER2] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - - self.nodes[ROUTER2].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER2].get_state(), 'router') - - self.nodes[ROUTER3].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER3].get_state(), 'router') - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - ROUTER_1 = pv.vars['ROUTER_1'] - ROUTER_2 = pv.vars['ROUTER_2'] - ROUTER_3 = pv.vars['ROUTER_3'] - - # Step 1: Verify ROUTER_1, Router2 and Leader are sending MLE advertisements. - pkts.filter_wpan_src64(LEADER).\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - must_next() - pv.verify_attached('ROUTER_1') - pv.verify_attached('ROUTER_2') - - # Step 3: The DUT sends a MLE Parent Request with an IP hop limit of - # 255 to the Link-Local All Routers multicast address (FF02::2). - # The following TLVs MUST be present in the MLE Parent Request: - # - Challenge TLV - # - Mode TLV - # - Scan Mask TLV - # If the DUT sends multiple MLE Parent Requests - # - The first one MUST be sent only to all Routers - # - Subsequent ones MAY be sent to all Routers and REEDS - # - Version TLV - - pkts.filter_wpan_src64(ROUTER_3).\ - filter_LLARMA().\ - filter_mle_cmd(MLE_PARENT_REQUEST).\ - filter(lambda p: { - CHALLENGE_TLV, - MODE_TLV, - SCAN_MASK_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255 and\ - p.mle.tlv.scan_mask.r == 1 and\ - p.mle.tlv.scan_mask.e == 0 - ).\ - must_next() - - # Step 4: ROUTER_1 and ROUTER_2 respond with a MLE Parent Response. - # The following TLVs MUST be present in the MLE Parent Response: - # - Challenge TLV - # - Connectivity TLV - # - Leader Data TLV - # - Link-layer Frame Counter TLV - # - Link Margin TLV - # - Response TLV - # - Source Address - # - Version TLV - # - MLE Frame Counter TLV (optional) - - for i in range(1, 3): - with pkts.save_index(): - pkts.filter_wpan_src64(pv.vars['ROUTER_%d' % i]).\ - filter_wpan_dst64(ROUTER_3).\ - filter_mle_cmd(MLE_PARENT_RESPONSE).\ - filter(lambda p: { - CHALLENGE_TLV, - CONNECTIVITY_TLV, - LEADER_DATA_TLV, - LINK_LAYER_FRAME_COUNTER_TLV, - LINK_MARGIN_TLV, - RESPONSE_TLV, - SOURCE_ADDRESS_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) - ).\ - must_next() - - # Step 5: The DUT MUST initiate the attach process with Router_1 by - # sending an MLE Child ID Request; if not, the test fails. - # The following TLVs MUST be present in the MLE Child ID Request: - # - Link-layer Frame Counter TLV - # - Mode TLV - # - Response TLV - # - Timeout TLV - # - TLV Request TLV - # - Address16 TLV - # - Network Data TLV - # - Route64 TLV (optional) - # - Version TLV - # - MLE Frame Counter TLV (optional) - # The following TLV MUST NOT be present in the MLE Child ID Request: - # - Address Registration TLV - - _pkt = pkts.filter_wpan_src64(ROUTER_3).\ - filter_wpan_dst64(ROUTER_1).\ - filter_mle_cmd(MLE_CHILD_ID_REQUEST).\ - filter(lambda p: { - LINK_LAYER_FRAME_COUNTER_TLV, - MODE_TLV, - RESPONSE_TLV, - TIMEOUT_TLV, - TLV_REQUEST_TLV, - ADDRESS16_TLV, - NETWORK_DATA_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.mle.tlv.addr16 is nullField and\ - p.thread_nwd.tlv.type is nullField - ).\ - must_next() - _pkt.must_not_verify(lambda p: (ADDRESS_REGISTRATION_TLV) in p.mle.tlv.type) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_1_11_REEDAttachLinkQuality.py b/tests/scripts/thread-cert/Cert_5_1_11_REEDAttachLinkQuality.py deleted file mode 100755 index 3973f71ab..000000000 --- a/tests/scripts/thread-cert/Cert_5_1_11_REEDAttachLinkQuality.py +++ /dev/null @@ -1,213 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import mle -import thread_cert -from pktverify.consts import MLE_ADVERTISEMENT, MLE_PARENT_REQUEST, MLE_PARENT_RESPONSE, MLE_CHILD_ID_REQUEST, SOURCE_ADDRESS_TLV, MODE_TLV, TIMEOUT_TLV, CHALLENGE_TLV, RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, ADDRESS16_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, TLV_REQUEST_TLV, SCAN_MASK_TLV, CONNECTIVITY_TLV, LINK_MARGIN_TLV, VERSION_TLV, ADDRESS_REGISTRATION_TLV -from pktverify.packet_verifier import PacketVerifier -from pktverify.null_field import nullField - -LEADER = 1 -REED = 2 -ROUTER2 = 3 -ROUTER1 = 4 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to validate that DUT will -# attach to a REED with the highest link quality, when routers -# with the highest link quality are not available. -# -# Test Topology: -# ------------- -# Leader -# / \ -# Router2 REED1 -# \ /(better link_quality) -# Router1[DUT] -# -# DUT Types: -# ---------- -# Router - - -class Cert_5_1_11_REEDAttachLinkQuality(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [REED, ROUTER2] - }, - REED: { - 'name': 'REED_1', - 'mode': 'rdn', - 'router_upgrade_threshold': 0, - 'allowlist': [LEADER, ROUTER1] - }, - ROUTER2: { - 'name': 'ROUTER_2', - 'mode': 'rdn', - 'allowlist': [LEADER, (ROUTER1, -85)] - }, - ROUTER1: { - 'name': 'ROUTER_1', - 'mode': 'rdn', - 'allowlist': [REED, ROUTER2] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[REED].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[REED].get_state(), 'child') - - self.nodes[ROUTER2].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER2].get_state(), 'router') - - self.nodes[ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - self.assertEqual(self.nodes[REED].get_state(), 'router') - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - REED_1 = pv.vars['REED_1'] - ROUTER_1 = pv.vars['ROUTER_1'] - ROUTER_2 = pv.vars['ROUTER_2'] - - # Step 1: Verify ROUTER_2 and Leader are sending MLE advertisements. - pkts.filter_wpan_src64(LEADER).\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - must_next() - pv.verify_attached('ROUTER_2') - - # Step 3: The DUT sends a MLE Parent Request with an IP hop limit of - # 255 to the Link-Local All Routers multicast address (FF02::2). - # The following TLVs MUST be present in the MLE Parent Request: - # - Challenge TLV - # - Mode TLV - # - Scan Mask TLV - # If the DUT sends multiple MLE Parent Requests - # - The first one MUST be sent only to all Routers - # - Subsequent ones MAY be sent to all Routers and REEDS - # - Version TLV - # If the first MLE Parent Request was sent to all Routers and - # REEDS, the test fails. - - pkts.filter_wpan_src64(ROUTER_1).\ - filter_LLARMA().\ - filter_mle_cmd(MLE_PARENT_REQUEST).\ - filter(lambda p: { - CHALLENGE_TLV, - MODE_TLV, - SCAN_MASK_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255 and\ - p.mle.tlv.scan_mask.r == 1 and\ - p.mle.tlv.scan_mask.e == 0 - ).\ - must_next() - - # Step 5: The DUT MUST send a MLE Parent Request with an IP hop limit of - # 255 to the Link-Local All Routers multicast address (FF02::2). - # The following TLVs MUST be present in the MLE Parent Request: - # - Challenge TLV - # - Mode TLV - # - Scan Mask TLV - # - The Scan Mask TLV MUST be sent to Routers And REEDs - # - Version TLV - # - - pkts.filter_wpan_src64(ROUTER_1).\ - filter_LLARMA().\ - filter_mle_cmd(MLE_PARENT_REQUEST).\ - filter(lambda p: { - CHALLENGE_TLV, - MODE_TLV, - SCAN_MASK_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255 and\ - p.mle.tlv.scan_mask.r == 1 and\ - p.mle.tlv.scan_mask.e == 1 - ).\ - must_next() - - # Step 6: The DUT MUST initiate the attach process with REED_1 by - # sending an MLE Child ID Request; if not, the test fails. - # The following TLVs MUST be present in the MLE Child ID Request: - # - Link-layer Frame Counter TLV - # - Mode TLV - # - Response TLV - # - Timeout TLV - # - TLV Request TLV - # - Address16 TLV - # - Network Data TLV - # - Route64 TLV (optional) - # - Version TLV - # - MLE Frame Counter TLV (optional) - # The following TLV MUST NOT be present in the MLE Child ID Request: - # - Address Registration TLV - - _pkt = pkts.filter_wpan_src64(ROUTER_1).\ - filter_wpan_dst64(REED_1).\ - filter_mle_cmd(MLE_CHILD_ID_REQUEST).\ - filter(lambda p: { - LINK_LAYER_FRAME_COUNTER_TLV, - MODE_TLV, - RESPONSE_TLV, - TIMEOUT_TLV, - TLV_REQUEST_TLV, - ADDRESS16_TLV, - NETWORK_DATA_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.mle.tlv.addr16 is nullField and\ - p.thread_nwd.tlv.type is nullField - ).\ - must_next() - _pkt.must_not_verify(lambda p: (ADDRESS_REGISTRATION_TLV) in p.mle.tlv.type) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_1_12_NewRouterNeighborSync.py b/tests/scripts/thread-cert/Cert_5_1_12_NewRouterNeighborSync.py deleted file mode 100755 index 589911949..000000000 --- a/tests/scripts/thread-cert/Cert_5_1_12_NewRouterNeighborSync.py +++ /dev/null @@ -1,208 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import mle -import thread_cert -from pktverify.consts import MLE_ADVERTISEMENT, MLE_PARENT_REQUEST, MLE_PARENT_RESPONSE, MLE_CHILD_UPDATE_RESPONSE, MLE_CHILD_ID_REQUEST, MLE_CHILD_ID_RESPONSE, MLE_LINK_REQUEST, MLE_LINK_ACCEPT, MLE_LINK_ACCEPT_AND_REQUEST, ADDR_SOL_URI, SOURCE_ADDRESS_TLV, MODE_TLV, TIMEOUT_TLV, CHALLENGE_TLV, RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, MLE_FRAME_COUNTER_TLV, ROUTE64_TLV, ADDRESS16_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, TLV_REQUEST_TLV, SCAN_MASK_TLV, CONNECTIVITY_TLV, LINK_MARGIN_TLV, VERSION_TLV, ADDRESS_REGISTRATION_TLV, NL_MAC_EXTENDED_ADDRESS_TLV, NL_RLOC16_TLV, NL_STATUS_TLV, NL_ROUTER_MASK_TLV, COAP_CODE_ACK -from pktverify.packet_verifier import PacketVerifier -from pktverify.null_field import nullField - -LEADER = 1 -ROUTER1 = 2 -ROUTER2 = 3 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to validate that when the DUT sees a new router for the first time, it will synchronize using the New Router Neighbor Synchronization procedure. -# -# Test Topology: -# ------------- -# Leader -# / \ -# Router2 Router1[DUT] -# -# DUT Types: -# ---------- -# Router - - -class Cert_5_1_12_NewRouterSync(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [ROUTER1, ROUTER2] - }, - ROUTER1: { - 'name': 'ROUTER_1', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - ROUTER2: { - 'name': 'ROUTER_2', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - - self.nodes[ROUTER2].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER2].get_state(), 'router') - - self.simulator.go(10) - - self.nodes[ROUTER1].add_allowlist(self.nodes[ROUTER2].get_addr64()) - self.nodes[ROUTER2].add_allowlist(self.nodes[ROUTER1].get_addr64()) - - self.simulator.go(35) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - ROUTER_1 = pv.vars['ROUTER_1'] - ROUTER_2 = pv.vars['ROUTER_2'] - - # Step 1: Verify topology is formed correctly. - - # Step 2: The DUT MUST send properly formatted MLE Advertisements with - # an IP Hop Limit of 255 to the Link-Local All Nodes multicast - # address (FF02::1). - # The following TLVs MUST be present in the MLE Advertisements: - # - Leader Data TLV - # - Route64 TLV - # - Source Address TLV - - pv.verify_attached('ROUTER_1') - pkts.filter_wpan_src64(ROUTER_1).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - filter(lambda p: { - LEADER_DATA_TLV, - ROUTE64_TLV, - SOURCE_ADDRESS_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255).\ - must_next() - - pv.verify_attached('ROUTER_2') - pkts.filter_wpan_src64(ROUTER_2).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - filter(lambda p: { - LEADER_DATA_TLV, - ROUTE64_TLV, - SOURCE_ADDRESS_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255).\ - must_next() - - # Step 4: The DUT and Router_2 exchange unicast Link Request and unicast - # Link Accept messages OR Link Accept and Request messages. - # - # The Link Request Message MUST be unicast and contain - # the following TLVs: - # - Challenge TLV - # - Leader Data TLV - # - Source Address TLV - # - Version TLV - # - TLV Request TLV: Link Margin - # - # Link Accept or Link Accept And Request Messages MUST be - # Unicast. - # The following TLVs MUST be present in the Link Accept or - # Link Accept And Request Messages : - # - Leader Data TLV - # - Link-layer Frame Counter TLV - # - Link Margin TLV - # - Response TLV - # - Source Address TLV - # - Version TLV - # - TLV Request TLV: Link Margin - # - Challenge TLV (optional) - # - MLE Frame Counter TLV (optional) - # The Challenge TLV and TLV Request TLV MUST be included - # if the response is an Accept and Request message. - - lq_src = ROUTER_1 - lq_dst = ROUTER_2 - _pkt = pkts.filter_mle_cmd(MLE_LINK_REQUEST).\ - filter(lambda p: { - CHALLENGE_TLV, - LEADER_DATA_TLV, - SOURCE_ADDRESS_TLV, - VERSION_TLV, - TLV_REQUEST_TLV, - LINK_MARGIN_TLV - } <= set(p.mle.tlv.type) and\ - p.mle.tlv.link_margin is nullField and\ - (p.wpan.src64 == ROUTER_1 or\ - p.wpan.src64 == ROUTER_2) - ).\ - must_next() - if _pkt.wpan.src64 != ROUTER_1: - _pkt.must_verify(lambda p: p.wpan.dst64 == ROUTER_1) - lq_src = ROUTER_2 - lq_dst = ROUTER_1 - - _pkt = pkts.filter_wpan_src64(lq_dst).\ - filter_wpan_dst64(lq_src).\ - filter_mle_cmd2(MLE_LINK_ACCEPT, MLE_LINK_ACCEPT_AND_REQUEST).\ - filter(lambda p: { - LEADER_DATA_TLV, - LINK_LAYER_FRAME_COUNTER_TLV, - LINK_MARGIN_TLV, - RESPONSE_TLV, - SOURCE_ADDRESS_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.mle.tlv.link_margin is not nullField - ).\ - must_next() - if _pkt.mle.cmd == MLE_LINK_ACCEPT_AND_REQUEST: - _pkt.must_verify(lambda p: {CHALLENGE_TLV, TLV_REQUEST_TLV} <= set(p.mle.tlv.type)) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_1_13_RouterReset.py b/tests/scripts/thread-cert/Cert_5_1_13_RouterReset.py deleted file mode 100755 index 4c0fc9bbc..000000000 --- a/tests/scripts/thread-cert/Cert_5_1_13_RouterReset.py +++ /dev/null @@ -1,206 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import mle -import thread_cert -from pktverify.consts import MLE_ADVERTISEMENT, MLE_LINK_REQUEST, MLE_LINK_ACCEPT, MLE_LINK_ACCEPT_AND_REQUEST, SOURCE_ADDRESS_TLV, CHALLENGE_TLV, RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, ROUTE64_TLV, ADDRESS16_TLV, LEADER_DATA_TLV, TLV_REQUEST_TLV, VERSION_TLV, MLE_MAX_RESPONSE_DELAY -from pktverify.packet_verifier import PacketVerifier -from pktverify.null_field import nullField - -LEADER = 1 -ROUTER = 2 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to validate that when a router resets, -# it will synchronize upon returning by using the Router Synchronization -# after Reset procedure. -# -# Test Topology: -# ------------- -# Leader -# | -# Router -# -# DUT Types: -# ---------- -# Leader -# Router - - -class Cert_5_1_13_RouterReset(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [ROUTER] - }, - ROUTER: { - 'name': 'ROUTER', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - } - - def _setUpRouter(self): - self.nodes[ROUTER].add_allowlist(self.nodes[LEADER].get_addr64()) - self.nodes[ROUTER].enable_allowlist() - self.nodes[ROUTER].set_router_selection_jitter(1) - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[ROUTER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER].get_state(), 'router') - self.collect_rloc16s() - - self.nodes[ROUTER].reset() - self._setUpRouter() - self.simulator.go(5) - - self.nodes[ROUTER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER].get_state(), 'router') - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - ROUTER = pv.vars['ROUTER'] - ROUTER_RLOC16 = pv.vars['ROUTER_RLOC16'] - - # Step 1: Verify topology is formed correctly. - - # Step 2: Devices MUST send properly formatted MLE Advertisements with - # an IP Hop Limit of 255 to the Link-Local All Nodes multicast - # address (FF02::1). - # The following TLVs MUST be present in the MLE Advertisements: - # - Leader Data TLV - # - Route64 TLV - # - Source Address TLV - - pv.verify_attached('ROUTER') - pkts.filter_wpan_src64(ROUTER).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - filter(lambda p: { - LEADER_DATA_TLV, - ROUTE64_TLV, - SOURCE_ADDRESS_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255 - ).\ - must_next() - pkts.filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - filter(lambda p: { - LEADER_DATA_TLV, - ROUTE64_TLV, - SOURCE_ADDRESS_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255 - ).\ - must_next() - - # Step 4: Router sends multicast Link Request message - # - # The Link Request Message MUST be sent to the Link-Local All Routers - # Routers multicast address (FF02::2) and contain the following TLVs: - # - Challenge TLV - # - TLV Request TLV - # - Address16 TLV - # - Route64 TLV - # - Version TLV - # - - _pkt_lq = pkts.filter_mle_cmd(MLE_LINK_REQUEST).\ - filter_LLARMA().\ - filter(lambda p: { - CHALLENGE_TLV, - VERSION_TLV, - TLV_REQUEST_TLV, - ADDRESS16_TLV, - ROUTE64_TLV - } <= set(p.mle.tlv.type) and\ - p.mle.tlv.addr16 is nullField and \ - p.mle.tlv.route64.id_mask is nullField - ).\ - must_next() - - # Step 5: Leader replies to Router with Link Accept message - # The following TLVs MUST be present in the Link Accept message: - # - Leader Data TLV - # - Link-layer Frame Counter TLV - # - Link Margin TLV - # - Response TLV - # - Source Address TLV - # - Version TLV - # - TLV Request TLV: Link Margin - # - Challenge TLV (optional) - # - MLE Frame Counter TLV (optional) - # The Challenge TLV MUST be included if the response is an - # Accept and Request message. - # Responses to multicast Link Requests MUST be delayed by a - # random time of up to MLE_MAX_RESPONSE_DELAY (1 second). - - _pkt = pkts.filter_wpan_src64(LEADER).\ - filter_wpan_dst64(ROUTER).\ - filter_mle_cmd2(MLE_LINK_ACCEPT, MLE_LINK_ACCEPT_AND_REQUEST).\ - filter(lambda p: { - ADDRESS16_TLV, - LEADER_DATA_TLV, - LINK_LAYER_FRAME_COUNTER_TLV, - RESPONSE_TLV, - ROUTE64_TLV, - SOURCE_ADDRESS_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.mle.tlv.addr16 is not nullField and \ - p.mle.tlv.route64.id_mask is not nullField and\ - p.mle.tlv.addr16 == ROUTER_RLOC16 and\ - p.sniff_timestamp - _pkt_lq.sniff_timestamp < - MLE_MAX_RESPONSE_DELAY + 0.1 - ).\ - must_next() - if _pkt.mle.cmd == MLE_LINK_ACCEPT_AND_REQUEST: - _pkt.must_verify(lambda p: [CHALLENGE_TLV] in p.mle.tlv.type) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_2_01_REEDAttach.py b/tests/scripts/thread-cert/Cert_5_2_01_REEDAttach.py deleted file mode 100755 index 5c7b88606..000000000 --- a/tests/scripts/thread-cert/Cert_5_2_01_REEDAttach.py +++ /dev/null @@ -1,305 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2018, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import command -import config -import mle -import thread_cert -from pktverify.consts import MLE_ADVERTISEMENT, MLE_PARENT_REQUEST, MLE_PARENT_RESPONSE, MLE_CHILD_ID_RESPONSE, ADDR_SOL_URI, SOURCE_ADDRESS_TLV, MODE_TLV, TIMEOUT_TLV, CHALLENGE_TLV, RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, ROUTE64_TLV, ADDRESS16_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, TLV_REQUEST_TLV, SCAN_MASK_TLV, CONNECTIVITY_TLV, LINK_MARGIN_TLV, VERSION_TLV, NL_MAC_EXTENDED_ADDRESS_TLV, NL_RLOC16_TLV, NL_STATUS_TLV, NL_ROUTER_MASK_TLV, COAP_CODE_ACK -from pktverify.packet_verifier import PacketVerifier -from pktverify.null_field import nullField - -LEADER = 1 -DUT_ROUTER1 = 2 -REED1 = 3 -MED1 = 4 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to show that the DUT is able to attach -# a REED and forward address solicits two hops away from the Leader. -# -# Test Topology: -# ------------- -# Leader -# | -# Router_1 -# | -# REED_1 -# | -# MED_1 -# -# DUT Types: -# ---------- -# Router - - -class Cert_5_2_01_REEDAttach(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [DUT_ROUTER1] - }, - DUT_ROUTER1: { - 'name': 'ROUTER_1', - 'mode': 'rdn', - 'allowlist': [LEADER, REED1] - }, - REED1: { - 'name': 'REED_1', - 'mode': 'rdn', - 'router_upgrade_threshold': 1, - 'allowlist': [DUT_ROUTER1, MED1] - }, - MED1: { - 'name': 'MED_1', - 'is_mtd': True, - 'mode': 'rn', - 'allowlist': [REED1] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[DUT_ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[DUT_ROUTER1].get_state(), 'router') - - self.nodes[REED1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[REED1].get_state(), 'child') - - self.nodes[MED1].start() - self.simulator.go(5) - self.assertEqual(self.nodes[MED1].get_state(), 'child') - - self.collect_rloc16s() - self.collect_ipaddrs() - - self.simulator.go(config.MAX_ADVERTISEMENT_INTERVAL) - - reed_mleid = self.nodes[REED1].get_ip6_address(config.ADDRESS_TYPE.ML_EID) - self.assertTrue(self.nodes[LEADER].ping(reed_mleid)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_MLEID = pv.vars['LEADER_MLEID'] - LEADER_RLOC16 = pv.vars['LEADER_RLOC16'] - ROUTER_1 = pv.vars['ROUTER_1'] - ROUTER_1_RLOC16 = pv.vars['ROUTER_1_RLOC16'] - REED_1 = pv.vars['REED_1'] - REED_1_MLEID = pv.vars['REED_1_MLEID'] - - # Step 1: Router_1 attaches to Leader and sends properly formatted MLE - # advertisements - # Advertisements MUST be sent with an IP hop limit of 255 to - # the Link-Local All Nodes multicast address (FF02::1). - # The following TLVs MUST be present in the MLE Advertisements: - # - Leader Data TLV - # - Route64 TLV - # - Source Address TLV - - pv.verify_attached('ROUTER_1') - pkts.filter_wpan_src64(ROUTER_1).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - filter(lambda p: { - LEADER_DATA_TLV, - ROUTE64_TLV, - SOURCE_ADDRESS_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255 - ).\ - must_next() - - # Step 2: Attach REED_1 to Router_1; REED_1 sends MLE Parent Request with - # an IP hop limit of 255 to the Link-Local All Routers multicast - # address (FF02::2). - # The following TLVs MUST be present in the MLE Parent Request: - # - Challenge TLV - # - Mode TLV - # - Scan Mask TLV - # If the DUT sends multiple MLE Parent Requests - # - The first one MUST be sent only to all Routers - # - Subsequent ones MAY be sent to all Routers and REEDS - # - Version TLV - - pkts.filter_wpan_src64(REED_1).\ - filter_LLARMA().\ - filter_mle_cmd(MLE_PARENT_REQUEST).\ - filter(lambda p: { - CHALLENGE_TLV, - MODE_TLV, - SCAN_MASK_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255 and\ - p.mle.tlv.scan_mask.r == 1 and\ - p.mle.tlv.scan_mask.e == 0).\ - must_next() - - # Step 3: Router_1 must respond with a MLE Parent Response. - # The following TLVs MUST be present in the MLE Parent Response: - # - Challenge TLV - # - Connectivity TLV - # - Leader Data TLV - # - Link-layer Frame Counter TLV - # - Link Margin TLV - # - Response TLV - # - Source Address - # - Version TLV - # - MLE Frame Counter TLV (optional) - - pkts.filter_wpan_src64(ROUTER_1).\ - filter_wpan_dst64(REED_1).\ - filter_mle_cmd(MLE_PARENT_RESPONSE).\ - filter(lambda p: { - CHALLENGE_TLV, - CONNECTIVITY_TLV, - LEADER_DATA_TLV, - LINK_LAYER_FRAME_COUNTER_TLV, - LINK_MARGIN_TLV, - RESPONSE_TLV, - SOURCE_ADDRESS_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type)).\ - must_next() - - # Step 4: Router_1 must respond with a Child ID Response. - # The following TLVs MUST be present in the Child ID Response: - # - Address16 TLV - # - Leader Data TLV - # - Network Data TLV - # - Source Address TLV - # - Route64 TLV (if requested) - - pkts.filter_wpan_src64(ROUTER_1).\ - filter_wpan_dst64(REED_1).\ - filter_mle_cmd(MLE_CHILD_ID_RESPONSE).\ - filter(lambda p: { - ADDRESS16_TLV, - LEADER_DATA_TLV, - NETWORK_DATA_TLV, - SOURCE_ADDRESS_TLV, - ROUTE64_TLV - } <= set(p.mle.tlv.type) or\ - { - ADDRESS16_TLV, - LEADER_DATA_TLV, - NETWORK_DATA_TLV, - SOURCE_ADDRESS_TLV - } <= set(p.mle.tlv.type) - ).\ - must_next() - - # Step 7: REED_1 sends an Address Solicit Request to Router_1. - # Ensure the Address Solicit Request is properly formatted: - # CoAP Request URI - # coap://:MM/a/as - # CoAP Payload - # - MAC Extended Address TLV - # - Status TLV - - _pkt1 = pkts.filter_wpan_src64(REED_1).\ - filter_wpan_dst16(ROUTER_1_RLOC16).\ - filter_coap_request(ADDR_SOL_URI).\ - filter(lambda p: { - NL_MAC_EXTENDED_ADDRESS_TLV, - NL_STATUS_TLV - } <= set(p.coap.tlv.type)\ - ).\ - must_next() - - # Step 8: Router_1 forward the REED_1's Address Solicit Request to - # Leader and Leader's Address Solicit Response to REED_1. - # Ensure the Address Solicit Response is properly formatted: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # - Status TLV (value = Success) - # - RLOC16 TLV - # - Router Mask TLV - - _pkt2 = pkts.filter_wpan_src64(ROUTER_1).\ - filter_wpan_dst16(LEADER_RLOC16).\ - filter_coap_request(ADDR_SOL_URI).\ - filter(lambda p: { - NL_MAC_EXTENDED_ADDRESS_TLV, - NL_STATUS_TLV - } <= set(p.coap.tlv.type)\ - ).\ - must_next() - - pkts.filter_wpan_src64(LEADER).\ - filter_wpan_dst16(_pkt2.wpan.src16).\ - filter_coap_ack(ADDR_SOL_URI).\ - filter(lambda p: { - NL_STATUS_TLV, - NL_RLOC16_TLV, - NL_ROUTER_MASK_TLV - } <= set(p.coap.tlv.type) and\ - p.coap.code == COAP_CODE_ACK and\ - p.thread_address.tlv.status == 0\ - ).\ - must_next() - pkts.filter_wpan_src64(ROUTER_1).\ - filter_wpan_dst16(_pkt1.wpan.src16).\ - filter_coap_ack(ADDR_SOL_URI).\ - filter(lambda p: { - NL_STATUS_TLV, - NL_RLOC16_TLV, - NL_ROUTER_MASK_TLV - } <= set(p.coap.tlv.type) and\ - p.coap.code == COAP_CODE_ACK and\ - p.thread_address.tlv.status == 0\ - ).\ - must_next() - - # Step 9: REED_1 responds with ICMPv6 Echo Reply - _pkt = pkts.filter_ipv6_src_dst(LEADER_MLEID, REED_1_MLEID).\ - filter_ping_request().\ - must_next() - pkts.filter_ipv6_src_dst(REED_1_MLEID, LEADER_MLEID).\ - filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_2_03_LeaderReject2Hops.py b/tests/scripts/thread-cert/Cert_5_2_03_LeaderReject2Hops.py deleted file mode 100755 index 4daf51d72..000000000 --- a/tests/scripts/thread-cert/Cert_5_2_03_LeaderReject2Hops.py +++ /dev/null @@ -1,428 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import mle -import network_layer -import thread_cert -from pktverify.consts import MLE_ADVERTISEMENT, MLE_PARENT_RESPONSE, MLE_CHILD_ID_RESPONSE, ADDR_SOL_URI, SOURCE_ADDRESS_TLV, CHALLENGE_TLV, RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, ADDRESS16_TLV, ROUTE64_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, CONNECTIVITY_TLV, LINK_MARGIN_TLV, VERSION_TLV, ADDRESS_REGISTRATION_TLV, NL_MAC_EXTENDED_ADDRESS_TLV, NL_RLOC16_TLV, NL_STATUS_TLV, NL_ROUTER_MASK_TLV, COAP_CODE_ACK, ADDR_SOL_NA, ADDR_SOL_SUCCESS -from pktverify.packet_verifier import PacketVerifier -from pktverify.null_field import nullField - -DUT_LEADER = 1 -ROUTER_1 = 2 -ROUTER_31 = 32 -ROUTER_32 = 33 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to show that the DUT will -# only allow 32 active routers on the network and reject the -# Address Solicit Request from a 33rd router - that is -# 2-hops away - with a No Address Available status. -# -# Test Topology: -# ------------- -# Leader[DUT] -# / \ -# Router_1 --- Router_31 -# | -# | -# Router_32 -# -# DUT Types: -# ---------- -# Leader - - -class Cert_5_2_3_LeaderReject2Hops(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - DUT_LEADER: { - 'name': - 'LEADER', - 'mode': - 'rdn', - 'panid': - 0xface, - 'router_downgrade_threshold': - 33, - 'router_upgrade_threshold': - 32, - 'allowlist': [ - ROUTER_1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, ROUTER_31 - ] - }, - ROUTER_1: { - 'name': 'ROUTER_1', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER, ROUTER_32] - }, - 3: { - 'name': 'ROUTER_2', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 4: { - 'name': 'ROUTER_3', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 5: { - 'name': 'ROUTER_4', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 6: { - 'name': 'ROUTER_5', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 7: { - 'name': 'ROUTER_6', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 8: { - 'name': 'ROUTER_7', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 9: { - 'name': 'ROUTER_8', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 10: { - 'name': 'ROUTER_9', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 11: { - 'name': 'ROUTER_10', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 12: { - 'name': 'ROUTER_11', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 13: { - 'name': 'ROUTER_12', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 14: { - 'name': 'ROUTER_13', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 15: { - 'name': 'ROUTER_14', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 16: { - 'name': 'ROUTER_15', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 17: { - 'name': 'ROUTER_16', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 18: { - 'name': 'ROUTER_17', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 19: { - 'name': 'ROUTER_18', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 20: { - 'name': 'ROUTER_19', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 21: { - 'name': 'ROUTER_20', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 22: { - 'name': 'ROUTER_21', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 23: { - 'name': 'ROUTER_22', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 24: { - 'name': 'ROUTER_23', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 25: { - 'name': 'ROUTER_24', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 26: { - 'name': 'ROUTER_25', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 27: { - 'name': 'ROUTER_26', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 28: { - 'name': 'ROUTER_27', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 29: { - 'name': 'ROUTER_28', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 30: { - 'name': 'ROUTER_29', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - 31: { - 'name': 'ROUTER_30', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - ROUTER_31: { - 'name': 'ROUTER_31', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [DUT_LEADER] - }, - ROUTER_32: { - 'name': 'ROUTER_32', - 'mode': 'rdn', - 'router_downgrade_threshold': 33, - 'router_upgrade_threshold': 33, - 'allowlist': [ROUTER_1] - }, - } - - def test(self): - self.nodes[DUT_LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[DUT_LEADER].get_state(), 'leader') - - for i in range(2, 32): - self.nodes[i].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[i].get_state(), 'router') - self.collect_rlocs() - - self.nodes[ROUTER_31].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER_31].get_state(), 'router') - - self.nodes[ROUTER_32].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - - def verify(self, pv: PacketVerifier): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_RLOC = pv.vars['LEADER_RLOC'] - ROUTER_31 = pv.vars['ROUTER_31'] - ROUTER_32 = pv.vars['ROUTER_32'] - - # Step 1: Topology is created, the DUT is the Leader of the network - # and there is a total of 32 active routers, including the Leader. - for i in range(1, 32): - pv.verify_attached('ROUTER_%d' % i) - - # Step 2: Router_31 to attaches to the network and sends an Address - # Solicit Request to become an active router. - - _pkt = pkts.filter_wpan_src64(ROUTER_31).\ - filter_ipv6_dst(LEADER_RLOC).\ - filter_coap_request(ADDR_SOL_URI).\ - filter(lambda p: { - NL_MAC_EXTENDED_ADDRESS_TLV, - NL_STATUS_TLV - } <= set(p.coap.tlv.type) - ).\ - must_next() - - # Step 3: Leader sends an Address Solicit Response. - # Ensure the Address Solicit Response is properly formatted: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # - Status TLV (value = Success) - # - RLOC16 TLV - # - Router Mask TLV - - pkts.filter_wpan_src64(LEADER).\ - filter_ipv6_dst(_pkt.ipv6.src).\ - filter_coap_ack(ADDR_SOL_URI).\ - filter(lambda p: { - NL_STATUS_TLV, - NL_RLOC16_TLV, - NL_ROUTER_MASK_TLV - } <= set(p.coap.tlv.type) and\ - p.coap.code == COAP_CODE_ACK and\ - p.thread_address.tlv.status == ADDR_SOL_SUCCESS\ - ).\ - must_next() - - # Step 4: Leader The DUT sends MLE Advertisements. - # The MLE Advertisements from the Leader MUST contain - # the Route64 TLV with 32 assigned Router IDs. - - pkts.filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - filter(lambda p: { - LEADER_DATA_TLV, - ROUTE64_TLV, - SOURCE_ADDRESS_TLV - } <= set(p.mle.tlv.type) and\ - len(p.mle.tlv.route64.cost) == 32 and\ - p.ipv6.hlim == 255 - ).\ - must_next() - - # Step 5: Router_32 to attach to any of the active routers, 2-hops - # from the leader, and to send an Address Solicit Request - # to become an active router. - - _pkt = pkts.filter_wpan_src64(ROUTER_32).\ - filter_ipv6_dst(LEADER_RLOC).\ - filter_coap_request(ADDR_SOL_URI).\ - filter(lambda p: { - NL_MAC_EXTENDED_ADDRESS_TLV, - NL_STATUS_TLV - } <= set(p.coap.tlv.type) - ).\ - must_next() - - # Step 6: Leader sends an Address Solicit Response. - # Ensure the Address Solicit Response is properly formatted: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # - Status TLV (value = No Address Available) - - pkts.filter_wpan_src64(LEADER).\ - filter_ipv6_dst(_pkt.ipv6.src).\ - filter_coap_ack(ADDR_SOL_URI).\ - filter(lambda p: - p.coap.code == COAP_CODE_ACK and\ - p.thread_address.tlv.status == ADDR_SOL_NA - ).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_2_04_REEDUpgrade.py b/tests/scripts/thread-cert/Cert_5_2_04_REEDUpgrade.py deleted file mode 100755 index 2591c8cad..000000000 --- a/tests/scripts/thread-cert/Cert_5_2_04_REEDUpgrade.py +++ /dev/null @@ -1,386 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import mle -import network_layer -import thread_cert -from pktverify.consts import MLE_PARENT_REQUEST, MLE_PARENT_RESPONSE, MLE_CHILD_ID_REQUEST, MLE_CHILD_ID_RESPONSE, MLE_LINK_REQUEST, ADDR_SOL_URI, SOURCE_ADDRESS_TLV, MODE_TLV, TIMEOUT_TLV, CHALLENGE_TLV, RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, MLE_FRAME_COUNTER_TLV, ROUTE64_TLV, ADDRESS16_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, TLV_REQUEST_TLV, SCAN_MASK_TLV, CONNECTIVITY_TLV, LINK_MARGIN_TLV, VERSION_TLV, ADDRESS_REGISTRATION_TLV, NL_MAC_EXTENDED_ADDRESS_TLV, NL_RLOC16_TLV, NL_STATUS_TLV, NL_ROUTER_MASK_TLV, COAP_CODE_ACK -from pktverify.packet_verifier import PacketVerifier -from pktverify.null_field import nullField - -LEADER = 1 -ROUTER = 16 -DUT_REED = 17 -MED = 18 -REED_ADVERTISEMENT_INTERVAL = 570 -REED_ADVERTISEMENT_MAX_JITTER = 60 -ROUTER_SELECTION_JITTER = 1 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to: -# 1) Verify that the DUT does not attempt to become a router if there -# are already 16 active routers on the Thread network AND it is not -# bringing children -# 2) Verify that the DUT transmits MLE Advertisement messages every -# REED_ADVERTISEMENT_INTERVAL (+REED_ADVERTISEMENT_MAX_JITTER) seconds -# 3) Verify that the DUT upgrades to a router by sending an Address Solicit -# Request when a child attempts to attach to it. -# -# Test Topology: -# ------------- -# Router_15 - Leader -# ... / \ -# Router_n Router_1(DUT) -# | -# REED(DUT) -# | -# MED -# -# DUT Types: -# ---------- -# REED - - -class Cert_5_2_4_REEDUpgrade(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ROUTER] - }, - 2: { - 'name': 'ROUTER_1', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 3: { - 'name': 'ROUTER_2', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 4: { - 'name': 'ROUTER_3', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 5: { - 'name': 'ROUTER_4', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 6: { - 'name': 'ROUTER_5', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 7: { - 'name': 'ROUTER_6', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 8: { - 'name': 'ROUTER_7', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 9: { - 'name': 'ROUTER_8', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 10: { - 'name': 'ROUTER_9', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 11: { - 'name': 'ROUTER_10', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 12: { - 'name': 'ROUTER_11', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 13: { - 'name': 'ROUTER_12', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 14: { - 'name': 'ROUTER_13', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 15: { - 'name': 'ROUTER_14', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - ROUTER: { - 'name': 'ROUTER_15', - 'mode': 'rdn', - 'allowlist': [LEADER, DUT_REED] - }, - DUT_REED: { - 'name': 'REED', - 'mode': 'rdn', - 'allowlist': [ROUTER, MED] - }, - MED: { - 'name': 'MED', - 'mode': 'rdn', - 'allowlist': [DUT_REED] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - for i in range(2, 17): - self.nodes[i].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[i].get_state(), 'router') - - self.nodes[DUT_REED].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.simulator.go(ROUTER_SELECTION_JITTER) - - self.collect_rloc16s() - self.collect_rlocs() - - self.simulator.go(REED_ADVERTISEMENT_INTERVAL + REED_ADVERTISEMENT_MAX_JITTER) - - self.nodes[MED].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.collect_ipaddrs() - - mleid = self.nodes[LEADER].get_ip6_address(config.ADDRESS_TYPE.ML_EID) - self.assertTrue(self.nodes[MED].ping(mleid)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER_RLOC16 = pv.vars['LEADER_RLOC16'] - LEADER_RLOC = pv.vars['LEADER_RLOC'] - LEADER_MLEID = pv.vars['LEADER_MLEID'] - REED = pv.vars['REED'] - REED_RLOC16 = pv.vars['REED_RLOC16'] - MED = pv.vars['MED'] - MED_RLOC16 = pv.vars['MED_RLOC16'] - MED_MLEID = pv.vars['MED_MLEID'] - - # Step 1: Verify topology is formed correctly except REED. - - with pkts.save_index(): - for i in range(1, 16): - pv.verify_attached('ROUTER_%d' % i) - - # Step 2: REED attaches to the network with 2-hops from the Leader - # and MUST NOT attempt to become an active router by sending - # an Address Solicit Request - - pv.verify_attached('REED') - lstart = pkts.index - - # Step 3: REED MUST send properly formatted MLE Advertisements. - # MLE Advertisements MUST be sent with an IP Hop Limit of - # 255 to the Link-Local All Nodes multicast address (FF02::1). - # The following TLVs MUST be present in the MLE Advertisements: - # - Leader Data TLV - # - Source Address TLV - # The following TLV MUST NOT be present in the MLE Advertisements: - # - Route64 TLV - - _pkt = pkts.filter_wpan_src64(REED).\ - filter_mle_advertisement('REED').\ - must_next() - lend = pkts.index - - pkts.range(lstart, lend).filter_wpan_src64(REED).\ - filter_coap_request(ADDR_SOL_URI).\ - filter(lambda p: { - NL_MAC_EXTENDED_ADDRESS_TLV, - NL_STATUS_TLV - } <= set(p.coap.tlv.type) - ).\ - must_not_next() - - # Step 5: REED MUST send a second MLE Advertisement after - # REED_ADVERTISEMENT_INTERVAL+JITTER where - # JITTER <= REED_ADVERTISEMENT_MAX_JITTER - - pkts.filter_wpan_src64(REED).\ - filter_mle_advertisement('REED').\ - filter(lambda p: - REED_ADVERTISEMENT_INTERVAL < - p.sniff_timestamp - _pkt.sniff_timestamp <= - REED_ADVERTISEMENT_INTERVAL + - REED_ADVERTISEMENT_MAX_JITTER - ).\ - must_next() - - # Step 6: MED sends multicast MLE Parent Request - # First one is to all routers, the second one is to - # all routers and reeds - - pkts.filter_wpan_src64(MED).\ - filter_LLARMA().\ - filter_mle_cmd(MLE_PARENT_REQUEST).\ - filter(lambda p: { - CHALLENGE_TLV, - MODE_TLV, - SCAN_MASK_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255 and\ - p.mle.tlv.scan_mask.r == 1 and\ - p.mle.tlv.scan_mask.e == 0).\ - must_next() - pkts.filter_wpan_src64(MED).\ - filter_LLARMA().\ - filter_mle_cmd(MLE_PARENT_REQUEST).\ - filter(lambda p: { - CHALLENGE_TLV, - MODE_TLV, - SCAN_MASK_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255 and\ - p.mle.tlv.scan_mask.r == 1 and\ - p.mle.tlv.scan_mask.e == 1).\ - must_next() - - # Step 7: REED MUST reply with a properly formatted MLE Parent Response - - pkts.filter_wpan_src64(REED).\ - filter_wpan_dst64(MED).\ - filter_mle_cmd(MLE_PARENT_RESPONSE).\ - filter(lambda p: { - CHALLENGE_TLV, - CONNECTIVITY_TLV, - LEADER_DATA_TLV, - LINK_LAYER_FRAME_COUNTER_TLV, - LINK_MARGIN_TLV, - RESPONSE_TLV, - SOURCE_ADDRESS_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type)).\ - must_next() - - # Step 8: MED sends MLE Child ID Request to REED - - _pkt = pkts.filter_wpan_src64(MED).\ - filter_wpan_dst64(REED).\ - filter_mle_cmd(MLE_CHILD_ID_REQUEST).\ - filter(lambda p: { - LINK_LAYER_FRAME_COUNTER_TLV, - MODE_TLV, - RESPONSE_TLV, - TIMEOUT_TLV, - TLV_REQUEST_TLV, - ADDRESS16_TLV, - NETWORK_DATA_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.mle.tlv.addr16 is nullField and\ - p.thread_nwd.tlv.type is nullField - ).\ - must_next() - _pkt.must_not_verify(lambda p: (ADDRESS_REGISTRATION_TLV) in p.mle.tlv.type) - - # Step 9: REED sends an Address Solicit Request to the Leader - # Ensure the Address Solicit Request is properly formatted: - # CoAP Request URI - # coap://:MM/a/as - # CoAP Payload - # - MAC Extended Address TLV - # - Status TLV - - pkts.filter_wpan_src64(REED).\ - filter_ipv6_dst(LEADER_RLOC).\ - filter_coap_request(ADDR_SOL_URI).\ - filter(lambda p: { - NL_MAC_EXTENDED_ADDRESS_TLV, - NL_STATUS_TLV - } <= set(p.coap.tlv.type) - ).\ - must_next() - - # Step 10: REED Sends a Link Request Message. - # This step is skipped due to change that new router no - # longer send multicast Link Request. - - # Step 11: The REED MLE Child ID Response MUST be properly - # formatted with MED_1’s new 16-bit address. - - with pkts.save_index(): - pkts.filter_wpan_src64(REED).\ - filter_wpan_dst64(MED).\ - filter_mle_cmd(MLE_CHILD_ID_RESPONSE).\ - filter(lambda p: { - ADDRESS16_TLV, - LEADER_DATA_TLV, - NETWORK_DATA_TLV, - SOURCE_ADDRESS_TLV, - ROUTE64_TLV - } <= set(p.mle.tlv.type) or\ - { - ADDRESS16_TLV, - LEADER_DATA_TLV, - NETWORK_DATA_TLV, - SOURCE_ADDRESS_TLV - } <= set(p.mle.tlv.type) and\ - p.mle.tlv.source_addr != REED_RLOC16 and\ - p.mle.tlv.addr16 != MED_RLOC16 - ).\ - must_next() - - # Step 12: The Leader MUST respond with an ICMPv6 Echo Reply - - _pkt = pkts.filter_ipv6_src_dst(MED_MLEID, LEADER_MLEID).\ - filter_ping_request().\ - must_next() - pkts.filter_ipv6_src_dst(LEADER_MLEID, MED_MLEID).\ - filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_2_05_AddressQuery.py b/tests/scripts/thread-cert/Cert_5_2_05_AddressQuery.py deleted file mode 100755 index 4422cd3f4..000000000 --- a/tests/scripts/thread-cert/Cert_5_2_05_AddressQuery.py +++ /dev/null @@ -1,370 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import command -import config -import thread_cert -from pktverify.consts import WIRESHARK_OVERRIDE_PREFS, MLE_PARENT_REQUEST, MLE_PARENT_RESPONSE, MLE_CHILD_ID_REQUEST, MLE_CHILD_ID_RESPONSE, MLE_LINK_REQUEST, ADDR_SOL_URI, ADDR_NTF_URI, SOURCE_ADDRESS_TLV, MODE_TLV, TIMEOUT_TLV, CHALLENGE_TLV, RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, MLE_FRAME_COUNTER_TLV, ROUTE64_TLV, ADDRESS16_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, TLV_REQUEST_TLV, SCAN_MASK_TLV, CONNECTIVITY_TLV, LINK_MARGIN_TLV, VERSION_TLV, ADDRESS_REGISTRATION_TLV, NL_MAC_EXTENDED_ADDRESS_TLV, NL_RLOC16_TLV, NL_STATUS_TLV, NL_TARGET_EID_TLV, NL_ML_EID_TLV, COAP_CODE_ACK -from pktverify.packet_verifier import PacketVerifier -from pktverify.null_field import nullField -from pktverify.bytes import Bytes - -LEADER = 1 -ROUTER1 = 2 -BR = 3 -MED = 17 -DUT_REED = 18 -ROUTER_SELECTION_JITTER = 1 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to validate that the DUT is able to generate -# Address Notification messages in response to Address Query messages. -# -# - Build a topology that has a total of 16 active routers, including the Leader, -# with no communication constraints and -# - MED only allows Leader -# - DUT only allows Router1 -# - DUT allows BR later as required in step 5. -# - The Leader is configured as a DHCPv6 server for prefix 2001:: -# - The Border Router is configured as a SLAAC server for prefix 2002:: -# -# Test Topology: -# ------------- -# MED -# | -# Router_15 - Leader -# ... / \ -# Router_2 Router_1 -# [BR] | -# REED(DUT) -# -# DUT Types: -# ---------- -# REED - - -class Cert_5_2_5_AddressQuery(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [ROUTER1, BR, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, MED] - }, - ROUTER1: { - 'name': 'ROUTER_1', - 'mode': 'rdn', - 'allowlist': [LEADER, DUT_REED] - }, - BR: { - 'name': 'ROUTER_2', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 4: { - 'name': 'ROUTER_3', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 5: { - 'name': 'ROUTER_4', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 6: { - 'name': 'ROUTER_5', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 7: { - 'name': 'ROUTER_6', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 8: { - 'name': 'ROUTER_7', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 9: { - 'name': 'ROUTER_8', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 10: { - 'name': 'ROUTER_9', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 11: { - 'name': 'ROUTER_10', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 12: { - 'name': 'ROUTER_11', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 13: { - 'name': 'ROUTER_12', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 14: { - 'name': 'ROUTER_13', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 15: { - 'name': 'ROUTER_14', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - 16: { - 'name': 'ROUTER_15', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - MED: { - 'name': 'MED', - 'is_mtd': True, - 'mode': 'rn', - 'allowlist': [LEADER] - }, - DUT_REED: { - 'name': 'REED', - 'mode': 'rdn', - 'allowlist': [ROUTER1] - }, - } - - # override wireshark preferences with case needed parameters - CASE_WIRESHARK_PREFS = WIRESHARK_OVERRIDE_PREFS - CASE_WIRESHARK_PREFS['6lowpan.context1'] = '2001::/64' - CASE_WIRESHARK_PREFS['6lowpan.context2'] = '2002::/64' - - def test(self): - # 1. LEADER: DHCPv6 Server for prefix 2001::/64. - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - self.nodes[LEADER].add_prefix('2001::/64', 'pdros') - self.nodes[LEADER].register_netdata() - - # 2. BR: SLAAC Server for prefix 2002::/64. - self.nodes[BR].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[BR].get_state(), 'router') - self.nodes[BR].add_prefix('2002::/64', 'paros') - self.nodes[BR].register_netdata() - - # 3. Bring up remaining devices except DUT_REED. - for i in range(2, 17): - if i == BR: - continue - self.nodes[i].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[i].get_state(), 'router') - - self.nodes[MED].start() - self.simulator.go(5) - self.assertEqual(self.nodes[MED].get_state(), 'child') - - # 4. Bring up DUT_REED. - self.nodes[DUT_REED].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.simulator.go(ROUTER_SELECTION_JITTER) - - # 5. Enable a link between the DUT and BR to create a one-way link. - self.nodes[DUT_REED].add_allowlist(self.nodes[BR].get_addr64()) - self.nodes[BR].add_allowlist(self.nodes[DUT_REED].get_addr64()) - - self.collect_ipaddrs() - self.collect_rlocs() - - # 6. Verify DUT_REED would send Address Notification when ping to its - # ML-EID. - mleid = self.nodes[DUT_REED].get_ip6_address(config.ADDRESS_TYPE.ML_EID) - self.assertTrue(self.nodes[MED].ping(mleid)) - - # Wait for sniffer collecting packets - self.simulator.go(1) - - # 7 & 8. Verify DUT_REED would send Address Notification when ping to - # its 2001::EID and 2002::EID. - flag2001 = 0 - flag2002 = 0 - for global_address in self.nodes[DUT_REED].get_ip6_address(config.ADDRESS_TYPE.GLOBAL): - if global_address[0:4] == '2001': - flag2001 += 1 - elif global_address[0:4] == '2002': - flag2002 += 1 - else: - raise "Error: Address is unexpected." - self.assertTrue(self.nodes[MED].ping(global_address)) - - # Wait for sniffer collecting packets - self.simulator.go(1) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER_RLOC = pv.vars['LEADER_RLOC'] - LEADER_MLEID = pv.vars['LEADER_MLEID'] - ROUTER_1 = pv.vars['ROUTER_1'] - REED = pv.vars['REED'] - REED_MLEID = pv.vars['REED_MLEID'] - REED_RLOC = pv.vars['REED_RLOC'] - MED = pv.vars['MED'] - MED_MLEID = pv.vars['MED_MLEID'] - MM = pv.vars['MM_PORT'] - REED2001 = '' - REED2002 = '' - MED2001 = '' - MED2002 = '' - - for addr in pv.vars['REED_IPADDRS']: - if addr.startswith(Bytes('2001')): - REED2001 = addr - if addr.startswith(Bytes('2002')): - REED2002 = addr - - for addr in pv.vars['MED_IPADDRS']: - if addr.startswith(Bytes('2001')): - MED2001 = addr - if addr.startswith(Bytes('2002')): - MED2002 = addr - - # Step 3: Verify topology is formed correctly except REED. - - for i in range(1, 16): - with pkts.save_index(): - pv.verify_attached('ROUTER_%d' % i) - - # Step 4: REED attaches to Router_1 and MUST NOT attempt to become - # an active router by sending an Address Solicit Request - - pv.verify_attached('REED', 'ROUTER_1') - pkts.filter_wpan_src64(REED).\ - filter_coap_request(ADDR_SOL_URI).\ - must_not_next() - - # Step 6: MED sends an ICMPv6 Echo Request from MED to REED using ML-EID. - # The DUT MUST send a properly formatted Address Notification message: - # CoAP Request URI-PATH - # CON POST coap://[
]:MM/a/an - # CoAP Payload - # - Target EID TLV - # - RLOC16 TLV - # - ML-EID TLV - # The IPv6 Source address MUST be the RLOC of the originator - # The IPv6 Destination address MUST be the RLOC of the destination - # The DUT MUST send an ICMPv6 Echo Reply - - _pkt = pkts.filter_ipv6_src_dst(MED_MLEID, REED_MLEID).\ - filter_ping_request().\ - must_next() - pkts.filter_ipv6_src_dst(REED_RLOC, LEADER_RLOC).\ - filter_coap_request(ADDR_NTF_URI, port=MM).\ - filter(lambda p: { - NL_TARGET_EID_TLV, - NL_RLOC16_TLV, - NL_ML_EID_TLV - } <= set(p.thread_address.tlv.type) - ).\ - must_next() - pkts.filter_ipv6_src_dst(REED_MLEID, MED_MLEID).\ - filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - must_next() - - # Step 7: MED sends an ICMPv6 Echo Request from MED to REED using 2001::EID. - # The DUT MUST send a properly formatted Address Notification message: - # CoAP Request URI-PATH - # CON POST coap://[
]:MM/a/an - # CoAP Payload - # - Target EID TLV - # - RLOC16 TLV - # - ML-EID TLV - # The IPv6 Source address MUST be the RLOC of the originator - # The IPv6 Destination address MUST be the RLOC of the destination - # The DUT MUST send an ICMPv6 Echo Reply - - _pkt = pkts.filter_ipv6_src_dst(MED2001, REED2001).\ - filter_ping_request().\ - must_next() - pkts.filter_ipv6_src_dst(REED_RLOC, LEADER_RLOC).\ - filter_coap_request(ADDR_NTF_URI, port=MM).\ - filter(lambda p: { - NL_TARGET_EID_TLV, - NL_RLOC16_TLV, - NL_ML_EID_TLV - } <= set(p.thread_address.tlv.type) - ).\ - must_next() - pkts.filter_ipv6_src_dst(REED2001, MED2001).\ - filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - must_next() - - # Step 8: MED sends an ICMPv6 Echo Request from MED to REED using 2002::EID. - # The DUT MUST send a properly formatted Address Notification message: - # CoAP Request URI-PATH - # CON POST coap://[
]:MM/a/an - # CoAP Payload - # - Target EID TLV - # - RLOC16 TLV - # - ML-EID TLV - # The IPv6 Source address MUST be the RLOC of the originator - # The IPv6 Destination address MUST be the RLOC of the destination - # The DUT MUST send an ICMPv6 Echo Reply - - _pkt = pkts.filter_ipv6_src_dst(MED2002, REED2002).\ - filter_ping_request().\ - must_next() - pkts.filter_ipv6_src_dst(REED_RLOC, LEADER_RLOC).\ - filter_coap_request(ADDR_NTF_URI, port=MM).\ - filter(lambda p: { - NL_TARGET_EID_TLV, - NL_RLOC16_TLV, - NL_ML_EID_TLV - } <= set(p.thread_address.tlv.type) - ).\ - must_next() - pkts.filter_ipv6_src_dst(REED2002, MED2002).\ - filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_2_06_RouterDowngrade.py b/tests/scripts/thread-cert/Cert_5_2_06_RouterDowngrade.py deleted file mode 100755 index 7c89d33ea..000000000 --- a/tests/scripts/thread-cert/Cert_5_2_06_RouterDowngrade.py +++ /dev/null @@ -1,327 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import command -import config -import mle -import thread_cert -import thread_cert -from pktverify.consts import MLE_PARENT_REQUEST, MLE_CHILD_ID_REQUEST, ADDR_REL_URI, SOURCE_ADDRESS_TLV, MODE_TLV, TIMEOUT_TLV, CHALLENGE_TLV, RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, ROUTE64_TLV, ADDRESS16_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, TLV_REQUEST_TLV, SCAN_MASK_TLV, CONNECTIVITY_TLV, LINK_MARGIN_TLV, VERSION_TLV, ADDRESS_REGISTRATION_TLV, NL_MAC_EXTENDED_ADDRESS_TLV, NL_RLOC16_TLV, COAP_CODE_ACK -from pktverify.packet_verifier import PacketVerifier -from pktverify.null_field import nullField - -LEADER = 1 -DUT_ROUTER1 = 2 -ROUTER2 = 3 -ROUTER23 = 24 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to verify that the DUT will downgrade -# to a REED when the network becomes too dense and the Router Downgrade -# Threshold conditions are met. -# -# Test Topology: -# ------------- -# Leader -# / \ -# Router_1 [DUT] ... Router_23 -# -# DUT Types: -# ---------- -# Router - - -class Cert_5_2_06_RouterDowngrade(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - DUT_ROUTER1: { - 'name': 'ROUTER_1', - 'mode': 'rdn', - }, - ROUTER2: { - 'name': 'ROUTER_2', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - 4: { - 'name': 'ROUTER_3', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - 5: { - 'name': 'ROUTER_4', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - 6: { - 'name': 'ROUTER_5', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - 7: { - 'name': 'ROUTER_6', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - 8: { - 'name': 'ROUTER_7', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - 9: { - 'name': 'ROUTER_8', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - 10: { - 'name': 'ROUTER_9', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - 11: { - 'name': 'ROUTER_10', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - 12: { - 'name': 'ROUTER_11', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - 13: { - 'name': 'ROUTER_12', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - 14: { - 'name': 'ROUTER_13', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - 15: { - 'name': 'ROUTER_14', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - 16: { - 'name': 'ROUTER_15', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - 17: { - 'name': 'ROUTER_16', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - 18: { - 'name': 'ROUTER_17', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - 19: { - 'name': 'ROUTER_18', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - 20: { - 'name': 'ROUTER_19', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - 21: { - 'name': 'ROUTER_20', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - 22: { - 'name': 'ROUTER_21', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - 23: { - 'name': 'ROUTER_22', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - ROUTER23: { - 'name': 'ROUTER_23', - 'mode': 'rdn', - 'router_downgrade_threshold': 32, - 'router_upgrade_threshold': 32 - }, - } - - def test(self): - # 1 Ensure topology is formed correctly without ROUTER23. - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - for i in range(2, 24): - self.nodes[i].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[i].get_state(), 'router') - self.collect_rloc16s() - - # All reference testbed devices have been configured with downgrade threshold as 32 except DUT_ROUTER1, - # so we don't need to ensure ROUTER23 has a better link quality on - # posix. - self.nodes[ROUTER23].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER23].get_state(), 'router') - - self.simulator.go(10) - self.assertEqual(self.nodes[DUT_ROUTER1].get_state(), 'child') - self.collect_rlocs() - - router1_rloc = self.nodes[DUT_ROUTER1].get_ip6_address(config.ADDRESS_TYPE.RLOC) - self.assertTrue(self.nodes[LEADER].ping(router1_rloc)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_RLOC = pv.vars['LEADER_RLOC'] - ROUTER_1 = pv.vars['ROUTER_1'] - ROUTER_1_RLOC = pv.vars['ROUTER_1_RLOC'] - ROUTER_1_RLOC16 = pv.vars['ROUTER_1_RLOC16'] - - # Step 1: Ensure topology is formed correctly - - for i in range(1, 24): - pv.verify_attached('ROUTER_%d' % i) - - # Step 3: Allow enough time for the DUT to get Network Data Updates - # and resign its Router ID. - # The DUT MUST first reconnect to the network as a Child by - # sending properly formatted Parent Request and Child ID Request - # messages. - # Once the DUT attaches as a Child, it MUST send an Address - # Release Message to the Leader: - # CoAP Request URI - # coap://[]:MM/a/ar - # CoAP Payload - # MAC Extended Address TLV - # RLOC16 TLV - - pkts.filter_wpan_src64(ROUTER_1).\ - filter_LLARMA().\ - filter_mle_cmd(MLE_PARENT_REQUEST).\ - filter(lambda p: { - CHALLENGE_TLV, - MODE_TLV, - SCAN_MASK_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255 and\ - p.mle.tlv.scan_mask.r == 1 and\ - p.mle.tlv.scan_mask.e == 0 - ).\ - must_next() - - _pkt = pkts.filter_wpan_src64(ROUTER_1).\ - filter_mle_cmd(MLE_CHILD_ID_REQUEST).\ - filter(lambda p: { - LINK_LAYER_FRAME_COUNTER_TLV, - MODE_TLV, - RESPONSE_TLV, - TIMEOUT_TLV, - TLV_REQUEST_TLV, - ADDRESS16_TLV, - NETWORK_DATA_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) and\ - p.mle.tlv.addr16 is nullField and\ - p.thread_nwd.tlv.type is nullField - ).\ - must_next() - _pkt.must_not_verify(lambda p: (ADDRESS_REGISTRATION_TLV) in p.mle.tlv.type) - - pkts.filter_wpan_src64(ROUTER_1).\ - filter_ipv6_dst(LEADER_RLOC).\ - filter_coap_request(ADDR_REL_URI).\ - filter(lambda p: { - NL_MAC_EXTENDED_ADDRESS_TLV, - NL_RLOC16_TLV - } <= set(p.coap.tlv.type) and\ - p.thread_address.tlv.rloc16 == ROUTER_1_RLOC16 - ).\ - must_next() - - # Step 4: Leader receives Address Release messages and sends a2.04 - # Changed CoAP response. - - pkts.filter_wpan_src64(LEADER).\ - filter_ipv6_dst(ROUTER_1_RLOC).\ - filter_coap_ack(ADDR_REL_URI).\ - must_next() - - # Step 5: ROUTER_1 responds with ICMPv6 Echo Reply - _pkt = pkts.filter_ipv6_src_dst(LEADER_RLOC, ROUTER_1_RLOC).\ - filter_ping_request().\ - must_next() - pkts.filter_ipv6_src_dst(ROUTER_1_RLOC, LEADER_RLOC).\ - filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_2_07_REEDSynchronization.py b/tests/scripts/thread-cert/Cert_5_2_07_REEDSynchronization.py deleted file mode 100755 index 6f16ab39e..000000000 --- a/tests/scripts/thread-cert/Cert_5_2_07_REEDSynchronization.py +++ /dev/null @@ -1,263 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import copy -import unittest - -import command -import config -import ipv6 -import mle -import thread_cert -from pktverify.consts import ADDR_SOL_URI, MLE_LINK_REQUEST, MLE_LINK_ACCEPT, MLE_LINK_ACCEPT_AND_REQUEST, SOURCE_ADDRESS_TLV, CHALLENGE_TLV, RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, LEADER_DATA_TLV, VERSION_TLV -from pktverify.packet_verifier import PacketVerifier -from pktverify.null_field import nullField - -LEADER = 1 -DUT_ROUTER1 = 2 -ROUTER2 = 3 -DUT_REED = 17 - -MLE_MIN_LINKS = 3 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to validate the REED’s Synchronization -# procedure after attaching to a network with multiple Routers. A REED -# MUST process incoming Advertisements and perform a one-way frame-counter -# synchronization with at least 3 neighboring Routers. When Router receives -# unicast MLE Link Request from REED, it replies with MLE Link Accept. -# -# Test Topology: -# ------------- -# Router_15 - Leader -# ... / \ -# Router_n Router_1(DUT) -# | -# REED(DUT) -# -# DUT Types: -# ---------- -# Router -# REED - - -class Cert_5_2_7_REEDSynchronization_Base(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - }, - DUT_ROUTER1: { - 'name': 'ROUTER_1', - 'mode': 'rdn', - }, - ROUTER2: { - 'name': 'ROUTER_2', - 'mode': 'rdn', - }, - 4: { - 'name': 'ROUTER_3', - 'mode': 'rdn', - }, - 5: { - 'name': 'ROUTER_4', - 'mode': 'rdn', - }, - 6: { - 'name': 'ROUTER_5', - 'mode': 'rdn', - }, - 7: { - 'name': 'ROUTER_6', - 'mode': 'rdn', - }, - 8: { - 'name': 'ROUTER_7', - 'mode': 'rdn', - }, - 9: { - 'name': 'ROUTER_8', - 'mode': 'rdn', - }, - 10: { - 'name': 'ROUTER_9', - 'mode': 'rdn', - }, - 11: { - 'name': 'ROUTER_10', - 'mode': 'rdn', - }, - 12: { - 'name': 'ROUTER_11', - 'mode': 'rdn', - }, - 13: { - 'name': 'ROUTER_12', - 'mode': 'rdn', - }, - 14: { - 'name': 'ROUTER_13', - 'mode': 'rdn', - }, - 15: { - 'name': 'ROUTER_14', - 'mode': 'rdn', - }, - 16: { - 'name': 'ROUTER_15', - 'mode': 'rdn', - }, - DUT_REED: { - 'name': 'REED', - 'mode': 'rdn', - }, - } - - DUT = 0 - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - for i in range(2, 17): - self.nodes[i].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - - for i in range(2, 17): - self.assertEqual(self.nodes[i].get_state(), 'router') - - # Avoid DUT_REED attach to DUT_ROUTER1. - if self.DUT == DUT_REED: - self.nodes[DUT_REED].\ - add_allowlist(self.nodes[DUT_ROUTER1].get_addr64(), - config.RSSI['LINK_QULITY_1']) - - if self.DUT == DUT_ROUTER1: - self.nodes[DUT_REED].\ - add_allowlist(self.nodes[DUT_ROUTER1].get_addr64(), - config.RSSI['LINK_QULITY_1']) - self.nodes[DUT_REED].add_allowlist(self.nodes[ROUTER2].get_addr64()) - self.nodes[DUT_REED].enable_allowlist() - - self.nodes[DUT_REED].start() - self.simulator.go(config.MAX_ADVERTISEMENT_INTERVAL) - self.assertEqual(self.nodes[DUT_REED].get_state(), 'child') - - self.simulator.go(config.MAX_ADVERTISEMENT_INTERVAL) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - ROUTER_1 = pv.vars['ROUTER_1'] - REED = pv.vars['REED'] - - # Step 1: Verify topology is formed correctly except REED. - - for i in range(1, 16): - with pkts.save_index(): - pv.verify_attached('ROUTER_%d' % i) - - # Step 2: REED attaches to the network and MUST NOT attempt to become - # an active router by sending an Address Solicit Request - - pv.verify_attached('REED') - pkts.filter_wpan_src64(REED).\ - filter_coap_request(ADDR_SOL_URI).\ - filter(lambda p: { - NL_MAC_EXTENDED_ADDRESS_TLV, - NL_STATUS_TLV - } <= set(p.coap.tlv.type) - ).\ - must_not_next() - - # Step 3: REED sends a unicast Link Request message to at lease 3 Routers - # - # The Link Request Message MUST contain the following TLVs: - # - Challenge TLV - # - Leader Data TLV - # - Source Address TLV - # - Version TLV - - if self.DUT == DUT_REED: - for i in range(0, MLE_MIN_LINKS): - pkts.filter_wpan_src64(REED).\ - filter_mle_cmd(MLE_LINK_REQUEST).\ - filter(lambda p: { - CHALLENGE_TLV, - LEADER_DATA_TLV, - SOURCE_ADDRESS_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) - ).\ - must_next() - - # Step 4: Router_1 sends Link Accept message - # The following TLVs MUST be present in the Link Accept message: - # - Link-layer Frame Counter TLV - # - Source Address TLV - # - Response TLV - # - Version TLV - # - MLE Frame Counter TLV (optional) - # - # The recipient does not make any change to its local state and - # MUST NOT reply with a Link Accept And Request message. - - if self.DUT == DUT_ROUTER1: - pkts.filter_wpan_dst64(REED).\ - filter_wpan_src64(ROUTER_1).\ - filter_mle_cmd(MLE_LINK_ACCEPT).\ - filter(lambda p: { - LINK_LAYER_FRAME_COUNTER_TLV, - RESPONSE_TLV, - SOURCE_ADDRESS_TLV, - VERSION_TLV - } <= set(p.mle.tlv.type) - ).\ - must_next() - pkts.filter_wpan_src64(REED).\ - filter_mle_cmd(MLE_LINK_ACCEPT_AND_REQUEST).\ - must_not_next() - - -class Cert_5_2_7_REEDSynchronization_REED(Cert_5_2_7_REEDSynchronization_Base): - DUT = DUT_REED - - -class Cert_5_2_7_REEDSynchronization_ROUTER(Cert_5_2_7_REEDSynchronization_Base): - DUT = DUT_ROUTER1 - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_3_01_LinkLocal.py b/tests/scripts/thread-cert/Cert_5_3_01_LinkLocal.py deleted file mode 100755 index fbb14df26..000000000 --- a/tests/scripts/thread-cert/Cert_5_3_01_LinkLocal.py +++ /dev/null @@ -1,201 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import thread_cert -from pktverify.consts import LINK_LOCAL_All_THREAD_NODES_MULTICAST_ADDRESS -from pktverify.packet_verifier import PacketVerifier - -LEADER = 1 -DUT_ROUTER1 = 2 -FRAGMENTED_DATA_LEN = 256 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to validate the Link-Local addresses -# that the DUT auto-configures. -# -# Test Topology: -# ------------- -# Leader -# | -# Router(DUT) -# -# DUT Types: -# ---------- -# Router - - -class Cert_5_3_1_LinkLocal(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - }, - DUT_ROUTER1: { - 'name': 'ROUTER', - 'mode': 'rdn', - }, - } - - def test(self): - # 1 - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[DUT_ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[DUT_ROUTER1].get_state(), 'router') - - self.collect_rlocs() - self.collect_ipaddrs() - - # 2 & 3 - link_local = self.nodes[DUT_ROUTER1].get_ip6_address(config.ADDRESS_TYPE.LINK_LOCAL) - self.assertTrue(self.nodes[LEADER].ping(link_local, size=FRAGMENTED_DATA_LEN)) - self.assertTrue(self.nodes[LEADER].ping(link_local)) - - # 4 & 5 - self.assertTrue(self.nodes[LEADER].ping(config.LINK_LOCAL_ALL_NODES_ADDRESS, size=FRAGMENTED_DATA_LEN)) - self.assertTrue(self.nodes[LEADER].ping(config.LINK_LOCAL_ALL_NODES_ADDRESS)) - - # 6 & 7 - self.assertTrue(self.nodes[LEADER].ping(config.LINK_LOCAL_ALL_ROUTERS_ADDRESS, size=FRAGMENTED_DATA_LEN)) - self.assertTrue(self.nodes[LEADER].ping(config.LINK_LOCAL_ALL_ROUTERS_ADDRESS)) - - # 8 - self.assertTrue(self.nodes[LEADER].ping(config.LINK_LOCAL_All_THREAD_NODES_MULTICAST_ADDRESS)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_LLA = pv.vars['LEADER_LLA'] - ROUTER_LLA = pv.vars['ROUTER_LLA'] - - # Step 1: Build the topology as described - pv.verify_attached('ROUTER') - - # Step 2: Leader sends a Fragmented ICMPv6 Echo Request to DUT’s - # MAC extended address based Link-Local address - # The DUT MUST respond with an ICMPv6 Echo Reply - - _pkt = pkts.filter_ping_request().\ - filter_ipv6_src_dst(LEADER_LLA, ROUTER_LLA).\ - filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(ROUTER_LLA, LEADER_LLA).\ - filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ - must_next() - - # Step 3: Leader sends an Unfragmented ICMPv6 Echo Request to DUT’s - # MAC extended address based Link-Local address - # The DUT MUST respond with an ICMPv6 Echo Reply - - _pkt = pkts.filter_ping_request().\ - filter_ipv6_src_dst(LEADER_LLA, ROUTER_LLA).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(ROUTER_LLA, LEADER_LLA).\ - must_next() - - # Step 4: Leader sends a Fragmented ICMPv6 Echo Request to the - # Link-Local All Nodes multicast address (FF02::1) - # The DUT MUST respond with an ICMPv6 Echo Reply - - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(ROUTER_LLA, LEADER_LLA).\ - filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ - must_next() - - # Step 5: Leader sends an Unfragmented ICMPv6 Echo Request to the - # Link-Local All Nodes multicast address (FF02::1) - # The DUT MUST respond with an ICMPv6 Echo Reply - - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(ROUTER_LLA, LEADER_LLA).\ - must_next() - - # Step 6: Leader sends a Fragmented ICMPv6 Echo Request to the - # Link-Local All Routers multicast address (FF02::2) - # The DUT MUST respond with an ICMPv6 Echo Reply - - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(LEADER).\ - filter_LLARMA().\ - filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(ROUTER_LLA, LEADER_LLA).\ - filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ - must_next() - - # Step 7: Leader sends an Unfragmented ICMPv6 Echo Request to the - # Link-Local All Routers multicast address (FF02::2) - # The DUT MUST respond with an ICMPv6 Echo Reply - - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(LEADER).\ - filter_LLARMA().\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(ROUTER_LLA, LEADER_LLA).\ - must_next() - - # Step 8: Leader sends an Unfragmented ICMPv6 Echo Request to the - # Link-Local All Thread Nodes multicast address - # The DUT MUST respond with an ICMPv6 Echo Reply - - _pkt = pkts.filter_ping_request().\ - filter_ipv6_src_dst(LEADER_LLA, - LINK_LOCAL_All_THREAD_NODES_MULTICAST_ADDRESS).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(ROUTER_LLA, LEADER_LLA).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_3_02_RealmLocal.py b/tests/scripts/thread-cert/Cert_5_3_02_RealmLocal.py deleted file mode 100755 index 9e2184fde..000000000 --- a/tests/scripts/thread-cert/Cert_5_3_02_RealmLocal.py +++ /dev/null @@ -1,295 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import thread_cert -from pktverify.consts import MLE_CHILD_ID_REQUEST, MLE_CHILD_ID_RESPONSE, REALM_LOCAL_ALL_NODES_ADDRESS, REALM_LOCAL_ALL_ROUTERS_ADDRESS, REALM_LOCAL_All_THREAD_NODES_MULTICAST_ADDRESS -from pktverify.packet_verifier import PacketVerifier - -LEADER = 1 -ROUTER1 = 2 -DUT_ROUTER2 = 3 -SED1 = 4 -FRAGMENTED_DATA_LEN = 256 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to validate the Realm-Local addresses -# that the DUT auto-configures. -# -# Test Topology: -# ------------- -# Leader -# | -# Router_1 - Router_2(DUT) -# | -# SED -# -# DUT Types: -# ---------- -# Router - - -class Cert_5_3_2_RealmLocal(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [ROUTER1] - }, - ROUTER1: { - 'name': 'ROUTER_1', - 'mode': 'rdn', - 'allowlist': [LEADER, DUT_ROUTER2] - }, - DUT_ROUTER2: { - 'name': 'ROUTER_2', - 'mode': 'rdn', - 'allowlist': [ROUTER1, SED1] - }, - SED1: { - 'name': 'SED', - 'is_mtd': True, - 'mode': 'n', - 'timeout': config.DEFAULT_CHILD_TIMEOUT, - 'allowlist': [DUT_ROUTER2] - }, - } - - def test(self): - # 1 - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - - self.nodes[DUT_ROUTER2].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[DUT_ROUTER2].get_state(), 'router') - - self.nodes[SED1].start() - self.simulator.go(5) - self.assertEqual(self.nodes[SED1].get_state(), 'child') - - self.collect_ipaddrs() - self.collect_rloc16s() - - # 2 & 3 - mleid = self.nodes[DUT_ROUTER2].get_ip6_address(config.ADDRESS_TYPE.ML_EID) - self.assertTrue(self.nodes[LEADER].ping(mleid, size=FRAGMENTED_DATA_LEN)) - self.simulator.go(2) - self.assertTrue(self.nodes[LEADER].ping(mleid)) - self.simulator.go(2) - - # 4 & 5 - self.assertTrue(self.nodes[LEADER].ping('ff03::1', num_responses=2, size=FRAGMENTED_DATA_LEN)) - self.simulator.go(5) - self.assertTrue(self.nodes[LEADER].ping('ff03::1', num_responses=2)) - self.simulator.go(5) - - # 6 & 7 - self.assertTrue(self.nodes[LEADER].ping('ff03::2', num_responses=2, size=FRAGMENTED_DATA_LEN)) - self.simulator.go(5) - self.assertTrue(self.nodes[LEADER].ping('ff03::2', num_responses=2)) - self.simulator.go(5) - - # 8 - self.assertTrue(self.nodes[LEADER].ping( - config.REALM_LOCAL_All_THREAD_NODES_MULTICAST_ADDRESS, - num_responses=3, - size=FRAGMENTED_DATA_LEN, - )) - self.simulator.go(5) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_MLEID = pv.vars['LEADER_MLEID'] - ROUTER_1 = pv.vars['ROUTER_1'] - ROUTER_2 = pv.vars['ROUTER_2'] - ROUTER_2_RLOC16 = pv.vars['ROUTER_2_RLOC16'] - ROUTER_2_MLEID = pv.vars['ROUTER_2_MLEID'] - SED = pv.vars['SED'] - SED_RLOC16 = pv.vars['SED_RLOC16'] - - # Step 1: Build the topology as described - pv.verify_attached('ROUTER_1', 'LEADER') - pv.verify_attached('ROUTER_2', 'ROUTER_1') - pv.verify_attached('SED', 'ROUTER_2', 'MTD') - - # Step 2: Leader sends a Fragmented ICMPv6 Echo Request to - # DUT's ML-EID - # The DUT MUST respond with an ICMPv6 Echo Reply - - _pkt = pkts.filter_ping_request().\ - filter_ipv6_src_dst(LEADER_MLEID, ROUTER_2_MLEID).\ - filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(ROUTER_2_MLEID, LEADER_MLEID).\ - filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ - must_next() - - # Step 3: Leader sends a Unfragmented ICMPv6 Echo Request to - # DUT’s ML-EID - # The DUT MUST respond with an ICMPv6 Echo Reply - - _pkt = pkts.filter_ping_request().\ - filter_ipv6_src_dst(LEADER_MLEID, ROUTER_2_MLEID).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(ROUTER_2_MLEID, LEADER_MLEID).\ - must_next() - - # Step 4: Leader sends a Fragmented ICMPv6 Echo Request to the - # Realm-Local All Nodes multicast address (FF03::1) - # The DUT MUST respond with an ICMPv6 Echo Reply - # The DUT MUST NOT forward the ICMPv6 Echo Request to SED - - _pkt1 = pkts.filter_ping_request().\ - filter_wpan_src64(LEADER).\ - filter_ipv6_dst(REALM_LOCAL_ALL_NODES_ADDRESS).\ - filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ - must_next() - with pkts.save_index(): - pkts.filter_ping_reply(identifier=_pkt1.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(ROUTER_2_MLEID, LEADER_MLEID).\ - filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ - must_next() - pkts.filter_ping_request(identifier=_pkt1.icmpv6.echo.identifier).\ - filter_wpan_src16_dst16(ROUTER_2_RLOC16, SED_RLOC16).\ - filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ - must_not_next() - - # Step 5: Leader sends an Unfragmented ICMPv6 Echo Request to the - # Realm-Local All Nodes multicast address (FF03::1) - # The DUT MUST respond with an ICMPv6 Echo Reply - # The DUT MUST NOT forward the ICMPv6 Echo Request to SED - - _pkt2 = pkts.filter_ping_request().\ - filter_wpan_src64(LEADER).\ - filter_ipv6_dst(REALM_LOCAL_ALL_NODES_ADDRESS).\ - filter(lambda p: p.icmpv6.echo.sequence_number != - _pkt1.icmpv6.echo.sequence_number - ).\ - must_next() - with pkts.save_index(): - pkts.filter_ping_reply(identifier=_pkt2.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(ROUTER_2_MLEID, LEADER_MLEID).\ - must_next() - pkts.filter_ping_request(identifier = _pkt2.icmpv6.echo.identifier).\ - filter_wpan_src16_dst16(ROUTER_2_RLOC16, SED_RLOC16).\ - must_not_next() - - # Step 6: Leader sends a Fragmented ICMPv6 Echo Request to the - # Realm-Local All Routers multicast address (FF03::2) - # The DUT MUST respond with an ICMPv6 Echo Reply - # The DUT MUST NOT forward the ICMPv6 Echo Request to SED - - _pkt1 = pkts.filter_ping_request().\ - filter_wpan_src64(LEADER).\ - filter_ipv6_dst(REALM_LOCAL_ALL_ROUTERS_ADDRESS).\ - filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ - must_next() - with pkts.save_index(): - pkts.filter_ping_reply(identifier=_pkt1.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(ROUTER_2_MLEID, LEADER_MLEID).\ - filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ - must_next() - pkts.filter_ping_request(identifier=_pkt1.icmpv6.echo.identifier).\ - filter_wpan_src16_dst16(ROUTER_2_RLOC16, SED_RLOC16).\ - filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ - must_not_next() - - # Step 7: Leader sends an Unfragmented ICMPv6 Echo Request to the - # Realm-Local All Routers multicast address (FF03::2) - # The DUT MUST respond with an ICMPv6 Echo Reply - # The DUT MUST NOT forward the ICMPv6 Echo Request to SED - - _pkt2 = pkts.filter_ping_request().\ - filter_wpan_src64(LEADER).\ - filter_ipv6_dst(REALM_LOCAL_ALL_ROUTERS_ADDRESS).\ - filter(lambda p: p.icmpv6.echo.sequence_number != - _pkt1.icmpv6.echo.sequence_number - ).\ - must_next() - with pkts.save_index(): - pkts.filter_ping_reply(identifier=_pkt2.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(ROUTER_2_MLEID, LEADER_MLEID).\ - must_next() - pkts.filter_ping_request(identifier=_pkt2.icmpv6.echo.identifier).\ - filter_wpan_src16_dst16(ROUTER_2_RLOC16, SED_RLOC16).\ - must_not_next() - - # Step 8: Leader sends a Fragmented ICMPv6 Echo Request to the - # Realm-Local All Thread Nodes multicast address - # The DUT MUST respond with an ICMPv6 Echo Reply - # The Realm-Local All Thread Nodes multicast address - # MUST be a realm-local Unicast Prefix-Based Multicast - # Address [RFC 3306], with: - # - flgs set to 3 (P = 1 and T = 1) - # - scop set to 3 - # - plen set to the Mesh Local Prefix length - # - network prefix set to the Mesh Local Prefix - # - group ID set to 1 - # The DUT MUST use IEEE 802.15.4 indirect transmissions - # to forward packet to SED - - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(LEADER).\ - filter_ipv6_dst(REALM_LOCAL_All_THREAD_NODES_MULTICAST_ADDRESS).\ - filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ - must_next() - with pkts.save_index(): - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(ROUTER_2_MLEID, LEADER_MLEID).\ - filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ - must_next() - pkts.filter_ping_request(identifier = _pkt.icmpv6.echo.identifier).\ - filter_wpan_src16_dst16(ROUTER_2_RLOC16, SED_RLOC16).\ - filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(SED).\ - filter_ipv6_dst(LEADER_MLEID).\ - filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_3_03_AddressQuery.py b/tests/scripts/thread-cert/Cert_5_3_03_AddressQuery.py deleted file mode 100755 index eb55ecd0e..000000000 --- a/tests/scripts/thread-cert/Cert_5_3_03_AddressQuery.py +++ /dev/null @@ -1,352 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import command -import config -import thread_cert -from pktverify.consts import MLE_CHILD_ID_REQUEST, MLE_CHILD_ID_RESPONSE, ADDR_QRY_URI, ADDR_NTF_URI, NL_ML_EID_TLV, NL_RLOC16_TLV, NL_TARGET_EID_TLV, COAP_CODE_POST -from pktverify.packet_verifier import PacketVerifier - -LEADER = 1 -ROUTER1 = 2 -DUT_ROUTER2 = 3 -ROUTER3 = 4 -MED1 = 5 -MED1_TIMEOUT = 3 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to validate that the DUT is able to generate -# Address Query messages and properly respond with Address Notification messages. -# -# Test Topology: -# ------------- -# Router_1 - Leader -# / \ -# Router_3 - Router_2(DUT) -# | -# MED -# -# DUT Types: -# ---------- -# Router - - -class Cert_5_3_3_AddressQuery(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [ROUTER1, DUT_ROUTER2, ROUTER3] - }, - ROUTER1: { - 'name': 'ROUTER_1', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - DUT_ROUTER2: { - 'name': 'ROUTER_2', - 'mode': 'rdn', - 'allowlist': [LEADER, ROUTER3, MED1] - }, - ROUTER3: { - 'name': 'ROUTER_3', - 'mode': 'rdn', - 'allowlist': [LEADER, DUT_ROUTER2] - }, - MED1: { - 'name': 'MED', - 'is_mtd': True, - 'mode': 'rn', - 'timeout': 3, - 'allowlist': [DUT_ROUTER2] - }, - } - - def test(self): - # 1 - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[ROUTER1].start() - self.nodes[DUT_ROUTER2].start() - self.nodes[ROUTER3].start() - self.nodes[MED1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - self.assertEqual(self.nodes[DUT_ROUTER2].get_state(), 'router') - self.assertEqual(self.nodes[ROUTER3].get_state(), 'router') - self.assertEqual(self.nodes[MED1].get_state(), 'child') - self.collect_ipaddrs() - self.collect_rlocs() - self.collect_rloc16s() - - # 2 - router3_mleid = self.nodes[ROUTER3].get_ip6_address(config.ADDRESS_TYPE.ML_EID) - self.assertTrue(self.nodes[MED1].ping(router3_mleid)) - - # 3 - # Wait the finish of address resolution traffic triggered by previous - # ping. - self.simulator.go(5) - - med1_mleid = self.nodes[MED1].get_ip6_address(config.ADDRESS_TYPE.ML_EID) - self.assertTrue(self.nodes[ROUTER1].ping(med1_mleid)) - - # 4 - # Wait the finish of address resolution traffic triggered by previous - # ping. - self.simulator.go(5) - - self.assertTrue(self.nodes[MED1].ping(router3_mleid)) - - # 5 - # Power off ROUTER3 and wait for leader to expire its Router ID. - # In this topology, ROUTER3 has two neighbors (Leader and DUT_ROUTER2), - # so the wait time is (MAX_NEIGHBOR_AGE (100s) + worst propagation time (32s * 15) for bad routing +\ - # INFINITE_COST_TIMEOUT (90s) + transmission time + extra redundancy), - # totally ~700s. - self.nodes[ROUTER3].stop() - self.simulator.go(700) - - self.assertFalse(self.nodes[MED1].ping(router3_mleid)) - - # 6 - self.nodes[MED1].stop() - self.simulator.go(MED1_TIMEOUT) - - self.assertFalse(self.nodes[ROUTER1].ping(med1_mleid)) - self.assertFalse(self.nodes[ROUTER1].ping(med1_mleid)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_MLEID = pv.vars['LEADER_MLEID'] - ROUTER_1 = pv.vars['ROUTER_1'] - ROUTER_1_RLOC = pv.vars['ROUTER_1_RLOC'] - ROUTER_1_MLEID = pv.vars['ROUTER_1_MLEID'] - ROUTER_2 = pv.vars['ROUTER_2'] - ROUTER_2_RLOC16 = pv.vars['ROUTER_2_RLOC16'] - ROUTER_2_RLOC = pv.vars['ROUTER_2_RLOC'] - ROUTER_2_MLEID = pv.vars['ROUTER_2_MLEID'] - MED = pv.vars['MED'] - MED_RLOC16 = pv.vars['MED_RLOC16'] - MED_MLEID = pv.vars['MED_MLEID'] - ROUTER_3 = pv.vars['ROUTER_3'] - ROUTER_3_MLEID = pv.vars['ROUTER_3_MLEID'] - MM = pv.vars['MM_PORT'] - - # Step 1: Build the topology as described - for i in range(1, 4): - with pkts.save_index(): - pv.verify_attached('ROUTER_%d' % i) - pkts.filter_wpan_src64(MED).\ - filter_wpan_dst64(ROUTER_2).\ - filter_mle_cmd(MLE_CHILD_ID_REQUEST).\ - must_next() - pkts.filter_wpan_src64(ROUTER_2).\ - filter_wpan_dst64(MED).\ - filter_mle_cmd(MLE_CHILD_ID_RESPONSE).\ - must_next() - - # Step 2: MED sends an ICMPv6 Echo Request to Router_3 ML-EID - # The DUT MUST generate an Address Query Request on MED’s behalf - # to find Router_3 address. - # The Address Query Request MUST be sent to the Realm-Local - # All-Routers address (FF03::2) - # CoAP URI-Path - # - NON POST coap:// - # CoAP Payload - # - Target EID TLV - # The DUT MUST receive and process the incoming Address Notification - # The DUT MUST then forward the ICMPv6 Echo Request from MED and - # forward the ICMPv6 Echo Reply to MED - - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(MED).\ - filter_ipv6_dst(ROUTER_3_MLEID).\ - must_next() - pkts.filter_wpan_src64(ROUTER_2).\ - filter_RLARMA().\ - filter_coap_request(ADDR_QRY_URI, port=MM).\ - filter(lambda p: p.thread_address.tlv.target_eid == ROUTER_3_MLEID).\ - must_next() - _pkt1 = pkts.filter_wpan_src64(ROUTER_3).\ - filter_ipv6_dst(ROUTER_2_RLOC).\ - filter_coap_request(ADDR_NTF_URI, port=MM).\ - filter(lambda p: { - NL_ML_EID_TLV, - NL_RLOC16_TLV, - NL_TARGET_EID_TLV - } <= set(p.coap.tlv.type) and\ - p.thread_address.tlv.target_eid == ROUTER_3_MLEID and\ - p.coap.code == COAP_CODE_POST - ).\ - must_next() - pkts.filter_ping_request(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_2).\ - filter_ipv6_dst(ROUTER_3_MLEID).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_3).\ - filter_dst16(ROUTER_2_RLOC16).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_2).\ - filter_wpan_dst16(MED_RLOC16).\ - must_next() - - # Step 3: Router_1 sends an ICMPv6 Echo Request to the MED ML-EID address - # The DUT MUST respond to the Address Query Request with a properly - # formatted Address Notification Message: - # CoAP URI-Path - # - CON POST coap://[
]:MM/a/an - # CoAP Payload - # - ML-EID TLV - # - RLOC16 TLV - # - Target EID TLV - # The IPv6 Source address MUST be the RLOC of the originator - # The IPv6 Destination address MUST be the RLOC of the destination - - pkts.filter_wpan_src64(ROUTER_1).\ - filter_RLARMA().\ - filter_coap_request(ADDR_QRY_URI, port=MM).\ - filter(lambda p: p.thread_address.tlv.target_eid == MED_MLEID).\ - must_next() - pkts.filter_ipv6_src_dst(ROUTER_2_RLOC, ROUTER_1_RLOC).\ - filter_coap_request(ADDR_NTF_URI, port=MM).\ - filter(lambda p: { - NL_ML_EID_TLV, - NL_RLOC16_TLV, - NL_TARGET_EID_TLV - } <= set(p.coap.tlv.type) and\ - p.thread_address.tlv.target_eid == MED_MLEID and\ - p.coap.code == COAP_CODE_POST - ).\ - must_next() - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(ROUTER_1).\ - filter_ipv6_dst(MED_MLEID).\ - must_next() - pkts.filter_ping_request(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_2).\ - filter_ipv6_dst(MED_MLEID).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(MED).\ - filter_wpan_dst16(ROUTER_2_RLOC16).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_2).\ - filter_ipv6_dst(ROUTER_1_MLEID).\ - must_next() - - # Step 4: MED sends an ICMPv6 Echo Request to the Router_3 ML-EID - # The DUT MUST NOT send an Address Query, as the Router_3 address - # should be cached - # The DUT MUST forward the ICMPv6 Echo Reply to MED - - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(MED).\ - filter_ipv6_dst(ROUTER_3_MLEID).\ - must_next() - lstart = pkts.index - pkts.filter_ping_request(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_2).\ - filter_ipv6_dst(ROUTER_3_MLEID).\ - must_next() - lend = pkts.index - - pkts.range(lstart, lend).\ - filter_wpan_src64(ROUTER_2).\ - filter_RLARMA().\ - filter_coap_request(ADDR_QRY_URI).\ - must_not_next() - - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_3).\ - filter_wpan_dst16(ROUTER_2_RLOC16).\ - must_next() - _pkt1 = pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_2).\ - filter_wpan_dst16(MED_RLOC16).\ - must_next() - - # Step 5: Power off Router_3 and wait for the Leader to expire its Router ID - # Send an ICMPv6 Echo Request from MED to the Router_3 ML-EID address - # The DUT MUST update its address cache and removes all entries based - # on Router_3’s Router ID. - # The DUT MUST send an Address Query to discover Router_3’s RLOC - # address. - - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(MED).\ - filter_ipv6_dst(ROUTER_3_MLEID).\ - filter(lambda p: p.sniff_timestamp - _pkt1.sniff_timestamp >= 700).\ - must_next() - pkts.filter_wpan_src64(ROUTER_2).\ - filter_RLARMA().\ - filter_coap_request(ADDR_QRY_URI, port=MM).\ - filter(lambda p: p.thread_address.tlv.target_eid == ROUTER_3_MLEID and\ - p.coap.code == COAP_CODE_POST - ).\ - must_next() - - # Step 6: Power off MED and wait for the DUT to timeout the child. - # Send two ICMPv6 Echo Requests from Router_1 to MED ML-EID - # The DUT MUST NOT respond with an Address Notification message - - pkts.filter_ping_request().\ - filter_wpan_src64(ROUTER_1).\ - filter_ipv6_dst(MED_MLEID).\ - must_next() - - pkts.filter_wpan_src64(ROUTER_1).\ - filter_RLARMA().\ - filter_coap_request(ADDR_QRY_URI, port=MM).\ - filter(lambda p: p.thread_address.tlv.target_eid == MED_MLEID and\ - p.coap.code == COAP_CODE_POST - ).\ - must_next() - - pkts.filter_ipv6_src_dst(ROUTER_2_RLOC, ROUTER_1_RLOC).\ - filter_coap_request(ADDR_NTF_URI).\ - must_not_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_3_04_AddressMapCache.py b/tests/scripts/thread-cert/Cert_5_3_04_AddressMapCache.py deleted file mode 100755 index 66e1d1edb..000000000 --- a/tests/scripts/thread-cert/Cert_5_3_04_AddressMapCache.py +++ /dev/null @@ -1,256 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import command -import config -import thread_cert -from pktverify.consts import MLE_CHILD_ID_REQUEST, MLE_CHILD_ID_RESPONSE, ADDR_QRY_URI, ADDR_NTF_URI, NL_ML_EID_TLV, NL_RLOC16_TLV, NL_TARGET_EID_TLV, COAP_CODE_POST -from pktverify.packet_verifier import PacketVerifier - -LEADER = 1 -DUT_ROUTER1 = 2 -SED1 = 3 -MED1 = 4 -MED2 = 5 -MED3 = 6 -MED4 = 7 - -MTDS = [SED1, MED1, MED2, MED3, MED4] - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to validate that the DUT is able to -# maintain an EID-to-RLOC Map Cache for a Sleepy End Device child attached to -# it. Each EID-to-RLOC Set MUST support at least four non-link-local unicast -# IPv6 addresses. -# -# Test Topology: -# ------------- -# Router_1 - Leader -# | / \ -# SED MED_1 .. MED_4 -# -# DUT Types: -# ---------- -# Router - - -class Cert_5_3_4_AddressMapCache(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [DUT_ROUTER1, MED1, MED2, MED3, MED4] - }, - DUT_ROUTER1: { - 'name': 'ROUTER', - 'mode': 'rdn', - 'allowlist': [LEADER, SED1] - }, - SED1: { - 'name': 'SED', - 'is_mtd': True, - 'mode': '-', - 'timeout': 5, - 'allowlist': [DUT_ROUTER1] - }, - MED1: { - 'name': 'MED_1', - 'is_mtd': True, - 'mode': 'rn', - 'allowlist': [LEADER] - }, - MED2: { - 'name': 'MED_2', - 'is_mtd': True, - 'mode': 'rn', - 'allowlist': [LEADER] - }, - MED3: { - 'name': 'MED_3', - 'is_mtd': True, - 'mode': 'rn', - 'allowlist': [LEADER] - }, - MED4: { - 'name': 'MED_4', - 'is_mtd': True, - 'mode': 'rn', - 'allowlist': [LEADER] - }, - } - - def test(self): - # 1 - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[DUT_ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[DUT_ROUTER1].get_state(), 'router') - - for i in MTDS: - self.nodes[i].start() - self.simulator.go(5) - - for i in MTDS: - self.assertEqual(self.nodes[i].get_state(), 'child') - - self.collect_ipaddrs() - self.collect_rlocs() - self.collect_rloc16s() - - # 2 - for MED in [MED1, MED2, MED3, MED4]: - ed_mleid = self.nodes[MED].get_ip6_address(config.ADDRESS_TYPE.ML_EID) - self.assertTrue(self.nodes[SED1].ping(ed_mleid)) - self.simulator.go(5) - - # 3 & 4 - for MED in [MED1, MED2, MED3, MED4]: - ed_mleid = self.nodes[MED].get_ip6_address(config.ADDRESS_TYPE.ML_EID) - self.assertTrue(self.nodes[SED1].ping(ed_mleid)) - self.simulator.go(5) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_RLOC16 = pv.vars['LEADER_RLOC16'] - ROUTER = pv.vars['ROUTER'] - ROUTER_RLOC = pv.vars['ROUTER_RLOC'] - SED = pv.vars['SED'] - SED_RLOC = pv.vars['SED_RLOC'] - SED_RLOC16 = pv.vars['SED_RLOC16'] - SED_MLEID = pv.vars['SED_MLEID'] - MM = pv.vars['MM_PORT'] - - # Step 1: Build the topology as described - pv.verify_attached('ROUTER') - for i in range(1, 5): - with pkts.save_index(): - pkts.filter_wpan_src64(pv.vars['MED_%d' %i]).\ - filter_wpan_dst64(LEADER).\ - filter_mle_cmd(MLE_CHILD_ID_REQUEST).\ - must_next() - pkts.filter_wpan_src64(LEADER).\ - filter_wpan_dst64(pv.vars['MED_%d' %i]).\ - filter_mle_cmd(MLE_CHILD_ID_RESPONSE).\ - must_next() - pkts.filter_wpan_src64(pv.vars['SED']).\ - filter_wpan_dst64(ROUTER).\ - filter_mle_cmd(MLE_CHILD_ID_REQUEST).\ - must_next() - pkts.filter_wpan_src64(ROUTER).\ - filter_wpan_dst64(pv.vars['SED']).\ - filter_mle_cmd(MLE_CHILD_ID_RESPONSE).\ - must_next() - - # Step 2: SED sends an ICMPv6 Echo Request to MED_1, MED_2, MED_3, MED_4 ML-EID - # The DUT MUST generate an Address Query Request on SED’s behalf - # to find each node’s RLOC. - # The Address Query Request MUST be sent to the Realm-Local - # All-Routers address (FF03::2) - # CoAP URI-Path - # - NON POST coap:// - # CoAP Payload - # - Target EID TLV - - # Step 3: Leader sends Address Notification Messages with RLOC of MED_1, MED_2, MED_3, MED_4 - for i in range(1, 5): - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(SED).\ - filter_ipv6_dst(pv.vars['MED_%d_MLEID' %i]).\ - must_next() - pkts.filter_wpan_src64(ROUTER).\ - filter_RLARMA().\ - filter_coap_request(ADDR_QRY_URI, port=MM).\ - filter(lambda p: p.thread_address.tlv.target_eid == pv.vars['MED_%d_MLEID' %i]).\ - must_next() - pkts.filter_wpan_src64(LEADER).\ - filter_ipv6_dst(ROUTER_RLOC).\ - filter_coap_request(ADDR_NTF_URI, port=MM).\ - filter(lambda p: { - NL_ML_EID_TLV, - NL_RLOC16_TLV, - NL_TARGET_EID_TLV - } <= set(p.coap.tlv.type) and\ - p.thread_address.tlv.target_eid == pv.vars['MED_%d_MLEID' %i] and\ - p.thread_address.tlv.rloc16 == LEADER_RLOC16 and\ - p.coap.code == COAP_CODE_POST - ).\ - must_next() - pkts.filter_ping_request(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER).\ - filter_ipv6_dst(pv.vars['MED_%d_MLEID' %i]).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(pv.vars['MED_%d' %i]).\ - filter_ipv6_dst(SED_MLEID).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER).\ - filter_wpan_dst16(SED_RLOC16).\ - must_next() - - # Step 4: SED sends another ICMPv6 Echo Request to MED_1, MED_2, MED_3, MED_4 ML-EID - # The DUT MUST not send an Address Query during this step; If an address query - # message is sent, the test fails - # An ICMPv6 Echo Reply MUST be sent for each ICMPv6 Echo Request from SED - for i in range(1, 5): - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(SED).\ - filter_ipv6_dst(pv.vars['MED_%d_MLEID' %i]).\ - must_next() - pkts.filter_wpan_src64(ROUTER).\ - filter_RLARMA().\ - filter_coap_request(ADDR_QRY_URI, port=MM).\ - must_not_next() - pkts.filter_ping_request(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER).\ - filter_ipv6_dst(pv.vars['MED_%d_MLEID' %i]).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(pv.vars['MED_%d' %i]).\ - filter_ipv6_dst(SED_MLEID).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER).\ - filter_wpan_dst16(SED_RLOC16).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_3_05_RoutingLinkQuality.py b/tests/scripts/thread-cert/Cert_5_3_05_RoutingLinkQuality.py deleted file mode 100755 index ce267a669..000000000 --- a/tests/scripts/thread-cert/Cert_5_3_05_RoutingLinkQuality.py +++ /dev/null @@ -1,243 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import command -import config -import thread_cert -from pktverify.packet_verifier import PacketVerifier - -LEADER = 1 -DUT_ROUTER1 = 2 -ROUTER2 = 3 -ROUTER3 = 4 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to ensure that the DUT routes traffic properly -# when link qualities between the nodes are adjusted. -# -# Test Topology: -# ------------- -# Leader -# / \ -# Router_2 - Router_1(DUT) -# | -# Router_3 -# -# DUT Types: -# ---------- -# Router - - -class Cert_5_3_5_RoutingLinkQuality(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [DUT_ROUTER1, ROUTER2] - }, - DUT_ROUTER1: { - 'name': 'ROUTER_1', - 'mode': 'rdn', - 'allowlist': [LEADER, ROUTER2, ROUTER3] - }, - ROUTER2: { - 'name': 'ROUTER_2', - 'mode': 'rdn', - 'allowlist': [LEADER, DUT_ROUTER1] - }, - ROUTER3: { - 'name': 'ROUTER_3', - 'mode': 'rdn', - 'allowlist': [DUT_ROUTER1] - }, - } - - def test(self): - # 1 - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - for router in range(DUT_ROUTER1, ROUTER3 + 1): - self.nodes[router].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - - for router in range(DUT_ROUTER1, ROUTER3 + 1): - self.assertEqual(self.nodes[router].get_state(), 'router') - - self.collect_rlocs() - self.collect_rloc16s() - - # 2 & 3 - leader_rloc = self.nodes[LEADER].get_ip6_address(config.ADDRESS_TYPE.RLOC) - self.assertTrue(self.nodes[ROUTER3].ping(leader_rloc)) - - # 4 & 5 - self.nodes[LEADER].add_allowlist(self.nodes[DUT_ROUTER1].get_addr64(), config.RSSI['LINK_QULITY_1']) - self.nodes[DUT_ROUTER1].add_allowlist(self.nodes[LEADER].get_addr64(), config.RSSI['LINK_QULITY_1']) - self.simulator.go(3 * config.MAX_ADVERTISEMENT_INTERVAL) - - self.assertTrue(self.nodes[ROUTER3].ping(leader_rloc)) - - # 6 & 7 - self.nodes[LEADER].add_allowlist(self.nodes[DUT_ROUTER1].get_addr64(), config.RSSI['LINK_QULITY_2']) - self.nodes[DUT_ROUTER1].add_allowlist(self.nodes[LEADER].get_addr64(), config.RSSI['LINK_QULITY_2']) - self.simulator.go(3 * config.MAX_ADVERTISEMENT_INTERVAL) - - self.assertTrue(self.nodes[ROUTER3].ping(leader_rloc)) - - # 8 & 9 - self.nodes[LEADER].add_allowlist(self.nodes[DUT_ROUTER1].get_addr64(), config.RSSI['LINK_QULITY_0']) - self.nodes[DUT_ROUTER1].add_allowlist(self.nodes[LEADER].get_addr64(), config.RSSI['LINK_QULITY_0']) - self.simulator.go(3 * config.MAX_ADVERTISEMENT_INTERVAL) - - self.assertTrue(self.nodes[ROUTER3].ping(leader_rloc)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_RLOC = pv.vars['LEADER_RLOC'] - LEADER_RLOC16 = pv.vars['LEADER_RLOC16'] - ROUTER_1 = pv.vars['ROUTER_1'] - ROUTER_1_RLOC = pv.vars['ROUTER_1_RLOC'] - ROUTER_1_RLOC16 = pv.vars['ROUTER_1_RLOC16'] - ROUTER_2 = pv.vars['ROUTER_2'] - ROUTER_2_RLOC16 = pv.vars['ROUTER_2_RLOC16'] - ROUTER_2_RLOC = pv.vars['ROUTER_2_RLOC'] - ROUTER_3 = pv.vars['ROUTER_3'] - ROUTER_3_RLOC = pv.vars['ROUTER_3_RLOC'] - MM = pv.vars['MM_PORT'] - - # Step 1: Ensure topology is formed correctly - for i in range(1, 4): - with pkts.save_index(): - pv.verify_attached('ROUTER_%d' % i) - - # Step 2: Modify the link quality between the DUT and the Leader to be 3 - # Step 3: Router_3 sends an ICMPv6 Echo Request to the Leader - # The ICMPv6 Echo Request MUST take the shortest path: - # Router_3 -> DUT -> Leader - # The hopsLft field of the 6LoWPAN Mesh Header MUST be greater than - # the route cost to the destination - - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(ROUTER_3).\ - filter_ipv6_dst(LEADER_RLOC).\ - must_next() - _pkt.must_verify(lambda p: p.lowpan.mesh.hops > 2) - pkts.filter_ping_request(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_1).\ - filter_wpan_dst16(LEADER_RLOC16).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(LEADER).\ - filter_ipv6_dst(ROUTER_3_RLOC).\ - must_next() - - # Step 4: Modify the link quality between the DUT and the Leader to be 1 - # Step 5: Router_3 sends an ICMPv6 Echo Request to the Leader - # The ICMPv6 Echo Request MUST take the shortest path: - # Router_3 -> DUT -> Router_2 -> Leader - # The hopsLft field of the 6LoWPAN Mesh Header MUST be greater than - # the route cost to the destination - - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(ROUTER_3).\ - filter_ipv6_dst(LEADER_RLOC).\ - must_next() - _pkt.must_verify(lambda p: p.lowpan.mesh.hops > 3) - pkts.filter_ping_request(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_1).\ - filter_wpan_dst16(ROUTER_2_RLOC16).\ - must_next() - pkts.filter_ping_request(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_2).\ - filter_wpan_dst16(LEADER_RLOC16).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(LEADER).\ - filter_ipv6_dst(ROUTER_3_RLOC).\ - must_next() - - # Step 6: Modify the link quality between the DUT and the Leader to be 2 - # Step 7: Router_3 sends an ICMPv6 Echo Request to the Leader - # The ICMPv6 Echo Request MUST take the shortest path: - # Router_3 -> DUT -> Leader - # The hopsLft field of the 6LoWPAN Mesh Header MUST be greater than - # the route cost to the destination - - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(ROUTER_3).\ - filter_ipv6_dst(LEADER_RLOC).\ - must_next() - _pkt.must_verify(lambda p: p.lowpan.mesh.hops > 2) - pkts.filter_ping_request(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_1).\ - filter_wpan_dst16(LEADER_RLOC16).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(LEADER).\ - filter_ipv6_dst(ROUTER_3_RLOC).\ - must_next() - - # Step 8: Modify the link quality between the DUT and the Leader to be 0 - # Step 9: Router_3 sends an ICMPv6 Echo Request to the Leader - # The ICMPv6 Echo Request MUST take the shortest path: - # Router_3 -> DUT -> Router_2 -> Leader - # The hopsLft field of the 6LoWPAN Mesh Header MUST be greater than - # the route cost to the destination - - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(ROUTER_3).\ - filter_ipv6_dst(LEADER_RLOC).\ - must_next() - _pkt.must_verify(lambda p: p.lowpan.mesh.hops > 3) - pkts.filter_ping_request(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_1).\ - filter_wpan_dst16(ROUTER_2_RLOC16).\ - must_next() - pkts.filter_ping_request(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_2).\ - filter_wpan_dst16(LEADER_RLOC16).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(LEADER).\ - filter_ipv6_dst(ROUTER_3_RLOC).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_3_06_RouterIdMask.py b/tests/scripts/thread-cert/Cert_5_3_06_RouterIdMask.py deleted file mode 100755 index 97455af05..000000000 --- a/tests/scripts/thread-cert/Cert_5_3_06_RouterIdMask.py +++ /dev/null @@ -1,229 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import thread_cert -from pktverify.consts import MLE_ADVERTISEMENT, MLE_CHILD_ID_REQUEST, MLE_CHILD_ID_RESPONSE -from pktverify.packet_verifier import PacketVerifier - -DUT_LEADER = 1 -ROUTER1 = 2 -ROUTER2 = 3 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to verify that the router ID mask is managed -# correctly, as the connectivity to a router or group of routers is lost and / or -# a new router is added to network. -# -# Test Topology: -# ------------- -# Leader(DUT) -# | -# Router_1 -# | -# Router_2 -# -# DUT Types: -# ---------- -# Leader - - -class Cert_5_3_6_RouterIdMask(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - DUT_LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [ROUTER1] - }, - ROUTER1: { - 'name': 'ROUTER_1', - 'mode': 'rdn', - 'allowlist': [DUT_LEADER, ROUTER2] - }, - ROUTER2: { - 'name': 'ROUTER_2', - 'mode': 'rdn', - 'allowlist': [ROUTER1] - }, - } - - def _setUpRouter2(self): - self.nodes[ROUTER2].add_allowlist(self.nodes[ROUTER1].get_addr64()) - self.nodes[ROUTER2].enable_allowlist() - self.nodes[ROUTER2].set_router_selection_jitter(1) - - def test(self): - # 1 - self.nodes[DUT_LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[DUT_LEADER].get_state(), 'leader') - - self.nodes[ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - - self.nodes[ROUTER2].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER2].get_state(), 'router') - - self.collect_rloc16s() - - # Wait DUT_LEADER to establish routing to ROUTER2 via ROUTER1's MLE - # advertisement. - self.simulator.go(config.MAX_ADVERTISEMENT_INTERVAL) - - # 2 - self.nodes[ROUTER2].reset() - self._setUpRouter2() - - # 3 & 4 - - self.simulator.go(720) - - # 5 - - self.nodes[ROUTER2].start() - self.simulator.go(config.ROUTER_RESET_DELAY) - self.assertEqual(self.nodes[ROUTER2].get_state(), 'router') - - self.simulator.go(config.MAX_ADVERTISEMENT_INTERVAL) - - # 6 - self.nodes[ROUTER1].reset() - self.nodes[ROUTER2].reset() - - self.simulator.go(720) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - ROUTER_1 = pv.vars['ROUTER_1'] - ROUTER_2 = pv.vars['ROUTER_2'] - - leader_rid = pv.vars['LEADER_RLOC16'] >> 10 - router_1_rid = pv.vars['ROUTER_1_RLOC16'] >> 10 - router_2_rid = pv.vars['ROUTER_2_RLOC16'] >> 10 - - # Step 1: Ensure topology is formed correctly - pv.verify_attached('ROUTER_1', 'LEADER') - pv.verify_attached('ROUTER_2', 'ROUTER_1') - - pkts.filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - filter(lambda p: - {1,2,1} == set(p.mle.tlv.route64.cost) and\ - {leader_rid, router_1_rid, router_2_rid} == - p.mle.tlv.route64.id_mask - ).\ - must_next() - - # Step 4: The DUT’s routing cost to Router_2 MUST count to infinity - # The DUT MUST remove Router_2 ID from its ID set - # Verify route data has settled - _pkt = pkts.filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - filter(lambda p: {1,0,1} == set(p.mle.tlv.route64.cost)).\ - must_next() - pkts.filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - filter(lambda p: - {1,1} == set(p.mle.tlv.route64.cost) and\ - {leader_rid, router_1_rid} == - p.mle.tlv.route64.id_mask - ).\ - must_next() - - # Step 5: Re-attach Router_2 to Router_1. - # The DUT MUST reset the MLE Advertisement trickle timer and - # send an Advertisement - pv.verify_attached('ROUTER_2', 'ROUTER_1') - # check trickle timer between the successive advertisements - with pkts.save_index(): - _pkt = pkts.filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - must_next() - # Time between MLE Advertisements after reset can be up to 3.5 seconds - # 0.0s: Reset Interval, reset interval to 1 seconds, random interval at 0.5 second - # 0.5s: Transmit MLE Advertisement - # 1.0s: Set interval to 2 seconds, random interval at 2 seconds - # 3.0s: Receive MLE Advertisement, reset interval to 1 second, random interval at 1.0 second - # 4.0s: Transmit MLE Advertisement - pkts.filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - filter(lambda p: p.sniff_timestamp - _pkt.sniff_timestamp <= 4).\ - must_next() - - # check router cost after the re-attach - pkts.filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - filter(lambda p: {1,2,1} == set(p.mle.tlv.route64.cost) and\ - {leader_rid, router_1_rid, router_2_rid} == - p.mle.tlv.route64.id_mask - ).\ - must_next() - - # Step 6: The DUT’s routing cost to Router_1 MUST go directly to - # infinity as there is no multi-hop cost for Router_1 - # The DUT MUST remove Router_1 & Router_2 IDs from its ID set - pkts.filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - filter(lambda p: {0, 0, 1} == set(p.mle.tlv.route64.cost)).\ - must_next() - pkts.filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - filter(lambda p: {0, 1} == set(p.mle.tlv.route64.cost)).\ - must_next() - pkts.filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - filter(lambda p: - [1] == p.mle.tlv.route64.cost and\ - {leader_rid} == - p.mle.tlv.route64.id_mask - ).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_3_07_DuplicateAddress.py b/tests/scripts/thread-cert/Cert_5_3_07_DuplicateAddress.py deleted file mode 100755 index 7a1cb77bf..000000000 --- a/tests/scripts/thread-cert/Cert_5_3_07_DuplicateAddress.py +++ /dev/null @@ -1,218 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import command -import config -import copy -import mle -import thread_cert -from pktverify.consts import WIRESHARK_OVERRIDE_PREFS, ADDR_ERR_URI, ADDR_QRY_URI, ADDR_NTF_URI, MLE_CHILD_ID_REQUEST, MLE_CHILD_ID_RESPONSE, REALM_LOCAL_ALL_ROUTERS_ADDRESS, NL_TARGET_EID_TLV, NL_RLOC16_TLV, NL_ML_EID_TLV -from pktverify.packet_verifier import PacketVerifier - -DUT_LEADER = 1 -ROUTER1 = 2 -ROUTER2 = 3 -MED1 = 4 -SED1 = 5 -MED2 = 6 - -MTDS = [MED1, SED1, MED2] -ON_MESH_PREFIX = '2001::/64' -IPV6_ADDR = '2001::1234' - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to validate the DUT’s ability to perform -# duplicate address detection. -# -# Test Topology: -# ------------- -# MED_2 - Leader(DUT) -# / \ -# Router_1 Router_2 -# | | -# MED_1 SED -# -# DUT Types: -# ---------- -# Leader - - -class Cert_5_3_7_DuplicateAddress(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - DUT_LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [ROUTER1, ROUTER2, MED2] - }, - ROUTER1: { - 'name': 'ROUTER_1', - 'mode': 'rdn', - 'allowlist': [DUT_LEADER, MED1] - }, - ROUTER2: { - 'name': 'ROUTER_2', - 'mode': 'rdn', - 'allowlist': [DUT_LEADER, SED1] - }, - MED1: { - 'name': 'MED_1', - 'is_mtd': True, - 'mode': 'rn', - 'allowlist': [ROUTER1] - }, - SED1: { - 'name': 'SED', - 'is_mtd': True, - 'mode': '-', - 'allowlist': [ROUTER2] - }, - MED2: { - 'name': 'MED_2', - 'is_mtd': True, - 'mode': 'rn', - 'allowlist': [DUT_LEADER] - }, - } - - # override wireshark preferences with case needed parameters - CASE_WIRESHARK_PREFS = copy.deepcopy(WIRESHARK_OVERRIDE_PREFS) - CASE_WIRESHARK_PREFS['6lowpan.context1'] = ON_MESH_PREFIX - - def test(self): - self.nodes[DUT_LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[DUT_LEADER].get_state(), 'leader') - - for i in range(ROUTER1, MED2 + 1): - self.nodes[i].start() - self.simulator.go(5) - - for i in [ROUTER1, ROUTER2]: - self.assertEqual(self.nodes[i].get_state(), 'router') - - for i in MTDS: - self.assertEqual(self.nodes[i].get_state(), 'child') - - self.collect_ipaddrs() - self.collect_rlocs() - - self.nodes[ROUTER2].add_prefix(ON_MESH_PREFIX, 'paros') - self.nodes[ROUTER2].register_netdata() - - self.nodes[MED1].add_ipaddr(IPV6_ADDR) - self.nodes[SED1].add_ipaddr(IPV6_ADDR) - self.simulator.go(5) - - self.nodes[MED2].ping(IPV6_ADDR) - self.simulator.go(5) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_RLOC = pv.vars['LEADER_RLOC'] - ROUTER_1 = pv.vars['ROUTER_1'] - ROUTER_2 = pv.vars['ROUTER_2'] - MED_1 = pv.vars['MED_1'] - MED_2 = pv.vars['MED_2'] - SED = pv.vars['SED'] - MM = pv.vars['MM_PORT'] - - # Step 1: Ensure topology is formed correctly - for i in (1, 2): - pv.verify_attached('ROUTER_%d' % i, 'LEADER') - pv.verify_attached('MED_1', 'ROUTER_1', 'MTD') - pv.verify_attached('SED', 'ROUTER_2', 'MTD') - pv.verify_attached('MED_2', 'LEADER', 'MTD') - - # Step 5: MED_2 sends ICMPv6 Echo Request to address configured on MED_1 - # and SED_1 with Prefix 2001:: - # The DUT MUST multicast an Address Query message to the Realm-Local - # All Routers address (FF03::2): - # CoAP URI-Path - # - NON POST coap:// - # CoAP Payload - # - Target EID TLV - - pkts.filter_ping_request().\ - filter_wpan_src64(MED_2). \ - filter_ipv6_dst(IPV6_ADDR). \ - must_next() - pkts.filter_wpan_src64(LEADER).\ - filter_RLARMA().\ - filter_coap_request(ADDR_QRY_URI, port=MM).\ - filter(lambda p: p.thread_address.tlv.target_eid == IPV6_ADDR).\ - must_next() - - # Step 6: Router_1 & Router_2 respond with Address Notification message - # with matching Target TLVs - - for i in (1, 2): - with pkts.save_index(): - pkts.filter_wpan_src64(pv.vars['ROUTER_%d' %i]).\ - filter_ipv6_dst(LEADER_RLOC).\ - filter_coap_request(ADDR_NTF_URI, port=MM).\ - filter(lambda p: { - NL_ML_EID_TLV, - NL_RLOC16_TLV, - NL_TARGET_EID_TLV - } <= set(p.coap.tlv.type) and\ - p.thread_address.tlv.target_eid == IPV6_ADDR - ).\ - must_next() - - # Step 7: The DUT MUST multicast an Address Error Notification to the Realm-Local - # All Routers address (FF03::2): - # CoAP URI-Path - # - NON POST coap://[]:MM/a/ae - # CoAP Payload - # - Target EID TLV - # - ML-EID TLV - # - # The IPv6 Source address MUST be the RLOC of the originator - - pkts.filter_ipv6_src_dst(LEADER_RLOC, REALM_LOCAL_ALL_ROUTERS_ADDRESS).\ - filter_coap_request(ADDR_ERR_URI, port=MM).\ - filter(lambda p: { - NL_ML_EID_TLV, - NL_TARGET_EID_TLV - } <= set(p.coap.tlv.type) and\ - p.thread_address.tlv.target_eid == IPV6_ADDR - ).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_3_08_ChildAddressSet.py b/tests/scripts/thread-cert/Cert_5_3_08_ChildAddressSet.py deleted file mode 100755 index c1d4f4be8..000000000 --- a/tests/scripts/thread-cert/Cert_5_3_08_ChildAddressSet.py +++ /dev/null @@ -1,222 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import command -import config -import copy -import ipv6 -import mle -import thread_cert -from pktverify.consts import WIRESHARK_OVERRIDE_PREFS, MLE_ADVERTISEMENT, ADDR_QRY_URI, SOURCE_ADDRESS_TLV, ROUTE64_TLV, LEADER_DATA_TLV -from pktverify.packet_verifier import PacketVerifier -from pktverify.bytes import Bytes - -DUT_LEADER = 1 -BR = 2 -MED1 = 3 -MED2 = 4 - -MTDS = [MED1, MED2] - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to validate that the DUT MTD Child Address Set -# can hold at least 4 IPv6 non-link-local addresses. -# -# Test Topology: -# ------------- -# MED_1 -# | -# BR - Leader(DUT) - MED_2 -# -# DUT Types: -# ---------- -# Leader - - -class Cert_5_3_8_ChildAddressSet(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - DUT_LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [BR, MED1, MED2] - }, - BR: { - 'mode': 'rdn', - 'allowlist': [DUT_LEADER] - }, - MED1: { - 'name': 'MED_1', - 'is_mtd': True, - 'mode': 'rn', - 'allowlist': [DUT_LEADER] - }, - MED2: { - 'name': 'MED_2', - 'is_mtd': True, - 'mode': 'rn', - 'allowlist': [DUT_LEADER] - }, - } - # override wireshark preferences with case needed parameters - CASE_WIRESHARK_PREFS = copy.deepcopy(WIRESHARK_OVERRIDE_PREFS) - CASE_WIRESHARK_PREFS['6lowpan.context1'] = '2001::/64' - CASE_WIRESHARK_PREFS['6lowpan.context2'] = '2002::/64' - CASE_WIRESHARK_PREFS['6lowpan.context3'] = '2003::/64' - - def test(self): - self.nodes[DUT_LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[DUT_LEADER].get_state(), 'leader') - - self.nodes[BR].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[BR].get_state(), 'router') - - # 1 BR: Configure BR to be a DHCPv6 server - self.nodes[BR].add_prefix('2001::/64', 'pdros') - self.nodes[BR].add_prefix('2002::/64', 'pdros') - self.nodes[BR].add_prefix('2003::/64', 'pdros') - self.nodes[BR].register_netdata() - - # 3 MED1, MED2: MED1 and MED2 attach to DUT_LEADER - for i in MTDS: - self.nodes[i].start() - self.simulator.go(5) - self.assertEqual(self.nodes[i].get_state(), 'child') - self.collect_ipaddrs() - - # 4 MED1: MED1 send an ICMPv6 Echo Request to the MED2 ML-EID - med2_ml_eid = self.nodes[MED2].get_ip6_address(config.ADDRESS_TYPE.ML_EID) - self.assertTrue(med2_ml_eid is not None) - self.assertTrue(self.nodes[MED1].ping(med2_ml_eid)) - - # Wait for sniffer got packets - self.simulator.go(1) - - # 5 MED1: MED1 send an ICMPv6 Echo Request to the MED2 2001::GUA - addr = self.nodes[MED2].get_addr("2001::/64") - self.assertTrue(addr is not None) - self.assertTrue(self.nodes[MED1].ping(addr)) - # Wait for sniffer got packets - self.simulator.go(1) - - # 6 MED1: MED1 send an ICMPv6 Echo Request to the MED2 2002::GUA - addr = self.nodes[MED2].get_addr("2002::/64") - self.assertTrue(addr is not None) - self.assertTrue(self.nodes[MED1].ping(addr)) - - # Wait for sniffer got packets - self.simulator.go(1) - - # 7 MED1: MED1 send an ICMPv6 Echo Request to the MED2 2003::GUA - addr = self.nodes[MED2].get_addr("2003::/64") - self.assertTrue(addr is not None) - self.assertTrue(self.nodes[MED1].ping(addr)) - - # Wait for sniffer got packets - self.simulator.go(1) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - MED_1 = pv.vars['MED_1'] - MED_1_MLEID = pv.vars['MED_1_MLEID'] - MED_2 = pv.vars['MED_2'] - MED_2_MLEID = pv.vars['MED_2_MLEID'] - MED_1_GUA = list() - MED_2_GUA = list() - MM = pv.vars['MM_PORT'] - names = locals() - - for i in (1, 2): - for addr in pv.vars['MED_%d_IPADDRS' % i]: - for j in range(1, 4): - if addr.startswith(Bytes('200%d' % j)): - names['MED_' + str(i) + '_GUA'].append(addr) - - # Step 2: Leader is sending properly formatted MLE Advertisements. - # Advertisements MUST be sent with an IP hop limit of 255 to - # the Link-Local All Nodes multicast address (FF02::1). - # The following TLVs MUST be present in the MLE Advertisements: - # - Leader Data TLV - # - Route64 TLV - # - Source Address TLV - - pkts.filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_ADVERTISEMENT).\ - filter(lambda p: { - LEADER_DATA_TLV, - ROUTE64_TLV, - SOURCE_ADDRESS_TLV - } <= set(p.mle.tlv.type) and\ - p.ipv6.hlim == 255).\ - must_next() - - # Step 3: Send a ICMPv6 Echo Request to the MED_2 ML-EID - # The DUT MUST NOT send an Address Query Request - # MED_2 MUST respond with an ICMPv6 Echo Reply - - _pkt = pkts.filter_ipv6_src_dst(MED_1_MLEID, MED_2_MLEID).\ - filter_ping_request().\ - must_next() - pkts.filter_wpan_src64(LEADER).\ - filter_RLARMA().\ - filter_coap_request(ADDR_QRY_URI, port=MM).\ - must_not_next() - pkts.filter_ipv6_src_dst(MED_2_MLEID, MED_1_MLEID).\ - filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - must_next() - - # Step 4-6: Send a ICMPv6 Echo Request to the MED_2 each GUA - # The DUT MUST NOT send an Address Query Request - # MED_2 MUST respond with an ICMPv6 Echo Reply - - for med_1_addr, med_2_addr in zip(MED_1_GUA, MED_2_GUA): - _pkt = pkts.filter_ipv6_src_dst(med_1_addr, med_2_addr).\ - filter_ping_request().\ - must_next() - pkts.filter_wpan_src64(LEADER).\ - filter_RLARMA().\ - filter_coap_request(ADDR_QRY_URI, port=MM).\ - must_not_next() - pkts.filter_ipv6_src_dst(med_2_addr, med_1_addr).\ - filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_3_09_AddressQuery.py b/tests/scripts/thread-cert/Cert_5_3_09_AddressQuery.py deleted file mode 100755 index 74608b38b..000000000 --- a/tests/scripts/thread-cert/Cert_5_3_09_AddressQuery.py +++ /dev/null @@ -1,328 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import copy -import unittest - -import command -import config -import copy -import ipv6 -import thread_cert -from pktverify.consts import WIRESHARK_OVERRIDE_PREFS, ADDR_QRY_URI, ADDR_NTF_URI, NL_ML_EID_TLV, NL_RLOC16_TLV, NL_TARGET_EID_TLV -from pktverify.packet_verifier import PacketVerifier -from pktverify.bytes import Bytes - -LEADER = 1 -ROUTER1 = 2 -DUT_ROUTER2 = 3 -ROUTER3 = 4 -SED1 = 5 -PREFIX_1 = '2001::/64' -GUA_1_START = '2001' -PREFIX_2 = '2002::/64' - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to validate that the DUT is able to generate -# Address Query and Address Notification messages properly. -# The Leader is configured as a Border Router with DHCPv6 server for prefixes -# 2001:: & 2002:: -# -# Test Topology: -# ------------- -# Router_1 - Leader -# / \ -# Router_3 Router_2(DUT) -# | -# SED -# -# DUT Types: -# ---------- -# Router - - -class Cert_5_3_09_AddressQuery(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [ROUTER1, DUT_ROUTER2, ROUTER3] - }, - ROUTER1: { - 'name': 'ROUTER_1', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - DUT_ROUTER2: { - 'name': 'ROUTER_2', - 'mode': 'rdn', - 'allowlist': [LEADER, SED1] - }, - ROUTER3: { - 'name': 'ROUTER_3', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - SED1: { - 'name': 'SED', - 'is_mtd': True, - 'mode': '-', - 'timeout': config.DEFAULT_CHILD_TIMEOUT, - 'allowlist': [DUT_ROUTER2] - }, - } - - # override wireshark preferences with case needed parameters - CASE_WIRESHARK_PREFS = copy.deepcopy(WIRESHARK_OVERRIDE_PREFS) - CASE_WIRESHARK_PREFS['6lowpan.context1'] = PREFIX_1 - CASE_WIRESHARK_PREFS['6lowpan.context2'] = PREFIX_2 - - def test(self): - # 1 & 2 ALL: Build and verify the topology - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - # Configure the LEADER to be a DHCPv6 Border Router for prefixes - self.nodes[LEADER].add_prefix(PREFIX_1, 'pdros') - self.nodes[LEADER].add_prefix(PREFIX_2, 'pdro') - self.nodes[LEADER].register_netdata() - - self.nodes[ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - - self.nodes[DUT_ROUTER2].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[DUT_ROUTER2].get_state(), 'router') - - self.nodes[ROUTER3].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER3].get_state(), 'router') - - self.nodes[SED1].start() - self.simulator.go(5) - self.assertEqual(self.nodes[SED1].get_state(), 'child') - - self.collect_rlocs() - self.collect_rloc16s() - self.collect_ipaddrs() - - # 3 SED1: The SED1 sends an ICMPv6 Echo Request to ROUTER3 using GUA - # PREFIX_1 address - router3_addr = self.nodes[ROUTER3].get_addr(PREFIX_1) - self.assertTrue(router3_addr is not None) - self.assertTrue(self.nodes[SED1].ping(router3_addr)) - - # 4 ROUTER1: ROUTER1 sends an ICMPv6 Echo Request to the SED1 using GUA - # PREFIX_1 address - sed1_addr = self.nodes[SED1].get_addr(PREFIX_1) - self.assertTrue(sed1_addr is not None) - self.assertTrue(self.nodes[ROUTER1].ping(sed1_addr)) - self.simulator.go(1) - - # 5 SED1: SED1 sends an ICMPv6 Echo Request to the ROUTER3 using GUA - # PREFIX_1 address - self.assertTrue(self.nodes[SED1].ping(router3_addr)) - self.simulator.go(1) - - # 6 DUT_ROUTER2: Power off ROUTER3 and wait 580s to allow LEADER to - # expire its Router ID - self.nodes[ROUTER3].stop() - self.simulator.go(580) - - # The SED1 sends an ICMPv6 Echo Request to ROUTER3 GUA PREFIX_1 address - self.assertFalse(self.nodes[SED1].ping(router3_addr)) - self.simulator.go(1) - - # 7 SED1: Power off SED1 and wait to allow DUT_ROUTER2 to timeout the - # child - self.nodes[SED1].stop() - self.simulator.go(3) - self.simulator.go(config.DEFAULT_CHILD_TIMEOUT) - - # ROUTER1 sends two ICMPv6 Echo Requests to SED1 GUA PREFIX_1 address - self.assertFalse(self.nodes[ROUTER1].ping(sed1_addr)) - self.assertFalse(self.nodes[ROUTER1].ping(sed1_addr)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - ROUTER_1 = pv.vars['ROUTER_1'] - ROUTER_1_RLOC = pv.vars['ROUTER_1_RLOC'] - ROUTER_2 = pv.vars['ROUTER_2'] - ROUTER_2_RLOC = pv.vars['ROUTER_2_RLOC'] - ROUTER_2_RLOC16 = pv.vars['ROUTER_2_RLOC16'] - ROUTER_3 = pv.vars['ROUTER_3'] - SED = pv.vars['SED'] - SED_RLOC16 = pv.vars['SED_RLOC16'] - MM = pv.vars['MM_PORT'] - GUA1 = {} - - for node in ('ROUTER_1', 'ROUTER_3', 'SED'): - for addr in pv.vars['%s_IPADDRS' % node]: - if addr.startswith(Bytes(GUA_1_START)): - GUA1[node] = addr - - # Step 1: Build the topology as described - - for i in range(1, 4): - pv.verify_attached('ROUTER_%d' % i, 'LEADER') - pv.verify_attached('SED', 'ROUTER_2', 'MTD') - - # Step 2: SED sends an ICMPv6 Echo Request to Router_3 using GUA 2001:: - # address - # The DUT MUST generate an Address Query Request on SED’s behalf - # to find each node’s RLOC. - # The Address Query Request MUST be sent to the Realm-Local - # All-Routers address (FF03::2) - # CoAP URI-Path - # - NON POST coap:// - # CoAP Payload - # - Target EID TLV - # The DUT MUST receive and process the incoming Address Query - # Response and forward the ICMPv6 Echo Reply packet to SED - - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(SED).\ - filter_ipv6_dst(GUA1['ROUTER_3']).\ - must_next() - pkts.filter_wpan_src64(ROUTER_2).\ - filter_RLARMA().\ - filter_coap_request(ADDR_QRY_URI, port=MM).\ - filter(lambda p: p.thread_address.tlv.target_eid == GUA1['ROUTER_3']).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_3).\ - filter_ipv6_dst(GUA1['SED']).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_2).\ - filter_wpan_dst16(SED_RLOC16).\ - must_next() - - # Step 3: Router_1 sends an ICMPv6 Echo Request to SED using GUA 2001:: - # address - # The DUT MUST respond to the Address Query Request with a properly - # formatted Address Notification Message: - # CoAP URI-Path - # - CON POST coap://[
]:MM/a/an - # CoAP Payload - # - ML-EID TLV - # - RLOC16 TLV - # - Target EID TLV - # The IPv6 Source address MUST be the RLOC of the originator - # The IPv6 Destination address MUST be the RLOC of the destination - - pkts.filter_wpan_src64(ROUTER_1).\ - filter_RLARMA().\ - filter_coap_request(ADDR_QRY_URI, port=MM).\ - filter(lambda p: p.thread_address.tlv.target_eid == GUA1['SED']).\ - must_next() - pkts.filter_ipv6_src_dst(ROUTER_2_RLOC, ROUTER_1_RLOC).\ - filter_coap_request(ADDR_NTF_URI, port=MM).\ - filter(lambda p: { - NL_ML_EID_TLV, - NL_RLOC16_TLV, - NL_TARGET_EID_TLV - } <= set(p.coap.tlv.type) and\ - p.thread_address.tlv.target_eid == GUA1['SED'] and\ - p.thread_address.tlv.rloc16 == ROUTER_2_RLOC16 - ).\ - must_next() - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(ROUTER_1).\ - filter_ipv6_dst(GUA1['SED']).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(SED).\ - filter_ipv6_dst(GUA1['ROUTER_1']).\ - must_next() - - # Step 5: SED sends an ICMPv6 Echo Request to Router_3 using GUA 2001:: - # address - # The DUT MUST not send an Address Query as Router_3 address should - # be cached. - # The DUT MUST forward the ICMPv6 Echo Reply to SED - - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(SED).\ - filter_ipv6_dst(GUA1['ROUTER_3']).\ - must_next() - lstart = pkts.index - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_3).\ - filter_ipv6_dst(GUA1['SED']).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_2).\ - filter_wpan_dst16(SED_RLOC16).\ - must_next() - lend = pkts.index - pkts.range(lstart, lend).filter_wpan_src64(ROUTER_2).\ - filter_RLARMA().\ - filter_coap_request(ADDR_QRY_URI, port=MM).\ - must_not_next() - - # Step 6: SED sends an ICMPv6 Echo Request to Router_3 using GUA 2001:: - # address - # The DUT MUST update its address cache and remove all entries - # based on Router_3’s Router ID. - # The DUT MUST send an Address Query to discover Router_3’s RLOC address. - pkts.filter_ping_request().\ - filter_wpan_src64(SED).\ - filter_ipv6_dst(GUA1['ROUTER_3']).\ - must_next() - pkts.filter_wpan_src64(ROUTER_2).\ - filter_RLARMA().\ - filter_coap_request(ADDR_QRY_URI, port=MM).\ - filter(lambda p: p.thread_address.tlv.target_eid == GUA1['ROUTER_3']).\ - must_next() - - # Step 7: Router_1 sends two ICMPv6 Echo Requests to SED using GUA 2001:: - # address - # The DUT MUST NOT respond with an Address Notification message - - pkts.filter_wpan_src64(ROUTER_2).\ - filter_ipv6_dst(ROUTER_1_RLOC).\ - filter_coap_request(ADDR_NTF_URI, port=MM).\ - must_not_next() - pkts.filter_ping_request().\ - filter_wpan_src64(ROUTER_1).\ - filter_ipv6_dst(GUA1['SED']).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_3_10_AddressQuery.py b/tests/scripts/thread-cert/Cert_5_3_10_AddressQuery.py deleted file mode 100755 index 8a6354804..000000000 --- a/tests/scripts/thread-cert/Cert_5_3_10_AddressQuery.py +++ /dev/null @@ -1,335 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import copy -import unittest - -import command -import config -import copy -import ipv6 -import thread_cert -from pktverify.consts import WIRESHARK_OVERRIDE_PREFS, ADDR_QRY_URI, ADDR_NTF_URI, NL_ML_EID_TLV, NL_RLOC16_TLV, NL_TARGET_EID_TLV -from pktverify.packet_verifier import PacketVerifier -from pktverify.bytes import Bytes -from pktverify.addrs import Ipv6Addr - -LEADER = 1 -BR = 2 -ROUTER1 = 3 -DUT_ROUTER2 = 4 -MED1 = 5 - -PREFIX_1 = '2003::/64' -GUA_1_START = '2003' -PREFIX_2 = '2004::/64' - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to validate that the DUT is able to generate -# Address Query and Address Notification messages -# The Border Router is configured as a SLAAC server for prefixes 2003:: & 2004:: -# -# Test Topology: -# ------------- -# BorderRouter - Leader -# / \ -# Router_1 - Router_2(DUT) -# | -# MED -# -# DUT Types: -# ---------- -# Router - - -class Cert_5_3_10_AddressQuery(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - SUPPORT_NCP = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [BR, ROUTER1, DUT_ROUTER2] - }, - BR: { - 'name': 'BR', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - ROUTER1: { - 'name': 'ROUTER_1', - 'mode': 'rdn', - 'allowlist': [LEADER, DUT_ROUTER2] - }, - DUT_ROUTER2: { - 'name': 'ROUTER_2', - 'mode': 'rdn', - 'allowlist': [LEADER, ROUTER1, MED1] - }, - MED1: { - 'name': 'MED', - 'is_mtd': True, - 'mode': 'rn', - 'allowlist': [DUT_ROUTER2] - }, - } - # override wireshark preferences with case needed parameters - CASE_WIRESHARK_PREFS = copy.deepcopy(WIRESHARK_OVERRIDE_PREFS) - CASE_WIRESHARK_PREFS['6lowpan.context1'] = PREFIX_1 - CASE_WIRESHARK_PREFS['6lowpan.context2'] = PREFIX_2 - - def test(self): - # 1 & 2 - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[BR].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[BR].get_state(), 'router') - - # Configure two On-Mesh Prefixes on the BR - self.nodes[BR].add_prefix(PREFIX_1, 'paros') - self.nodes[BR].add_prefix(PREFIX_2, 'paros') - self.nodes[BR].register_netdata() - - self.nodes[DUT_ROUTER2].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[DUT_ROUTER2].get_state(), 'router') - - self.nodes[ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - - self.nodes[MED1].start() - self.simulator.go(5) - self.assertEqual(self.nodes[MED1].get_state(), 'child') - - self.collect_rlocs() - self.collect_rloc16s() - self.collect_ipaddrs() - - # 3 MED1: MED1 sends an ICMPv6 Echo Request to Router1 using GUA - # PREFIX_1 address - router1_addr = self.nodes[ROUTER1].get_addr(PREFIX_1) - self.assertTrue(router1_addr is not None) - self.assertTrue(self.nodes[MED1].ping(router1_addr)) - self.simulator.go(1) - - # 4 BR: BR sends an ICMPv6 Echo Request to MED1 using GUA PREFIX_1 - # address - med1_addr = self.nodes[MED1].get_addr(PREFIX_1) - self.assertTrue(med1_addr is not None) - self.assertTrue(self.nodes[BR].ping(med1_addr)) - self.simulator.go(1) - - # 5 MED1: MED1 sends an ICMPv6 Echo Request to ROUTER1 using GUA PREFIX_1 - # address - self.assertTrue(self.nodes[MED1].ping(router1_addr)) - self.simulator.go(1) - - # 6 DUT_ROUTER2: Power off ROUTER1 and wait 580 seconds to allow the - # LEADER to expire its Router ID - router1_id = self.nodes[ROUTER1].get_router_id() - self.nodes[ROUTER1].stop() - self.simulator.go(580) - - # Send an ICMPv6 Echo Request from MED1 to ROUTER1 GUA PREFIX_1 address - self.assertFalse(self.nodes[MED1].ping(router1_addr)) - self.simulator.go(1) - - # 7 MED1: Power off MED1 and wait to allow DUT_ROUTER2 to timeout the - # child - self.nodes[MED1].stop() - self.simulator.go(config.MLE_END_DEVICE_TIMEOUT) - - # BR sends two ICMPv6 Echo Requests to MED1 GUA PREFIX_1 address - self.assertFalse(self.nodes[BR].ping(med1_addr)) - self.assertFalse(self.nodes[BR].ping(med1_addr)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - ROUTER_1 = pv.vars['ROUTER_1'] - ROUTER_2 = pv.vars['ROUTER_2'] - ROUTER_2_RLOC = pv.vars['ROUTER_2_RLOC'] - ROUTER_2_RLOC16 = pv.vars['ROUTER_2_RLOC16'] - BR = pv.vars['BR'] - BR_RLOC = pv.vars['BR_RLOC'] - MED = pv.vars['MED'] - MED_RLOC16 = pv.vars['MED_RLOC16'] - MM = pv.vars['MM_PORT'] - GUA1 = {} - - for node in ('ROUTER_1', 'BR', 'MED'): - for addr in pv.vars['%s_IPADDRS' % node]: - if addr.startswith(Bytes(GUA_1_START)): - GUA1[node] = addr - - # Step 2: Build the topology as described - - pv.verify_attached('BR', 'LEADER') - for i in (2, 1): - pv.verify_attached('ROUTER_%d' % i, 'LEADER') - pv.verify_attached('MED', 'ROUTER_2', 'MTD') - - # Step 3: MED sends an ICMPv6 Echo Request to Router_1 using GUA 2003:: - # address - # The DUT MUST generate an Address Query Request on MED’s behalf - # to find each node’s RLOC. - # The Address Query Request MUST be sent to the Realm-Local - # All-Routers address (FF03::2) - # CoAP URI-Path - # - NON POST coap:// - # CoAP Payload - # - Target EID TLV - # The DUT MUST receive and process the incoming Address Query - # Response and forward the ICMPv6 Echo Request packet to Router_1 - - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(MED).\ - filter_ipv6_dst(GUA1['ROUTER_1']).\ - must_next() - pkts.filter_wpan_src64(ROUTER_2).\ - filter_RLARMA().\ - filter_coap_request(ADDR_QRY_URI, port=MM).\ - filter(lambda p: p.thread_address.tlv.target_eid == GUA1['ROUTER_1']).\ - must_next() - pkts.filter_ping_request(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_2).\ - filter_ipv6_dst(GUA1['ROUTER_1']).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_1).\ - filter_ipv6_dst(GUA1['MED']).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_2).\ - filter_wpan_dst16(MED_RLOC16).\ - must_next() - - # Step 4: Border Router sends an ICMPv6 Echo Request to MED using GUA 2003:: - # address - # The DUT MUST respond to the Address Query Request with a properly - # formatted Address Notification Message: - # CoAP URI-Path - # - CON POST coap://[
]:MM/a/an - # CoAP Payload - # - ML-EID TLV - # - RLOC16 TLV - # - Target EID TLV - # The IPv6 Source address MUST be the RLOC of the originator - # The IPv6 Destination address MUST be the RLOC of the destination - - pkts.filter_wpan_src64(BR).\ - filter_RLARMA().\ - filter_coap_request(ADDR_QRY_URI, port=MM).\ - filter(lambda p: p.thread_address.tlv.target_eid == GUA1['MED']).\ - must_next() - pkts.filter_ipv6_src_dst(ROUTER_2_RLOC, BR_RLOC).\ - filter_coap_request(ADDR_NTF_URI, port=MM).\ - filter(lambda p: { - NL_ML_EID_TLV, - NL_RLOC16_TLV, - NL_TARGET_EID_TLV - } <= set(p.coap.tlv.type) and\ - p.thread_address.tlv.target_eid == GUA1['MED'] and\ - p.thread_address.tlv.rloc16 == ROUTER_2_RLOC16 - ).\ - must_next() - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(BR).\ - filter_ipv6_dst(GUA1['MED']).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(MED).\ - filter_ipv6_dst(GUA1['BR']).\ - must_next() - - # Step 5: MED sends an ICMPv6 Echo Request to Router_1 using GUA 2003:: - # address - # The DUT MUST not send an Address Query as Router_1 address should - # be cached. - # The DUT MUST forward the ICMPv6 Echo Reply to MED - - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(MED).\ - filter_ipv6_dst(GUA1['ROUTER_1']).\ - must_next() - lstart = pkts.index - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_1).\ - filter_ipv6_dst(GUA1['MED']).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(ROUTER_2).\ - filter_wpan_dst16(MED_RLOC16).\ - must_next() - lend = pkts.index - pkts.range(lstart, lend).filter_wpan_src64(ROUTER_2).\ - filter_RLARMA().\ - filter_coap_request(ADDR_QRY_URI, port=MM).\ - must_not_next() - - # Step 6: MED sends an ICMPv6 Echo Request to Router_1 using GUA 2003:: - # address - # The DUT MUST update its address cache and remove all entries - # based on Router_1’s Router ID. - # The DUT MUST send an Address Query to discover Router_1’s RLOC address. - - pkts.filter_ping_request().\ - filter_wpan_src64(MED).\ - filter_ipv6_dst(GUA1['ROUTER_1']).\ - must_next() - pkts.filter_wpan_src64(ROUTER_2).\ - filter_RLARMA().\ - filter_coap_request(ADDR_QRY_URI, port=MM).\ - filter(lambda p: p.thread_address.tlv.target_eid == GUA1['ROUTER_1']).\ - must_next() - - # Step 7: Border Router sends two ICMPv6 Echo Requests to MED using GUA 2003:: - # address - # The DUT MUST NOT respond with an Address Notification message - - pkts.filter_wpan_src64(ROUTER_2).\ - filter_ipv6_dst(BR_RLOC).\ - filter_coap_request(ADDR_NTF_URI, port=MM).\ - must_not_next() - pkts.filter_ping_request().\ - filter_wpan_src64(BR).\ - filter_ipv6_dst(GUA1['MED']).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_3_11_AddressQueryTimeoutIntervals.py b/tests/scripts/thread-cert/Cert_5_3_11_AddressQueryTimeoutIntervals.py deleted file mode 100755 index 7e0f304eb..000000000 --- a/tests/scripts/thread-cert/Cert_5_3_11_AddressQueryTimeoutIntervals.py +++ /dev/null @@ -1,199 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2018, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import command -import config -import thread_cert -from pktverify.consts import ADDR_QRY_URI, ADDR_NTF_URI, NL_ML_EID_TLV, NL_RLOC16_TLV, NL_TARGET_EID_TLV -from pktverify.packet_verifier import PacketVerifier -from pktverify.bytes import Bytes -from pktverify.addrs import Ipv6Addr - -LEADER = 1 -DUT_ROUTER1 = 2 -MED1 = 3 -X = 'fd00:db8:0000:0000:aa55:aa55:aa55:aa55' - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to validate the way AQ_TIMEOUT and -# AQ_RETRY_TIMEOUT intervals are used in the Address Query transmission -# algorithm. -# -# Test Topology: -# ------------- -# Leader -# | -# Router(DUT) -# | -# MED -# -# DUT Types: -# ---------- -# Router - - -class Cert_5_3_11_AddressQueryTimeoutIntervals(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [DUT_ROUTER1] - }, - DUT_ROUTER1: { - 'name': 'ROUTER', - 'mode': 'rdn', - 'allowlist': [LEADER, MED1] - }, - MED1: { - 'name': 'MED', - 'is_mtd': True, - 'mode': 'rn', - 'allowlist': [DUT_ROUTER1] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[DUT_ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[DUT_ROUTER1].get_state(), 'router') - - self.nodes[MED1].start() - self.simulator.go(5) - self.assertEqual(self.nodes[MED1].get_state(), 'child') - - self.collect_rlocs() - - # 2 MED1: MED1 sends an ICMPv6 Echo Request to a non-existent - # mesh-local address X - self.assertFalse(self.nodes[MED1].ping(X)) - - self.simulator.go(config.AQ_TIMEOUT) - - # 3 MED1: MED1 sends an ICMPv6 Echo Request to a non-existent mesh-local address X before - # ADDRESS_QUERY_INITIAL_RETRY_DELAY timeout expires - self.assertFalse(self.nodes[MED1].ping(X)) - - self.simulator.go(config.ADDRESS_QUERY_INITIAL_RETRY_DELAY) - - # 4 MED1: MED1 sends an ICMPv6 Echo Request to a non-existent mesh-local address X after - # ADDRESS_QUERY_INITIAL_RETRY_DELAY timeout expired - self.assertFalse(self.nodes[MED1].ping(X)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - ROUTER = pv.vars['ROUTER'] - ROUTER_RLOC = pv.vars['ROUTER_RLOC'] - MED = pv.vars['MED'] - MM = pv.vars['MM_PORT'] - - # Step 1: Build the topology as described - - pv.verify_attached('ROUTER', 'LEADER') - pv.verify_attached('MED', 'ROUTER', 'MTD') - - # Step 2: MED sends an ICMPv6 Echo Request to a nonexistent mesh-local - # address X - # The DUT MUST generate an Address Query Request on MED’s behalf - # The Address Query Request MUST be sent to the Realm-Local - # All-Routers address (FF03::2) - # CoAP URI-Path - # - NON POST coap:// - # CoAP Payload - # - Target EID TLV – non-existent mesh-local - # An Address Query Notification MUST NOT be received within - # AQ_TIMEOUT interval. - - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(MED).\ - filter_ipv6_dst(Ipv6Addr(X)).\ - must_next() - step2_start = pkts.index - - pkts.filter_wpan_src64(ROUTER).\ - filter_RLARMA().\ - filter_coap_request(ADDR_QRY_URI, port=MM).\ - filter(lambda p: p.thread_address.tlv.target_eid == Ipv6Addr(X)).\ - must_next() - - # Step 3: MED sends an ICMPv6 Echo Request to a nonexistent mesh-local - # address X before ADDRESS_QUERY_INITIAL_RETRY_DELAY timeout - # expired - # The DUT MUST NOT initiate a new Address Query frame - - pkts.filter_ping_request().\ - filter_wpan_src64(MED).\ - filter_ipv6_dst(Ipv6Addr(X)).\ - must_next() - step2_end = pkts.index - - pkts.range(step2_start, step2_end).filter_ipv6_dst(ROUTER_RLOC).\ - filter_coap_request(ADDR_NTF_URI, port=MM).\ - must_not_next() - - # Step 4: MED sends an ICMPv6 Echo Request to a nonexistent mesh-local - # address X after ADDRESS_QUERY_INITIAL_RETRY_DELAY timeout - # expired - # The DUT MUST generate an Address Query Request on MED’s behalf - # The Address Query Request MUST be sent to the Realm-Local - # All-Routers address (FF03::2) - # CoAP URI-Path - # - NON POST coap:// - # CoAP Payload - # - Target EID TLV – non-existent mesh-local - - pkts.filter_ping_request().\ - filter_wpan_src64(MED).\ - filter_ipv6_dst(Ipv6Addr(X)).\ - must_next() - step3_end = pkts.index - pkts.range(step2_end, step3_end).filter_wpan_src64(ROUTER).\ - filter_RLARMA().\ - filter_coap_request(ADDR_QRY_URI, port=MM).\ - must_not_next() - pkts.filter_wpan_src64(ROUTER).\ - filter_RLARMA().\ - filter_coap_request(ADDR_QRY_URI, port=MM).\ - filter(lambda p: p.thread_address.tlv.target_eid == Ipv6Addr(X)).\ - must_next() - - -if __name__ == '__main__': - unittest.main()