xref: /aosp_15_r20/external/openthread/tests/scripts/thread-cert/test_ping.py (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1*cfb92d14SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*cfb92d14SAndroid Build Coastguard Worker#
3*cfb92d14SAndroid Build Coastguard Worker#  Copyright (c) 2021, The OpenThread Authors.
4*cfb92d14SAndroid Build Coastguard Worker#  All rights reserved.
5*cfb92d14SAndroid Build Coastguard Worker#
6*cfb92d14SAndroid Build Coastguard Worker#  Redistribution and use in source and binary forms, with or without
7*cfb92d14SAndroid Build Coastguard Worker#  modification, are permitted provided that the following conditions are met:
8*cfb92d14SAndroid Build Coastguard Worker#  1. Redistributions of source code must retain the above copyright
9*cfb92d14SAndroid Build Coastguard Worker#     notice, this list of conditions and the following disclaimer.
10*cfb92d14SAndroid Build Coastguard Worker#  2. Redistributions in binary form must reproduce the above copyright
11*cfb92d14SAndroid Build Coastguard Worker#     notice, this list of conditions and the following disclaimer in the
12*cfb92d14SAndroid Build Coastguard Worker#     documentation and/or other materials provided with the distribution.
13*cfb92d14SAndroid Build Coastguard Worker#  3. Neither the name of the copyright holder nor the
14*cfb92d14SAndroid Build Coastguard Worker#     names of its contributors may be used to endorse or promote products
15*cfb92d14SAndroid Build Coastguard Worker#     derived from this software without specific prior written permission.
16*cfb92d14SAndroid Build Coastguard Worker#
17*cfb92d14SAndroid Build Coastguard Worker#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
18*cfb92d14SAndroid Build Coastguard Worker#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19*cfb92d14SAndroid Build Coastguard Worker#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20*cfb92d14SAndroid Build Coastguard Worker#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21*cfb92d14SAndroid Build Coastguard Worker#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22*cfb92d14SAndroid Build Coastguard Worker#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23*cfb92d14SAndroid Build Coastguard Worker#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24*cfb92d14SAndroid Build Coastguard Worker#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25*cfb92d14SAndroid Build Coastguard Worker#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26*cfb92d14SAndroid Build Coastguard Worker#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27*cfb92d14SAndroid Build Coastguard Worker#  POSSIBILITY OF SUCH DAMAGE.
28*cfb92d14SAndroid Build Coastguard Worker#
29*cfb92d14SAndroid Build Coastguard Worker
30*cfb92d14SAndroid Build Coastguard Workerimport logging
31*cfb92d14SAndroid Build Coastguard Workerimport unittest
32*cfb92d14SAndroid Build Coastguard Worker
33*cfb92d14SAndroid Build Coastguard Workerimport pktverify
34*cfb92d14SAndroid Build Coastguard Workerfrom pktverify import packet_verifier
35*cfb92d14SAndroid Build Coastguard Workerfrom pktverify.consts import MA1, MA1g, MA2
36*cfb92d14SAndroid Build Coastguard Workerimport config
37*cfb92d14SAndroid Build Coastguard Workerimport thread_cert
38*cfb92d14SAndroid Build Coastguard Worker
39*cfb92d14SAndroid Build Coastguard Worker# Test description:
40*cfb92d14SAndroid Build Coastguard Worker# The purpose of this test is to verify the functionality of ping command.
41*cfb92d14SAndroid Build Coastguard Worker#
42*cfb92d14SAndroid Build Coastguard Worker# Topology:
43*cfb92d14SAndroid Build Coastguard Worker#
44*cfb92d14SAndroid Build Coastguard Worker#
45*cfb92d14SAndroid Build Coastguard Worker#  ROUTER_2 ----- ROUTER_1 ---- ROUTER_3
46*cfb92d14SAndroid Build Coastguard Worker#
47*cfb92d14SAndroid Build Coastguard Worker#
48*cfb92d14SAndroid Build Coastguard Worker
49*cfb92d14SAndroid Build Coastguard WorkerROUTER_1 = 1
50*cfb92d14SAndroid Build Coastguard WorkerROUTER_2 = 2
51*cfb92d14SAndroid Build Coastguard WorkerROUTER_3 = 3
52*cfb92d14SAndroid Build Coastguard Worker
53*cfb92d14SAndroid Build Coastguard Worker
54*cfb92d14SAndroid Build Coastguard Workerclass TestPing(thread_cert.TestCase):
55*cfb92d14SAndroid Build Coastguard Worker    USE_MESSAGE_FACTORY = False
56*cfb92d14SAndroid Build Coastguard Worker    SUPPORT_NCP = False
57*cfb92d14SAndroid Build Coastguard Worker
58*cfb92d14SAndroid Build Coastguard Worker    TOPOLOGY = {
59*cfb92d14SAndroid Build Coastguard Worker        ROUTER_1: {
60*cfb92d14SAndroid Build Coastguard Worker            'name': 'Router_1',
61*cfb92d14SAndroid Build Coastguard Worker            'allowlist': [ROUTER_2, ROUTER_3],
62*cfb92d14SAndroid Build Coastguard Worker        },
63*cfb92d14SAndroid Build Coastguard Worker        ROUTER_2: {
64*cfb92d14SAndroid Build Coastguard Worker            'name': 'Router_2',
65*cfb92d14SAndroid Build Coastguard Worker            'allowlist': [ROUTER_1],
66*cfb92d14SAndroid Build Coastguard Worker        },
67*cfb92d14SAndroid Build Coastguard Worker        ROUTER_3: {
68*cfb92d14SAndroid Build Coastguard Worker            'name': 'Router_3',
69*cfb92d14SAndroid Build Coastguard Worker            'allowlist': [ROUTER_1],
70*cfb92d14SAndroid Build Coastguard Worker        },
71*cfb92d14SAndroid Build Coastguard Worker    }
72*cfb92d14SAndroid Build Coastguard Worker
73*cfb92d14SAndroid Build Coastguard Worker    def test(self):
74*cfb92d14SAndroid Build Coastguard Worker        router1 = self.nodes[ROUTER_1]
75*cfb92d14SAndroid Build Coastguard Worker        router2 = self.nodes[ROUTER_2]
76*cfb92d14SAndroid Build Coastguard Worker        router3 = self.nodes[ROUTER_3]
77*cfb92d14SAndroid Build Coastguard Worker
78*cfb92d14SAndroid Build Coastguard Worker        router1.start()
79*cfb92d14SAndroid Build Coastguard Worker        self.simulator.go(config.LEADER_STARTUP_DELAY)
80*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual('leader', router1.get_state())
81*cfb92d14SAndroid Build Coastguard Worker
82*cfb92d14SAndroid Build Coastguard Worker        router2.start()
83*cfb92d14SAndroid Build Coastguard Worker        self.simulator.go(config.ROUTER_STARTUP_DELAY)
84*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual('router', router2.get_state())
85*cfb92d14SAndroid Build Coastguard Worker
86*cfb92d14SAndroid Build Coastguard Worker        router3.start()
87*cfb92d14SAndroid Build Coastguard Worker        self.simulator.go(config.ROUTER_STARTUP_DELAY)
88*cfb92d14SAndroid Build Coastguard Worker        self.assertEqual('router', router3.get_state())
89*cfb92d14SAndroid Build Coastguard Worker
90*cfb92d14SAndroid Build Coastguard Worker        # 1. ROUTER_1 pings ROUTER_2.
91*cfb92d14SAndroid Build Coastguard Worker        self.assertTrue(router1.ping(router2.get_ip6_address(config.ADDRESS_TYPE.RLOC)))
92*cfb92d14SAndroid Build Coastguard Worker
93*cfb92d14SAndroid Build Coastguard Worker        # 2. ROUTER_1 pings ROUTER_2 multiple times.
94*cfb92d14SAndroid Build Coastguard Worker        self.assertTrue(router1.ping(router2.get_ip6_address(config.ADDRESS_TYPE.RLOC), count=5))
95*cfb92d14SAndroid Build Coastguard Worker
96*cfb92d14SAndroid Build Coastguard Worker        # 3. ROUTER_2 pings ROUTER_1 from the link-local address to the
97*cfb92d14SAndroid Build Coastguard Worker        # link-local address.
98*cfb92d14SAndroid Build Coastguard Worker        self.assertTrue(
99*cfb92d14SAndroid Build Coastguard Worker            router2.ping(router1.get_ip6_address(config.ADDRESS_TYPE.LINK_LOCAL),
100*cfb92d14SAndroid Build Coastguard Worker                         interface=router2.get_ip6_address(config.ADDRESS_TYPE.LINK_LOCAL)))
101*cfb92d14SAndroid Build Coastguard Worker
102*cfb92d14SAndroid Build Coastguard Worker        # 4. ROUTER_2 pings ROUTER_3 using the RLOC.
103*cfb92d14SAndroid Build Coastguard Worker        self.assertTrue(router2.ping(router3.get_ip6_address(config.ADDRESS_TYPE.RLOC)))
104*cfb92d14SAndroid Build Coastguard Worker
105*cfb92d14SAndroid Build Coastguard Worker        # 5. ROUTER_2 pings ROUTER_3's link-local address. The ping should fail.
106*cfb92d14SAndroid Build Coastguard Worker        self.assertFalse(router2.ping(router3.get_ip6_address(config.ADDRESS_TYPE.LINK_LOCAL)))
107*cfb92d14SAndroid Build Coastguard Worker
108*cfb92d14SAndroid Build Coastguard Worker        # 6. ROUTER_2 pings ROUTER_3's RLOC from the link-local address. The
109*cfb92d14SAndroid Build Coastguard Worker        # ping should fail.
110*cfb92d14SAndroid Build Coastguard Worker        self.assertFalse(
111*cfb92d14SAndroid Build Coastguard Worker            router2.ping(router3.get_ip6_address(config.ADDRESS_TYPE.RLOC),
112*cfb92d14SAndroid Build Coastguard Worker                         interface=router2.get_ip6_address(config.ADDRESS_TYPE.LINK_LOCAL)))
113*cfb92d14SAndroid Build Coastguard Worker
114*cfb92d14SAndroid Build Coastguard Worker        # 7. ROUTER_2 pings ROUTER_3's RLOC from an non-existent address. The
115*cfb92d14SAndroid Build Coastguard Worker        # ping command should be rejected by CLI.
116*cfb92d14SAndroid Build Coastguard Worker        self.assertFalse(router2.ping(router3.get_ip6_address(config.ADDRESS_TYPE.RLOC), interface='1::1'))
117*cfb92d14SAndroid Build Coastguard Worker
118*cfb92d14SAndroid Build Coastguard Worker        self.collect_ipaddrs()
119*cfb92d14SAndroid Build Coastguard Worker        self.collect_rloc16s()
120*cfb92d14SAndroid Build Coastguard Worker        self.collect_rlocs()
121*cfb92d14SAndroid Build Coastguard Worker        self.collect_extra_vars()
122*cfb92d14SAndroid Build Coastguard Worker
123*cfb92d14SAndroid Build Coastguard Worker    def verify(self, pv: pktverify.packet_verifier.PacketVerifier):
124*cfb92d14SAndroid Build Coastguard Worker        pkts = pv.pkts
125*cfb92d14SAndroid Build Coastguard Worker        vars = pv.vars
126*cfb92d14SAndroid Build Coastguard Worker        pv.summary.show()
127*cfb92d14SAndroid Build Coastguard Worker
128*cfb92d14SAndroid Build Coastguard Worker        logging.info(f'vars = {vars}')
129*cfb92d14SAndroid Build Coastguard Worker
130*cfb92d14SAndroid Build Coastguard Worker        # Ensure the topology is formed correctly
131*cfb92d14SAndroid Build Coastguard Worker        pv.verify_attached('Router_2', 'Router_1')
132*cfb92d14SAndroid Build Coastguard Worker        pv.verify_attached('Router_3', 'Router_1')
133*cfb92d14SAndroid Build Coastguard Worker
134*cfb92d14SAndroid Build Coastguard Worker        # 1. Router_1 pings Router_2.
135*cfb92d14SAndroid Build Coastguard Worker        _pkt = pkts.filter_wpan_src64(vars['Router_1']) \
136*cfb92d14SAndroid Build Coastguard Worker            .filter_ipv6_2dsts(vars['Router_2_RLOC'], vars['Router_2_LLA']) \
137*cfb92d14SAndroid Build Coastguard Worker            .filter_ping_request() \
138*cfb92d14SAndroid Build Coastguard Worker            .must_next()
139*cfb92d14SAndroid Build Coastguard Worker
140*cfb92d14SAndroid Build Coastguard Worker        pkts.filter_wpan_src64(vars['Router_2']) \
141*cfb92d14SAndroid Build Coastguard Worker            .filter_ipv6_dst(_pkt.ipv6.src) \
142*cfb92d14SAndroid Build Coastguard Worker            .filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier) \
143*cfb92d14SAndroid Build Coastguard Worker            .must_next()
144*cfb92d14SAndroid Build Coastguard Worker
145*cfb92d14SAndroid Build Coastguard Worker        # 2. Router_1 pings Router_2 multiple times.
146*cfb92d14SAndroid Build Coastguard Worker        for i in range(5):
147*cfb92d14SAndroid Build Coastguard Worker            _pkt = pkts.filter_wpan_src64(vars['Router_1']) \
148*cfb92d14SAndroid Build Coastguard Worker                .filter_ipv6_2dsts(vars['Router_2_RLOC'], vars['Router_2_LLA']) \
149*cfb92d14SAndroid Build Coastguard Worker                .filter_ping_request() \
150*cfb92d14SAndroid Build Coastguard Worker                .must_next()
151*cfb92d14SAndroid Build Coastguard Worker            pkts.filter_wpan_src64(vars['Router_2']) \
152*cfb92d14SAndroid Build Coastguard Worker                .filter_ipv6_dst(_pkt.ipv6.src) \
153*cfb92d14SAndroid Build Coastguard Worker                .filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier) \
154*cfb92d14SAndroid Build Coastguard Worker                .must_next()
155*cfb92d14SAndroid Build Coastguard Worker
156*cfb92d14SAndroid Build Coastguard Worker        # 3. Router_2 pings Router_1 from the link-local address to the
157*cfb92d14SAndroid Build Coastguard Worker        # link-local address.
158*cfb92d14SAndroid Build Coastguard Worker        _pkt = pkts.filter_wpan_src64(vars['Router_2']) \
159*cfb92d14SAndroid Build Coastguard Worker            .filter_ipv6_src_dst(vars['Router_2_LLA'], vars['Router_1_LLA']) \
160*cfb92d14SAndroid Build Coastguard Worker            .filter_ping_request() \
161*cfb92d14SAndroid Build Coastguard Worker            .must_next()
162*cfb92d14SAndroid Build Coastguard Worker
163*cfb92d14SAndroid Build Coastguard Worker        pkts.filter_wpan_src64(vars['Router_1']) \
164*cfb92d14SAndroid Build Coastguard Worker            .filter_ipv6_dst(_pkt.ipv6.src) \
165*cfb92d14SAndroid Build Coastguard Worker            .filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier) \
166*cfb92d14SAndroid Build Coastguard Worker            .must_next()
167*cfb92d14SAndroid Build Coastguard Worker
168*cfb92d14SAndroid Build Coastguard Worker        # 4. Router_2 pings Router_3 using the RLOC.
169*cfb92d14SAndroid Build Coastguard Worker        _pkt = pkts.filter_wpan_src64(vars['Router_2']) \
170*cfb92d14SAndroid Build Coastguard Worker            .filter_ipv6_dst(vars['Router_3_RLOC']) \
171*cfb92d14SAndroid Build Coastguard Worker            .filter_ping_request() \
172*cfb92d14SAndroid Build Coastguard Worker            .must_next()
173*cfb92d14SAndroid Build Coastguard Worker
174*cfb92d14SAndroid Build Coastguard Worker        pkts.filter_wpan_src64(vars['Router_3']) \
175*cfb92d14SAndroid Build Coastguard Worker            .filter_ipv6_dst(_pkt.ipv6.src) \
176*cfb92d14SAndroid Build Coastguard Worker            .filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier) \
177*cfb92d14SAndroid Build Coastguard Worker            .must_next()
178*cfb92d14SAndroid Build Coastguard Worker
179*cfb92d14SAndroid Build Coastguard Worker        # 5. Router_2 pings Router_3's link-local address. The ping should fail.
180*cfb92d14SAndroid Build Coastguard Worker        _pkt = pkts.filter_wpan_src64(vars['Router_2']) \
181*cfb92d14SAndroid Build Coastguard Worker            .filter_ipv6_dst(vars['Router_3_LLA']) \
182*cfb92d14SAndroid Build Coastguard Worker            .filter_ping_request() \
183*cfb92d14SAndroid Build Coastguard Worker            .must_next()
184*cfb92d14SAndroid Build Coastguard Worker
185*cfb92d14SAndroid Build Coastguard Worker        pkts.filter_wpan_src64(vars['Router_3']) \
186*cfb92d14SAndroid Build Coastguard Worker            .filter_ipv6_dst(_pkt.ipv6.src) \
187*cfb92d14SAndroid Build Coastguard Worker            .filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier) \
188*cfb92d14SAndroid Build Coastguard Worker            .must_not_next()
189*cfb92d14SAndroid Build Coastguard Worker
190*cfb92d14SAndroid Build Coastguard Worker        # 5. Router_2 pings Router_3's RLOC from the link-local address. The
191*cfb92d14SAndroid Build Coastguard Worker        # ping should fail.
192*cfb92d14SAndroid Build Coastguard Worker        _pkt = pkts.filter_wpan_src64(vars['Router_2']) \
193*cfb92d14SAndroid Build Coastguard Worker            .filter_ipv6_src_dst(vars['Router_2_LLA'], vars['Router_3_RLOC']) \
194*cfb92d14SAndroid Build Coastguard Worker            .filter_ping_request() \
195*cfb92d14SAndroid Build Coastguard Worker            .must_next()
196*cfb92d14SAndroid Build Coastguard Worker
197*cfb92d14SAndroid Build Coastguard Worker
198*cfb92d14SAndroid Build Coastguard Workerif __name__ == '__main__':
199*cfb92d14SAndroid Build Coastguard Worker    unittest.main()
200