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 unittest 31 32import config 33import mle 34import thread_cert 35from pktverify.consts import MLE_CHILD_ID_RESPONSE, ADDR_QRY_URI, ADDR_NTF_URI, NL_TARGET_EID_TLV 36from pktverify.packet_verifier import PacketVerifier 37 38LEADER = 1 39ROUTER = 2 40MED = 3 41SED = 4 42 43MTDS = [MED, SED] 44 45# Test Purpose and Description: 46# ----------------------------- 47# The purpose of the test case is to verify that when the timer reaches 48# the value of the Timeout TLV sent by the Child, the Parent stops 49# responding to Address Query on the Child's behalf 50# 51# Test Topology: 52# -------------- 53# Leader 54# | 55# Router 56# / \ 57# MED SED 58# 59# DUT Types: 60# ---------- 61# Router 62 63 64class Cert_5_1_02_ChildAddressTimeout(thread_cert.TestCase): 65 USE_MESSAGE_FACTORY = False 66 67 TOPOLOGY = { 68 LEADER: { 69 'name': 'LEADER', 70 'mode': 'rdn', 71 'allowlist': [ROUTER] 72 }, 73 ROUTER: { 74 'name': 'ROUTER', 75 'mode': 'rdn', 76 'allowlist': [LEADER, MED, SED] 77 }, 78 MED: { 79 'name': 'MED', 80 'is_mtd': True, 81 'mode': 'rn', 82 'timeout': config.DEFAULT_CHILD_TIMEOUT, 83 'allowlist': [ROUTER] 84 }, 85 SED: { 86 'name': 'SED', 87 'is_mtd': True, 88 'mode': 'n', 89 'timeout': config.DEFAULT_CHILD_TIMEOUT, 90 'allowlist': [ROUTER] 91 }, 92 } 93 94 def test(self): 95 self.nodes[LEADER].start() 96 self.simulator.go(config.LEADER_STARTUP_DELAY) 97 self.assertEqual(self.nodes[LEADER].get_state(), 'leader') 98 99 self.nodes[ROUTER].start() 100 self.simulator.go(config.ROUTER_STARTUP_DELAY) 101 self.assertEqual(self.nodes[ROUTER].get_state(), 'router') 102 103 self.nodes[MED].start() 104 self.simulator.go(5) 105 self.assertEqual(self.nodes[MED].get_state(), 'child') 106 107 self.nodes[SED].start() 108 self.simulator.go(5) 109 self.assertEqual(self.nodes[SED].get_state(), 'child') 110 111 self.collect_ipaddrs() 112 113 med_mleid = self.nodes[MED].get_ip6_address(config.ADDRESS_TYPE.ML_EID) 114 sed_mleid = self.nodes[SED].get_ip6_address(config.ADDRESS_TYPE.ML_EID) 115 116 self.nodes[MED].stop() 117 self.nodes[SED].stop() 118 self.simulator.go(config.DEFAULT_CHILD_TIMEOUT + 5) 119 self.assertFalse(self.nodes[LEADER].ping(med_mleid)) 120 self.assertFalse(self.nodes[LEADER].ping(sed_mleid)) 121 122 def verify(self, pv): 123 pkts = pv.pkts 124 pv.summary.show() 125 126 LEADER = pv.vars['LEADER'] 127 ROUTER = pv.vars['ROUTER'] 128 MED = pv.vars['MED'] 129 MED_MLEID = pv.vars['MED_MLEID'] 130 SED = pv.vars['SED'] 131 SED_MLEID = pv.vars['SED_MLEID'] 132 MM = pv.vars['MM_PORT'] 133 134 # Step 1: Verify topology is formed correctly 135 136 pv.verify_attached('ROUTER') 137 138 pkts.filter_wpan_src64(ROUTER).\ 139 filter_wpan_dst64(MED).\ 140 filter_mle_cmd(MLE_CHILD_ID_RESPONSE).\ 141 must_next() 142 143 pkts.filter_wpan_src64(ROUTER).\ 144 filter_wpan_dst64(SED).\ 145 filter_mle_cmd(MLE_CHILD_ID_RESPONSE).\ 146 must_next() 147 148 # Step 2: Power off both devices and allow for the keep-alive timeout to expire 149 # Step 3: The Leader sends an ICMPv6 Echo Request to MED and attempts to perform 150 # address resolution by sending an Address Query Request 151 152 pkts.filter_wpan_src64(LEADER).\ 153 filter_RLARMA().\ 154 filter_coap_request(ADDR_QRY_URI, port=MM).\ 155 filter(lambda p: p.thread_address.tlv.type == [NL_TARGET_EID_TLV] and\ 156 p.thread_address.tlv.target_eid == MED_MLEID).\ 157 must_next() 158 159 # Step 4: Router MUST NOT respond with an Address Notification Message 160 161 pkts.filter_wpan_src64(ROUTER).\ 162 filter_coap_request(ADDR_NTF_URI).\ 163 must_not_next() 164 165 # Step 5: The Leader sends an ICMPv6 Echo Request to SED and attempts to perform 166 # address resolution by sending an Address Query Request 167 168 pkts.filter_wpan_src64(LEADER).\ 169 filter_RLARMA().\ 170 filter(lambda p: p.thread_address.tlv.type == [NL_TARGET_EID_TLV] and\ 171 p.thread_address.tlv.target_eid == SED_MLEID).\ 172 filter_coap_request(ADDR_QRY_URI, port=MM).\ 173 must_next() 174 175 # Step 6: Router MUST NOT respond with an Address Notification Message 176 177 pkts.filter_wpan_src64(ROUTER).\ 178 filter_coap_request(ADDR_NTF_URI).\ 179 must_not_next() 180 181 182if __name__ == '__main__': 183 unittest.main() 184