• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     static const char *kOriginStrings[] = {
616         "service-data", // (0) Service::DnsSrpUnicast::kFromServiceData
617         "server-data",  // (1) Service::DnsSrpUnicast::kFromServerData
618     };
619 
620     class TestLeader : public Leader
621     {
622     public:
623         void Populate(const uint8_t *aTlvs, uint8_t aTlvsLength)
624         {
625             memcpy(GetBytes(), aTlvs, aTlvsLength);
626             SetLength(aTlvsLength);
627         }
628     };
629 
630     Instance *instance;
631 
632     printf("\n\n-------------------------------------------------");
633     printf("\nTestNetworkDataDsnSrpServices()\n");
634 
635     instance = testInitInstance();
636     VerifyOrQuit(instance != nullptr);
637 
638     {
639         struct AnycastEntry
640         {
641             uint16_t mAloc16;
642             uint8_t  mSequenceNumber;
643 
644             bool Matches(Service::DnsSrpAnycast::Info aInfo) const
645             {
646                 VerifyOrQuit(aInfo.mAnycastAddress.GetIid().IsAnycastServiceLocator());
647 
648                 return (aInfo.mAnycastAddress.GetIid().GetLocator() == mAloc16) &&
649                        (aInfo.mSequenceNumber == mSequenceNumber);
650             }
651         };
652 
653         struct UnicastEntry
654         {
655             const char                    *mAddress;
656             uint16_t                       mPort;
657             Service::DnsSrpUnicast::Origin mOrigin;
658             uint16_t                       mRloc16;
659 
660             bool Matches(Service::DnsSrpUnicast::Info aInfo) const
661             {
662                 Ip6::SockAddr sockAddr;
663 
664                 SuccessOrQuit(sockAddr.GetAddress().FromString(mAddress));
665                 sockAddr.SetPort(mPort);
666 
667                 return (aInfo.mSockAddr == sockAddr) && (aInfo.mOrigin == mOrigin) && (aInfo.mRloc16 == mRloc16);
668             }
669         };
670 
671         const uint8_t kNetworkData[] = {
672             0x0b, 0x08, 0x80, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x28, 0x00, 0x0b, 0x08, 0x81, 0x02, 0x5c, 0xff, 0x0d, 0x02,
673             0x6c, 0x00, 0x0b, 0x09, 0x82, 0x02, 0x5c, 0x03, 0x0d, 0x03, 0x4c, 0x00, 0xaa, 0x0b, 0x35, 0x83, 0x13, 0x5d,
674             0xfd, 0xde, 0xad, 0x00, 0xbe, 0xef, 0x00, 0x00, 0x2d, 0x0e, 0xc6, 0x27, 0x55, 0x56, 0x18, 0xd9, 0x12, 0x34,
675             0x0d, 0x02, 0x00, 0x00, 0x0d, 0x14, 0x6c, 0x00, 0xfd, 0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11,
676             0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0xab, 0xcd, 0x0d, 0x04, 0x28, 0x00, 0x56, 0x78, 0x0b, 0x23, 0x84, 0x01,
677             0x5d, 0x0d, 0x02, 0x00, 0x00, 0x0d, 0x14, 0x4c, 0x00, 0xfd, 0x00, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde,
678             0xf0, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0x00, 0x0e, 0x0d, 0x04, 0x6c, 0x00, 0xcd, 0x12,
679         };
680 
681         const AnycastEntry kAnycastEntries[] = {
682             {0xfc10, 0x02},
683             {0xfc11, 0xff},
684             {0xfc12, 0x03},
685         };
686 
687         const UnicastEntry kUnicastEntries[] = {
688             {"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, Service::DnsSrpUnicast::kFromServiceData, 0xfffe},
689             {"fd00:aabb:ccdd:eeff:11:2233:4455:6677", 0xabcd, Service::DnsSrpUnicast::kFromServerData, 0x6c00},
690             {"fdde:ad00:beef:0:0:ff:fe00:2800", 0x5678, Service::DnsSrpUnicast::kFromServerData, 0x2800},
691             {"fd00:1234:5678:9abc:def0:123:4567:89ab", 0x0e, Service::DnsSrpUnicast::kFromServerData, 0x4c00},
692             {"fdde:ad00:beef:0:0:ff:fe00:6c00", 0xcd12, Service::DnsSrpUnicast::kFromServerData, 0x6c00},
693         };
694 
695         const uint16_t kExpectedRlocs[] = {0x6c00, 0x2800, 0x4c00, 0x0000};
696 
697         const uint8_t kPreferredAnycastEntryIndex = 2;
698 
699         Service::Manager            &manager = instance->Get<Service::Manager>();
700         Service::Manager::Iterator   iterator;
701         Service::DnsSrpAnycast::Info anycastInfo;
702         Service::DnsSrpUnicast::Info unicastInfo;
703         Rlocs                        rlocs;
704 
705         reinterpret_cast<TestLeader &>(instance->Get<Leader>()).Populate(kNetworkData, sizeof(kNetworkData));
706 
707         DumpBuffer("netdata", kNetworkData, sizeof(kNetworkData));
708 
709         // Verify `FindRlocs()`
710 
711         instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kAnyRole, rlocs);
712         VerifyRlocsArray(rlocs, kExpectedRlocs);
713 
714         instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs);
715         VerifyRlocsArray(rlocs, kExpectedRlocs);
716 
717         instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs);
718         VerifyOrQuit(rlocs.GetLength() == 0);
719 
720         instance->Get<Leader>().FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
721         VerifyOrQuit(rlocs.GetLength() == 0);
722 
723         // Verify all the "DNS/SRP Anycast Service" entries in Network Data
724 
725         printf("\n- - - - - - - - - - - - - - - - - - - -");
726         printf("\nDNS/SRP Anycast Service entries\n");
727 
728         for (const AnycastEntry &entry : kAnycastEntries)
729         {
730             SuccessOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo));
731 
732             printf("\nanycastInfo { %s, seq:%d }", anycastInfo.mAnycastAddress.ToString().AsCString(),
733                    anycastInfo.mSequenceNumber);
734 
735             VerifyOrQuit(entry.Matches(anycastInfo), "GetNextDnsSrpAnycastInfo() returned incorrect info");
736         }
737 
738         VerifyOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo) == kErrorNotFound,
739                      "GetNextDnsSrpAnycastInfo() returned unexpected extra entry");
740 
741         // Find the preferred "DNS/SRP Anycast Service" entries in Network Data
742 
743         SuccessOrQuit(manager.FindPreferredDnsSrpAnycastInfo(anycastInfo));
744 
745         printf("\n\nPreferred anycastInfo { %s, seq:%d }", anycastInfo.mAnycastAddress.ToString().AsCString(),
746                anycastInfo.mSequenceNumber);
747 
748         VerifyOrQuit(kAnycastEntries[kPreferredAnycastEntryIndex].Matches(anycastInfo),
749                      "FindPreferredDnsSrpAnycastInfo() returned invalid info");
750 
751         printf("\n\n- - - - - - - - - - - - - - - - - - - -");
752         printf("\nDNS/SRP Unicast Service entries\n");
753 
754         iterator.Clear();
755 
756         for (const UnicastEntry &entry : kUnicastEntries)
757         {
758             SuccessOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, unicastInfo));
759             printf("\nunicastInfo { %s, origin:%s, rloc16:%04x }", unicastInfo.mSockAddr.ToString().AsCString(),
760                    kOriginStrings[unicastInfo.mOrigin], unicastInfo.mRloc16);
761 
762             VerifyOrQuit(entry.Matches(unicastInfo), "GetNextDnsSrpUnicastInfo() returned incorrect info");
763         }
764 
765         VerifyOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, unicastInfo) == kErrorNotFound,
766                      "GetNextDnsSrpUnicastInfo() returned unexpected extra entry");
767 
768         printf("\n");
769     }
770 
771     testFreeInstance(instance);
772 }
773 
TestNetworkDataDsnSrpAnycastSeqNumSelection(void)774 void TestNetworkDataDsnSrpAnycastSeqNumSelection(void)
775 {
776     class TestLeader : public Leader
777     {
778     public:
779         void Populate(const uint8_t *aTlvs, uint8_t aTlvsLength)
780         {
781             memcpy(GetBytes(), aTlvs, aTlvsLength);
782             SetLength(aTlvsLength);
783         }
784     };
785 
786     struct TestInfo
787     {
788         const uint8_t *mNetworkData;
789         uint8_t        mNetworkDataLength;
790         const uint8_t *mSeqNumbers;
791         uint8_t        mSeqNumbersLength;
792         uint8_t        mPreferredSeqNum;
793     };
794 
795     Instance *instance;
796 
797     printf("\n\n-------------------------------------------------");
798     printf("\nTestNetworkDataDsnSrpAnycastSeqNumSelection()\n");
799 
800     instance = testInitInstance();
801     VerifyOrQuit(instance != nullptr);
802 
803     const uint8_t kNetworkData1[] = {
804         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Service TLV
805         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
806         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x81, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
807     };
808     const uint8_t kSeqNumbers1[]    = {1, 129};
809     const uint8_t kPreferredSeqNum1 = 129;
810 
811     const uint8_t kNetworkData2[] = {
812         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Service TLV
813         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x85, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
814         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x05, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
815     };
816     const uint8_t kSeqNumbers2[]    = {133, 5};
817     const uint8_t kPreferredSeqNum2 = 133;
818 
819     const uint8_t kNetworkData3[] = {
820         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Service TLV
821         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
822         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
823         0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
824     };
825     const uint8_t kSeqNumbers3[]    = {1, 2, 255};
826     const uint8_t kPreferredSeqNum3 = 2;
827 
828     const uint8_t kNetworkData4[] = {
829         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Service TLV
830         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
831         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
832         0x0b, 0x08, 0x82, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
833     };
834     const uint8_t kSeqNumbers4[]    = {10, 130, 250};
835     const uint8_t kPreferredSeqNum4 = 250;
836 
837     const uint8_t kNetworkData5[] = {
838         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Service TLV
839         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
840         0x0b, 0x08, 0x81, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
841         0x0b, 0x08, 0x82, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
842     };
843     const uint8_t kSeqNumbers5[]    = {130, 250, 10};
844     const uint8_t kPreferredSeqNum5 = 250;
845 
846     const uint8_t kNetworkData6[] = {
847         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Service TLV
848         0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
849         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
850         0x0b, 0x08, 0x82, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
851     };
852     const uint8_t kSeqNumbers6[]    = {250, 10, 130};
853     const uint8_t kPreferredSeqNum6 = 250;
854 
855     const uint8_t kNetworkData7[] = {
856         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Service TLV
857         0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
858         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
859         0x0b, 0x08, 0x82, 0x02, 0x5c, 0x8A, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
860     };
861     const uint8_t kSeqNumbers7[]    = {250, 10, 138};
862     const uint8_t kPreferredSeqNum7 = 250;
863 
864     const uint8_t kNetworkData8[] = {
865         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Service TLV
866         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
867         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
868         0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
869         0x0b, 0x08, 0x83, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV
870 
871     };
872     const uint8_t kSeqNumbers8[]    = {1, 2, 255, 254};
873     const uint8_t kPreferredSeqNum8 = 2;
874 
875     const uint8_t kNetworkData9[] = {
876         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Service TLV
877         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
878         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
879         0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
880         0x0b, 0x08, 0x83, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV
881 
882     };
883     const uint8_t kSeqNumbers9[]    = {1, 2, 255, 254};
884     const uint8_t kPreferredSeqNum9 = 2;
885 
886     const uint8_t kNetworkData10[] = {
887         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Service TLV
888         0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
889         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
890         0x0b, 0x08, 0x82, 0x02, 0x5c, 0x78, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
891         0x0b, 0x08, 0x83, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV
892 
893     };
894     const uint8_t kSeqNumbers10[]    = {254, 2, 120, 1};
895     const uint8_t kPreferredSeqNum10 = 120;
896 
897     const uint8_t kNetworkData11[] = {
898         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Service TLV
899         0x0b, 0x08, 0x80, 0x02, 0x5c, 0xf0, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
900         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
901         0x0b, 0x08, 0x82, 0x02, 0x5c, 0x78, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
902         0x0b, 0x08, 0x83, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV
903 
904     };
905     const uint8_t kSeqNumbers11[]    = {240, 2, 120, 1};
906     const uint8_t kPreferredSeqNum11 = 240;
907 
908     const TestInfo kTests[] = {
909         {kNetworkData1, sizeof(kNetworkData1), kSeqNumbers1, sizeof(kSeqNumbers1), kPreferredSeqNum1},
910         {kNetworkData2, sizeof(kNetworkData2), kSeqNumbers2, sizeof(kSeqNumbers2), kPreferredSeqNum2},
911         {kNetworkData3, sizeof(kNetworkData3), kSeqNumbers3, sizeof(kSeqNumbers3), kPreferredSeqNum3},
912         {kNetworkData4, sizeof(kNetworkData4), kSeqNumbers4, sizeof(kSeqNumbers4), kPreferredSeqNum4},
913         {kNetworkData5, sizeof(kNetworkData5), kSeqNumbers5, sizeof(kSeqNumbers5), kPreferredSeqNum5},
914         {kNetworkData6, sizeof(kNetworkData6), kSeqNumbers6, sizeof(kSeqNumbers6), kPreferredSeqNum6},
915         {kNetworkData7, sizeof(kNetworkData7), kSeqNumbers7, sizeof(kSeqNumbers7), kPreferredSeqNum7},
916         {kNetworkData8, sizeof(kNetworkData8), kSeqNumbers8, sizeof(kSeqNumbers8), kPreferredSeqNum8},
917         {kNetworkData9, sizeof(kNetworkData9), kSeqNumbers9, sizeof(kSeqNumbers9), kPreferredSeqNum9},
918         {kNetworkData10, sizeof(kNetworkData10), kSeqNumbers10, sizeof(kSeqNumbers10), kPreferredSeqNum10},
919         {kNetworkData11, sizeof(kNetworkData11), kSeqNumbers11, sizeof(kSeqNumbers11), kPreferredSeqNum11},
920     };
921 
922     Service::Manager &manager   = instance->Get<Service::Manager>();
923     uint8_t           testIndex = 0;
924 
925     for (const TestInfo &test : kTests)
926     {
927         Service::Manager::Iterator   iterator;
928         Service::DnsSrpAnycast::Info anycastInfo;
929 
930         reinterpret_cast<TestLeader &>(instance->Get<Leader>()).Populate(test.mNetworkData, test.mNetworkDataLength);
931 
932         printf("\n- - - - - - - - - - - - - - - - - - - -");
933         printf("\nDNS/SRP Anycast Service entries for test %d", ++testIndex);
934 
935         for (uint8_t index = 0; index < test.mSeqNumbersLength; index++)
936         {
937             SuccessOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo));
938 
939             printf("\n { %s, seq:%d }", anycastInfo.mAnycastAddress.ToString().AsCString(),
940                    anycastInfo.mSequenceNumber);
941 
942             VerifyOrQuit(anycastInfo.mSequenceNumber == test.mSeqNumbers[index]);
943         }
944 
945         VerifyOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo) == kErrorNotFound);
946         SuccessOrQuit(manager.FindPreferredDnsSrpAnycastInfo(anycastInfo));
947 
948         printf("\n preferred -> seq:%d ", anycastInfo.mSequenceNumber);
949         VerifyOrQuit(anycastInfo.mSequenceNumber == test.mPreferredSeqNum);
950     }
951 
952     testFreeInstance(instance);
953 }
954 
955 } // namespace NetworkData
956 } // namespace ot
957 
main(void)958 int main(void)
959 {
960     ot::NetworkData::TestNetworkDataIterator();
961 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
962     ot::NetworkData::TestNetworkDataFindNextService();
963 #endif
964     ot::NetworkData::TestNetworkDataDsnSrpServices();
965     ot::NetworkData::TestNetworkDataDsnSrpAnycastSeqNumSelection();
966 
967     printf("\nAll tests passed\n");
968     return 0;
969 }
970