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 LINK_LOCAL_All_THREAD_NODES_MULTICAST_ADDRESS 35from pktverify.packet_verifier import PacketVerifier 36 37LEADER = 1 38DUT_ROUTER1 = 2 39FRAGMENTED_DATA_LEN = 256 40 41# Test Purpose and Description: 42# ----------------------------- 43# The purpose of this test case is to validate the Link-Local addresses 44# that the DUT auto-configures. 45# 46# Test Topology: 47# ------------- 48# Leader 49# | 50# Router(DUT) 51# 52# DUT Types: 53# ---------- 54# Router 55 56 57class Cert_5_3_1_LinkLocal(thread_cert.TestCase): 58 USE_MESSAGE_FACTORY = False 59 60 TOPOLOGY = { 61 LEADER: { 62 'name': 'LEADER', 63 'mode': 'rdn', 64 }, 65 DUT_ROUTER1: { 66 'name': 'ROUTER', 67 'mode': 'rdn', 68 }, 69 } 70 71 def test(self): 72 # 1 73 self.nodes[LEADER].start() 74 self.simulator.go(5) 75 self.assertEqual(self.nodes[LEADER].get_state(), 'leader') 76 77 self.nodes[DUT_ROUTER1].start() 78 self.simulator.go(5) 79 self.assertEqual(self.nodes[DUT_ROUTER1].get_state(), 'router') 80 81 self.collect_rlocs() 82 self.collect_ipaddrs() 83 84 # 2 & 3 85 link_local = self.nodes[DUT_ROUTER1].get_ip6_address(config.ADDRESS_TYPE.LINK_LOCAL) 86 self.assertTrue(self.nodes[LEADER].ping(link_local, size=FRAGMENTED_DATA_LEN)) 87 self.assertTrue(self.nodes[LEADER].ping(link_local)) 88 89 # 4 & 5 90 self.assertTrue(self.nodes[LEADER].ping(config.LINK_LOCAL_ALL_NODES_ADDRESS, size=FRAGMENTED_DATA_LEN)) 91 self.assertTrue(self.nodes[LEADER].ping(config.LINK_LOCAL_ALL_NODES_ADDRESS)) 92 93 # 6 & 7 94 self.assertTrue(self.nodes[LEADER].ping(config.LINK_LOCAL_ALL_ROUTERS_ADDRESS, size=FRAGMENTED_DATA_LEN)) 95 self.assertTrue(self.nodes[LEADER].ping(config.LINK_LOCAL_ALL_ROUTERS_ADDRESS)) 96 97 # 8 98 self.assertTrue(self.nodes[LEADER].ping(config.LINK_LOCAL_All_THREAD_NODES_MULTICAST_ADDRESS)) 99 100 def verify(self, pv): 101 pkts = pv.pkts 102 pv.summary.show() 103 104 LEADER = pv.vars['LEADER'] 105 LEADER_LLA = pv.vars['LEADER_LLA'] 106 ROUTER_LLA = pv.vars['ROUTER_LLA'] 107 108 # Step 1: Build the topology as described 109 pv.verify_attached('ROUTER') 110 111 # Step 2: Leader sends a Fragmented ICMPv6 Echo Request to DUT’s 112 # MAC extended address based Link-Local address 113 # The DUT MUST respond with an ICMPv6 Echo Reply 114 115 _pkt = pkts.filter_ping_request().\ 116 filter_ipv6_src_dst(LEADER_LLA, ROUTER_LLA).\ 117 filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ 118 must_next() 119 pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ 120 filter_ipv6_src_dst(ROUTER_LLA, LEADER_LLA).\ 121 filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ 122 must_next() 123 124 # Step 3: Leader sends an Unfragmented ICMPv6 Echo Request to DUT’s 125 # MAC extended address based Link-Local address 126 # The DUT MUST respond with an ICMPv6 Echo Reply 127 128 _pkt = pkts.filter_ping_request().\ 129 filter_ipv6_src_dst(LEADER_LLA, ROUTER_LLA).\ 130 must_next() 131 pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ 132 filter_ipv6_src_dst(ROUTER_LLA, LEADER_LLA).\ 133 must_next() 134 135 # Step 4: Leader sends a Fragmented ICMPv6 Echo Request to the 136 # Link-Local All Nodes multicast address (FF02::1) 137 # The DUT MUST respond with an ICMPv6 Echo Reply 138 139 _pkt = pkts.filter_ping_request().\ 140 filter_wpan_src64(LEADER).\ 141 filter_LLANMA().\ 142 filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ 143 must_next() 144 pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ 145 filter_ipv6_src_dst(ROUTER_LLA, LEADER_LLA).\ 146 filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ 147 must_next() 148 149 # Step 5: Leader sends an Unfragmented ICMPv6 Echo Request to the 150 # Link-Local All Nodes multicast address (FF02::1) 151 # The DUT MUST respond with an ICMPv6 Echo Reply 152 153 _pkt = pkts.filter_ping_request().\ 154 filter_wpan_src64(LEADER).\ 155 filter_LLANMA().\ 156 must_next() 157 pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ 158 filter_ipv6_src_dst(ROUTER_LLA, LEADER_LLA).\ 159 must_next() 160 161 # Step 6: Leader sends a Fragmented ICMPv6 Echo Request to the 162 # Link-Local All Routers multicast address (FF02::2) 163 # The DUT MUST respond with an ICMPv6 Echo Reply 164 165 _pkt = pkts.filter_ping_request().\ 166 filter_wpan_src64(LEADER).\ 167 filter_LLARMA().\ 168 filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ 169 must_next() 170 pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ 171 filter_ipv6_src_dst(ROUTER_LLA, LEADER_LLA).\ 172 filter(lambda p: p.icmpv6.data.len == FRAGMENTED_DATA_LEN).\ 173 must_next() 174 175 # Step 7: Leader sends an Unfragmented ICMPv6 Echo Request to the 176 # Link-Local All Routers multicast address (FF02::2) 177 # The DUT MUST respond with an ICMPv6 Echo Reply 178 179 _pkt = pkts.filter_ping_request().\ 180 filter_wpan_src64(LEADER).\ 181 filter_LLARMA().\ 182 must_next() 183 pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ 184 filter_ipv6_src_dst(ROUTER_LLA, LEADER_LLA).\ 185 must_next() 186 187 # Step 8: Leader sends an Unfragmented ICMPv6 Echo Request to the 188 # Link-Local All Thread Nodes multicast address 189 # The DUT MUST respond with an ICMPv6 Echo Reply 190 191 _pkt = pkts.filter_ping_request().\ 192 filter_ipv6_src_dst(LEADER_LLA, 193 LINK_LOCAL_All_THREAD_NODES_MULTICAST_ADDRESS).\ 194 must_next() 195 pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ 196 filter_ipv6_src_dst(ROUTER_LLA, LEADER_LLA).\ 197 must_next() 198 199 200if __name__ == '__main__': 201 unittest.main() 202