1#!/usr/bin/env python3 2# 3# Copyright (c) 2016, The OpenThread Authors. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions are met: 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# 2. Redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution. 13# 3. Neither the name of the copyright holder nor the 14# names of its contributors may be used to endorse or promote products 15# derived from this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27# POSSIBILITY OF SUCH DAMAGE. 28# 29 30import copy 31import unittest 32 33import config 34import mle 35import thread_cert 36from pktverify.consts import MLE_PARENT_REQUEST, MLE_PARENT_RESPONSE, MLE_CHILD_UPDATE_RESPONSE, MLE_CHILD_ID_REQUEST, MLE_CHILD_ID_RESPONSE, 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 37from pktverify.packet_verifier import PacketVerifier 38from pktverify.null_field import nullField 39 40LEADER = 1 41ED = 2 42 43# Test Purpose and Description: 44# ----------------------------- 45# The purpose of this test case is to validate that the DUT is able to successfully 46# attach to a network 47# 48# Test Topology: 49# ------------- 50# Leader 51# | 52# DUT 53# 54# DUT Types: 55# ---------- 56# ED 57# SED 58 59 60class Cert_6_1_1_RouterAttach_Base(thread_cert.TestCase): 61 USE_MESSAGE_FACTORY = False 62 63 TOPOLOGY = { 64 LEADER: { 65 'name': 'LEADER', 66 'mode': 'rdn', 67 'allowlist': [ED] 68 }, 69 ED: { 70 'name': 'DUT', 71 'is_mtd': True, 72 'allowlist': [LEADER] 73 }, 74 } 75 76 def test(self): 77 self.nodes[LEADER].start() 78 self.simulator.go(config.LEADER_STARTUP_DELAY) 79 self.assertEqual(self.nodes[LEADER].get_state(), 'leader') 80 81 self.nodes[ED].start() 82 self.simulator.go(5) 83 self.assertEqual(self.nodes[ED].get_state(), 'child') 84 85 self.collect_ipaddrs() 86 87 ed_addr = self.nodes[ED].get_ip6_address(config.ADDRESS_TYPE.LINK_LOCAL) 88 self.assertTrue(self.nodes[LEADER].ping(ed_addr)) 89 90 def verify(self, pv): 91 pkts = pv.pkts 92 pv.summary.show() 93 94 LEADER = pv.vars['LEADER'] 95 LEADER_LLA = pv.vars['LEADER_LLA'] 96 DUT = pv.vars['DUT'] 97 DUT_LLA = pv.vars['DUT_LLA'] 98 99 # Step 1: Ensure the Leader is sending MLE Advertisements. 100 101 pkts.filter_wpan_src64(LEADER).\ 102 filter_mle_advertisement('Leader').\ 103 must_next() 104 105 # Step 2: DUT sends a MLE Parent Request with an IP hop limit of 106 # 255 to the Link-Local All Routers multicast address (FF02::2). 107 # The following TLVs MUST be present in the MLE Parent Request: 108 # - Challenge TLV 109 # - Mode TLV 110 # - Scan Mask TLV 111 # If the DUT sends multiple MLE Parent Requests 112 # - The first one MUST be sent only to all Routers 113 # - Subsequent ones MAY be sent to all Routers and REEDS 114 # - Version TLV 115 # If the first MLE Parent Request was sent to all Routers and 116 # REEDS, the test fails. 117 # In securing the first three messages of the attaching process, 118 # the full four-byte key sequence number MUST be included in 119 # the Auxiliary Security Header used for MLE security. 120 # 121 # To send the full four-byte key sequence number, the Key 122 # Identifier Mode of the Security Control Field SHALL be set to 123 # ‘0x02’, indicating the presence of a four-byte Key Source, 124 # which SHALL contain the four-byte key sequence number in 125 # network byte order. 126 127 pkts.filter_wpan_src64(DUT).\ 128 filter_LLARMA().\ 129 filter_mle_cmd(MLE_PARENT_REQUEST).\ 130 filter(lambda p: { 131 CHALLENGE_TLV, 132 MODE_TLV, 133 SCAN_MASK_TLV, 134 VERSION_TLV 135 } <= set(p.mle.tlv.type) and\ 136 p.ipv6.hlim == 255 and\ 137 p.mle.tlv.scan_mask.r == 1 and\ 138 p.mle.tlv.scan_mask.e == 0 and\ 139 p.wpan.aux_sec.key_id_mode == 0x2 140 ).\ 141 must_next() 142 143 # Step 3: Leader responds with a MLE Parent Response. 144 # The following TLVs MUST be present in the MLE Parent Response: 145 # - Challenge TLV 146 # - Connectivity TLV 147 # - Leader Data TLV 148 # - Link-layer Frame Counter TLV 149 # - Link Margin TLV 150 # - Response TLV 151 # - Source Address 152 # - Version TLV 153 # - MLE Frame Counter TLV (optional) 154 155 pkts.filter_wpan_src64(LEADER).\ 156 filter_wpan_dst64(DUT).\ 157 filter_mle_cmd(MLE_PARENT_RESPONSE).\ 158 filter(lambda p: { 159 CHALLENGE_TLV, 160 CONNECTIVITY_TLV, 161 LEADER_DATA_TLV, 162 LINK_LAYER_FRAME_COUNTER_TLV, 163 LINK_MARGIN_TLV, 164 RESPONSE_TLV, 165 SOURCE_ADDRESS_TLV, 166 VERSION_TLV 167 } <= set(p.mle.tlv.type)).\ 168 must_next() 169 170 # Step 4: Router sends a MLE Child ID Request. 171 # The following TLVs MUST be present in the MLE Child ID Request: 172 # - Link-layer Frame Counter TLV 173 # - Address Registration TLV 174 # - Mode TLV 175 # - Response TLV 176 # - Timeout TLV 177 # - TLV Request TLV 178 # - Version TLV 179 # - MLE Frame Counter TLV (optional) 180 181 pkts.filter_wpan_src64(DUT).\ 182 filter_wpan_dst64(LEADER).\ 183 filter_mle_cmd(MLE_CHILD_ID_REQUEST).\ 184 filter(lambda p: { 185 ADDRESS_REGISTRATION_TLV, 186 LINK_LAYER_FRAME_COUNTER_TLV, 187 MODE_TLV, 188 RESPONSE_TLV, 189 TIMEOUT_TLV, 190 TLV_REQUEST_TLV, 191 VERSION_TLV 192 } <= set(p.mle.tlv.type) and\ 193 p.wpan.aux_sec.key_id_mode == 0x2 194 ).\ 195 must_next() 196 197 # Step 5: Leader responds with a Child ID Response. 198 199 pkts.filter_wpan_src64(LEADER).\ 200 filter_wpan_dst64(DUT).\ 201 filter_mle_cmd(MLE_CHILD_ID_RESPONSE).\ 202 filter(lambda p: { 203 ADDRESS16_TLV, 204 LEADER_DATA_TLV, 205 NETWORK_DATA_TLV, 206 SOURCE_ADDRESS_TLV 207 } <= set(p.mle.tlv.type) 208 ).\ 209 must_next() 210 211 # Step 6: Verify connectivity by sending an ICMPv6 Echo Request 212 # to the DUT link local address 213 # DUT responds with ICMPv6 Echo Reply 214 215 _pkt = pkts.filter_ping_request().\ 216 filter_ipv6_src_dst(LEADER_LLA, DUT_LLA).\ 217 must_next() 218 pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ 219 filter_ipv6_src_dst(DUT_LLA, LEADER_LLA).\ 220 must_next() 221 222 223class Cert_6_1_1_RouterAttach_ED(Cert_6_1_1_RouterAttach_Base): 224 TOPOLOGY = copy.deepcopy(Cert_6_1_1_RouterAttach_Base.TOPOLOGY) 225 TOPOLOGY[ED]['mode'] = 'rn' 226 227 228class Cert_6_1_1_RouterAttach_SED(Cert_6_1_1_RouterAttach_Base): 229 TOPOLOGY = copy.deepcopy(Cert_6_1_1_RouterAttach_Base.TOPOLOGY) 230 TOPOLOGY[ED]['mode'] = '-' 231 TOPOLOGY[ED]['timeout'] = config.DEFAULT_CHILD_TIMEOUT 232 233 234del (Cert_6_1_1_RouterAttach_Base) 235 236if __name__ == '__main__': 237 unittest.main() 238