xref: /aosp_15_r20/external/openthread/tests/unit/test_network_data.cpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1 /*
2  *  Copyright (c) 2017, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <openthread/config.h>
30 
31 #include "common/array.hpp"
32 #include "common/code_utils.hpp"
33 #include "instance/instance.hpp"
34 #include "thread/network_data_leader.hpp"
35 #include "thread/network_data_local.hpp"
36 #include "thread/network_data_service.hpp"
37 
38 #include "test_platform.h"
39 #include "test_util.hpp"
40 
41 namespace ot {
42 namespace NetworkData {
43 
PrintExternalRouteConfig(const ExternalRouteConfig & aConfig)44 void PrintExternalRouteConfig(const ExternalRouteConfig &aConfig)
45 {
46     printf("\nroute-prefix:");
47 
48     for (uint8_t b : aConfig.mPrefix.mPrefix.mFields.m8)
49     {
50         printf("%02x", b);
51     }
52 
53     printf(", length:%d, rloc16:%04x, preference:%d, nat64:%d, stable:%d, nexthop:%d", aConfig.mPrefix.mLength,
54            aConfig.mRloc16, aConfig.mPreference, aConfig.mNat64, aConfig.mStable, aConfig.mNextHopIsThisDevice);
55 }
56 
PrintOnMeshPrefixConfig(const OnMeshPrefixConfig & aConfig)57 void PrintOnMeshPrefixConfig(const OnMeshPrefixConfig &aConfig)
58 {
59     printf("\non-mesh-prefix:");
60 
61     for (uint8_t b : aConfig.mPrefix.mPrefix.mFields.m8)
62     {
63         printf("%02x", b);
64     }
65 
66     printf(", length:%d, rloc16:%04x, preference:%d, stable:%d, def-route:%d", aConfig.mPrefix.mLength, aConfig.mRloc16,
67            aConfig.mPreference, aConfig.mStable, aConfig.mDefaultRoute);
68 }
69 
70 // Returns true if the two given ExternalRouteConfig match (intentionally ignoring mNextHopIsThisDevice).
CompareExternalRouteConfig(const otExternalRouteConfig & aConfig1,const otExternalRouteConfig & aConfig2)71 bool CompareExternalRouteConfig(const otExternalRouteConfig &aConfig1, const otExternalRouteConfig &aConfig2)
72 {
73     return (memcmp(aConfig1.mPrefix.mPrefix.mFields.m8, aConfig2.mPrefix.mPrefix.mFields.m8,
74                    sizeof(aConfig1.mPrefix.mPrefix)) == 0) &&
75            (aConfig1.mPrefix.mLength == aConfig2.mPrefix.mLength) && (aConfig1.mRloc16 == aConfig2.mRloc16) &&
76            (aConfig1.mPreference == aConfig2.mPreference) && (aConfig1.mStable == aConfig2.mStable);
77 }
78 
79 // Returns true if the two given OnMeshprefix match.
CompareOnMeshPrefixConfig(const otBorderRouterConfig & aConfig1,const otBorderRouterConfig & aConfig2)80 bool CompareOnMeshPrefixConfig(const otBorderRouterConfig &aConfig1, const otBorderRouterConfig &aConfig2)
81 {
82     return (memcmp(aConfig1.mPrefix.mPrefix.mFields.m8, aConfig2.mPrefix.mPrefix.mFields.m8,
83                    sizeof(aConfig1.mPrefix.mPrefix)) == 0) &&
84            (aConfig1.mPrefix.mLength == aConfig2.mPrefix.mLength) && (aConfig1.mRloc16 == aConfig2.mRloc16) &&
85            (aConfig1.mPreference == aConfig2.mPreference) && (aConfig1.mStable == aConfig2.mStable) &&
86            (aConfig1.mDefaultRoute == aConfig2.mDefaultRoute) && (aConfig1.mOnMesh == aConfig2.mOnMesh);
87 }
88 
VerifyRlocsArray(const Rlocs & aRlocs,const uint16_t (& aExpectedRlocs)[kLength])89 template <uint8_t kLength> void VerifyRlocsArray(const Rlocs &aRlocs, const uint16_t (&aExpectedRlocs)[kLength])
90 {
91     VerifyOrQuit(aRlocs.GetLength() == kLength);
92 
93     printf("\nRLOCs: { ");
94 
95     for (uint16_t rloc : aRlocs)
96     {
97         printf("0x%04x ", rloc);
98     }
99 
100     printf("}");
101 
102     for (uint16_t index = 0; index < kLength; index++)
103     {
104         VerifyOrQuit(aRlocs.Contains(aExpectedRlocs[index]));
105     }
106 }
107 
TestNetworkDataIterator(void)108 void TestNetworkDataIterator(void)
109 {
110     Instance           *instance;
111     Iterator            iter = kIteratorInit;
112     ExternalRouteConfig rconfig;
113     OnMeshPrefixConfig  pconfig;
114     Rlocs               rlocs;
115 
116     instance = testInitInstance();
117     VerifyOrQuit(instance != nullptr);
118 
119     {
120         const uint8_t kNetworkData[] = {
121             0x08, 0x04, 0x0B, 0x02, 0x00, 0x00, 0x03, 0x14, 0x00, 0x40, 0xFD, 0x00, 0x12, 0x34,
122             0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xC8, 0x00, 0x40, 0x01, 0x03, 0x54, 0x00, 0x00,
123         };
124 
125         otExternalRouteConfig routes[] = {
126             {
127                 {
128                     {{{0xfd, 0x00, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129                        0x00}}},
130                     64,
131                 },
132                 0xc800, // mRloc16
133                 1,      // mPreference
134                 false,  // mNat64
135                 false,  // mStable
136                 false,  // mNextHopIsThisDevice
137                 false,  // mAdvPio
138             },
139             {
140                 {
141                     {{{0xfd, 0x00, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142                        0x00}}},
143                     64,
144                 },
145                 0x5400, // mRloc16
146                 0,      // mPreference
147                 false,  // mNat64
148                 true,   // mStable
149                 false,  // mNextHopIsThisDevice
150                 false,  // mAdvPio
151             },
152         };
153 
154         const uint16_t kRlocs[]            = {0xc800, 0x5400};
155         const uint16_t kNonExistingRlocs[] = {0xc700, 0x0000, 0x5401};
156 
157         NetworkData netData(*instance, kNetworkData, sizeof(kNetworkData));
158 
159         iter = OT_NETWORK_DATA_ITERATOR_INIT;
160 
161         printf("\nTest #1: Network data 1");
162         printf("\n-------------------------------------------------");
163 
164         for (const auto &route : routes)
165         {
166             SuccessOrQuit(netData.GetNextExternalRoute(iter, rconfig));
167             PrintExternalRouteConfig(rconfig);
168             VerifyOrQuit(CompareExternalRouteConfig(rconfig, route));
169         }
170 
171         netData.FindRlocs(kAnyBrOrServer, kAnyRole, rlocs);
172         VerifyRlocsArray(rlocs, kRlocs);
173 
174         netData.FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs);
175         VerifyRlocsArray(rlocs, kRlocs);
176 
177         netData.FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs);
178         VerifyOrQuit(rlocs.GetLength() == 0);
179 
180         netData.FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
181         VerifyRlocsArray(rlocs, kRlocs);
182         VerifyOrQuit(netData.CountBorderRouters(kAnyRole) == GetArrayLength(kRlocs));
183 
184         netData.FindRlocs(kBrProvidingExternalIpConn, kRouterRoleOnly, rlocs);
185         VerifyRlocsArray(rlocs, kRlocs);
186         VerifyOrQuit(netData.CountBorderRouters(kRouterRoleOnly) == GetArrayLength(kRlocs));
187 
188         netData.FindRlocs(kBrProvidingExternalIpConn, kChildRoleOnly, rlocs);
189         VerifyOrQuit(rlocs.GetLength() == 0);
190         VerifyOrQuit(netData.CountBorderRouters(kChildRoleOnly) == 0);
191 
192         for (uint16_t rloc16 : kRlocs)
193         {
194             VerifyOrQuit(netData.ContainsBorderRouterWithRloc(rloc16));
195         }
196 
197         for (uint16_t rloc16 : kNonExistingRlocs)
198         {
199             VerifyOrQuit(!netData.ContainsBorderRouterWithRloc(rloc16));
200         }
201     }
202 
203     {
204         const uint8_t kNetworkData[] = {
205             0x08, 0x04, 0x0B, 0x02, 0x00, 0x00, 0x03, 0x1E, 0x00, 0x40, 0xFD, 0x00, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00,
206             0x07, 0x02, 0x11, 0x40, 0x00, 0x03, 0x10, 0x00, 0x40, 0x01, 0x03, 0x54, 0x00, 0x00, 0x05, 0x04, 0x54, 0x00,
207             0x31, 0x00, 0x02, 0x0F, 0x00, 0x40, 0xFD, 0x00, 0xAB, 0xBA, 0xCD, 0xDC, 0x00, 0x00, 0x00, 0x03, 0x10, 0x00,
208             0x20, 0x03, 0x0E, 0x00, 0x20, 0xFD, 0x00, 0xAB, 0xBA, 0x01, 0x06, 0x54, 0x00, 0x00, 0x04, 0x01, 0x00,
209         };
210 
211         otExternalRouteConfig routes[] = {
212             {
213                 {
214                     {{{0xfd, 0x00, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
215                        0x00}}},
216                     64,
217                 },
218                 0x1000, // mRloc16
219                 1,      // mPreference
220                 false,  // mNat64
221                 false,  // mStable
222                 false,  // mNextHopIsThisDevice
223             },
224             {
225                 {
226                     {{{0xfd, 0x00, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
227                        0x00}}},
228                     64,
229                 },
230                 0x5400, // mRloc16
231                 0,      // mPreference
232                 false,  // mNat64
233                 true,   // mStable
234                 false,  // mNextHopIsThisDevice
235             },
236             {
237                 {
238                     {{{0xfd, 0x00, 0xab, 0xba, 0xcd, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
239                        0x00}}},
240                     64,
241                 },
242                 0x1000, // mRloc16
243                 0,      // mPreference
244                 true,   // mNat64
245                 false,  // mStable
246                 false,  // mNextHopIsThisDevice
247             },
248             {
249                 {
250                     {{{0xfd, 0x00, 0xab, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
251                        0x00}}},
252                     32,
253                 },
254                 0x5400, // mRloc16
255                 0,      // mPreference
256                 false,  // mNat64
257                 true,   // mStable
258                 false,  // mNextHopIsThisDevice
259             },
260             {
261                 {
262                     {{{0xfd, 0x00, 0xab, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
263                        0x00}}},
264                     32,
265                 },
266                 0x0401, // mRloc16
267                 0,      // mPreference
268                 false,  // mNat64
269                 true,   // mStable
270                 false,  // mNextHopIsThisDevice
271             },
272         };
273 
274         const uint16_t kRlocsAnyRole[]     = {0x1000, 0x5400, 0x0401};
275         const uint16_t kRlocsRouterRole[]  = {0x1000, 0x5400};
276         const uint16_t kRlocsChildRole[]   = {0x0401};
277         const uint16_t kNonExistingRlocs[] = {0x6000, 0x0000, 0x0402};
278 
279         NetworkData netData(*instance, kNetworkData, sizeof(kNetworkData));
280 
281         iter = OT_NETWORK_DATA_ITERATOR_INIT;
282 
283         printf("\nTest #2: Network data 2");
284         printf("\n-------------------------------------------------");
285 
286         for (const auto &route : routes)
287         {
288             SuccessOrQuit(netData.GetNextExternalRoute(iter, rconfig));
289             PrintExternalRouteConfig(rconfig);
290             VerifyOrQuit(CompareExternalRouteConfig(rconfig, route));
291         }
292 
293         netData.FindRlocs(kAnyBrOrServer, kAnyRole, rlocs);
294         VerifyRlocsArray(rlocs, kRlocsAnyRole);
295 
296         netData.FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs);
297         VerifyRlocsArray(rlocs, kRlocsRouterRole);
298 
299         netData.FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs);
300         VerifyRlocsArray(rlocs, kRlocsChildRole);
301 
302         netData.FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
303         VerifyRlocsArray(rlocs, kRlocsAnyRole);
304         VerifyOrQuit(netData.CountBorderRouters(kAnyRole) == GetArrayLength(kRlocsAnyRole));
305 
306         netData.FindRlocs(kBrProvidingExternalIpConn, kRouterRoleOnly, rlocs);
307         VerifyRlocsArray(rlocs, kRlocsRouterRole);
308         VerifyOrQuit(netData.CountBorderRouters(kRouterRoleOnly) == GetArrayLength(kRlocsRouterRole));
309 
310         netData.FindRlocs(kBrProvidingExternalIpConn, kChildRoleOnly, rlocs);
311         VerifyRlocsArray(rlocs, kRlocsChildRole);
312         VerifyOrQuit(netData.CountBorderRouters(kChildRoleOnly) == GetArrayLength(kRlocsChildRole));
313 
314         netData.FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
315         VerifyRlocsArray(rlocs, kRlocsAnyRole);
316 
317         for (uint16_t rloc16 : kRlocsAnyRole)
318         {
319             VerifyOrQuit(netData.ContainsBorderRouterWithRloc(rloc16));
320         }
321 
322         for (uint16_t rloc16 : kNonExistingRlocs)
323         {
324             VerifyOrQuit(!netData.ContainsBorderRouterWithRloc(rloc16));
325         }
326     }
327 
328     {
329         const uint8_t kNetworkData[] = {
330             0x08, 0x04, 0x0b, 0x02, 0x36, 0xcc, 0x03, 0x1c, 0x00, 0x40, 0xfd, 0x00, 0xbe, 0xef, 0xca, 0xfe,
331             0x00, 0x00, 0x05, 0x0c, 0x28, 0x00, 0x33, 0x00, 0x28, 0x01, 0x33, 0x00, 0x4c, 0x00, 0x31, 0x00,
332             0x07, 0x02, 0x11, 0x40, 0x03, 0x14, 0x00, 0x40, 0xfd, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00,
333             0x05, 0x04, 0x28, 0x00, 0x73, 0x00, 0x07, 0x02, 0x12, 0x40, 0x03, 0x12, 0x00, 0x40, 0xfd, 0x00,
334             0x33, 0x33, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0xec, 0x00, 0x00, 0x28, 0x01, 0xc0,
335         };
336 
337         otExternalRouteConfig routes[] = {
338             {
339                 {
340                     {{{0xfd, 0x00, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341                        0x00}}},
342                     64,
343                 },
344                 0xec00, // mRloc16
345                 0,      // mPreference
346                 false,  // mNat64
347                 true,   // mStable
348                 false,  // mNextHopIsThisDevice
349             },
350             {
351                 {
352                     {{{0xfd, 0x00, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
353                        0x00}}},
354                     64,
355                 },
356                 0x2801, // mRloc16
357                 -1,     // mPreference
358                 false,  // mNat64
359                 true,   // mStable
360                 false,  // mNextHopIsThisDevice
361             },
362         };
363 
364         otBorderRouterConfig prefixes[] = {
365             {
366                 {
367                     {{{0xfd, 0x00, 0xbe, 0xef, 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
368                        0x00}}},
369                     64,
370                 },
371                 0,      // mPreference
372                 true,   // mPreferred
373                 true,   // mSlaac
374                 false,  // mDhcp
375                 true,   // mConfigure
376                 true,   // mDefaultRoute
377                 true,   // mOnMesh
378                 true,   // mStable
379                 false,  // mNdDns
380                 false,  // mDp
381                 0x2800, // mRloc16
382             },
383             {
384                 {
385                     {{{0xfd, 0x00, 0xbe, 0xef, 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
386                        0x00}}},
387                     64,
388                 },
389                 0,      // mPreference
390                 true,   // mPreferred
391                 true,   // mSlaac
392                 false,  // mDhcp
393                 true,   // mConfigure
394                 true,   // mDefaultRoute
395                 true,   // mOnMesh
396                 true,   // mStable
397                 false,  // mNdDns
398                 false,  // mDp
399                 0x2801, // mRloc16
400             },
401             {
402                 {
403                     {{{0xfd, 0x00, 0xbe, 0xef, 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
404                        0x00}}},
405                     64,
406                 },
407                 0,      // mPreference
408                 true,   // mPreferred
409                 true,   // mSlaac
410                 false,  // mDhcp
411                 true,   // mConfigure
412                 false,  // mDefaultRoute
413                 true,   // mOnMesh
414                 true,   // mStable
415                 false,  // mNdDns
416                 false,  // mDp
417                 0x4c00, // mRloc16
418             },
419             {
420                 {
421                     {{{0xfd, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
422                        0x00}}},
423                     64,
424                 },
425                 1,      // mPreference
426                 true,   // mPreferred
427                 true,   // mSlaac
428                 false,  // mDhcp
429                 true,   // mConfigure
430                 true,   // mDefaultRoute
431                 true,   // mOnMesh
432                 true,   // mStable
433                 false,  // mNdDns
434                 false,  // mDp
435                 0x2800, // mRloc16
436             },
437         };
438 
439         const uint16_t kRlocsAnyRole[]      = {0xec00, 0x2801, 0x2800, 0x4c00};
440         const uint16_t kRlocsRouterRole[]   = {0xec00, 0x2800, 0x4c00};
441         const uint16_t kRlocsChildRole[]    = {0x2801};
442         const uint16_t kBrRlocsAnyRole[]    = {0xec00, 0x2801, 0x2800};
443         const uint16_t kBrRlocsRouterRole[] = {0xec00, 0x2800};
444         const uint16_t kBrRlocsChildRole[]  = {0x2801};
445         const uint16_t kNonExistingRlocs[]  = {0x6000, 0x0000, 0x2806, 0x4c00};
446 
447         NetworkData netData(*instance, kNetworkData, sizeof(kNetworkData));
448 
449         printf("\nTest #3: Network data 3");
450         printf("\n-------------------------------------------------");
451 
452         iter = OT_NETWORK_DATA_ITERATOR_INIT;
453 
454         for (const auto &route : routes)
455         {
456             SuccessOrQuit(netData.GetNextExternalRoute(iter, rconfig));
457             PrintExternalRouteConfig(rconfig);
458             VerifyOrQuit(CompareExternalRouteConfig(rconfig, route));
459         }
460 
461         iter = OT_NETWORK_DATA_ITERATOR_INIT;
462 
463         for (const auto &prefix : prefixes)
464         {
465             SuccessOrQuit(netData.GetNextOnMeshPrefix(iter, pconfig));
466             PrintOnMeshPrefixConfig(pconfig);
467             VerifyOrQuit(CompareOnMeshPrefixConfig(pconfig, prefix));
468         }
469 
470         netData.FindRlocs(kAnyBrOrServer, kAnyRole, rlocs);
471         VerifyRlocsArray(rlocs, kRlocsAnyRole);
472 
473         netData.FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs);
474         VerifyRlocsArray(rlocs, kRlocsRouterRole);
475 
476         netData.FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs);
477         VerifyRlocsArray(rlocs, kRlocsChildRole);
478 
479         netData.FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
480         VerifyRlocsArray(rlocs, kBrRlocsAnyRole);
481         VerifyOrQuit(netData.CountBorderRouters(kAnyRole) == GetArrayLength(kBrRlocsAnyRole));
482 
483         netData.FindRlocs(kBrProvidingExternalIpConn, kRouterRoleOnly, rlocs);
484         VerifyRlocsArray(rlocs, kBrRlocsRouterRole);
485         VerifyOrQuit(netData.CountBorderRouters(kRouterRoleOnly) == GetArrayLength(kBrRlocsRouterRole));
486 
487         netData.FindRlocs(kBrProvidingExternalIpConn, kChildRoleOnly, rlocs);
488         VerifyRlocsArray(rlocs, kBrRlocsChildRole);
489         VerifyOrQuit(netData.CountBorderRouters(kChildRoleOnly) == GetArrayLength(kBrRlocsChildRole));
490 
491         for (uint16_t rloc16 : kBrRlocsAnyRole)
492         {
493             VerifyOrQuit(netData.ContainsBorderRouterWithRloc(rloc16));
494         }
495 
496         for (uint16_t rloc16 : kNonExistingRlocs)
497         {
498             VerifyOrQuit(!netData.ContainsBorderRouterWithRloc(rloc16));
499         }
500     }
501 
502     testFreeInstance(instance);
503 }
504 
505 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
506 
507 class TestNetworkData : public Local
508 {
509 public:
TestNetworkData(Instance & aInstance)510     explicit TestNetworkData(Instance &aInstance)
511         : Local(aInstance)
512     {
513     }
514 
AddService(const ServiceData & aServiceData)515     Error AddService(const ServiceData &aServiceData)
516     {
517         return Local::AddService(ServiceTlv::kThreadEnterpriseNumber, aServiceData, true, ServerData());
518     }
519 
ValidateServiceData(const ServiceTlv * aServiceTlv,const ServiceData & aServiceData) const520     Error ValidateServiceData(const ServiceTlv *aServiceTlv, const ServiceData &aServiceData) const
521     {
522         Error       error = kErrorFailed;
523         ServiceData serviceData;
524 
525         VerifyOrExit(aServiceTlv != nullptr);
526         aServiceTlv->GetServiceData(serviceData);
527 
528         VerifyOrExit(aServiceData == serviceData);
529         error = kErrorNone;
530 
531     exit:
532         return error;
533     }
534 
Test(void)535     void Test(void)
536     {
537         const uint8_t kServiceData1[] = {0x02};
538         const uint8_t kServiceData2[] = {0xab};
539         const uint8_t kServiceData3[] = {0xab, 0x00};
540         const uint8_t kServiceData4[] = {0x02, 0xab, 0xcd, 0xef};
541         const uint8_t kServiceData5[] = {0x02, 0xab, 0xcd};
542 
543         const ServiceTlv *tlv;
544         ServiceData       serviceData1;
545         ServiceData       serviceData2;
546         ServiceData       serviceData3;
547         ServiceData       serviceData4;
548         ServiceData       serviceData5;
549 
550         serviceData1.InitFrom(kServiceData1);
551         serviceData2.InitFrom(kServiceData2);
552         serviceData3.InitFrom(kServiceData3);
553         serviceData4.InitFrom(kServiceData4);
554         serviceData5.InitFrom(kServiceData5);
555 
556         SuccessOrQuit(AddService(serviceData1));
557         SuccessOrQuit(AddService(serviceData2));
558         SuccessOrQuit(AddService(serviceData3));
559         SuccessOrQuit(AddService(serviceData4));
560         SuccessOrQuit(AddService(serviceData5));
561 
562         DumpBuffer("netdata", GetBytes(), GetLength());
563 
564         // Iterate through all entries that start with { 0x02 } (kServiceData1)
565         tlv = nullptr;
566         tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData1, kServicePrefixMatch);
567         SuccessOrQuit(ValidateServiceData(tlv, serviceData1));
568         tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData1, kServicePrefixMatch);
569         SuccessOrQuit(ValidateServiceData(tlv, serviceData4));
570         tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData1, kServicePrefixMatch);
571         SuccessOrQuit(ValidateServiceData(tlv, serviceData5));
572         tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData1, kServicePrefixMatch);
573         VerifyOrQuit(tlv == nullptr, "FindNextService() returned extra TLV");
574 
575         // Iterate through all entries that start with { 0xab } (serviceData2)
576         tlv = nullptr;
577         tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData2, kServicePrefixMatch);
578         SuccessOrQuit(ValidateServiceData(tlv, serviceData2));
579         tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData2, kServicePrefixMatch);
580         SuccessOrQuit(ValidateServiceData(tlv, serviceData3));
581         tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData2, kServicePrefixMatch);
582         VerifyOrQuit(tlv == nullptr, "FindNextService() returned extra TLV");
583 
584         // Iterate through all entries that start with serviceData5
585         tlv = nullptr;
586         tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData5, kServicePrefixMatch);
587         SuccessOrQuit(ValidateServiceData(tlv, serviceData4));
588         tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData5, kServicePrefixMatch);
589         SuccessOrQuit(ValidateServiceData(tlv, serviceData5));
590         tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData5, kServicePrefixMatch);
591         VerifyOrQuit(tlv == nullptr, "FindNextService() returned extra TLV");
592     }
593 };
594 
TestNetworkDataFindNextService(void)595 void TestNetworkDataFindNextService(void)
596 {
597     Instance *instance;
598 
599     printf("\n\n-------------------------------------------------");
600     printf("\nTestNetworkDataFindNextService()\n");
601 
602     instance = testInitInstance();
603     VerifyOrQuit(instance != nullptr);
604 
605     {
606         TestNetworkData netData(*instance);
607         netData.Test();
608     }
609 }
610 
611 #endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
612 
TestNetworkDataDsnSrpServices(void)613 void TestNetworkDataDsnSrpServices(void)
614 {
615     class TestLeader : public Leader
616     {
617     public:
618         void Populate(const uint8_t *aTlvs, uint8_t aTlvsLength)
619         {
620             memcpy(GetBytes(), aTlvs, aTlvsLength);
621             SetLength(aTlvsLength);
622         }
623     };
624 
625     Instance *instance;
626 
627     printf("\n\n-------------------------------------------------");
628     printf("\nTestNetworkDataDsnSrpServices()\n");
629 
630     instance = testInitInstance();
631     VerifyOrQuit(instance != nullptr);
632 
633     {
634         struct AnycastEntry
635         {
636             uint16_t mAloc16;
637             uint8_t  mSequenceNumber;
638             uint16_t mRloc16;
639 
640             bool Matches(Service::DnsSrpAnycastInfo aInfo) const
641             {
642                 VerifyOrQuit(aInfo.mAnycastAddress.GetIid().IsAnycastServiceLocator());
643 
644                 return (aInfo.mAnycastAddress.GetIid().GetLocator() == mAloc16) &&
645                        (aInfo.mSequenceNumber == mSequenceNumber) && (aInfo.mRloc16 == mRloc16);
646             }
647         };
648 
649         struct UnicastEntry
650         {
651             const char *mAddress;
652             uint16_t    mPort;
653             uint16_t    mRloc16;
654 
655             bool Matches(const Service::DnsSrpUnicastInfo &aInfo) const
656             {
657                 Ip6::SockAddr sockAddr;
658 
659                 SuccessOrQuit(sockAddr.GetAddress().FromString(mAddress));
660                 sockAddr.SetPort(mPort);
661 
662                 return (aInfo.mSockAddr == sockAddr) && (aInfo.mRloc16 == mRloc16);
663             }
664         };
665 
666         const uint8_t kNetworkData[] = {
667             0x0b, 0x08, 0x80, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x28, 0x00, 0x0b, 0x08, 0x81, 0x02, 0x5c, 0xff, 0x0d,
668             0x02, 0x6c, 0x00, 0x0b, 0x09, 0x82, 0x02, 0x5c, 0x03, 0x0d, 0x03, 0x4c, 0x00, 0xaa, 0x0b, 0x35, 0x83,
669             0x13, 0x5d, 0xfd, 0xde, 0xad, 0x00, 0xbe, 0xef, 0x00, 0x00, 0x2d, 0x0e, 0xc6, 0x27, 0x55, 0x56, 0x18,
670             0xd9, 0x12, 0x34, 0x0d, 0x02, 0x00, 0x00, 0x0d, 0x14, 0x6c, 0x00, 0xfd, 0x00, 0xaa, 0xbb, 0xcc, 0xdd,
671             0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0xab, 0xcd, 0x0d, 0x04, 0x28, 0x00, 0x56,
672             0x78, 0x0b, 0x23, 0x84, 0x01, 0x5d, 0x0d, 0x02, 0x00, 0x00, 0x0d, 0x14, 0x4c, 0x00, 0xfd, 0x00, 0x12,
673             0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0x00, 0x0e, 0x0d, 0x04,
674             0x6c, 0x00, 0xcd, 0x12, 0x0b, 0x08, 0x84, 0x01, 0x5c, 0x0d, 0x02, 0x14, 0x01, 0x0d, 0x0b, 0x10, 0x83,
675             0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x12, 0x00, 0x0d, 0x02, 0x12, 0x01, 0x0d, 0x02, 0x16, 0x00,
676         };
677 
678         const AnycastEntry kAnycastEntries[] = {
679             {0xfc10, 0x02, 0x2800}, {0xfc11, 0xff, 0x6c00}, {0xfc12, 0x03, 0x4c00},
680             {0xfc13, 0xfe, 0x1200}, {0xfc13, 0xfe, 0x1201}, {0xfc13, 0xfe, 0x1600},
681         };
682 
683         const UnicastEntry kUnicastEntriesFromServerData[] = {
684             {"fd00:aabb:ccdd:eeff:11:2233:4455:6677", 0xabcd, 0x6c00},
685             {"fdde:ad00:beef:0:0:ff:fe00:2800", 0x5678, 0x2800},
686             {"fd00:1234:5678:9abc:def0:123:4567:89ab", 0x0e, 0x4c00},
687             {"fdde:ad00:beef:0:0:ff:fe00:6c00", 0xcd12, 0x6c00},
688         };
689 
690         const UnicastEntry kUnicastEntriesFromServiceData[] = {
691             {"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, 0x0000},
692             {"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, 0x6c00},
693             {"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, 0x2800},
694         };
695 
696         const uint16_t kExpectedRlocs[]       = {0x6c00, 0x2800, 0x4c00, 0x0000, 0x1200, 0x1201, 0x1600, 0x1401};
697         const uint16_t kExpectedRouterRlocs[] = {0x6c00, 0x2800, 0x4c00, 0x0000, 0x1200, 0x1600};
698         const uint16_t kExpectedChildRlocs[]  = {0x1201, 0x1401};
699 
700         const uint8_t kPreferredAnycastEntryIndex = 2;
701 
702         Service::Manager          &manager = instance->Get<Service::Manager>();
703         Service::Manager::Iterator iterator;
704         Service::DnsSrpAnycastInfo anycastInfo;
705         Service::DnsSrpUnicastInfo unicastInfo;
706         Service::DnsSrpUnicastType type;
707         Rlocs                      rlocs;
708 
709         reinterpret_cast<TestLeader &>(instance->Get<Leader>()).Populate(kNetworkData, sizeof(kNetworkData));
710 
711         DumpBuffer("netdata", kNetworkData, sizeof(kNetworkData));
712 
713         // Verify `FindRlocs()`
714 
715         instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kAnyRole, rlocs);
716         VerifyRlocsArray(rlocs, kExpectedRlocs);
717 
718         instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs);
719         VerifyRlocsArray(rlocs, kExpectedRouterRlocs);
720 
721         instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs);
722         VerifyRlocsArray(rlocs, kExpectedChildRlocs);
723 
724         instance->Get<Leader>().FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
725         VerifyOrQuit(rlocs.GetLength() == 0);
726 
727         // Verify all the "DNS/SRP Anycast Service" entries in Network Data
728 
729         printf("\n- - - - - - - - - - - - - - - - - - - -");
730         printf("\nDNS/SRP Anycast Service entries\n");
731 
732         for (const AnycastEntry &entry : kAnycastEntries)
733         {
734             SuccessOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo));
735 
736             printf("\nanycastInfo { %s, seq:%d, rlco16:%04x }", anycastInfo.mAnycastAddress.ToString().AsCString(),
737                    anycastInfo.mSequenceNumber, anycastInfo.mRloc16);
738 
739             VerifyOrQuit(entry.Matches(anycastInfo), "GetNextDnsSrpAnycastInfo() returned incorrect info");
740         }
741 
742         VerifyOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo) == kErrorNotFound,
743                      "GetNextDnsSrpAnycastInfo() returned unexpected extra entry");
744 
745         // Find the preferred "DNS/SRP Anycast Service" entries in Network Data
746 
747         SuccessOrQuit(manager.FindPreferredDnsSrpAnycastInfo(anycastInfo));
748 
749         printf("\n\nPreferred anycastInfo { %s, seq:%d }", anycastInfo.mAnycastAddress.ToString().AsCString(),
750                anycastInfo.mSequenceNumber);
751 
752         VerifyOrQuit(kAnycastEntries[kPreferredAnycastEntryIndex].Matches(anycastInfo),
753                      "FindPreferredDnsSrpAnycastInfo() returned invalid info");
754 
755         printf("\n\n- - - - - - - - - - - - - - - - - - - -");
756         printf("\nDNS/SRP Unicast Service entries (server data)\n");
757 
758         iterator.Clear();
759         type = Service::kAddrInServerData;
760 
761         for (const UnicastEntry &entry : kUnicastEntriesFromServerData)
762         {
763             SuccessOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, type, unicastInfo));
764             printf("\nunicastInfo { %s, rloc16:%04x }", unicastInfo.mSockAddr.ToString().AsCString(),
765                    unicastInfo.mRloc16);
766 
767             VerifyOrQuit(entry.Matches(unicastInfo), "GetNextDnsSrpUnicastInfo() returned incorrect info");
768         }
769 
770         VerifyOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, type, unicastInfo) == kErrorNotFound,
771                      "GetNextDnsSrpUnicastInfo() returned unexpected extra entry");
772 
773         printf("\n\n- - - - - - - - - - - - - - - - - - - -");
774         printf("\nDNS/SRP Unicast Service entries (service data)\n");
775 
776         iterator.Clear();
777         type = Service::kAddrInServiceData;
778 
779         for (const UnicastEntry &entry : kUnicastEntriesFromServiceData)
780         {
781             SuccessOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, type, unicastInfo));
782             printf("\nunicastInfo { %s, rloc16:%04x }", unicastInfo.mSockAddr.ToString().AsCString(),
783                    unicastInfo.mRloc16);
784 
785             VerifyOrQuit(entry.Matches(unicastInfo), "GetNextDnsSrpUnicastInfo() returned incorrect info");
786         }
787 
788         VerifyOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, type, unicastInfo) == kErrorNotFound,
789                      "GetNextDnsSrpUnicastInfo() returned unexpected extra entry");
790 
791         printf("\n");
792     }
793 
794     testFreeInstance(instance);
795 }
796 
TestNetworkDataDsnSrpAnycastSeqNumSelection(void)797 void TestNetworkDataDsnSrpAnycastSeqNumSelection(void)
798 {
799     class TestLeader : public Leader
800     {
801     public:
802         void Populate(const uint8_t *aTlvs, uint8_t aTlvsLength)
803         {
804             memcpy(GetBytes(), aTlvs, aTlvsLength);
805             SetLength(aTlvsLength);
806         }
807     };
808 
809     struct TestInfo
810     {
811         const uint8_t *mNetworkData;
812         uint8_t        mNetworkDataLength;
813         const uint8_t *mSeqNumbers;
814         uint8_t        mSeqNumbersLength;
815         uint8_t        mPreferredSeqNum;
816     };
817 
818     Instance *instance;
819 
820     printf("\n\n-------------------------------------------------");
821     printf("\nTestNetworkDataDsnSrpAnycastSeqNumSelection()\n");
822 
823     instance = testInitInstance();
824     VerifyOrQuit(instance != nullptr);
825 
826     const uint8_t kNetworkData1[] = {
827         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Service TLV
828         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
829         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x81, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
830     };
831     const uint8_t kSeqNumbers1[]    = {1, 129};
832     const uint8_t kPreferredSeqNum1 = 129;
833 
834     const uint8_t kNetworkData2[] = {
835         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Service TLV
836         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x85, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
837         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x05, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
838     };
839     const uint8_t kSeqNumbers2[]    = {133, 5};
840     const uint8_t kPreferredSeqNum2 = 133;
841 
842     const uint8_t kNetworkData3[] = {
843         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Service TLV
844         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
845         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
846         0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
847     };
848     const uint8_t kSeqNumbers3[]    = {1, 2, 255};
849     const uint8_t kPreferredSeqNum3 = 2;
850 
851     const uint8_t kNetworkData4[] = {
852         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Service TLV
853         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
854         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
855         0x0b, 0x08, 0x82, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
856     };
857     const uint8_t kSeqNumbers4[]    = {10, 130, 250};
858     const uint8_t kPreferredSeqNum4 = 250;
859 
860     const uint8_t kNetworkData5[] = {
861         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Service TLV
862         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
863         0x0b, 0x08, 0x81, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
864         0x0b, 0x08, 0x82, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
865     };
866     const uint8_t kSeqNumbers5[]    = {130, 250, 10};
867     const uint8_t kPreferredSeqNum5 = 250;
868 
869     const uint8_t kNetworkData6[] = {
870         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Service TLV
871         0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
872         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
873         0x0b, 0x08, 0x82, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
874     };
875     const uint8_t kSeqNumbers6[]    = {250, 10, 130};
876     const uint8_t kPreferredSeqNum6 = 250;
877 
878     const uint8_t kNetworkData7[] = {
879         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Service TLV
880         0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
881         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
882         0x0b, 0x08, 0x82, 0x02, 0x5c, 0x8A, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
883     };
884     const uint8_t kSeqNumbers7[]    = {250, 10, 138};
885     const uint8_t kPreferredSeqNum7 = 250;
886 
887     const uint8_t kNetworkData8[] = {
888         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Service TLV
889         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
890         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
891         0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
892         0x0b, 0x08, 0x83, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV
893 
894     };
895     const uint8_t kSeqNumbers8[]    = {1, 2, 255, 254};
896     const uint8_t kPreferredSeqNum8 = 2;
897 
898     const uint8_t kNetworkData9[] = {
899         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Service TLV
900         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
901         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
902         0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
903         0x0b, 0x08, 0x83, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV
904 
905     };
906     const uint8_t kSeqNumbers9[]    = {1, 2, 255, 254};
907     const uint8_t kPreferredSeqNum9 = 2;
908 
909     const uint8_t kNetworkData10[] = {
910         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Service TLV
911         0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
912         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
913         0x0b, 0x08, 0x82, 0x02, 0x5c, 0x78, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
914         0x0b, 0x08, 0x83, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV
915 
916     };
917     const uint8_t kSeqNumbers10[]    = {254, 2, 120, 1};
918     const uint8_t kPreferredSeqNum10 = 120;
919 
920     const uint8_t kNetworkData11[] = {
921         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Service TLV
922         0x0b, 0x08, 0x80, 0x02, 0x5c, 0xf0, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
923         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
924         0x0b, 0x08, 0x82, 0x02, 0x5c, 0x78, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
925         0x0b, 0x08, 0x83, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV
926 
927     };
928     const uint8_t kSeqNumbers11[]    = {240, 2, 120, 1};
929     const uint8_t kPreferredSeqNum11 = 240;
930 
931     const TestInfo kTests[] = {
932         {kNetworkData1, sizeof(kNetworkData1), kSeqNumbers1, sizeof(kSeqNumbers1), kPreferredSeqNum1},
933         {kNetworkData2, sizeof(kNetworkData2), kSeqNumbers2, sizeof(kSeqNumbers2), kPreferredSeqNum2},
934         {kNetworkData3, sizeof(kNetworkData3), kSeqNumbers3, sizeof(kSeqNumbers3), kPreferredSeqNum3},
935         {kNetworkData4, sizeof(kNetworkData4), kSeqNumbers4, sizeof(kSeqNumbers4), kPreferredSeqNum4},
936         {kNetworkData5, sizeof(kNetworkData5), kSeqNumbers5, sizeof(kSeqNumbers5), kPreferredSeqNum5},
937         {kNetworkData6, sizeof(kNetworkData6), kSeqNumbers6, sizeof(kSeqNumbers6), kPreferredSeqNum6},
938         {kNetworkData7, sizeof(kNetworkData7), kSeqNumbers7, sizeof(kSeqNumbers7), kPreferredSeqNum7},
939         {kNetworkData8, sizeof(kNetworkData8), kSeqNumbers8, sizeof(kSeqNumbers8), kPreferredSeqNum8},
940         {kNetworkData9, sizeof(kNetworkData9), kSeqNumbers9, sizeof(kSeqNumbers9), kPreferredSeqNum9},
941         {kNetworkData10, sizeof(kNetworkData10), kSeqNumbers10, sizeof(kSeqNumbers10), kPreferredSeqNum10},
942         {kNetworkData11, sizeof(kNetworkData11), kSeqNumbers11, sizeof(kSeqNumbers11), kPreferredSeqNum11},
943     };
944 
945     Service::Manager &manager   = instance->Get<Service::Manager>();
946     uint8_t           testIndex = 0;
947 
948     for (const TestInfo &test : kTests)
949     {
950         Service::Manager::Iterator iterator;
951         Service::DnsSrpAnycastInfo anycastInfo;
952 
953         reinterpret_cast<TestLeader &>(instance->Get<Leader>()).Populate(test.mNetworkData, test.mNetworkDataLength);
954 
955         printf("\n- - - - - - - - - - - - - - - - - - - -");
956         printf("\nDNS/SRP Anycast Service entries for test %d", ++testIndex);
957 
958         for (uint8_t index = 0; index < test.mSeqNumbersLength; index++)
959         {
960             SuccessOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo));
961 
962             printf("\n { %s, seq:%d, rlco16:%04x }", anycastInfo.mAnycastAddress.ToString().AsCString(),
963                    anycastInfo.mSequenceNumber, anycastInfo.mRloc16);
964 
965             VerifyOrQuit(anycastInfo.mSequenceNumber == test.mSeqNumbers[index]);
966             VerifyOrQuit(anycastInfo.mRloc16 == 0x5000 + index);
967         }
968 
969         VerifyOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo) == kErrorNotFound);
970         SuccessOrQuit(manager.FindPreferredDnsSrpAnycastInfo(anycastInfo));
971 
972         printf("\n preferred -> seq:%d ", anycastInfo.mSequenceNumber);
973         VerifyOrQuit(anycastInfo.mSequenceNumber == test.mPreferredSeqNum);
974     }
975 
976     testFreeInstance(instance);
977 }
978 
979 } // namespace NetworkData
980 } // namespace ot
981 
main(void)982 int main(void)
983 {
984     ot::NetworkData::TestNetworkDataIterator();
985 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
986     ot::NetworkData::TestNetworkDataFindNextService();
987 #endif
988     ot::NetworkData::TestNetworkDataDsnSrpServices();
989     ot::NetworkData::TestNetworkDataDsnSrpAnycastSeqNumSelection();
990 
991     printf("\nAll tests passed\n");
992     return 0;
993 }
994