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 thread_cert 34from pktverify.consts import MLE_ADVERTISEMENT, MLE_CHILD_ID_RESPONSE, MLE_DATA_REQUEST, MLE_DATA_RESPONSE, TLV_REQUEST_TLV, NETWORK_DATA_TLV, SOURCE_ADDRESS_TLV, LEADER_DATA_TLV, NWD_PREFIX_TLV, NWD_BORDER_ROUTER_TLV, NWD_6LOWPAN_ID_TLV 35from pktverify.packet_verifier import PacketVerifier 36 37LEADER = 1 38ROUTER1 = 2 39ROUTER2 = 3 40ROUTER3 = 4 41ROUTER15 = 16 42REED1 = 17 43 44 45class Cert_5_6_7_NetworkDataRequestREED(thread_cert.TestCase): 46 TOPOLOGY = { 47 LEADER: { 48 'name': 'LEADER', 49 'mode': 'rdn', 50 'allowlist': [ROUTER1, ROUTER2, ROUTER3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ROUTER15] 51 }, 52 ROUTER1: { 53 'name': 'ROUTER_1', 54 'mode': 'rdn', 55 'allowlist': [LEADER] 56 }, 57 ROUTER2: { 58 'name': 'ROUTER_2', 59 'mode': 'rdn', 60 'allowlist': [LEADER, REED1] 61 }, 62 ROUTER3: { 63 'mode': 'rdn', 64 'allowlist': [LEADER] 65 }, 66 5: { 67 'mode': 'rdn', 68 'allowlist': [LEADER] 69 }, 70 6: { 71 'mode': 'rdn', 72 'allowlist': [LEADER] 73 }, 74 7: { 75 'mode': 'rdn', 76 'allowlist': [LEADER] 77 }, 78 8: { 79 'mode': 'rdn', 80 'allowlist': [LEADER] 81 }, 82 9: { 83 'mode': 'rdn', 84 'allowlist': [LEADER] 85 }, 86 10: { 87 'mode': 'rdn', 88 'allowlist': [LEADER] 89 }, 90 11: { 91 'mode': 'rdn', 92 'allowlist': [LEADER] 93 }, 94 12: { 95 'mode': 'rdn', 96 'allowlist': [LEADER] 97 }, 98 13: { 99 'mode': 'rdn', 100 'allowlist': [LEADER] 101 }, 102 14: { 103 'mode': 'rdn', 104 'allowlist': [LEADER] 105 }, 106 15: { 107 'mode': 'rdn', 108 'allowlist': [LEADER] 109 }, 110 ROUTER15: { 111 'mode': 'rdn', 112 'allowlist': [LEADER] 113 }, 114 REED1: { 115 'name': 'REED', 116 'mode': 'rdn', 117 'allowlist': [ROUTER2] 118 }, 119 } 120 121 def test(self): 122 self.nodes[LEADER].start() 123 self.simulator.go(config.LEADER_STARTUP_DELAY) 124 self.assertEqual(self.nodes[LEADER].get_state(), 'leader') 125 126 for i in range(ROUTER1, ROUTER15 + 1): 127 self.nodes[i].start() 128 self.simulator.go(config.ROUTER_STARTUP_DELAY) 129 self.assertEqual(self.nodes[i].get_state(), 'router') 130 131 self.nodes[REED1].start() 132 self.simulator.go(5) 133 self.assertEqual(self.nodes[REED1].get_state(), 'child') 134 135 self.nodes[ROUTER2].remove_allowlist(self.nodes[REED1].get_addr64()) 136 self.nodes[REED1].remove_allowlist(self.nodes[ROUTER2].get_addr64()) 137 138 self.nodes[LEADER].add_prefix('2001:2:0:3::/64', 'paros') 139 self.nodes[LEADER].register_netdata() 140 141 # Set lowpan context of sniffer 142 self.simulator.set_lowpan_context(1, '2001:2:0:3::/64') 143 144 self.simulator.go(2) 145 146 self.nodes[ROUTER2].add_allowlist(self.nodes[REED1].get_addr64()) 147 self.nodes[REED1].add_allowlist(self.nodes[ROUTER2].get_addr64()) 148 149 self.simulator.go(30) 150 self.simulator.go(600) 151 152 addrs = self.nodes[REED1].get_addrs() 153 self.assertTrue(any('2001:2:0:3' in addr[0:10] for addr in addrs)) 154 for addr in addrs: 155 if addr[0:10] == '2001:2:0:3': 156 self.assertTrue(self.nodes[LEADER].ping(addr)) 157 158 def verify(self, pv): 159 pkts = pv.pkts 160 pv.summary.show() 161 162 LEADER = pv.vars['LEADER'] 163 REED = pv.vars['REED'] 164 165 # Step 4: Leader multicasts a MLE Data Response with the new information 166 _pkt = pkts.filter_mle_cmd(MLE_CHILD_ID_RESPONSE).filter_wpan_dst64(REED).must_next() 167 pkts.filter_wpan_src64(LEADER).filter_mle_cmd(MLE_DATA_RESPONSE).must_next().must_verify( 168 lambda p: {NWD_PREFIX_TLV, NWD_BORDER_ROUTER_TLV, NWD_6LOWPAN_ID_TLV} <= set(p.thread_nwd.tlv.type)) 169 170 # Step 8: REED1 MUST send a MLE Data Request to its parent to get the new Network Dataset. 171 # MLE Data Request includes a TLV Request TLV for Network Data TLV 172 pkts.filter_wpan_src64(REED).filter_mle_cmd(MLE_DATA_REQUEST).must_next().must_verify( 173 lambda p: {TLV_REQUEST_TLV, NETWORK_DATA_TLV} <= set(p.mle.tlv.type)) 174 175 # Step 10: REED1 send MLE Advertisement 176 pkts.filter_wpan_src64(REED).filter_mle_cmd(MLE_ADVERTISEMENT).must_next().must_verify( 177 lambda p: p.mle.tlv.leader_data.data_version == (_pkt.mle.tlv.leader_data.data_version + 1) % 256) 178 179 180if __name__ == '__main__': 181 unittest.main() 182