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             uint8_t  mVersion;
639             uint16_t mRloc16;
640 
641             bool Matches(Service::DnsSrpAnycastInfo aInfo) const
642             {
643                 VerifyOrQuit(aInfo.mAnycastAddress.GetIid().IsAnycastServiceLocator());
644 
645                 return (aInfo.mAnycastAddress.GetIid().GetLocator() == mAloc16) &&
646                        (aInfo.mSequenceNumber == mSequenceNumber) && (aInfo.mVersion == mVersion) &&
647                        (aInfo.mRloc16 == mRloc16);
648             }
649         };
650 
651         struct UnicastEntry
652         {
653             const char *mAddress;
654             uint16_t    mPort;
655             uint8_t     mVersion;
656             uint16_t    mRloc16;
657 
658             bool Matches(const Service::DnsSrpUnicastInfo &aInfo) const
659             {
660                 Ip6::SockAddr sockAddr;
661 
662                 SuccessOrQuit(sockAddr.GetAddress().FromString(mAddress));
663                 sockAddr.SetPort(mPort);
664 
665                 return (aInfo.mSockAddr == sockAddr) && (aInfo.mVersion == mVersion) && (aInfo.mRloc16 == mRloc16);
666             }
667         };
668 
669         const uint8_t kNetworkData[] = {
670             0x0b, 0x08, 0x80, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x28, 0x00,
671 
672             0x0b, 0x09, 0x81, 0x02, 0x5c, 0xff, 0x0d, 0x03, 0x6c, 0x00, 0x05,
673 
674             0x0b, 0x09, 0x82, 0x03, 0x5c, 0x03, 0xaa, 0x0d, 0x02, 0x4c, 0x00,
675 
676             0x0b, 0x36, 0x83, 0x14, 0x5d, 0xfd, 0xde, 0xad, 0x00, 0xbe, 0xef, 0x00, 0x00, 0x2d,
677             0x0e, 0xc6, 0x27, 0x55, 0x56, 0x18, 0xd9, 0x12, 0x34, 0x03, 0x0d, 0x02, 0x00, 0x00,
678             0x0d, 0x14, 0x6c, 0x00, 0xfd, 0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11,
679             0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0xab, 0xcd, 0x0d, 0x04, 0x28, 0x00, 0x56, 0x78,
680 
681             0x0b, 0x24, 0x84, 0x01, 0x5d, 0x0d, 0x02, 0x00, 0x00, 0x0d, 0x15, 0x4c, 0x00, 0xfd,
682             0x00, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x01, 0x23, 0x45, 0x67, 0x89,
683             0xab, 0x00, 0x0e, 0x01, 0x0d, 0x04, 0x6c, 0x00, 0xcd, 0x12,
684 
685             0x0b, 0x08, 0x84, 0x01, 0x5c, 0x0d, 0x02, 0x14, 0x01, 0x0d,
686 
687             0x0b, 0x07, 0x83, 0x01, 0x5c, 0x0d, 0x02, 0x28, 0x00,
688 
689             0x0b, 0x13, 0x83, 0x02, 0x5c, 0xfe, 0x0d, 0x03, 0x12, 0x00, 0x07, 0x0d, 0x03, 0x12,
690             0x01, 0x06, 0x0d, 0x03, 0x16, 0x00, 0x07,
691         };
692 
693         const AnycastEntry kAnycastEntries[] = {
694             {0xfc10, 0x02, 0, 0x2800}, {0xfc11, 0xff, 5, 0x6c00}, {0xfc12, 0x03, 0, 0x4c00},
695             {0xfc13, 0xfe, 7, 0x1200}, {0xfc13, 0xfe, 6, 0x1201}, {0xfc13, 0xfe, 7, 0x1600},
696         };
697 
698         const UnicastEntry kUnicastEntriesFromServerData[] = {
699             {"fd00:aabb:ccdd:eeff:11:2233:4455:6677", 0xabcd, 0, 0x6c00},
700             {"fdde:ad00:beef:0:0:ff:fe00:2800", 0x5678, 0, 0x2800},
701             {"fd00:1234:5678:9abc:def0:123:4567:89ab", 0x0e, 1, 0x4c00},
702             {"fdde:ad00:beef:0:0:ff:fe00:6c00", 0xcd12, 0, 0x6c00},
703         };
704 
705         const UnicastEntry kUnicastEntriesFromServiceData[] = {
706             {"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, 3, 0x0000},
707             {"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, 3, 0x6c00},
708             {"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, 3, 0x2800},
709         };
710 
711         const uint16_t kExpectedRlocs[]       = {0x6c00, 0x2800, 0x4c00, 0x0000, 0x1200, 0x1201, 0x1600, 0x1401};
712         const uint16_t kExpectedRouterRlocs[] = {0x6c00, 0x2800, 0x4c00, 0x0000, 0x1200, 0x1600};
713         const uint16_t kExpectedChildRlocs[]  = {0x1201, 0x1401};
714 
715         const uint8_t kPreferredAnycastEntryIndex = 2;
716 
717         Service::Manager          &manager = instance->Get<Service::Manager>();
718         Service::Manager::Iterator iterator;
719         Service::DnsSrpAnycastInfo anycastInfo;
720         Service::DnsSrpUnicastInfo unicastInfo;
721         Service::DnsSrpUnicastType type;
722         Rlocs                      rlocs;
723 
724         reinterpret_cast<TestLeader &>(instance->Get<Leader>()).Populate(kNetworkData, sizeof(kNetworkData));
725 
726         DumpBuffer("netdata", kNetworkData, sizeof(kNetworkData));
727 
728         // Verify `FindRlocs()`
729 
730         instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kAnyRole, rlocs);
731         VerifyRlocsArray(rlocs, kExpectedRlocs);
732 
733         instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs);
734         VerifyRlocsArray(rlocs, kExpectedRouterRlocs);
735 
736         instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs);
737         VerifyRlocsArray(rlocs, kExpectedChildRlocs);
738 
739         instance->Get<Leader>().FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
740         VerifyOrQuit(rlocs.GetLength() == 0);
741 
742         // Verify all the "DNS/SRP Anycast Service" entries in Network Data
743 
744         printf("\n- - - - - - - - - - - - - - - - - - - -");
745         printf("\nDNS/SRP Anycast Service entries\n");
746 
747         for (const AnycastEntry &entry : kAnycastEntries)
748         {
749             SuccessOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo));
750 
751             printf("\nanycastInfo { %s, seq:%d, rlco16:%04x, version:%u }",
752                    anycastInfo.mAnycastAddress.ToString().AsCString(), anycastInfo.mSequenceNumber, anycastInfo.mRloc16,
753                    anycastInfo.mVersion);
754 
755             VerifyOrQuit(entry.Matches(anycastInfo), "GetNextDnsSrpAnycastInfo() returned incorrect info");
756         }
757 
758         VerifyOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo) == kErrorNotFound,
759                      "GetNextDnsSrpAnycastInfo() returned unexpected extra entry");
760 
761         // Find the preferred "DNS/SRP Anycast Service" entries in Network Data
762 
763         SuccessOrQuit(manager.FindPreferredDnsSrpAnycastInfo(anycastInfo));
764 
765         printf("\n\nPreferred anycastInfo { %s, seq:%d, version:%u }",
766                anycastInfo.mAnycastAddress.ToString().AsCString(), anycastInfo.mSequenceNumber, anycastInfo.mVersion);
767 
768         VerifyOrQuit(kAnycastEntries[kPreferredAnycastEntryIndex].Matches(anycastInfo),
769                      "FindPreferredDnsSrpAnycastInfo() returned invalid info");
770 
771         printf("\n\n- - - - - - - - - - - - - - - - - - - -");
772         printf("\nDNS/SRP Unicast Service entries (server data)\n");
773 
774         iterator.Clear();
775         type = Service::kAddrInServerData;
776 
777         for (const UnicastEntry &entry : kUnicastEntriesFromServerData)
778         {
779             SuccessOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, type, unicastInfo));
780             printf("\nunicastInfo { %s, rloc16:%04x }", unicastInfo.mSockAddr.ToString().AsCString(),
781                    unicastInfo.mRloc16);
782 
783             VerifyOrQuit(entry.Matches(unicastInfo), "GetNextDnsSrpUnicastInfo() returned incorrect info");
784         }
785 
786         VerifyOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, type, unicastInfo) == kErrorNotFound,
787                      "GetNextDnsSrpUnicastInfo() returned unexpected extra entry");
788 
789         printf("\n\n- - - - - - - - - - - - - - - - - - - -");
790         printf("\nDNS/SRP Unicast Service entries (service data)\n");
791 
792         iterator.Clear();
793         type = Service::kAddrInServiceData;
794 
795         for (const UnicastEntry &entry : kUnicastEntriesFromServiceData)
796         {
797             SuccessOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, type, unicastInfo));
798             printf("\nunicastInfo { %s, rloc16:%04x }", unicastInfo.mSockAddr.ToString().AsCString(),
799                    unicastInfo.mRloc16);
800 
801             VerifyOrQuit(entry.Matches(unicastInfo), "GetNextDnsSrpUnicastInfo() returned incorrect info");
802         }
803 
804         VerifyOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, type, unicastInfo) == kErrorNotFound,
805                      "GetNextDnsSrpUnicastInfo() returned unexpected extra entry");
806 
807         printf("\n");
808     }
809 
810     testFreeInstance(instance);
811 }
812 
TestNetworkDataDsnSrpAnycastSeqNumSelection(void)813 void TestNetworkDataDsnSrpAnycastSeqNumSelection(void)
814 {
815     class TestLeader : public Leader
816     {
817     public:
818         void Populate(const uint8_t *aTlvs, uint8_t aTlvsLength)
819         {
820             memcpy(GetBytes(), aTlvs, aTlvsLength);
821             SetLength(aTlvsLength);
822         }
823     };
824 
825     struct TestInfo
826     {
827         const uint8_t *mNetworkData;
828         uint8_t        mNetworkDataLength;
829         const uint8_t *mSeqNumbers;
830         uint8_t        mSeqNumbersLength;
831         uint8_t        mPreferredSeqNum;
832         uint8_t        mPreferredVersion;
833     };
834 
835     Instance *instance;
836 
837     printf("\n\n-------------------------------------------------");
838     printf("\nTestNetworkDataDsnSrpAnycastSeqNumSelection()\n");
839 
840     instance = testInitInstance();
841     VerifyOrQuit(instance != nullptr);
842 
843     const uint8_t kNetworkData1[] = {
844         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
845         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Service TLV
846         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x81, 0x0d, 0x02, 0x50, 0x01, // Service TLV
847     };
848     const uint8_t kSeqNumbers1[]    = {1, 129};
849     const uint8_t kPreferredSeqNum1 = 129;
850     const uint8_t kPreferredVer1    = 0;
851 
852     const uint8_t kNetworkData2[] = {
853         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
854         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x85, 0x0d, 0x02, 0x50, 0x00, // Service TLV
855         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x05, 0x0d, 0x02, 0x50, 0x01, // Service TLV
856     };
857     const uint8_t kSeqNumbers2[]    = {133, 5};
858     const uint8_t kPreferredSeqNum2 = 133;
859     const uint8_t kPreferredVer2    = 0;
860 
861     const uint8_t kNetworkData3[] = {
862         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
863         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Service TLV
864         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Service TLV
865         0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Service TLV
866     };
867     const uint8_t kSeqNumbers3[]    = {1, 2, 255};
868     const uint8_t kPreferredSeqNum3 = 2;
869     const uint8_t kPreferredVer3    = 0;
870 
871     const uint8_t kNetworkData4[] = {
872         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
873         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x00, // Service TLV
874         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x01, // Service TLV
875         0x0b, 0x08, 0x82, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x02, // Service TLV
876     };
877     const uint8_t kSeqNumbers4[]    = {10, 130, 250};
878     const uint8_t kPreferredSeqNum4 = 250;
879     const uint8_t kPreferredVer4    = 0;
880 
881     const uint8_t kNetworkData5[] = {
882         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
883         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x00, // Service TLV
884         0x0b, 0x08, 0x81, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x01, // Service TLV
885         0x0b, 0x08, 0x82, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x02, // Service TLV
886     };
887     const uint8_t kSeqNumbers5[]    = {130, 250, 10};
888     const uint8_t kPreferredSeqNum5 = 250;
889     const uint8_t kPreferredVer5    = 0;
890 
891     const uint8_t kNetworkData6[] = {
892         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
893         0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x00, // Service TLV
894         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x01, // Service TLV
895         0x0b, 0x08, 0x82, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x02, // Service TLV
896     };
897     const uint8_t kSeqNumbers6[]    = {250, 10, 130};
898     const uint8_t kPreferredSeqNum6 = 250;
899     const uint8_t kPreferredVer6    = 0;
900 
901     const uint8_t kNetworkData7[] = {
902         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
903         0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x00, // Service TLV
904         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x01, // Service TLV
905         0x0b, 0x08, 0x82, 0x02, 0x5c, 0x8A, 0x0d, 0x02, 0x50, 0x02, // Service TLV
906     };
907     const uint8_t kSeqNumbers7[]    = {250, 10, 138};
908     const uint8_t kPreferredSeqNum7 = 250;
909     const uint8_t kPreferredVer7    = 0;
910 
911     const uint8_t kNetworkData8[] = {
912         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
913         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Service TLV
914         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Service TLV
915         0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Service TLV
916         0x0b, 0x08, 0x83, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x03, // Service TLV
917 
918     };
919     const uint8_t kSeqNumbers8[]    = {1, 2, 255, 254};
920     const uint8_t kPreferredSeqNum8 = 2;
921     const uint8_t kPreferredVer8    = 0;
922 
923     const uint8_t kNetworkData9[] = {
924         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
925         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Service TLV
926         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Service TLV
927         0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Service TLV
928         0x0b, 0x08, 0x83, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x03, // Service TLV
929 
930     };
931     const uint8_t kSeqNumbers9[]    = {1, 2, 255, 254};
932     const uint8_t kPreferredSeqNum9 = 2;
933     const uint8_t kPreferredVer9    = 0;
934 
935     const uint8_t kNetworkData10[] = {
936         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
937         0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
938         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
939         0x0b, 0x08, 0x82, 0x02, 0x5c, 0x78, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
940         0x0b, 0x08, 0x83, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV
941 
942     };
943     const uint8_t kSeqNumbers10[]    = {254, 2, 120, 1};
944     const uint8_t kPreferredSeqNum10 = 120;
945     const uint8_t kPreferredVer10    = 0;
946 
947     const uint8_t kNetworkData11[] = {
948         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
949         0x0b, 0x08, 0x80, 0x02, 0x5c, 0xf0, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
950         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
951         0x0b, 0x08, 0x82, 0x02, 0x5c, 0x78, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
952         0x0b, 0x08, 0x83, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV
953 
954     };
955     const uint8_t kSeqNumbers11[]    = {240, 2, 120, 1};
956     const uint8_t kPreferredSeqNum11 = 240;
957     const uint8_t kPreferredVer11    = 0;
958 
959     const uint8_t kNetworkData12[] = {
960         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                               // Commissioning Data TLV
961         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00,       // Service TLV
962         0x0b, 0x09, 0x81, 0x02, 0x5c, 0x81, 0x0d, 0x03, 0x50, 0x01, 0x01, // Service TLV
963     };
964     const uint8_t kSeqNumbers12[]    = {1, 129};
965     const uint8_t kPreferredSeqNum12 = 129;
966     const uint8_t kPreferredVer12    = 1;
967 
968     const uint8_t kNetworkData13[] = {
969         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
970         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Service TLV
971         0x0b, 0x0e, 0x81, 0x02, 0x5c, 0x81,                         // Service TLV
972         0x0d, 0x03, 0x50, 0x01, 0x02,                               // Server sub-TLV
973         0x0d, 0x03, 0x50, 0x02, 0x02,                               // Server sub-TLV
974     };
975     const uint8_t kSeqNumbers13[]    = {1, 129, 129};
976     const uint8_t kPreferredSeqNum13 = 129;
977     const uint8_t kPreferredVer13    = 2;
978 
979     const uint8_t kNetworkData14[] = {
980         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Commissioning Data TLV
981         0x0b, 0x13, 0x81, 0x02, 0x5c, 0x07, // Service TLV
982         0x0d, 0x03, 0x50, 0x00, 0x01,       // Server sub-TLV
983         0x0d, 0x03, 0x50, 0x01, 0x02,       // Server sub-TLV
984         0x0d, 0x03, 0x50, 0x02, 0x03,       // Server sub-TLV
985     };
986     const uint8_t kSeqNumbers14[]    = {7, 7, 7};
987     const uint8_t kPreferredSeqNum14 = 7;
988     const uint8_t kPreferredVer14    = 1;
989 
990     const uint8_t kNetworkData15[] = {
991         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Commissioning Data TLV
992         0x0b, 0x17, 0x81, 0x02, 0x5c, 0x03, // Service TLV
993         0x0d, 0x03, 0x50, 0x00, 0x01,       // Server sub-TLV
994         0x0d, 0x03, 0x50, 0x01, 0x02,       // Server sub-TLV
995         0x0d, 0x02, 0x50, 0x02,             // Server sub-TLV
996         0x0d, 0x03, 0x50, 0x03, 0x01,       // Server sub-TLV
997     };
998     const uint8_t kSeqNumbers15[]    = {3, 3, 3, 3};
999     const uint8_t kPreferredSeqNum15 = 3;
1000     const uint8_t kPreferredVer15    = 0;
1001 
1002 #define TEST_CASE(Num)                                                                            \
1003     {                                                                                             \
1004         kNetworkData##Num, sizeof(kNetworkData##Num), kSeqNumbers##Num, sizeof(kSeqNumbers##Num), \
1005             kPreferredSeqNum##Num, kPreferredVer##Num                                             \
1006     }
1007 
1008     const TestInfo kTests[] = {
1009         TEST_CASE(1),  TEST_CASE(2),  TEST_CASE(3),  TEST_CASE(4),  TEST_CASE(5),
1010         TEST_CASE(6),  TEST_CASE(7),  TEST_CASE(8),  TEST_CASE(9),  TEST_CASE(10),
1011         TEST_CASE(11), TEST_CASE(12), TEST_CASE(13), TEST_CASE(14), TEST_CASE(15),
1012     };
1013 
1014     Service::Manager &manager   = instance->Get<Service::Manager>();
1015     uint8_t           testIndex = 0;
1016 
1017     for (const TestInfo &test : kTests)
1018     {
1019         Service::Manager::Iterator iterator;
1020         Service::DnsSrpAnycastInfo anycastInfo;
1021 
1022         reinterpret_cast<TestLeader &>(instance->Get<Leader>()).Populate(test.mNetworkData, test.mNetworkDataLength);
1023 
1024         printf("\n- - - - - - - - - - - - - - - - - - - -");
1025         printf("\nDNS/SRP Anycast Service entries for test %d", ++testIndex);
1026 
1027         for (uint8_t index = 0; index < test.mSeqNumbersLength; index++)
1028         {
1029             SuccessOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo));
1030 
1031             printf("\n { %s, seq:%u, version:%u, rlco16:%04x }", anycastInfo.mAnycastAddress.ToString().AsCString(),
1032 
1033                    anycastInfo.mSequenceNumber, anycastInfo.mVersion, anycastInfo.mRloc16);
1034 
1035             VerifyOrQuit(anycastInfo.mSequenceNumber == test.mSeqNumbers[index]);
1036             VerifyOrQuit(anycastInfo.mRloc16 == 0x5000 + index);
1037         }
1038 
1039         VerifyOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo) == kErrorNotFound);
1040         SuccessOrQuit(manager.FindPreferredDnsSrpAnycastInfo(anycastInfo));
1041 
1042         printf("\n preferred -> seq:%u, version:%u ", anycastInfo.mSequenceNumber, anycastInfo.mVersion);
1043         VerifyOrQuit(anycastInfo.mSequenceNumber == test.mPreferredSeqNum);
1044         VerifyOrQuit(anycastInfo.mVersion == test.mPreferredVersion);
1045     }
1046 
1047     testFreeInstance(instance);
1048 }
1049 
1050 } // namespace NetworkData
1051 } // namespace ot
1052 
main(void)1053 int main(void)
1054 {
1055     ot::NetworkData::TestNetworkDataIterator();
1056 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
1057     ot::NetworkData::TestNetworkDataFindNextService();
1058 #endif
1059     ot::NetworkData::TestNetworkDataDsnSrpServices();
1060     ot::NetworkData::TestNetworkDataDsnSrpAnycastSeqNumSelection();
1061 
1062     printf("\nAll tests passed\n");
1063     return 0;
1064 }
1065