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