• 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         // Network Data:
121         // - An invalid TLV type.
122         // - An invalid Prefix TLV with prefix length of 129 (and two HasRoute sub-TLVs).
123         // - An invalid Prefix TLV with short length (length = 1)
124         // - An invalid Prefix TLV with no prefix.
125         // - A valid Prefix TLV with two HasRoute sub-TLVs
126 
127         const uint8_t kNetworkData[] = {
128             0xff, 0x03, 0x01, 0x02, 0x03,
129 
130             0x03, 0x1D, 0x00, 0x81, 0xFD, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB,
131             0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x00, 0x03, 0xb8, 0x00, 0x40, 0x01, 0x03, 0x14, 0x00, 0x00,
132 
133             0x03, 0x01, 0x00,
134 
135             0x03, 0x02, 0x00, 0x40,
136 
137             0x03, 0x14, 0x00, 0x40, 0xFD, 0x00, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xC8, 0x00,
138             0x40, 0x01, 0x03, 0x54, 0x00, 0x00,
139         };
140 
141         otExternalRouteConfig routes[] = {
142             {
143                 {
144                     {{{0xfd, 0x00, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145                        0x00}}},
146                     64,
147                 },
148                 0xc800, // mRloc16
149                 1,      // mPreference
150                 false,  // mNat64
151                 false,  // mStable
152                 false,  // mNextHopIsThisDevice
153                 false,  // mAdvPio
154             },
155             {
156                 {
157                     {{{0xfd, 0x00, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158                        0x00}}},
159                     64,
160                 },
161                 0x5400, // mRloc16
162                 0,      // mPreference
163                 false,  // mNat64
164                 true,   // mStable
165                 false,  // mNextHopIsThisDevice
166                 false,  // mAdvPio
167             },
168         };
169 
170         const uint16_t kRlocs[]            = {0xc800, 0x5400};
171         const uint16_t kNonExistingRlocs[] = {0xc700, 0x0000, 0x5401};
172 
173         NetworkData netData(*instance, kNetworkData, sizeof(kNetworkData));
174 
175         iter = OT_NETWORK_DATA_ITERATOR_INIT;
176 
177         printf("\nTest #1: Network data 1");
178         printf("\n-------------------------------------------------");
179 
180         for (const auto &route : routes)
181         {
182             SuccessOrQuit(netData.GetNextExternalRoute(iter, rconfig));
183             PrintExternalRouteConfig(rconfig);
184             VerifyOrQuit(CompareExternalRouteConfig(rconfig, route));
185         }
186 
187         VerifyOrQuit(netData.GetNextExternalRoute(iter, rconfig) == kErrorNotFound);
188 
189         netData.FindRlocs(kAnyBrOrServer, kAnyRole, rlocs);
190         VerifyRlocsArray(rlocs, kRlocs);
191 
192         netData.FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs);
193         VerifyRlocsArray(rlocs, kRlocs);
194 
195         netData.FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs);
196         VerifyOrQuit(rlocs.GetLength() == 0);
197 
198         netData.FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
199         VerifyRlocsArray(rlocs, kRlocs);
200         VerifyOrQuit(netData.CountBorderRouters(kAnyRole) == GetArrayLength(kRlocs));
201 
202         netData.FindRlocs(kBrProvidingExternalIpConn, kRouterRoleOnly, rlocs);
203         VerifyRlocsArray(rlocs, kRlocs);
204         VerifyOrQuit(netData.CountBorderRouters(kRouterRoleOnly) == GetArrayLength(kRlocs));
205 
206         netData.FindRlocs(kBrProvidingExternalIpConn, kChildRoleOnly, rlocs);
207         VerifyOrQuit(rlocs.GetLength() == 0);
208         VerifyOrQuit(netData.CountBorderRouters(kChildRoleOnly) == 0);
209 
210         for (uint16_t rloc16 : kRlocs)
211         {
212             VerifyOrQuit(netData.ContainsBorderRouterWithRloc(rloc16));
213         }
214 
215         for (uint16_t rloc16 : kNonExistingRlocs)
216         {
217             VerifyOrQuit(!netData.ContainsBorderRouterWithRloc(rloc16));
218         }
219     }
220 
221     {
222         const uint8_t kNetworkData[] = {
223             0x08, 0x04, 0x0B, 0x02, 0x00, 0x00, 0x03, 0x1E, 0x00, 0x40, 0xFD, 0x00, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00,
224             0x07, 0x02, 0x11, 0x40, 0x00, 0x03, 0x10, 0x00, 0x40, 0x01, 0x03, 0x54, 0x00, 0x00, 0x05, 0x04, 0x54, 0x00,
225             0x31, 0x00, 0x02, 0x0F, 0x00, 0x40, 0xFD, 0x00, 0xAB, 0xBA, 0xCD, 0xDC, 0x00, 0x00, 0x00, 0x03, 0x10, 0x00,
226             0x20, 0x03, 0x0E, 0x00, 0x20, 0xFD, 0x00, 0xAB, 0xBA, 0x01, 0x06, 0x54, 0x00, 0x00, 0x04, 0x01, 0x00,
227         };
228 
229         otExternalRouteConfig routes[] = {
230             {
231                 {
232                     {{{0xfd, 0x00, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
233                        0x00}}},
234                     64,
235                 },
236                 0x1000, // mRloc16
237                 1,      // mPreference
238                 false,  // mNat64
239                 false,  // mStable
240                 false,  // mNextHopIsThisDevice
241             },
242             {
243                 {
244                     {{{0xfd, 0x00, 0x12, 0x34, 0x56, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
245                        0x00}}},
246                     64,
247                 },
248                 0x5400, // mRloc16
249                 0,      // mPreference
250                 false,  // mNat64
251                 true,   // mStable
252                 false,  // mNextHopIsThisDevice
253             },
254             {
255                 {
256                     {{{0xfd, 0x00, 0xab, 0xba, 0xcd, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
257                        0x00}}},
258                     64,
259                 },
260                 0x1000, // mRloc16
261                 0,      // mPreference
262                 true,   // mNat64
263                 false,  // mStable
264                 false,  // mNextHopIsThisDevice
265             },
266             {
267                 {
268                     {{{0xfd, 0x00, 0xab, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
269                        0x00}}},
270                     32,
271                 },
272                 0x5400, // mRloc16
273                 0,      // mPreference
274                 false,  // mNat64
275                 true,   // mStable
276                 false,  // mNextHopIsThisDevice
277             },
278             {
279                 {
280                     {{{0xfd, 0x00, 0xab, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
281                        0x00}}},
282                     32,
283                 },
284                 0x0401, // mRloc16
285                 0,      // mPreference
286                 false,  // mNat64
287                 true,   // mStable
288                 false,  // mNextHopIsThisDevice
289             },
290         };
291 
292         const uint16_t kRlocsAnyRole[]     = {0x1000, 0x5400, 0x0401};
293         const uint16_t kRlocsRouterRole[]  = {0x1000, 0x5400};
294         const uint16_t kRlocsChildRole[]   = {0x0401};
295         const uint16_t kNonExistingRlocs[] = {0x6000, 0x0000, 0x0402};
296 
297         NetworkData netData(*instance, kNetworkData, sizeof(kNetworkData));
298 
299         iter = OT_NETWORK_DATA_ITERATOR_INIT;
300 
301         printf("\nTest #2: Network data 2");
302         printf("\n-------------------------------------------------");
303 
304         for (const auto &route : routes)
305         {
306             SuccessOrQuit(netData.GetNextExternalRoute(iter, rconfig));
307             PrintExternalRouteConfig(rconfig);
308             VerifyOrQuit(CompareExternalRouteConfig(rconfig, route));
309         }
310 
311         netData.FindRlocs(kAnyBrOrServer, kAnyRole, rlocs);
312         VerifyRlocsArray(rlocs, kRlocsAnyRole);
313 
314         netData.FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs);
315         VerifyRlocsArray(rlocs, kRlocsRouterRole);
316 
317         netData.FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs);
318         VerifyRlocsArray(rlocs, kRlocsChildRole);
319 
320         netData.FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
321         VerifyRlocsArray(rlocs, kRlocsAnyRole);
322         VerifyOrQuit(netData.CountBorderRouters(kAnyRole) == GetArrayLength(kRlocsAnyRole));
323 
324         netData.FindRlocs(kBrProvidingExternalIpConn, kRouterRoleOnly, rlocs);
325         VerifyRlocsArray(rlocs, kRlocsRouterRole);
326         VerifyOrQuit(netData.CountBorderRouters(kRouterRoleOnly) == GetArrayLength(kRlocsRouterRole));
327 
328         netData.FindRlocs(kBrProvidingExternalIpConn, kChildRoleOnly, rlocs);
329         VerifyRlocsArray(rlocs, kRlocsChildRole);
330         VerifyOrQuit(netData.CountBorderRouters(kChildRoleOnly) == GetArrayLength(kRlocsChildRole));
331 
332         netData.FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
333         VerifyRlocsArray(rlocs, kRlocsAnyRole);
334 
335         for (uint16_t rloc16 : kRlocsAnyRole)
336         {
337             VerifyOrQuit(netData.ContainsBorderRouterWithRloc(rloc16));
338         }
339 
340         for (uint16_t rloc16 : kNonExistingRlocs)
341         {
342             VerifyOrQuit(!netData.ContainsBorderRouterWithRloc(rloc16));
343         }
344     }
345 
346     {
347         const uint8_t kNetworkData[] = {
348             0x08, 0x04, 0x0b, 0x02, 0x36, 0xcc, 0x03, 0x1c, 0x00, 0x40, 0xfd, 0x00, 0xbe, 0xef, 0xca, 0xfe,
349             0x00, 0x00, 0x05, 0x0c, 0x28, 0x00, 0x33, 0x00, 0x28, 0x01, 0x33, 0x00, 0x4c, 0x00, 0x31, 0x00,
350             0x07, 0x02, 0x11, 0x40, 0x03, 0x14, 0x00, 0x40, 0xfd, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00,
351             0x05, 0x04, 0x28, 0x00, 0x73, 0x00, 0x07, 0x02, 0x12, 0x40, 0x03, 0x12, 0x00, 0x40, 0xfd, 0x00,
352             0x33, 0x33, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0xec, 0x00, 0x00, 0x28, 0x01, 0xc0,
353         };
354 
355         otExternalRouteConfig routes[] = {
356             {
357                 {
358                     {{{0xfd, 0x00, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
359                        0x00}}},
360                     64,
361                 },
362                 0xec00, // mRloc16
363                 0,      // mPreference
364                 false,  // mNat64
365                 true,   // mStable
366                 false,  // mNextHopIsThisDevice
367             },
368             {
369                 {
370                     {{{0xfd, 0x00, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
371                        0x00}}},
372                     64,
373                 },
374                 0x2801, // mRloc16
375                 -1,     // mPreference
376                 false,  // mNat64
377                 true,   // mStable
378                 false,  // mNextHopIsThisDevice
379             },
380         };
381 
382         otBorderRouterConfig prefixes[] = {
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                 0x2800, // 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                 true,   // mDefaultRoute
413                 true,   // mOnMesh
414                 true,   // mStable
415                 false,  // mNdDns
416                 false,  // mDp
417                 0x2801, // mRloc16
418             },
419             {
420                 {
421                     {{{0xfd, 0x00, 0xbe, 0xef, 0xca, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
422                        0x00}}},
423                     64,
424                 },
425                 0,      // mPreference
426                 true,   // mPreferred
427                 true,   // mSlaac
428                 false,  // mDhcp
429                 true,   // mConfigure
430                 false,  // mDefaultRoute
431                 true,   // mOnMesh
432                 true,   // mStable
433                 false,  // mNdDns
434                 false,  // mDp
435                 0x4c00, // mRloc16
436             },
437             {
438                 {
439                     {{{0xfd, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
440                        0x00}}},
441                     64,
442                 },
443                 1,      // mPreference
444                 true,   // mPreferred
445                 true,   // mSlaac
446                 false,  // mDhcp
447                 true,   // mConfigure
448                 true,   // mDefaultRoute
449                 true,   // mOnMesh
450                 true,   // mStable
451                 false,  // mNdDns
452                 false,  // mDp
453                 0x2800, // mRloc16
454             },
455         };
456 
457         const uint16_t kRlocsAnyRole[]      = {0xec00, 0x2801, 0x2800, 0x4c00};
458         const uint16_t kRlocsRouterRole[]   = {0xec00, 0x2800, 0x4c00};
459         const uint16_t kRlocsChildRole[]    = {0x2801};
460         const uint16_t kBrRlocsAnyRole[]    = {0xec00, 0x2801, 0x2800};
461         const uint16_t kBrRlocsRouterRole[] = {0xec00, 0x2800};
462         const uint16_t kBrRlocsChildRole[]  = {0x2801};
463         const uint16_t kNonExistingRlocs[]  = {0x6000, 0x0000, 0x2806, 0x4c00};
464 
465         NetworkData netData(*instance, kNetworkData, sizeof(kNetworkData));
466 
467         printf("\nTest #3: Network data 3");
468         printf("\n-------------------------------------------------");
469 
470         iter = OT_NETWORK_DATA_ITERATOR_INIT;
471 
472         for (const auto &route : routes)
473         {
474             SuccessOrQuit(netData.GetNextExternalRoute(iter, rconfig));
475             PrintExternalRouteConfig(rconfig);
476             VerifyOrQuit(CompareExternalRouteConfig(rconfig, route));
477         }
478 
479         iter = OT_NETWORK_DATA_ITERATOR_INIT;
480 
481         for (const auto &prefix : prefixes)
482         {
483             SuccessOrQuit(netData.GetNextOnMeshPrefix(iter, pconfig));
484             PrintOnMeshPrefixConfig(pconfig);
485             VerifyOrQuit(CompareOnMeshPrefixConfig(pconfig, prefix));
486         }
487 
488         netData.FindRlocs(kAnyBrOrServer, kAnyRole, rlocs);
489         VerifyRlocsArray(rlocs, kRlocsAnyRole);
490 
491         netData.FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs);
492         VerifyRlocsArray(rlocs, kRlocsRouterRole);
493 
494         netData.FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs);
495         VerifyRlocsArray(rlocs, kRlocsChildRole);
496 
497         netData.FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
498         VerifyRlocsArray(rlocs, kBrRlocsAnyRole);
499         VerifyOrQuit(netData.CountBorderRouters(kAnyRole) == GetArrayLength(kBrRlocsAnyRole));
500 
501         netData.FindRlocs(kBrProvidingExternalIpConn, kRouterRoleOnly, rlocs);
502         VerifyRlocsArray(rlocs, kBrRlocsRouterRole);
503         VerifyOrQuit(netData.CountBorderRouters(kRouterRoleOnly) == GetArrayLength(kBrRlocsRouterRole));
504 
505         netData.FindRlocs(kBrProvidingExternalIpConn, kChildRoleOnly, rlocs);
506         VerifyRlocsArray(rlocs, kBrRlocsChildRole);
507         VerifyOrQuit(netData.CountBorderRouters(kChildRoleOnly) == GetArrayLength(kBrRlocsChildRole));
508 
509         for (uint16_t rloc16 : kBrRlocsAnyRole)
510         {
511             VerifyOrQuit(netData.ContainsBorderRouterWithRloc(rloc16));
512         }
513 
514         for (uint16_t rloc16 : kNonExistingRlocs)
515         {
516             VerifyOrQuit(!netData.ContainsBorderRouterWithRloc(rloc16));
517         }
518     }
519 
520     testFreeInstance(instance);
521 }
522 
523 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
524 
525 class TestNetworkData : public Local
526 {
527 public:
TestNetworkData(Instance & aInstance)528     explicit TestNetworkData(Instance &aInstance)
529         : Local(aInstance)
530     {
531     }
532 
AddService(const ServiceData & aServiceData)533     Error AddService(const ServiceData &aServiceData)
534     {
535         return Local::AddService(ServiceTlv::kThreadEnterpriseNumber, aServiceData, true, ServerData());
536     }
537 
ValidateServiceData(const ServiceTlv * aServiceTlv,const ServiceData & aServiceData) const538     Error ValidateServiceData(const ServiceTlv *aServiceTlv, const ServiceData &aServiceData) const
539     {
540         Error       error = kErrorFailed;
541         ServiceData serviceData;
542 
543         VerifyOrExit(aServiceTlv != nullptr);
544         aServiceTlv->GetServiceData(serviceData);
545 
546         VerifyOrExit(aServiceData == serviceData);
547         error = kErrorNone;
548 
549     exit:
550         return error;
551     }
552 
Test(void)553     void Test(void)
554     {
555         const uint8_t kServiceData1[] = {0x02};
556         const uint8_t kServiceData2[] = {0xab};
557         const uint8_t kServiceData3[] = {0xab, 0x00};
558         const uint8_t kServiceData4[] = {0x02, 0xab, 0xcd, 0xef};
559         const uint8_t kServiceData5[] = {0x02, 0xab, 0xcd};
560 
561         const ServiceTlv *tlv;
562         ServiceData       serviceData1;
563         ServiceData       serviceData2;
564         ServiceData       serviceData3;
565         ServiceData       serviceData4;
566         ServiceData       serviceData5;
567 
568         serviceData1.InitFrom(kServiceData1);
569         serviceData2.InitFrom(kServiceData2);
570         serviceData3.InitFrom(kServiceData3);
571         serviceData4.InitFrom(kServiceData4);
572         serviceData5.InitFrom(kServiceData5);
573 
574         SuccessOrQuit(AddService(serviceData1));
575         SuccessOrQuit(AddService(serviceData2));
576         SuccessOrQuit(AddService(serviceData3));
577         SuccessOrQuit(AddService(serviceData4));
578         SuccessOrQuit(AddService(serviceData5));
579 
580         DumpBuffer("netdata", GetBytes(), GetLength());
581 
582         // Iterate through all entries that start with { 0x02 } (kServiceData1)
583         tlv = nullptr;
584         tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData1, kServicePrefixMatch);
585         SuccessOrQuit(ValidateServiceData(tlv, serviceData1));
586         tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData1, kServicePrefixMatch);
587         SuccessOrQuit(ValidateServiceData(tlv, serviceData4));
588         tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData1, kServicePrefixMatch);
589         SuccessOrQuit(ValidateServiceData(tlv, serviceData5));
590         tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData1, kServicePrefixMatch);
591         VerifyOrQuit(tlv == nullptr, "FindNextService() returned extra TLV");
592 
593         // Iterate through all entries that start with { 0xab } (serviceData2)
594         tlv = nullptr;
595         tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData2, kServicePrefixMatch);
596         SuccessOrQuit(ValidateServiceData(tlv, serviceData2));
597         tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData2, kServicePrefixMatch);
598         SuccessOrQuit(ValidateServiceData(tlv, serviceData3));
599         tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData2, kServicePrefixMatch);
600         VerifyOrQuit(tlv == nullptr, "FindNextService() returned extra TLV");
601 
602         // Iterate through all entries that start with serviceData5
603         tlv = nullptr;
604         tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData5, kServicePrefixMatch);
605         SuccessOrQuit(ValidateServiceData(tlv, serviceData4));
606         tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData5, kServicePrefixMatch);
607         SuccessOrQuit(ValidateServiceData(tlv, serviceData5));
608         tlv = FindNextService(tlv, ServiceTlv::kThreadEnterpriseNumber, serviceData5, kServicePrefixMatch);
609         VerifyOrQuit(tlv == nullptr, "FindNextService() returned extra TLV");
610     }
611 };
612 
TestNetworkDataFindNextService(void)613 void TestNetworkDataFindNextService(void)
614 {
615     Instance *instance;
616 
617     printf("\n\n-------------------------------------------------");
618     printf("\nTestNetworkDataFindNextService()\n");
619 
620     instance = testInitInstance();
621     VerifyOrQuit(instance != nullptr);
622 
623     {
624         TestNetworkData netData(*instance);
625         netData.Test();
626     }
627 }
628 
629 #endif // OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
630 
TestNetworkDataDsnSrpServices(void)631 void TestNetworkDataDsnSrpServices(void)
632 {
633     class TestLeader : public Leader
634     {
635     public:
636         void Populate(const uint8_t *aTlvs, uint8_t aTlvsLength)
637         {
638             memcpy(GetBytes(), aTlvs, aTlvsLength);
639             SetLength(aTlvsLength);
640         }
641     };
642 
643     Instance *instance;
644 
645     printf("\n\n-------------------------------------------------");
646     printf("\nTestNetworkDataDsnSrpServices()\n");
647 
648     instance = testInitInstance();
649     VerifyOrQuit(instance != nullptr);
650 
651     {
652         struct AnycastEntry
653         {
654             uint16_t mAloc16;
655             uint8_t  mSequenceNumber;
656             uint8_t  mVersion;
657             uint16_t mRloc16;
658 
659             bool Matches(Service::DnsSrpAnycastInfo aInfo) const
660             {
661                 VerifyOrQuit(aInfo.mAnycastAddress.GetIid().IsAnycastServiceLocator());
662 
663                 return (aInfo.mAnycastAddress.GetIid().GetLocator() == mAloc16) &&
664                        (aInfo.mSequenceNumber == mSequenceNumber) && (aInfo.mVersion == mVersion) &&
665                        (aInfo.mRloc16 == mRloc16);
666             }
667         };
668 
669         struct UnicastEntry
670         {
671             const char *mAddress;
672             uint16_t    mPort;
673             uint8_t     mVersion;
674             uint16_t    mRloc16;
675 
676             bool Matches(const Service::DnsSrpUnicastInfo &aInfo) const
677             {
678                 Ip6::SockAddr sockAddr;
679 
680                 SuccessOrQuit(sockAddr.GetAddress().FromString(mAddress));
681                 sockAddr.SetPort(mPort);
682 
683                 return (aInfo.mSockAddr == sockAddr) && (aInfo.mVersion == mVersion) && (aInfo.mRloc16 == mRloc16);
684             }
685         };
686 
687         const uint8_t kNetworkData[] = {
688             0x0b, 0x01, 0x00,
689 
690             0x0b, 0x0b, 0x80, 0x02, 0x5c, 0x02, 0x0d, 0x01, 0x00, 0x0d, 0x02, 0x28, 0x00,
691 
692             0x0b, 0x09, 0x81, 0x02, 0x5c, 0xff, 0x0d, 0x03, 0x6c, 0x00, 0x05,
693 
694             0x0b, 0x09, 0x82, 0x03, 0x5c, 0x03, 0xaa, 0x0d, 0x02, 0x4c, 0x00,
695 
696             0x0b, 0x36, 0x83, 0x14, 0x5d, 0xfd, 0xde, 0xad, 0x00, 0xbe, 0xef, 0x00, 0x00, 0x2d,
697             0x0e, 0xc6, 0x27, 0x55, 0x56, 0x18, 0xd9, 0x12, 0x34, 0x03, 0x0d, 0x02, 0x00, 0x00,
698             0x0d, 0x14, 0x6c, 0x00, 0xfd, 0x00, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11,
699             0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0xab, 0xcd, 0x0d, 0x04, 0x28, 0x00, 0x56, 0x78,
700 
701             0x0b, 0x24, 0x84, 0x01, 0x5d, 0x0d, 0x02, 0x00, 0x00, 0x0d, 0x15, 0x4c, 0x00, 0xfd,
702             0x00, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x01, 0x23, 0x45, 0x67, 0x89,
703             0xab, 0x00, 0x0e, 0x01, 0x0d, 0x04, 0x6c, 0x00, 0xcd, 0x12,
704 
705             0x0b, 0x08, 0x84, 0x01, 0x5c, 0x0d, 0x02, 0x14, 0x01, 0x0d,
706 
707             0x0b, 0x07, 0x83, 0x01, 0x5c, 0x0d, 0x02, 0x28, 0x00,
708 
709             0x0b, 0x13, 0x83, 0x02, 0x5c, 0xfe, 0x0d, 0x03, 0x12, 0x00, 0x07, 0x0d, 0x03, 0x12,
710             0x01, 0x06, 0x0d, 0x03, 0x16, 0x00, 0x07,
711         };
712 
713         const AnycastEntry kAnycastEntries[] = {
714             {0xfc10, 0x02, 0, 0x2800}, {0xfc11, 0xff, 5, 0x6c00}, {0xfc12, 0x03, 0, 0x4c00},
715             {0xfc13, 0xfe, 7, 0x1200}, {0xfc13, 0xfe, 6, 0x1201}, {0xfc13, 0xfe, 7, 0x1600},
716         };
717 
718         const UnicastEntry kUnicastEntriesFromServerData[] = {
719             {"fd00:aabb:ccdd:eeff:11:2233:4455:6677", 0xabcd, 0, 0x6c00},
720             {"fdde:ad00:beef:0:0:ff:fe00:2800", 0x5678, 0, 0x2800},
721             {"fd00:1234:5678:9abc:def0:123:4567:89ab", 0x0e, 1, 0x4c00},
722             {"fdde:ad00:beef:0:0:ff:fe00:6c00", 0xcd12, 0, 0x6c00},
723         };
724 
725         const UnicastEntry kUnicastEntriesFromServiceData[] = {
726             {"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, 3, 0x0000},
727             {"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, 3, 0x6c00},
728             {"fdde:ad00:beef:0:2d0e:c627:5556:18d9", 0x1234, 3, 0x2800},
729         };
730 
731         const uint16_t kExpectedRlocs[]       = {0x6c00, 0x2800, 0x4c00, 0x0000, 0x1200, 0x1201, 0x1600, 0x1401};
732         const uint16_t kExpectedRouterRlocs[] = {0x6c00, 0x2800, 0x4c00, 0x0000, 0x1200, 0x1600};
733         const uint16_t kExpectedChildRlocs[]  = {0x1201, 0x1401};
734 
735         const uint8_t kPreferredAnycastEntryIndex = 2;
736 
737         Service::Manager          &manager = instance->Get<Service::Manager>();
738         Service::Manager::Iterator iterator;
739         Service::DnsSrpAnycastInfo anycastInfo;
740         Service::DnsSrpUnicastInfo unicastInfo;
741         Service::DnsSrpUnicastType type;
742         Rlocs                      rlocs;
743 
744         reinterpret_cast<TestLeader &>(instance->Get<Leader>()).Populate(kNetworkData, sizeof(kNetworkData));
745 
746         DumpBuffer("netdata", kNetworkData, sizeof(kNetworkData));
747 
748         // Verify `FindRlocs()`
749 
750         instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kAnyRole, rlocs);
751         VerifyRlocsArray(rlocs, kExpectedRlocs);
752 
753         instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kRouterRoleOnly, rlocs);
754         VerifyRlocsArray(rlocs, kExpectedRouterRlocs);
755 
756         instance->Get<Leader>().FindRlocs(kAnyBrOrServer, kChildRoleOnly, rlocs);
757         VerifyRlocsArray(rlocs, kExpectedChildRlocs);
758 
759         instance->Get<Leader>().FindRlocs(kBrProvidingExternalIpConn, kAnyRole, rlocs);
760         VerifyOrQuit(rlocs.GetLength() == 0);
761 
762         // Verify all the "DNS/SRP Anycast Service" entries in Network Data
763 
764         printf("\n- - - - - - - - - - - - - - - - - - - -");
765         printf("\nDNS/SRP Anycast Service entries\n");
766 
767         for (const AnycastEntry &entry : kAnycastEntries)
768         {
769             SuccessOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo));
770 
771             printf("\nanycastInfo { %s, seq:%d, rlco16:%04x, version:%u }",
772                    anycastInfo.mAnycastAddress.ToString().AsCString(), anycastInfo.mSequenceNumber, anycastInfo.mRloc16,
773                    anycastInfo.mVersion);
774 
775             VerifyOrQuit(entry.Matches(anycastInfo), "GetNextDnsSrpAnycastInfo() returned incorrect info");
776         }
777 
778         VerifyOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo) == kErrorNotFound,
779                      "GetNextDnsSrpAnycastInfo() returned unexpected extra entry");
780 
781         // Find the preferred "DNS/SRP Anycast Service" entries in Network Data
782 
783         SuccessOrQuit(manager.FindPreferredDnsSrpAnycastInfo(anycastInfo));
784 
785         printf("\n\nPreferred anycastInfo { %s, seq:%d, version:%u }",
786                anycastInfo.mAnycastAddress.ToString().AsCString(), anycastInfo.mSequenceNumber, anycastInfo.mVersion);
787 
788         VerifyOrQuit(kAnycastEntries[kPreferredAnycastEntryIndex].Matches(anycastInfo),
789                      "FindPreferredDnsSrpAnycastInfo() returned invalid info");
790 
791         printf("\n\n- - - - - - - - - - - - - - - - - - - -");
792         printf("\nDNS/SRP Unicast Service entries (server data)\n");
793 
794         iterator.Clear();
795         type = Service::kAddrInServerData;
796 
797         for (const UnicastEntry &entry : kUnicastEntriesFromServerData)
798         {
799             SuccessOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, type, unicastInfo));
800             printf("\nunicastInfo { %s, rloc16:%04x }", unicastInfo.mSockAddr.ToString().AsCString(),
801                    unicastInfo.mRloc16);
802 
803             VerifyOrQuit(entry.Matches(unicastInfo), "GetNextDnsSrpUnicastInfo() returned incorrect info");
804         }
805 
806         VerifyOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, type, unicastInfo) == kErrorNotFound,
807                      "GetNextDnsSrpUnicastInfo() returned unexpected extra entry");
808 
809         printf("\n\n- - - - - - - - - - - - - - - - - - - -");
810         printf("\nDNS/SRP Unicast Service entries (service data)\n");
811 
812         iterator.Clear();
813         type = Service::kAddrInServiceData;
814 
815         for (const UnicastEntry &entry : kUnicastEntriesFromServiceData)
816         {
817             SuccessOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, type, unicastInfo));
818             printf("\nunicastInfo { %s, rloc16:%04x }", unicastInfo.mSockAddr.ToString().AsCString(),
819                    unicastInfo.mRloc16);
820 
821             VerifyOrQuit(entry.Matches(unicastInfo), "GetNextDnsSrpUnicastInfo() returned incorrect info");
822         }
823 
824         VerifyOrQuit(manager.GetNextDnsSrpUnicastInfo(iterator, type, unicastInfo) == kErrorNotFound,
825                      "GetNextDnsSrpUnicastInfo() returned unexpected extra entry");
826 
827         printf("\n");
828     }
829 
830     testFreeInstance(instance);
831 }
832 
TestNetworkDataDsnSrpAnycastSeqNumSelection(void)833 void TestNetworkDataDsnSrpAnycastSeqNumSelection(void)
834 {
835     class TestLeader : public Leader
836     {
837     public:
838         void Populate(const uint8_t *aTlvs, uint8_t aTlvsLength)
839         {
840             memcpy(GetBytes(), aTlvs, aTlvsLength);
841             SetLength(aTlvsLength);
842         }
843     };
844 
845     struct TestInfo
846     {
847         const uint8_t *mNetworkData;
848         uint8_t        mNetworkDataLength;
849         const uint8_t *mSeqNumbers;
850         uint8_t        mSeqNumbersLength;
851         uint8_t        mPreferredSeqNum;
852         uint8_t        mPreferredVersion;
853     };
854 
855     Instance *instance;
856 
857     printf("\n\n-------------------------------------------------");
858     printf("\nTestNetworkDataDsnSrpAnycastSeqNumSelection()\n");
859 
860     instance = testInitInstance();
861     VerifyOrQuit(instance != nullptr);
862 
863     const uint8_t kNetworkData1[] = {
864         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
865         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Service TLV
866         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x81, 0x0d, 0x02, 0x50, 0x01, // Service TLV
867     };
868     const uint8_t kSeqNumbers1[]    = {1, 129};
869     const uint8_t kPreferredSeqNum1 = 129;
870     const uint8_t kPreferredVer1    = 0;
871 
872     const uint8_t kNetworkData2[] = {
873         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
874         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x85, 0x0d, 0x02, 0x50, 0x00, // Service TLV
875         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x05, 0x0d, 0x02, 0x50, 0x01, // Service TLV
876     };
877     const uint8_t kSeqNumbers2[]    = {133, 5};
878     const uint8_t kPreferredSeqNum2 = 133;
879     const uint8_t kPreferredVer2    = 0;
880 
881     const uint8_t kNetworkData3[] = {
882         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
883         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Service TLV
884         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Service TLV
885         0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Service TLV
886     };
887     const uint8_t kSeqNumbers3[]    = {1, 2, 255};
888     const uint8_t kPreferredSeqNum3 = 2;
889     const uint8_t kPreferredVer3    = 0;
890 
891     const uint8_t kNetworkData4[] = {
892         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
893         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x00, // Service TLV
894         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x01, // Service TLV
895         0x0b, 0x08, 0x82, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x02, // Service TLV
896     };
897     const uint8_t kSeqNumbers4[]    = {10, 130, 250};
898     const uint8_t kPreferredSeqNum4 = 250;
899     const uint8_t kPreferredVer4    = 0;
900 
901     const uint8_t kNetworkData5[] = {
902         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
903         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x00, // Service TLV
904         0x0b, 0x08, 0x81, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x01, // Service TLV
905         0x0b, 0x08, 0x82, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x02, // Service TLV
906     };
907     const uint8_t kSeqNumbers5[]    = {130, 250, 10};
908     const uint8_t kPreferredSeqNum5 = 250;
909     const uint8_t kPreferredVer5    = 0;
910 
911     const uint8_t kNetworkData6[] = {
912         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
913         0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x00, // Service TLV
914         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x01, // Service TLV
915         0x0b, 0x08, 0x82, 0x02, 0x5c, 0x82, 0x0d, 0x02, 0x50, 0x02, // Service TLV
916     };
917     const uint8_t kSeqNumbers6[]    = {250, 10, 130};
918     const uint8_t kPreferredSeqNum6 = 250;
919     const uint8_t kPreferredVer6    = 0;
920 
921     const uint8_t kNetworkData7[] = {
922         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
923         0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfa, 0x0d, 0x02, 0x50, 0x00, // Service TLV
924         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x0a, 0x0d, 0x02, 0x50, 0x01, // Service TLV
925         0x0b, 0x08, 0x82, 0x02, 0x5c, 0x8A, 0x0d, 0x02, 0x50, 0x02, // Service TLV
926     };
927     const uint8_t kSeqNumbers7[]    = {250, 10, 138};
928     const uint8_t kPreferredSeqNum7 = 250;
929     const uint8_t kPreferredVer7    = 0;
930 
931     const uint8_t kNetworkData8[] = {
932         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
933         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Service TLV
934         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Service TLV
935         0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Service TLV
936         0x0b, 0x08, 0x83, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x03, // Service TLV
937 
938     };
939     const uint8_t kSeqNumbers8[]    = {1, 2, 255, 254};
940     const uint8_t kPreferredSeqNum8 = 2;
941     const uint8_t kPreferredVer8    = 0;
942 
943     const uint8_t kNetworkData9[] = {
944         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
945         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Service TLV
946         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Service TLV
947         0x0b, 0x08, 0x82, 0x02, 0x5c, 0xff, 0x0d, 0x02, 0x50, 0x02, // Service TLV
948         0x0b, 0x08, 0x83, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x03, // Service TLV
949 
950     };
951     const uint8_t kSeqNumbers9[]    = {1, 2, 255, 254};
952     const uint8_t kPreferredSeqNum9 = 2;
953     const uint8_t kPreferredVer9    = 0;
954 
955     const uint8_t kNetworkData10[] = {
956         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
957         0x0b, 0x08, 0x80, 0x02, 0x5c, 0xfe, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
958         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
959         0x0b, 0x08, 0x82, 0x02, 0x5c, 0x78, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
960         0x0b, 0x08, 0x83, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV
961 
962     };
963     const uint8_t kSeqNumbers10[]    = {254, 2, 120, 1};
964     const uint8_t kPreferredSeqNum10 = 120;
965     const uint8_t kPreferredVer10    = 0;
966 
967     const uint8_t kNetworkData11[] = {
968         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
969         0x0b, 0x08, 0x80, 0x02, 0x5c, 0xf0, 0x0d, 0x02, 0x50, 0x00, // Server sub-TLV
970         0x0b, 0x08, 0x81, 0x02, 0x5c, 0x02, 0x0d, 0x02, 0x50, 0x01, // Server sub-TLV
971         0x0b, 0x08, 0x82, 0x02, 0x5c, 0x78, 0x0d, 0x02, 0x50, 0x02, // Server sub-TLV
972         0x0b, 0x08, 0x83, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x03, // Server sub-TLV
973 
974     };
975     const uint8_t kSeqNumbers11[]    = {240, 2, 120, 1};
976     const uint8_t kPreferredSeqNum11 = 240;
977     const uint8_t kPreferredVer11    = 0;
978 
979     const uint8_t kNetworkData12[] = {
980         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                               // Commissioning Data TLV
981         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00,       // Service TLV
982         0x0b, 0x09, 0x81, 0x02, 0x5c, 0x81, 0x0d, 0x03, 0x50, 0x01, 0x01, // Service TLV
983     };
984     const uint8_t kSeqNumbers12[]    = {1, 129};
985     const uint8_t kPreferredSeqNum12 = 129;
986     const uint8_t kPreferredVer12    = 1;
987 
988     const uint8_t kNetworkData13[] = {
989         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0,                         // Commissioning Data TLV
990         0x0b, 0x08, 0x80, 0x02, 0x5c, 0x01, 0x0d, 0x02, 0x50, 0x00, // Service TLV
991         0x0b, 0x0e, 0x81, 0x02, 0x5c, 0x81,                         // Service TLV
992         0x0d, 0x03, 0x50, 0x01, 0x02,                               // Server sub-TLV
993         0x0d, 0x03, 0x50, 0x02, 0x02,                               // Server sub-TLV
994     };
995     const uint8_t kSeqNumbers13[]    = {1, 129, 129};
996     const uint8_t kPreferredSeqNum13 = 129;
997     const uint8_t kPreferredVer13    = 2;
998 
999     const uint8_t kNetworkData14[] = {
1000         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Commissioning Data TLV
1001         0x0b, 0x13, 0x81, 0x02, 0x5c, 0x07, // Service TLV
1002         0x0d, 0x03, 0x50, 0x00, 0x01,       // Server sub-TLV
1003         0x0d, 0x03, 0x50, 0x01, 0x02,       // Server sub-TLV
1004         0x0d, 0x03, 0x50, 0x02, 0x03,       // Server sub-TLV
1005     };
1006     const uint8_t kSeqNumbers14[]    = {7, 7, 7};
1007     const uint8_t kPreferredSeqNum14 = 7;
1008     const uint8_t kPreferredVer14    = 1;
1009 
1010     const uint8_t kNetworkData15[] = {
1011         0x08, 0x04, 0x0b, 0x02, 0x50, 0xb0, // Commissioning Data TLV
1012         0x0b, 0x17, 0x81, 0x02, 0x5c, 0x03, // Service TLV
1013         0x0d, 0x03, 0x50, 0x00, 0x01,       // Server sub-TLV
1014         0x0d, 0x03, 0x50, 0x01, 0x02,       // Server sub-TLV
1015         0x0d, 0x02, 0x50, 0x02,             // Server sub-TLV
1016         0x0d, 0x03, 0x50, 0x03, 0x01,       // Server sub-TLV
1017     };
1018     const uint8_t kSeqNumbers15[]    = {3, 3, 3, 3};
1019     const uint8_t kPreferredSeqNum15 = 3;
1020     const uint8_t kPreferredVer15    = 0;
1021 
1022 #define TEST_CASE(Num)                                                                            \
1023     {                                                                                             \
1024         kNetworkData##Num, sizeof(kNetworkData##Num), kSeqNumbers##Num, sizeof(kSeqNumbers##Num), \
1025             kPreferredSeqNum##Num, kPreferredVer##Num                                             \
1026     }
1027 
1028     const TestInfo kTests[] = {
1029         TEST_CASE(1),  TEST_CASE(2),  TEST_CASE(3),  TEST_CASE(4),  TEST_CASE(5),
1030         TEST_CASE(6),  TEST_CASE(7),  TEST_CASE(8),  TEST_CASE(9),  TEST_CASE(10),
1031         TEST_CASE(11), TEST_CASE(12), TEST_CASE(13), TEST_CASE(14), TEST_CASE(15),
1032     };
1033 
1034     Service::Manager &manager   = instance->Get<Service::Manager>();
1035     uint8_t           testIndex = 0;
1036 
1037     for (const TestInfo &test : kTests)
1038     {
1039         Service::Manager::Iterator iterator;
1040         Service::DnsSrpAnycastInfo anycastInfo;
1041 
1042         reinterpret_cast<TestLeader &>(instance->Get<Leader>()).Populate(test.mNetworkData, test.mNetworkDataLength);
1043 
1044         printf("\n- - - - - - - - - - - - - - - - - - - -");
1045         printf("\nDNS/SRP Anycast Service entries for test %d", ++testIndex);
1046 
1047         for (uint8_t index = 0; index < test.mSeqNumbersLength; index++)
1048         {
1049             SuccessOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo));
1050 
1051             printf("\n { %s, seq:%u, version:%u, rlco16:%04x }", anycastInfo.mAnycastAddress.ToString().AsCString(),
1052 
1053                    anycastInfo.mSequenceNumber, anycastInfo.mVersion, anycastInfo.mRloc16);
1054 
1055             VerifyOrQuit(anycastInfo.mSequenceNumber == test.mSeqNumbers[index]);
1056             VerifyOrQuit(anycastInfo.mRloc16 == 0x5000 + index);
1057         }
1058 
1059         VerifyOrQuit(manager.GetNextDnsSrpAnycastInfo(iterator, anycastInfo) == kErrorNotFound);
1060         SuccessOrQuit(manager.FindPreferredDnsSrpAnycastInfo(anycastInfo));
1061 
1062         printf("\n preferred -> seq:%u, version:%u ", anycastInfo.mSequenceNumber, anycastInfo.mVersion);
1063         VerifyOrQuit(anycastInfo.mSequenceNumber == test.mPreferredSeqNum);
1064         VerifyOrQuit(anycastInfo.mVersion == test.mPreferredVersion);
1065     }
1066 
1067     testFreeInstance(instance);
1068 }
1069 
1070 } // namespace NetworkData
1071 } // namespace ot
1072 
main(void)1073 int main(void)
1074 {
1075     ot::NetworkData::TestNetworkDataIterator();
1076 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
1077     ot::NetworkData::TestNetworkDataFindNextService();
1078 #endif
1079     ot::NetworkData::TestNetworkDataDsnSrpServices();
1080     ot::NetworkData::TestNetworkDataDsnSrpAnycastSeqNumSelection();
1081 
1082     printf("\nAll tests passed\n");
1083     return 0;
1084 }
1085