Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / inet / tests / TestInetAddress.cpp
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *    Copyright (c) 2018-2019 Google LLC
5  *    Copyright (c) 2015-2018 Nest Labs, Inc.
6  *
7  *    Licensed under the Apache License, Version 2.0 (the "License");
8  *    you may not use this file except in compliance with the License.
9  *    You may obtain a copy of the License at
10  *
11  *        http://www.apache.org/licenses/LICENSE-2.0
12  *
13  *    Unless required by applicable law or agreed to in writing, software
14  *    distributed under the License is distributed on an "AS IS" BASIS,
15  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  *    See the License for the specific language governing permissions and
17  *    limitations under the License.
18  */
19
20 /**
21  *  @file
22  *    This file implements a unit test suite for <tt>chip::Inet::IPAddress</tt>,
23  *    a class to store and format IPV4 and IPV6 Internet Protocol addresses.
24  *
25  */
26
27 #include <inet/IPAddress.h>
28
29 #include <string.h>
30
31 #if CHIP_SYSTEM_CONFIG_USE_LWIP
32 #include <lwip/init.h>
33 #include <lwip/ip_addr.h>
34
35 #if LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS
36 #define htonl(x) lwip_htonl(x)
37 #endif
38
39 #else
40 #include <netinet/in.h>
41 #include <sys/socket.h>
42 #endif
43
44 #include <nlunit-test.h>
45
46 #include <inet/IPPrefix.h>
47
48 #include <support/CodeUtils.h>
49 #include <support/UnitTestRegistration.h>
50
51 using namespace chip;
52 using namespace chip::Inet;
53
54 // Preprocessor Defintions
55
56 // clang-format off
57 #define LLA_PREFIX             0xfe800000
58 #define ULA_PREFIX             0xfd000000
59 #define MCAST_PREFIX           0xff000000
60 #define NUM_MCAST_SCOPES       7
61 #define NUM_MCAST_GROUPS       2
62 #define NUM_BYTES_IN_IPV6      16
63 #define ULA_UP_24_BIT_MASK     0xffffff0000
64 #define ULA_LO_16_BIT_MASK     0x000000ffff
65 #define NUM_FIELDS_IN_ADDR     sizeof (IPAddress) / sizeof (uint32_t)
66 // clang-format on
67
68 namespace {
69
70 // Type Defintions
71
72 // Test input vector format.
73
74 enum
75 {
76     // clang-format off
77
78     kTestIsIPv4             = true,
79     kTestIsIPv6             = false,
80
81     kTestIsIPv4Multicast    = true,
82     kTestIsNotIPv4Multicast = false,
83
84     kTestIsIPv4Broadcast    = true,
85     kTestIsNotIPv4Broadcast = false,
86
87     kTestIsMulticast        = true,
88     kTestIsNotMulticast     = false,
89
90     kTestIsIPv6Multicast    = true,
91     kTestIsNotIPv6Multicast = false,
92
93     kTestIsIPv6ULA          = true,
94     kTestIsNotIPv6ULA       = false,
95
96     kTestIsIPv6LLA          = true,
97     kTestIsNotIPv6LLA       = false
98
99     // clang-format on
100 };
101
102 struct IPAddressContext
103 {
104     uint32_t mAddrQuartets[4];
105     const IPAddressType mAddrType;
106     const char * mAddrString;
107 };
108
109 typedef const struct IPAddressContext * IPAddressContextIterator;
110
111 struct IPAddressContextRange
112 {
113     IPAddressContextIterator mBegin;
114     IPAddressContextIterator mEnd;
115 };
116
117 struct IPAddressExpandedContext
118 {
119     IPAddressContext mAddr;
120     bool isIPv4;
121     bool isIPv4Multicast;
122     bool isIPv4Broadcast;
123     bool isMulticast;
124     bool isIPv6Multicast;
125     bool isIPv6ULA;
126     bool isIPv6LLA;
127
128     uint64_t global;
129     uint16_t subnet;
130     uint64_t interface;
131 };
132
133 typedef const struct IPAddressExpandedContext * IPAddressExpandedContextIterator;
134
135 struct IPAddressExpandedContextRange
136 {
137     IPAddressExpandedContextIterator mBegin;
138     IPAddressExpandedContextIterator mEnd;
139 };
140
141 struct TestContext
142 {
143     const IPAddressContextRange mIPv6WellKnownMulticastContextRange;
144     const IPAddressContextRange mIPv6TransientMulticastContextRange;
145     const IPAddressContextRange mIPv6PrefixMulticastContextRange;
146     const IPAddressExpandedContextRange mIPAddressExpandedContextRange;
147 };
148
149 // Global Variables
150
151 // clang-format off
152 const IPv6MulticastScope sIPv6MulticastScopes[NUM_MCAST_SCOPES] =
153 {
154     kIPv6MulticastScope_Interface,
155     kIPv6MulticastScope_Link,
156 #if INET_CONFIG_ENABLE_IPV4
157     kIPv6MulticastScope_IPv4,
158 #else
159     kIPv6MulticastScope_Realm,
160 #endif // INET_CONFIG_ENABLE_IPV4
161     kIPv6MulticastScope_Admin,
162     kIPv6MulticastScope_Site,
163     kIPv6MulticastScope_Organization,
164     kIPv6MulticastScope_Global
165 };
166
167 const IPV6MulticastGroup sIPv6WellKnownMulticastGroups[NUM_MCAST_GROUPS] = {
168     kIPV6MulticastGroup_AllNodes,
169     kIPV6MulticastGroup_AllRouters
170 };
171
172 // Test input data.
173
174 const struct IPAddressExpandedContext sIPAddressContext[] =
175 {
176     {
177          { { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, kIPAddressType_Any,
178         "::" },
179         kTestIsIPv6, kTestIsNotIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsNotMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
180         0x0, 0x0, 0x0
181     },
182     {
183         { { 0x26200001, 0x10e70400, 0xe83fb28f, 0x9c3a1941 }, kIPAddressType_IPv6,
184                                                                   "2620:1:10e7:400:e83f:b28f:9c3a:1941" } ,
185         kTestIsIPv6, kTestIsNotIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsNotMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
186         0x0, 0x0, 0x0
187     },
188     {
189          { { 0xfe800000, 0x00000000, 0x8edcd4ff, 0xfe3aebfb }, kIPAddressType_IPv6,
190         "fe80::8edc:d4ff:fe3a:ebfb" },
191         kTestIsIPv6, kTestIsNotIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsNotMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsIPv6LLA,
192         0x0, 0x0, 0x0
193     },
194     {
195          { { 0xff010000, 0x00000000, 0x00000000, 0x00000001 }, kIPAddressType_IPv6,
196         "ff01::1" },
197         kTestIsIPv6, kTestIsNotIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
198         0x0, 0x0, 0x0
199     },
200     {
201          { { 0xfd000000, 0x00010001, 0x00000000, 0x00000001 }, kIPAddressType_IPv6,
202         "fd00:0:1:1::1" },
203         kTestIsIPv6, kTestIsNotIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsNotMulticast, kTestIsNotIPv6Multicast, kTestIsIPv6ULA, kTestIsNotIPv6LLA,
204         0x1, 1, 1
205     },
206     {
207          { { 0xfd123456, 0x0001abcd, 0xabcdef00, 0xfedcba09 }, kIPAddressType_IPv6,
208         "fd12:3456:1:abcd:abcd:ef00:fedc:ba09" },
209         kTestIsIPv6, kTestIsNotIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsNotMulticast, kTestIsNotIPv6Multicast, kTestIsIPv6ULA, kTestIsNotIPv6LLA,
210         0x1234560001, 0xabcd, 0xabcdef00fedcba09
211     },
212     {
213          { { 0xfdffffff, 0xffffffff, 0xffffffff, 0xffffffff }, kIPAddressType_IPv6,
214         "fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" },
215         kTestIsIPv6, kTestIsNotIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsNotMulticast, kTestIsNotIPv6Multicast, kTestIsIPv6ULA, kTestIsNotIPv6LLA,
216         0xffffffffff, 0xffff, 0xffffffffffffffff
217     },
218 #if INET_CONFIG_ENABLE_IPV4
219     // IPv4-only
220     {
221          { { 0x00000000, 0x00000000, 0x0000ffff, 0xffffff00 }, kIPAddressType_IPv4,
222         "255.255.255.0" },
223         kTestIsIPv4, kTestIsNotIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsNotMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
224         0x0, 0x0, 0x0
225     },
226     {
227          { { 0x00000000, 0x00000000, 0x0000ffff, 0x7f000001 }, kIPAddressType_IPv4,
228         "127.0.0.1" },
229         kTestIsIPv4, kTestIsNotIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsNotMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
230         0x0, 0x0, 0x0
231     },
232     // IPv4 and IPv4 multicast
233
234     // IPv4 Local subnetwork multicast
235     {
236          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe0000000 }, kIPAddressType_IPv4,
237         "224.0.0.0" },
238         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
239         0x0, 0x0, 0x0
240     },
241     {
242          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe0000001 }, kIPAddressType_IPv4,
243         "224.0.0.1" },
244         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
245         0x0, 0x0, 0x0
246     },
247     {
248          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe0000080 }, kIPAddressType_IPv4,
249         "224.0.0.128" },
250         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
251         0x0, 0x0, 0x0
252     },
253     {
254          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe00000fe }, kIPAddressType_IPv4,
255         "224.0.0.254" },
256         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
257         0x0, 0x0, 0x0
258     },
259     {
260          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe00000ff }, kIPAddressType_IPv4,
261         "224.0.0.255" },
262         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
263         0x0, 0x0, 0x0
264     },
265     // IPv4 Internetwork control multicast
266     {
267          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe0000100 }, kIPAddressType_IPv4,
268         "224.0.1.0" },
269         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
270         0x0, 0x0, 0x0
271     },
272     {
273          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe0000101 }, kIPAddressType_IPv4,
274         "224.0.1.1" },
275         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
276         0x0, 0x0, 0x0
277     },
278     {
279          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe0000180 }, kIPAddressType_IPv4,
280         "224.0.1.128" },
281         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
282         0x0, 0x0, 0x0
283     },
284     {
285          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe00001fe }, kIPAddressType_IPv4,
286         "224.0.1.254" },
287         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
288         0x0, 0x0, 0x0
289     },
290     {
291          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe00001ff }, kIPAddressType_IPv4,
292         "224.0.1.255" },
293         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
294         0x0, 0x0, 0x0
295     },
296     // IPv4 AD-HOC block 1 multicast
297     {
298          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe0000200 }, kIPAddressType_IPv4,
299         "224.0.2.0" },
300         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
301         0x0, 0x0, 0x0
302     },
303     {
304          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe0000201 }, kIPAddressType_IPv4,
305         "224.0.2.1" },
306         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
307         0x0, 0x0, 0x0
308     },
309     {
310          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe0008100 }, kIPAddressType_IPv4,
311         "224.0.129.0" },
312         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
313         0x0, 0x0, 0x0
314     },
315     {
316          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe000fffe }, kIPAddressType_IPv4,
317         "224.0.255.254" },
318         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
319         0x0, 0x0, 0x0
320     },
321     {
322          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe000ffff }, kIPAddressType_IPv4,
323         "224.0.255.255" },
324         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
325         0x0, 0x0, 0x0
326     },
327     // IPv4 AD-HOC block 2 multicast
328     {
329          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe0030000 }, kIPAddressType_IPv4,
330         "224.3.0.0" },
331         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
332         0x0, 0x0, 0x0
333     },
334     {
335          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe0030001 }, kIPAddressType_IPv4,
336         "224.3.0.1" },
337         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
338         0x0, 0x0, 0x0
339     },
340     {
341          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe0040000 }, kIPAddressType_IPv4,
342         "224.4.0.0" },
343         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
344         0x0, 0x0, 0x0
345     },
346     {
347          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe004fffe }, kIPAddressType_IPv4,
348         "224.4.255.254" },
349         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
350         0x0, 0x0, 0x0
351     },
352     {
353          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe004ffff }, kIPAddressType_IPv4,
354         "224.4.255.255" },
355         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
356         0x0, 0x0, 0x0
357     },
358     // IPv4 source-specific multicast
359     {
360          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe8000000 }, kIPAddressType_IPv4,
361         "232.0.0.0" },
362         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
363         0x0, 0x0, 0x0
364     },
365     {
366          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe8000001 }, kIPAddressType_IPv4,
367         "232.0.0.1" },
368         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
369         0x0, 0x0, 0x0
370     },
371     {
372          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe8800000 }, kIPAddressType_IPv4,
373         "232.128.0.0" },
374         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
375         0x0, 0x0, 0x0
376     },
377     {
378          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe8fffffe }, kIPAddressType_IPv4,
379         "232.255.255.254" },
380         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
381         0x0, 0x0, 0x0
382     },
383     {
384          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe8ffffff }, kIPAddressType_IPv4,
385         "232.255.255.255" },
386         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
387         0x0, 0x0, 0x0
388     },
389     // IPv4 GLOP addressing multicast
390     {
391          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe9000000 }, kIPAddressType_IPv4,
392         "233.0.0.0" },
393         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
394         0x0, 0x0, 0x0
395     },
396     {
397          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe9000001 }, kIPAddressType_IPv4,
398         "233.0.0.1" },
399         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
400         0x0, 0x0, 0x0
401     },
402     {
403          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe97e0000 }, kIPAddressType_IPv4,
404         "233.126.0.0" },
405         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
406         0x0, 0x0, 0x0
407     },
408     {
409          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe9fbfffe }, kIPAddressType_IPv4,
410         "233.251.255.254" },
411         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
412         0x0, 0x0, 0x0
413     },
414     {
415          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe9fbffff }, kIPAddressType_IPv4,
416         "233.251.255.255" },
417         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
418         0x0, 0x0, 0x0
419     },
420     // IPv4 AD-HOC block 3 multicast
421     {
422          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe9fc0000 }, kIPAddressType_IPv4,
423         "233.252.0.0" },
424         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
425         0x0, 0x0, 0x0
426     },
427     {
428          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe9fc0001 }, kIPAddressType_IPv4,
429         "233.252.0.1" },
430         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
431         0x0, 0x0, 0x0
432     },
433     {
434          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe9fe0000 }, kIPAddressType_IPv4,
435         "233.254.0.0" },
436         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
437         0x0, 0x0, 0x0
438     },
439     {
440          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe9fffffe }, kIPAddressType_IPv4,
441         "233.255.255.254" },
442         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
443         0x0, 0x0, 0x0
444     },
445     {
446          { { 0x00000000, 0x00000000, 0x0000ffff, 0xe9ffffff }, kIPAddressType_IPv4,
447         "233.255.255.255" },
448         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
449         0x0, 0x0, 0x0
450     },
451     // IPv4 unicast-prefix-based multicast
452     {
453          { { 0x00000000, 0x00000000, 0x0000ffff, 0xea000000 }, kIPAddressType_IPv4,
454         "234.0.0.0" },
455         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
456         0x0, 0x0, 0x0
457     },
458     {
459          { { 0x00000000, 0x00000000, 0x0000ffff, 0xea000001 }, kIPAddressType_IPv4,
460         "234.0.0.1" },
461         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
462         0x0, 0x0, 0x0
463     },
464     {
465          { { 0x00000000, 0x00000000, 0x0000ffff, 0xea800000 }, kIPAddressType_IPv4,
466         "234.128.0.0" },
467         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
468         0x0, 0x0, 0x0
469     },
470     {
471          { { 0x00000000, 0x00000000, 0x0000ffff, 0xeafffffe }, kIPAddressType_IPv4,
472         "234.255.255.254" },
473         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
474         0x0, 0x0, 0x0
475     },
476     {
477          { { 0x00000000, 0x00000000, 0x0000ffff, 0xeaffffff }, kIPAddressType_IPv4,
478         "234.255.255.255" },
479         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
480         0x0, 0x0, 0x0
481     },
482     // IPv4 administratively scoped multicast
483     {
484          { { 0x00000000, 0x00000000, 0x0000ffff, 0xef000000 }, kIPAddressType_IPv4,
485         "239.0.0.0" },
486         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
487         0x0, 0x0, 0x0
488     },
489     {
490          { { 0x00000000, 0x00000000, 0x0000ffff, 0xef000001 }, kIPAddressType_IPv4,
491         "239.0.0.1" },
492         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
493         0x0, 0x0, 0x0
494     },
495     {
496          { { 0x00000000, 0x00000000, 0x0000ffff, 0xef800000 }, kIPAddressType_IPv4,
497         "239.128.0.0" },
498         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
499         0x0, 0x0, 0x0
500     },
501     {
502          { { 0x00000000, 0x00000000, 0x0000ffff, 0xeffffffe }, kIPAddressType_IPv4,
503         "239.255.255.254" },
504         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
505         0x0, 0x0, 0x0
506     },
507     {
508          { { 0x00000000, 0x00000000, 0x0000ffff, 0xefffffff }, kIPAddressType_IPv4,
509         "239.255.255.255" },
510         kTestIsIPv4, kTestIsIPv4Multicast, kTestIsNotIPv4Broadcast, kTestIsMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
511         0x0, 0x0, 0x0
512     },
513     // IP4 and IPv4 broadcast
514     {
515          { { 0x00000000, 0x00000000, 0x0000ffff, 0xffffffff }, kIPAddressType_IPv4,
516         "255.255.255.255" },
517         kTestIsIPv4, kTestIsNotIPv4Multicast, kTestIsIPv4Broadcast, kTestIsNotMulticast, kTestIsNotIPv6Multicast, kTestIsNotIPv6ULA, kTestIsNotIPv6LLA,
518         0x0, 0x0, 0x0
519     }
520 #endif // INET_CONFIG_ENABLE_IPV4
521 };
522 // clang-format on
523
524 const IPAddressContext sIPv6WellKnownMulticastContext[] = {
525     // Well-known
526
527     // All-nodes in Various Scopes
528
529     { { 0xff010000, 0x00000000, 0x00000000, 0x00000001 }, kIPAddressType_IPv6, "ff01::1" },
530     { { 0xff020000, 0x00000000, 0x00000000, 0x00000001 }, kIPAddressType_IPv6, "ff02::1" },
531     { { 0xff030000, 0x00000000, 0x00000000, 0x00000001 }, kIPAddressType_IPv6, "ff03::1" },
532     { { 0xff040000, 0x00000000, 0x00000000, 0x00000001 }, kIPAddressType_IPv6, "ff04::1" },
533     { { 0xff050000, 0x00000000, 0x00000000, 0x00000001 }, kIPAddressType_IPv6, "ff05::1" },
534     { { 0xff080000, 0x00000000, 0x00000000, 0x00000001 }, kIPAddressType_IPv6, "ff08::1" },
535     { { 0xff0e0000, 0x00000000, 0x00000000, 0x00000001 }, kIPAddressType_IPv6, "ff0e::1" },
536
537     // All-routers in Various Scopes
538
539     { { 0xff010000, 0x00000000, 0x00000000, 0x00000002 }, kIPAddressType_IPv6, "ff01::2" },
540     { { 0xff020000, 0x00000000, 0x00000000, 0x00000002 }, kIPAddressType_IPv6, "ff02::2" },
541     { { 0xff030000, 0x00000000, 0x00000000, 0x00000002 }, kIPAddressType_IPv6, "ff03::2" },
542     { { 0xff040000, 0x00000000, 0x00000000, 0x00000002 }, kIPAddressType_IPv6, "ff04::2" },
543     { { 0xff050000, 0x00000000, 0x00000000, 0x00000002 }, kIPAddressType_IPv6, "ff05::2" },
544     { { 0xff080000, 0x00000000, 0x00000000, 0x00000002 }, kIPAddressType_IPv6, "ff08::2" },
545     { { 0xff0e0000, 0x00000000, 0x00000000, 0x00000002 }, kIPAddressType_IPv6, "ff0e::2" }
546 };
547
548 const IPAddressContext sIPv6TransientMulticastContext[] = {
549     // Transient
550
551     // Short Transient Group in Various Scopes
552
553     { { 0xff110000, 0x00000000, 0x00000000, 0x00000001 }, kIPAddressType_IPv6, "ff11::1" },
554     { { 0xff120000, 0x00000000, 0x00000000, 0x00000001 }, kIPAddressType_IPv6, "ff12::1" },
555     { { 0xff130000, 0x00000000, 0x00000000, 0x00000001 }, kIPAddressType_IPv6, "ff13::1" },
556     { { 0xff140000, 0x00000000, 0x00000000, 0x00000001 }, kIPAddressType_IPv6, "ff14::1" },
557     { { 0xff150000, 0x00000000, 0x00000000, 0x00000001 }, kIPAddressType_IPv6, "ff15::1" },
558     { { 0xff180000, 0x00000000, 0x00000000, 0x00000001 }, kIPAddressType_IPv6, "ff18::1" },
559     { { 0xff1e0000, 0x00000000, 0x00000000, 0x00000001 }, kIPAddressType_IPv6, "ff1e::1" },
560
561     // Long Transient Group in Various Scopes
562
563     { { 0xff11d5d6, 0x2ba27847, 0x6452587a, 0xc9550b5a }, kIPAddressType_IPv6, "ff11:d5d6:2ba2:7847:6452:587a:c955:b5a" },
564     { { 0xff12d5d6, 0x2ba27847, 0x6452587a, 0xc9550b5a }, kIPAddressType_IPv6, "ff12:d5d6:2ba2:7847:6452:587a:c955:b5a" },
565     { { 0xff13d5d6, 0x2ba27847, 0x6452587a, 0xc9550b5a }, kIPAddressType_IPv6, "ff13:d5d6:2ba2:7847:6452:587a:c955:b5a" },
566     { { 0xff14d5d6, 0x2ba27847, 0x6452587a, 0xc9550b5a }, kIPAddressType_IPv6, "ff14:d5d6:2ba2:7847:6452:587a:c955:b5a" },
567     { { 0xff15d5d6, 0x2ba27847, 0x6452587a, 0xc9550b5a }, kIPAddressType_IPv6, "ff15:d5d6:2ba2:7847:6452:587a:c955:b5a" },
568     { { 0xff18d5d6, 0x2ba27847, 0x6452587a, 0xc9550b5a }, kIPAddressType_IPv6, "ff18:d5d6:2ba2:7847:6452:587a:c955:b5a" },
569     { { 0xff1ed5d6, 0x2ba27847, 0x6452587a, 0xc9550b5a }, kIPAddressType_IPv6, "ff1e:d5d6:2ba2:7847:6452:587a:c955:b5a" }
570 };
571
572 const IPAddressContext sIPv6PrefixMulticastContext[] = {
573     // Prefix
574
575     // 56-bit Prefix with Short Group in Various Scopes
576
577     { { 0xff310038, 0x373acba4, 0xd2ad8d00, 0x00010001 }, kIPAddressType_IPv6, "ff31:38:373a:cba4:d2ad:8d00:1:1" },
578     { { 0xff320038, 0x373acba4, 0xd2ad8d00, 0x00010001 }, kIPAddressType_IPv6, "ff32:38:373a:cba4:d2ad:8d00:1:1" },
579     { { 0xff330038, 0x373acba4, 0xd2ad8d00, 0x00010001 }, kIPAddressType_IPv6, "ff33:38:373a:cba4:d2ad:8d00:1:1" },
580     { { 0xff340038, 0x373acba4, 0xd2ad8d00, 0x00010001 }, kIPAddressType_IPv6, "ff34:38:373a:cba4:d2ad:8d00:1:1" },
581     { { 0xff350038, 0x373acba4, 0xd2ad8d00, 0x00010001 }, kIPAddressType_IPv6, "ff35:38:373a:cba4:d2ad:8d00:1:1" },
582     { { 0xff380038, 0x373acba4, 0xd2ad8d00, 0x00010001 }, kIPAddressType_IPv6, "ff38:38:373a:cba4:d2ad:8d00:1:1" },
583     { { 0xff3e0038, 0x373acba4, 0xd2ad8d00, 0x00010001 }, kIPAddressType_IPv6, "ff3e:38:373a:cba4:d2ad:8d00:1:1" },
584
585     // 56-bit Prefix with Long Group in Various Scopes
586
587     { { 0xff310038, 0x373acba4, 0xd2ad8d00, 0xafff5258 }, kIPAddressType_IPv6, "ff31:38:373a:cba4:d2ad:8d00:afff:5258" },
588     { { 0xff320038, 0x373acba4, 0xd2ad8d00, 0xafff5258 }, kIPAddressType_IPv6, "ff32:38:373a:cba4:d2ad:8d00:afff:5258" },
589     { { 0xff330038, 0x373acba4, 0xd2ad8d00, 0xafff5258 }, kIPAddressType_IPv6, "ff33:38:373a:cba4:d2ad:8d00:afff:5258" },
590     { { 0xff340038, 0x373acba4, 0xd2ad8d00, 0xafff5258 }, kIPAddressType_IPv6, "ff34:38:373a:cba4:d2ad:8d00:afff:5258" },
591     { { 0xff350038, 0x373acba4, 0xd2ad8d00, 0xafff5258 }, kIPAddressType_IPv6, "ff35:38:373a:cba4:d2ad:8d00:afff:5258" },
592     { { 0xff380038, 0x373acba4, 0xd2ad8d00, 0xafff5258 }, kIPAddressType_IPv6, "ff38:38:373a:cba4:d2ad:8d00:afff:5258" },
593     { { 0xff3e0038, 0x373acba4, 0xd2ad8d00, 0xafff5258 }, kIPAddressType_IPv6, "ff3e:38:373a:cba4:d2ad:8d00:afff:5258" },
594
595     // 64-bit Prefix with Short Group in Various Scopes
596
597     { { 0xff310040, 0x66643dfb, 0xafa4385b, 0x00010001 }, kIPAddressType_IPv6, "ff31:40:6664:3dfb:afa4:385b:1:1" },
598     { { 0xff320040, 0x66643dfb, 0xafa4385b, 0x00010001 }, kIPAddressType_IPv6, "ff32:40:6664:3dfb:afa4:385b:1:1" },
599     { { 0xff330040, 0x66643dfb, 0xafa4385b, 0x00010001 }, kIPAddressType_IPv6, "ff33:40:6664:3dfb:afa4:385b:1:1" },
600     { { 0xff340040, 0x66643dfb, 0xafa4385b, 0x00010001 }, kIPAddressType_IPv6, "ff34:40:6664:3dfb:afa4:385b:1:1" },
601     { { 0xff350040, 0x66643dfb, 0xafa4385b, 0x00010001 }, kIPAddressType_IPv6, "ff35:40:6664:3dfb:afa4:385b:1:1" },
602     { { 0xff380040, 0x66643dfb, 0xafa4385b, 0x00010001 }, kIPAddressType_IPv6, "ff38:40:6664:3dfb:afa4:385b:1:1" },
603     { { 0xff3e0040, 0x66643dfb, 0xafa4385b, 0x00010001 }, kIPAddressType_IPv6, "ff3e:40:6664:3dfb:afa4:385b:1:1" },
604
605     // 64-bit Prefix with Long Group in Various Scopes
606
607     { { 0xff310040, 0x66643dfb, 0xafa4385b, 0xafff5258 }, kIPAddressType_IPv6, "ff31:40:6664:3dfb:afa4:385b:afff:5258" },
608     { { 0xff320040, 0x66643dfb, 0xafa4385b, 0xafff5258 }, kIPAddressType_IPv6, "ff32:40:6664:3dfb:afa4:385b:afff:5258" },
609     { { 0xff330040, 0x66643dfb, 0xafa4385b, 0xafff5258 }, kIPAddressType_IPv6, "ff33:40:6664:3dfb:afa4:385b:afff:5258" },
610     { { 0xff340040, 0x66643dfb, 0xafa4385b, 0xafff5258 }, kIPAddressType_IPv6, "ff34:40:6664:3dfb:afa4:385b:afff:5258" },
611     { { 0xff350040, 0x66643dfb, 0xafa4385b, 0xafff5258 }, kIPAddressType_IPv6, "ff35:40:6664:3dfb:afa4:385b:afff:5258" },
612     { { 0xff380040, 0x66643dfb, 0xafa4385b, 0xafff5258 }, kIPAddressType_IPv6, "ff38:40:6664:3dfb:afa4:385b:afff:5258" },
613     { { 0xff3e0040, 0x66643dfb, 0xafa4385b, 0xafff5258 }, kIPAddressType_IPv6, "ff3e:40:6664:3dfb:afa4:385b:afff:5258" }
614 };
615
616 const size_t kIPv6WellKnownMulticastTestElements = sizeof(sIPv6WellKnownMulticastContext) / sizeof(struct IPAddressContext);
617 const size_t kIPv6TransientMulticastTestElements = sizeof(sIPv6TransientMulticastContext) / sizeof(struct IPAddressContext);
618 const size_t kIPv6PrefixMulticastTestElements    = sizeof(sIPv6PrefixMulticastContext) / sizeof(struct IPAddressContext);
619 const size_t kIPAddressTestElements              = sizeof(sIPAddressContext) / sizeof(struct IPAddressExpandedContext);
620
621 // clang-format off
622 const TestContext sTestContext = {
623     {
624         &sIPv6WellKnownMulticastContext[0],
625         &sIPv6WellKnownMulticastContext[kIPv6WellKnownMulticastTestElements]
626     },
627     {
628         &sIPv6TransientMulticastContext[0],
629         &sIPv6TransientMulticastContext[kIPv6TransientMulticastTestElements]
630     },
631     {
632         &sIPv6PrefixMulticastContext[0],
633         &sIPv6PrefixMulticastContext[kIPv6PrefixMulticastTestElements]
634     },
635     {
636         &sIPAddressContext[0],
637         &sIPAddressContext[kIPAddressTestElements]
638     }
639 };
640 // clang-format on
641
642 // Utility functions.
643
644 /**
645  *   Load input test directly into IPAddress.
646  */
647 void SetupIPAddress(IPAddress & addr, const struct IPAddressExpandedContext * inContext)
648 {
649     for (size_t i = 0; i < NUM_FIELDS_IN_ADDR; i++)
650     {
651         addr.Addr[i] = htonl(inContext->mAddr.mAddrQuartets[i]);
652     }
653 }
654
655 /**
656  *   Zero out IP address.
657  */
658 void ClearIPAddress(IPAddress & addr)
659 {
660     addr = IPAddress::Any;
661 }
662
663 void CheckAddressQuartet(nlTestSuite * inSuite, const uint32_t & inFirstAddressQuartet, const uint32_t & inSecondAddressQuartet,
664                          const size_t & inWhich)
665 {
666     const bool lResult = (inFirstAddressQuartet == inSecondAddressQuartet);
667
668     NL_TEST_ASSERT(inSuite, lResult == true);
669
670     if (!lResult)
671     {
672         fprintf(stdout, "Address quartet %zu mismatch: actual 0x%08x, expected: 0x%08x\n", inWhich, inFirstAddressQuartet,
673                 inSecondAddressQuartet);
674     }
675 }
676
677 void CheckAddressQuartet(nlTestSuite * inSuite, const IPAddressContext & inContext, const IPAddress & inAddress,
678                          const size_t & inWhich)
679 {
680     CheckAddressQuartet(inSuite, inAddress.Addr[inWhich], htonl(inContext.mAddrQuartets[inWhich]), inWhich);
681 }
682
683 void CheckAddressQuartets(nlTestSuite * inSuite, const IPAddress & inFirstAddress, const IPAddress & inSecondAddress)
684 {
685     for (size_t i = 0; i < 4; i++)
686     {
687         CheckAddressQuartet(inSuite, inFirstAddress.Addr[i], inSecondAddress.Addr[i], i);
688     }
689 }
690
691 void CheckAddressQuartets(nlTestSuite * inSuite, const IPAddressContext & inContext, const IPAddress & inAddress)
692 {
693     for (size_t i = 0; i < 4; i++)
694     {
695         CheckAddressQuartet(inSuite, inContext, inAddress, i);
696     }
697 }
698
699 void CheckAddressString(nlTestSuite * inSuite, const char * inActual, const char * inExpected)
700 {
701     const int lResult = strcasecmp(inActual, inExpected);
702
703     NL_TEST_ASSERT(inSuite, lResult == 0);
704
705     if (lResult != 0)
706     {
707         fprintf(stdout, "Address format mismatch: actual %s, expected %s\n", inActual, inExpected);
708     }
709 }
710
711 void CheckAddress(nlTestSuite * inSuite, const IPAddressContext & inContext, const IPAddress & inAddress)
712 {
713     char lAddressBuffer[INET6_ADDRSTRLEN];
714     IPAddress lParsedAddress;
715     int lResult;
716
717     // Compare the address quartets to their control values.
718
719     CheckAddressQuartets(inSuite, inContext, inAddress);
720
721     // Convert the address to a string and compare it to the control string.
722
723     inAddress.ToString(lAddressBuffer);
724
725     CheckAddressString(inSuite, lAddressBuffer, inContext.mAddrString);
726
727     // Convert the control string to an address and compare the parsed address to the created address.
728
729     lResult = IPAddress::FromString(inContext.mAddrString, lParsedAddress);
730     NL_TEST_ASSERT(inSuite, lResult == true);
731
732     lResult = (inAddress == lParsedAddress);
733
734     if (!static_cast<bool>(lResult))
735     {
736         fprintf(stdout, "Address parse mismatch for %s\n", inContext.mAddrString);
737     }
738 }
739
740 // Test functions invoked from the suite.
741
742 /**
743  *  Test IP address conversion from a string.
744  */
745 void CheckFromString(nlTestSuite * inSuite, void * inContext)
746 {
747     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
748     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
749     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
750
751     while (lCurrent != lEnd)
752     {
753         IPAddress test_addr;
754
755         IPAddress::FromString(lCurrent->mAddr.mAddrString, test_addr);
756
757         CheckAddressQuartets(inSuite, lCurrent->mAddr, test_addr);
758
759         char tmpBuf[INET6_ADDRSTRLEN];
760         size_t addrStrLen = strlen(lCurrent->mAddr.mAddrString);
761
762         memset(tmpBuf, '1', sizeof(tmpBuf));
763         memcpy(tmpBuf, lCurrent->mAddr.mAddrString, addrStrLen);
764
765         IPAddress::FromString(tmpBuf, addrStrLen, test_addr);
766
767         CheckAddressQuartets(inSuite, lCurrent->mAddr, test_addr);
768
769         ++lCurrent;
770     }
771 }
772
773 /**
774  *  Test IP address conversion to a string.
775  */
776 void CheckToString(nlTestSuite * inSuite, void * inContext)
777 {
778     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
779     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
780     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
781     char lAddressBuffer[INET6_ADDRSTRLEN];
782     IPAddress lAddress;
783
784     while (lCurrent != lEnd)
785     {
786         SetupIPAddress(lAddress, lCurrent);
787
788         lAddress.ToString(lAddressBuffer);
789
790         CheckAddressString(inSuite, lAddressBuffer, lCurrent->mAddr.mAddrString);
791
792         ++lCurrent;
793     }
794 }
795
796 /**
797  *  Test correct identification of IPv6 ULA addresses.
798  */
799 void CheckIsIPv6ULA(nlTestSuite * inSuite, void * inContext)
800 {
801     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
802     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
803     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
804
805     while (lCurrent != lEnd)
806     {
807         IPAddress test_addr;
808
809         SetupIPAddress(test_addr, lCurrent);
810
811         NL_TEST_ASSERT(inSuite, test_addr.IsIPv6ULA() == lCurrent->isIPv6ULA);
812
813         ++lCurrent;
814     }
815 }
816
817 /**
818  *  Test correct identification of IPv6 Link Local addresses.
819  */
820 void CheckIsIPv6LLA(nlTestSuite * inSuite, void * inContext)
821 {
822     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
823     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
824     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
825
826     while (lCurrent != lEnd)
827     {
828         IPAddress test_addr;
829
830         SetupIPAddress(test_addr, lCurrent);
831
832         NL_TEST_ASSERT(inSuite, test_addr.IsIPv6LinkLocal() == lCurrent->isIPv6LLA);
833
834         ++lCurrent;
835     }
836 }
837
838 /**
839  *  Test correct identification of IPv6 multicast addresses.
840  */
841 void CheckIsIPv6Multicast(nlTestSuite * inSuite, void * inContext)
842 {
843     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
844     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
845     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
846
847     while (lCurrent != lEnd)
848     {
849         IPAddress test_addr;
850
851         SetupIPAddress(test_addr, lCurrent);
852
853         NL_TEST_ASSERT(inSuite, test_addr.IsIPv6Multicast() == lCurrent->isIPv6Multicast);
854
855         ++lCurrent;
856     }
857 }
858
859 /**
860  *  Test correct identification of multicast addresses.
861  */
862 void CheckIsMulticast(nlTestSuite * inSuite, void * inContext)
863 {
864     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
865     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
866     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
867
868     while (lCurrent != lEnd)
869     {
870         IPAddress test_addr;
871
872         SetupIPAddress(test_addr, lCurrent);
873
874         NL_TEST_ASSERT(inSuite, test_addr.IsMulticast() == lCurrent->isMulticast);
875
876         ++lCurrent;
877     }
878 }
879
880 /**
881  *  Test IPAddress equal operator.
882  */
883 void CheckOperatorEqual(nlTestSuite * inSuite, void * inContext)
884 {
885     const struct TestContext * lContext            = static_cast<const struct TestContext *>(inContext);
886     IPAddressExpandedContextIterator lFirstCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
887     IPAddressExpandedContextIterator lFirstEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
888
889     while (lFirstCurrent != lFirstEnd)
890     {
891         IPAddressExpandedContextIterator lSecondCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
892         IPAddressExpandedContextIterator lSecondEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
893         IPAddress test_addr_1;
894
895         SetupIPAddress(test_addr_1, lFirstCurrent);
896
897         while (lSecondCurrent != lSecondEnd)
898         {
899             IPAddress test_addr_2;
900
901             SetupIPAddress(test_addr_2, lSecondCurrent);
902
903             if (lFirstCurrent == lSecondCurrent)
904             {
905                 NL_TEST_ASSERT(inSuite, test_addr_1 == test_addr_2);
906             }
907             else
908             {
909                 NL_TEST_ASSERT(inSuite, !(test_addr_1 == test_addr_2));
910             }
911
912             ++lSecondCurrent;
913         }
914
915         ++lFirstCurrent;
916     }
917 }
918
919 /**
920  *  Test IPAddress not-equal operator.
921  */
922 void CheckOperatorNotEqual(nlTestSuite * inSuite, void * inContext)
923 {
924     const struct TestContext * lContext            = static_cast<const struct TestContext *>(inContext);
925     IPAddressExpandedContextIterator lFirstCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
926     IPAddressExpandedContextIterator lFirstEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
927
928     while (lFirstCurrent != lFirstEnd)
929     {
930         IPAddressExpandedContextIterator lSecondCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
931         IPAddressExpandedContextIterator lSecondEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
932         IPAddress test_addr_1;
933
934         SetupIPAddress(test_addr_1, lFirstCurrent);
935
936         while (lSecondCurrent != lSecondEnd)
937         {
938             IPAddress test_addr_2;
939
940             SetupIPAddress(test_addr_2, lSecondCurrent);
941
942             if (lFirstCurrent == lSecondCurrent)
943             {
944                 NL_TEST_ASSERT(inSuite, !(test_addr_1 != test_addr_2));
945             }
946             else
947             {
948                 NL_TEST_ASSERT(inSuite, test_addr_1 != test_addr_2);
949             }
950
951             ++lSecondCurrent;
952         }
953
954         ++lFirstCurrent;
955     }
956 }
957
958 /**
959  *  Test IPAddress assign operator.
960  */
961 void CheckOperatorAssign(nlTestSuite * inSuite, void * inContext)
962 {
963     const struct TestContext * lContext            = static_cast<const struct TestContext *>(inContext);
964     IPAddressExpandedContextIterator lFirstCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
965     IPAddressExpandedContextIterator lFirstEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
966
967     while (lFirstCurrent != lFirstEnd)
968     {
969         IPAddressExpandedContextIterator lSecondCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
970         IPAddressExpandedContextIterator lSecondEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
971
972         while (lSecondCurrent != lSecondEnd)
973         {
974             IPAddress test_addr_1, test_addr_2;
975
976             ClearIPAddress(test_addr_1);
977             SetupIPAddress(test_addr_2, lSecondCurrent);
978
979             // Use operator to assign IPAddress from test_addr_2 to test_addr_1
980             test_addr_1 = test_addr_2;
981
982             CheckAddressQuartets(inSuite, test_addr_1, test_addr_2);
983
984             ++lSecondCurrent;
985         }
986
987         ++lFirstCurrent;
988     }
989 }
990
991 /**
992  *   Test IPAddress v6 conversion to native representation.
993  */
994 void CheckToIPv6(nlTestSuite * inSuite, void * inContext)
995 {
996     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
997     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
998     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
999
1000     while (lCurrent != lEnd)
1001     {
1002         IPAddress test_addr;
1003         uint32_t addr[4];
1004
1005         addr[0] = htonl(lCurrent->mAddr.mAddrQuartets[0]);
1006         addr[1] = htonl(lCurrent->mAddr.mAddrQuartets[1]);
1007         addr[2] = htonl(lCurrent->mAddr.mAddrQuartets[2]);
1008         addr[3] = htonl(lCurrent->mAddr.mAddrQuartets[3]);
1009
1010         SetupIPAddress(test_addr, lCurrent);
1011
1012 #if CHIP_SYSTEM_CONFIG_USE_LWIP
1013         ip6_addr_t ip_addr_1, ip_addr_2;
1014         ip_addr_1 = *(ip6_addr_t *) addr;
1015 #else
1016         struct in6_addr ip_addr_1, ip_addr_2;
1017         ip_addr_1 = *reinterpret_cast<struct in6_addr *>(addr);
1018 #endif
1019         ip_addr_2 = test_addr.ToIPv6();
1020
1021         NL_TEST_ASSERT(inSuite, !memcmp(&ip_addr_1, &ip_addr_2, sizeof(ip_addr_1)));
1022
1023         ++lCurrent;
1024     }
1025 }
1026
1027 /**
1028  *   Test native IPv6 conversion into IPAddress.
1029  */
1030 void CheckFromIPv6(nlTestSuite * inSuite, void * inContext)
1031 {
1032     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
1033     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
1034     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
1035
1036     while (lCurrent != lEnd)
1037     {
1038         IPAddress test_addr_1, test_addr_2;
1039         uint32_t addr[4];
1040
1041         addr[0] = htonl(lCurrent->mAddr.mAddrQuartets[0]);
1042         addr[1] = htonl(lCurrent->mAddr.mAddrQuartets[1]);
1043         addr[2] = htonl(lCurrent->mAddr.mAddrQuartets[2]);
1044         addr[3] = htonl(lCurrent->mAddr.mAddrQuartets[3]);
1045
1046         SetupIPAddress(test_addr_1, lCurrent);
1047         ClearIPAddress(test_addr_2);
1048
1049 #if CHIP_SYSTEM_CONFIG_USE_LWIP
1050         ip6_addr_t ip_addr;
1051         ip_addr = *(ip6_addr_t *) addr;
1052 #else
1053         struct in6_addr ip_addr;
1054         ip_addr = *reinterpret_cast<struct in6_addr *>(addr);
1055 #endif
1056         test_addr_2 = IPAddress::FromIPv6(ip_addr);
1057
1058         CheckAddressQuartets(inSuite, test_addr_1, test_addr_2);
1059
1060         ++lCurrent;
1061     }
1062 }
1063
1064 #if INET_CONFIG_ENABLE_IPV4
1065 /**
1066  *  Test correct identification of IPv4 addresses.
1067  */
1068 void CheckIsIPv4(nlTestSuite * inSuite, void * inContext)
1069 {
1070     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
1071     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
1072     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
1073
1074     while (lCurrent != lEnd)
1075     {
1076         IPAddress test_addr;
1077
1078         SetupIPAddress(test_addr, lCurrent);
1079
1080         NL_TEST_ASSERT(inSuite, test_addr.IsIPv4() == lCurrent->isIPv4);
1081
1082         ++lCurrent;
1083     }
1084 }
1085
1086 /**
1087  *  Test correct identification of IPv4 multicast addresses.
1088  */
1089 void CheckIsIPv4Multicast(nlTestSuite * inSuite, void * inContext)
1090 {
1091     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
1092     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
1093     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
1094
1095     while (lCurrent != lEnd)
1096     {
1097         IPAddress test_addr;
1098
1099         SetupIPAddress(test_addr, lCurrent);
1100
1101         NL_TEST_ASSERT(inSuite, test_addr.IsIPv4Multicast() == lCurrent->isIPv4Multicast);
1102
1103         ++lCurrent;
1104     }
1105 }
1106
1107 /**
1108  *  Test correct identification of IPv4 broadcast addresses.
1109  */
1110 void CheckIsIPv4Broadcast(nlTestSuite * inSuite, void * inContext)
1111 {
1112     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
1113     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
1114     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
1115
1116     while (lCurrent != lEnd)
1117     {
1118         IPAddress test_addr;
1119
1120         SetupIPAddress(test_addr, lCurrent);
1121
1122         NL_TEST_ASSERT(inSuite, test_addr.IsIPv4Broadcast() == lCurrent->isIPv4Broadcast);
1123
1124         ++lCurrent;
1125     }
1126 }
1127
1128 /**
1129  *   Test IPAddress v4 conversion to native representation.
1130  */
1131 void CheckToIPv4(nlTestSuite * inSuite, void * inContext)
1132 {
1133     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
1134     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
1135     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
1136
1137     while (lCurrent != lEnd)
1138     {
1139         IPAddress test_addr;
1140
1141         SetupIPAddress(test_addr, lCurrent);
1142
1143 #if CHIP_SYSTEM_CONFIG_USE_LWIP
1144         ip4_addr_t ip_addr_1, ip_addr_2;
1145
1146         ip_addr_1.addr = htonl(lCurrent->mAddr.mAddrQuartets[3]);
1147 #else
1148         struct in_addr ip_addr_1, ip_addr_2;
1149
1150         ip_addr_1.s_addr = htonl(lCurrent->mAddr.mAddrQuartets[3]);
1151 #endif
1152         ip_addr_2 = test_addr.ToIPv4();
1153
1154         NL_TEST_ASSERT(inSuite, !memcmp(&ip_addr_1, &ip_addr_2, sizeof(ip_addr_1)));
1155
1156         ++lCurrent;
1157     }
1158 }
1159
1160 /**
1161  *   Test native IPv4 conversion into IPAddress.
1162  */
1163 void CheckFromIPv4(nlTestSuite * inSuite, void * inContext)
1164 {
1165     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
1166     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
1167     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
1168
1169     while (lCurrent != lEnd)
1170     {
1171         IPAddress test_addr_1, test_addr_2;
1172
1173         SetupIPAddress(test_addr_1, lCurrent);
1174         ClearIPAddress(test_addr_2);
1175
1176         // Convert to IPv4 (test_addr_1);
1177         test_addr_1.Addr[0] = 0;
1178         test_addr_1.Addr[1] = 0;
1179
1180 #if CHIP_SYSTEM_CONFIG_USE_LWIP
1181         ip4_addr_t ip_addr;
1182         ip_addr.addr        = htonl(lCurrent->mAddr.mAddrQuartets[3]);
1183         test_addr_1.Addr[2] = lwip_htonl(0xffff);
1184 #else
1185         struct in_addr ip_addr;
1186         ip_addr.s_addr      = htonl(lCurrent->mAddr.mAddrQuartets[3]);
1187         test_addr_1.Addr[2] = htonl(0xffff);
1188 #endif
1189         test_addr_2 = IPAddress::FromIPv4(ip_addr);
1190
1191         CheckAddressQuartets(inSuite, test_addr_1, test_addr_2);
1192
1193         ++lCurrent;
1194     }
1195 }
1196 #endif // INET_CONFIG_ENABLE_IPV4
1197
1198 /**
1199  *   Test IPAddress address conversion from socket.
1200  */
1201 void CheckFromSocket(nlTestSuite * inSuite, void * inContext)
1202 {
1203 #if CHIP_SYSTEM_CONFIG_USE_LWIP
1204     (void) inSuite;
1205     // This test is only supported for non LWIP stack.
1206 #else // INET_LWIP
1207     const struct TestContext * lContext = static_cast<const struct TestContext *>(inContext);
1208     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
1209     IPAddressExpandedContextIterator lEnd = lContext->mIPAddressExpandedContextRange.mEnd;
1210
1211     while (lCurrent != lEnd)
1212     {
1213         IPAddress test_addr_1, test_addr_2;
1214         uint32_t addr[4];
1215         struct sockaddr_in6 sock_v6;
1216 #if INET_CONFIG_ENABLE_IPV4
1217         struct sockaddr_in sock_v4;
1218 #endif // INET_CONFIG_ENABLE_IPV4
1219
1220         addr[0] = htonl(lCurrent->mAddr.mAddrQuartets[0]);
1221         addr[1] = htonl(lCurrent->mAddr.mAddrQuartets[1]);
1222         addr[2] = htonl(lCurrent->mAddr.mAddrQuartets[2]);
1223         addr[3] = htonl(lCurrent->mAddr.mAddrQuartets[3]);
1224
1225         SetupIPAddress(test_addr_1, lCurrent);
1226         ClearIPAddress(test_addr_2);
1227
1228         switch (lCurrent->mAddr.mAddrType)
1229         {
1230 #if INET_CONFIG_ENABLE_IPV4
1231         case kIPAddressType_IPv4:
1232             memset(&sock_v4, 0, sizeof(struct sockaddr_in));
1233             sock_v4.sin_family = AF_INET;
1234             memcpy(&sock_v4.sin_addr.s_addr, &addr[3], sizeof(struct in_addr));
1235             test_addr_2 = IPAddress::FromSockAddr(reinterpret_cast<struct sockaddr &>(sock_v4));
1236             break;
1237 #endif // INET_CONFIG_ENABLE_IPV4
1238
1239         case kIPAddressType_IPv6:
1240             memset(&sock_v6, 0, sizeof(struct sockaddr_in6));
1241             sock_v6.sin6_family = AF_INET6;
1242             memcpy(&sock_v6.sin6_addr.s6_addr, addr, sizeof(struct in6_addr));
1243             test_addr_2 = IPAddress::FromSockAddr(reinterpret_cast<struct sockaddr &>(sock_v6));
1244             break;
1245
1246         case kIPAddressType_Any:
1247             memset(&sock_v6, 0, sizeof(struct sockaddr_in6));
1248             sock_v6.sin6_family = 0;
1249             memcpy(&sock_v6.sin6_addr.s6_addr, addr, sizeof(struct in6_addr));
1250             test_addr_2 = IPAddress::FromSockAddr(reinterpret_cast<struct sockaddr &>(sock_v6));
1251             break;
1252
1253         default:
1254             continue;
1255         }
1256
1257         CheckAddressQuartets(inSuite, test_addr_1, test_addr_2);
1258
1259         ++lCurrent;
1260     }
1261 #endif // INET_LWIP
1262 }
1263
1264 /**
1265  *  Test IP address type.
1266  */
1267 void CheckType(nlTestSuite * inSuite, void * inContext)
1268 {
1269     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
1270     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
1271     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
1272
1273     while (lCurrent != lEnd)
1274     {
1275         IPAddress test_addr;
1276
1277         SetupIPAddress(test_addr, lCurrent);
1278
1279         NL_TEST_ASSERT(inSuite, test_addr.Type() == lCurrent->mAddr.mAddrType);
1280
1281         ++lCurrent;
1282     }
1283 }
1284
1285 /**
1286  *  Test the Any address global.
1287  */
1288 void CheckAnyAddress(nlTestSuite * inSuite, void * inContext)
1289 {
1290     const IPAddress test_addr = IPAddress::Any;
1291     IPAddressType test_type   = test_addr.Type();
1292
1293     NL_TEST_ASSERT(inSuite, test_type == kIPAddressType_Any);
1294 }
1295
1296 /**
1297  *  Test IP address interface ID.
1298  */
1299 void CheckInterface(nlTestSuite * inSuite, void * inContext)
1300 {
1301     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
1302     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
1303     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
1304
1305     while (lCurrent != lEnd)
1306     {
1307         IPAddress test_addr;
1308
1309         SetupIPAddress(test_addr, lCurrent);
1310
1311         NL_TEST_ASSERT(inSuite, test_addr.InterfaceId() == lCurrent->interface);
1312
1313         ++lCurrent;
1314     }
1315 }
1316
1317 /**
1318  *  Test IP address subnet.
1319  */
1320 void CheckSubnet(nlTestSuite * inSuite, void * inContext)
1321 {
1322     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
1323     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
1324     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
1325
1326     while (lCurrent != lEnd)
1327     {
1328         IPAddress test_addr;
1329
1330         SetupIPAddress(test_addr, lCurrent);
1331
1332         NL_TEST_ASSERT(inSuite, test_addr.Subnet() == lCurrent->subnet);
1333
1334         ++lCurrent;
1335     }
1336 }
1337
1338 /**
1339  *  Test IP address global ID.
1340  */
1341 void CheckGlobal(nlTestSuite * inSuite, void * inContext)
1342 {
1343     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
1344     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
1345     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
1346
1347     while (lCurrent != lEnd)
1348     {
1349         IPAddress test_addr;
1350
1351         SetupIPAddress(test_addr, lCurrent);
1352
1353         NL_TEST_ASSERT(inSuite, test_addr.GlobalId() == lCurrent->global);
1354
1355         ++lCurrent;
1356     }
1357 }
1358
1359 /**
1360  *  Test address encoding with chip::Encoding.
1361  */
1362 void CheckEncoding(nlTestSuite * inSuite, void * inContext)
1363 {
1364     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
1365     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
1366     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
1367
1368     while (lCurrent != lEnd)
1369     {
1370         IPAddress test_addr;
1371         uint8_t * p;
1372         uint8_t buffer[NUM_BYTES_IN_IPV6];
1373
1374         SetupIPAddress(test_addr, lCurrent);
1375         memset(&buffer, 0, NUM_BYTES_IN_IPV6);
1376         p = buffer;
1377
1378         // Call EncodeAddress function that we test.
1379         test_addr.WriteAddress(p);
1380
1381         // buffer has address in network byte order
1382         NL_TEST_ASSERT(inSuite, buffer[3] == (uint8_t)(lCurrent->mAddr.mAddrQuartets[0]));
1383         NL_TEST_ASSERT(inSuite, buffer[2] == (uint8_t)(lCurrent->mAddr.mAddrQuartets[0] >> 8));
1384         NL_TEST_ASSERT(inSuite, buffer[1] == (uint8_t)(lCurrent->mAddr.mAddrQuartets[0] >> 16));
1385         NL_TEST_ASSERT(inSuite, buffer[0] == (uint8_t)(lCurrent->mAddr.mAddrQuartets[0] >> 24));
1386
1387         NL_TEST_ASSERT(inSuite, buffer[7] == (uint8_t)(lCurrent->mAddr.mAddrQuartets[1]));
1388         NL_TEST_ASSERT(inSuite, buffer[6] == (uint8_t)(lCurrent->mAddr.mAddrQuartets[1] >> 8));
1389         NL_TEST_ASSERT(inSuite, buffer[5] == (uint8_t)(lCurrent->mAddr.mAddrQuartets[1] >> 16));
1390         NL_TEST_ASSERT(inSuite, buffer[4] == (uint8_t)(lCurrent->mAddr.mAddrQuartets[1] >> 24));
1391
1392         NL_TEST_ASSERT(inSuite, buffer[11] == (uint8_t)(lCurrent->mAddr.mAddrQuartets[2]));
1393         NL_TEST_ASSERT(inSuite, buffer[10] == (uint8_t)(lCurrent->mAddr.mAddrQuartets[2] >> 8));
1394         NL_TEST_ASSERT(inSuite, buffer[9] == (uint8_t)(lCurrent->mAddr.mAddrQuartets[2] >> 16));
1395         NL_TEST_ASSERT(inSuite, buffer[8] == (uint8_t)(lCurrent->mAddr.mAddrQuartets[2] >> 24));
1396
1397         NL_TEST_ASSERT(inSuite, buffer[15] == (uint8_t)(lCurrent->mAddr.mAddrQuartets[3]));
1398         NL_TEST_ASSERT(inSuite, buffer[14] == (uint8_t)(lCurrent->mAddr.mAddrQuartets[3] >> 8));
1399         NL_TEST_ASSERT(inSuite, buffer[13] == (uint8_t)(lCurrent->mAddr.mAddrQuartets[3] >> 16));
1400         NL_TEST_ASSERT(inSuite, buffer[12] == (uint8_t)(lCurrent->mAddr.mAddrQuartets[3] >> 24));
1401
1402         ++lCurrent;
1403     }
1404 }
1405
1406 /**
1407  *  Test address decoding with chip::Decoding.
1408  */
1409 void CheckDecoding(nlTestSuite * inSuite, void * inContext)
1410 {
1411     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
1412     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
1413     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
1414
1415     while (lCurrent != lEnd)
1416     {
1417         IPAddress test_addr_1, test_addr_2;
1418         uint8_t buffer[NUM_BYTES_IN_IPV6];
1419         const uint8_t * p;
1420         uint8_t b;
1421
1422         SetupIPAddress(test_addr_1, lCurrent);
1423         ClearIPAddress(test_addr_2);
1424         memset(&buffer, 0, NUM_BYTES_IN_IPV6);
1425         p = buffer;
1426
1427         for (b = 0; b < NUM_BYTES_IN_IPV6; b++)
1428         {
1429             buffer[b] = static_cast<uint8_t>(lCurrent->mAddr.mAddrQuartets[b / 4] >> ((3 - b % 4) * 8));
1430         }
1431
1432         // Call ReadAddress function that we test.
1433         IPAddress::ReadAddress(const_cast<const uint8_t *&>(p), test_addr_2);
1434
1435         CheckAddressQuartets(inSuite, test_addr_1, test_addr_2);
1436
1437         ++lCurrent;
1438     }
1439 }
1440
1441 /**
1442  *  Test address symmetricity of encoding and decoding with chip::(De/En)code.
1443  */
1444 void CheckEcodeDecodeSymmetricity(nlTestSuite * inSuite, void * inContext)
1445 {
1446     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
1447     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
1448     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
1449
1450     while (lCurrent != lEnd)
1451     {
1452         IPAddress test_addr_1, test_addr_2;
1453         uint8_t buffer[NUM_BYTES_IN_IPV6];
1454         uint8_t * p;
1455
1456         SetupIPAddress(test_addr_1, lCurrent);
1457         ClearIPAddress(test_addr_2);
1458         memset(&buffer, 0, NUM_BYTES_IN_IPV6);
1459
1460         p = buffer;
1461
1462         // Call EncodeAddress function that we test.
1463         test_addr_1.WriteAddress(p);
1464
1465         // Move pointer back to the beginning of the buffer.
1466         p = buffer;
1467
1468         // Call ReadAddress function that we test.
1469         IPAddress::ReadAddress(const_cast<const uint8_t *&>(p), test_addr_2);
1470
1471         CheckAddressQuartets(inSuite, test_addr_1, test_addr_2);
1472
1473         ++lCurrent;
1474     }
1475 }
1476
1477 /**
1478  *  Test assembling ULA address.
1479  */
1480 void CheckMakeULA(nlTestSuite * inSuite, void * inContext)
1481 {
1482     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
1483     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
1484     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
1485
1486     while (lCurrent != lEnd)
1487     {
1488         IPAddress test_addr;
1489
1490         // Call MakeULA function that we test.
1491         test_addr = IPAddress::MakeULA(lCurrent->global, lCurrent->subnet, lCurrent->interface);
1492
1493         NL_TEST_ASSERT(inSuite, test_addr.Addr[0] == htonl(ULA_PREFIX | (lCurrent->global & ULA_UP_24_BIT_MASK) >> 16));
1494         NL_TEST_ASSERT(inSuite, test_addr.Addr[1] == htonl((lCurrent->global & ULA_LO_16_BIT_MASK) << 16 | lCurrent->subnet));
1495         NL_TEST_ASSERT(inSuite, test_addr.Addr[2] == htonl(lCurrent->interface >> 32));
1496         NL_TEST_ASSERT(inSuite, test_addr.Addr[3] == htonl(lCurrent->interface));
1497
1498         ++lCurrent;
1499     }
1500 }
1501
1502 /**
1503  *  Test assembling LLA address.
1504  */
1505 void CheckMakeLLA(nlTestSuite * inSuite, void * inContext)
1506 {
1507     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
1508     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
1509     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
1510
1511     while (lCurrent != lEnd)
1512     {
1513         IPAddress test_addr;
1514
1515         // Call MakeLLA function that we test.
1516         test_addr = IPAddress::MakeLLA(lCurrent->interface);
1517
1518         NL_TEST_ASSERT(inSuite, test_addr.Addr[0] == htonl(LLA_PREFIX));
1519         NL_TEST_ASSERT(inSuite, test_addr.Addr[1] == 0);
1520         NL_TEST_ASSERT(inSuite, test_addr.Addr[2] == htonl(lCurrent->interface >> 32));
1521         NL_TEST_ASSERT(inSuite, test_addr.Addr[3] == htonl(lCurrent->interface));
1522
1523         ++lCurrent;
1524     }
1525 }
1526
1527 void CheckMakeIPv6WellKnownMulticast(nlTestSuite * inSuite, void * inContext)
1528 {
1529     const struct TestContext * lContext = static_cast<const struct TestContext *>(inContext);
1530     IPAddressContextIterator lCurrent   = lContext->mIPv6WellKnownMulticastContextRange.mBegin;
1531     IPAddressContextIterator lEnd       = lContext->mIPv6WellKnownMulticastContextRange.mEnd;
1532     size_t lGroupIndex;
1533     size_t lScopeIndex;
1534     IPAddress lAddress;
1535
1536     if (lCurrent != lEnd)
1537     {
1538         for (lGroupIndex = 0; lGroupIndex < NUM_MCAST_GROUPS && (lCurrent != lEnd); lGroupIndex++)
1539         {
1540             for (lScopeIndex = 0; lScopeIndex < NUM_MCAST_SCOPES && (lCurrent != lEnd); lScopeIndex++)
1541             {
1542                 const IPv6MulticastScope lScope = sIPv6MulticastScopes[lScopeIndex];
1543                 const IPV6MulticastGroup lGroup = sIPv6WellKnownMulticastGroups[lGroupIndex];
1544
1545                 lAddress = IPAddress::MakeIPv6WellKnownMulticast(lScope, lGroup);
1546
1547                 CheckAddress(inSuite, *lCurrent, lAddress);
1548
1549                 ++lCurrent;
1550             }
1551         }
1552     }
1553 }
1554
1555 void CheckMakeIPv6TransientMulticast(nlTestSuite * inSuite, void * inContext)
1556 {
1557     const struct TestContext * lContext = static_cast<const struct TestContext *>(inContext);
1558     IPAddressContextIterator lCurrent   = lContext->mIPv6TransientMulticastContextRange.mBegin;
1559     IPAddressContextIterator lEnd       = lContext->mIPv6TransientMulticastContextRange.mEnd;
1560     const uint8_t lFlags                = 0;
1561     size_t lScopeIndex;
1562     IPAddress lAddress;
1563
1564     if (lCurrent != lEnd)
1565     {
1566         // Short Transient Group in Various Scopes
1567
1568         for (lScopeIndex = 0; lScopeIndex < NUM_MCAST_SCOPES && (lCurrent != lEnd); lScopeIndex++)
1569         {
1570             const IPv6MulticastScope lScope                             = sIPv6MulticastScopes[lScopeIndex];
1571             const uint8_t lGroup[NL_INET_IPV6_MCAST_GROUP_LEN_IN_BYTES] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1572                                                                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
1573
1574             lAddress = IPAddress::MakeIPv6TransientMulticast(lFlags, lScope, lGroup);
1575
1576             CheckAddress(inSuite, *lCurrent, lAddress);
1577
1578             ++lCurrent;
1579         }
1580
1581         // Long Transient Group in Various Scopes
1582
1583         for (lScopeIndex = 0; lScopeIndex < NUM_MCAST_SCOPES && (lCurrent != lEnd); lScopeIndex++)
1584         {
1585             const IPv6MulticastScope lScope                             = sIPv6MulticastScopes[lScopeIndex];
1586             const uint8_t lGroup[NL_INET_IPV6_MCAST_GROUP_LEN_IN_BYTES] = { 0xd5, 0xd6, 0x2b, 0xa2, 0x78, 0x47, 0x64,
1587                                                                             0x52, 0x58, 0x7a, 0xc9, 0x55, 0x0b, 0x5a };
1588
1589             lAddress = IPAddress::MakeIPv6TransientMulticast(lFlags, lScope, lGroup);
1590
1591             CheckAddress(inSuite, *lCurrent, lAddress);
1592
1593             ++lCurrent;
1594         }
1595     }
1596 }
1597
1598 void CheckMakeIPv6PrefixMulticast(nlTestSuite * inSuite, void * inContext)
1599 {
1600     const struct TestContext * lContext = static_cast<const struct TestContext *>(inContext);
1601     IPAddressContextIterator lCurrent   = lContext->mIPv6PrefixMulticastContextRange.mBegin;
1602     IPAddressContextIterator lEnd       = lContext->mIPv6PrefixMulticastContextRange.mEnd;
1603     uint8_t lPrefixLength;
1604     uint64_t lPrefix;
1605     uint32_t lGroup;
1606     size_t lScopeIndex;
1607     IPAddress lAddress;
1608
1609     if (lCurrent != lEnd)
1610     {
1611         // 56-bit Prefix with Short Group in Various Scopes
1612
1613         lPrefixLength = 56;
1614         lPrefix       = 0x373acba4d2ad8d00;
1615         lGroup        = 0x00010001;
1616
1617         for (lScopeIndex = 0; lScopeIndex < NUM_MCAST_SCOPES && (lCurrent != lEnd); lScopeIndex++)
1618         {
1619             const IPv6MulticastScope lScope = sIPv6MulticastScopes[lScopeIndex];
1620
1621             lAddress = IPAddress::MakeIPv6PrefixMulticast(lScope, lPrefixLength, lPrefix, lGroup);
1622
1623             CheckAddress(inSuite, *lCurrent, lAddress);
1624
1625             ++lCurrent;
1626         }
1627
1628         // 56-bit Prefix with Long Group in Various Scopes
1629
1630         lPrefixLength = 56;
1631         lPrefix       = 0x373acba4d2ad8d00;
1632         lGroup        = 0xafff5258;
1633
1634         for (lScopeIndex = 0; lScopeIndex < NUM_MCAST_SCOPES && (lCurrent != lEnd); lScopeIndex++)
1635         {
1636             const IPv6MulticastScope lScope = sIPv6MulticastScopes[lScopeIndex];
1637
1638             lAddress = IPAddress::MakeIPv6PrefixMulticast(lScope, lPrefixLength, lPrefix, lGroup);
1639
1640             CheckAddress(inSuite, *lCurrent, lAddress);
1641
1642             ++lCurrent;
1643         }
1644
1645         // 64-bit Prefix with Short Group in Various Scopes
1646
1647         lPrefixLength = 64;
1648         lPrefix       = 0x66643dfbafa4385b;
1649         lGroup        = 0x00010001;
1650
1651         for (lScopeIndex = 0; lScopeIndex < NUM_MCAST_SCOPES && (lCurrent != lEnd); lScopeIndex++)
1652         {
1653             const IPv6MulticastScope lScope = sIPv6MulticastScopes[lScopeIndex];
1654
1655             lAddress = IPAddress::MakeIPv6PrefixMulticast(lScope, lPrefixLength, lPrefix, lGroup);
1656
1657             CheckAddress(inSuite, *lCurrent, lAddress);
1658
1659             ++lCurrent;
1660         }
1661
1662         // 64-bit Prefix with Long Group in Various Scopes
1663
1664         lPrefixLength = 64;
1665         lPrefix       = 0x66643dfbafa4385b;
1666         lGroup        = 0xafff5258;
1667
1668         for (lScopeIndex = 0; lScopeIndex < NUM_MCAST_SCOPES && (lCurrent != lEnd); lScopeIndex++)
1669         {
1670             const IPv6MulticastScope lScope = sIPv6MulticastScopes[lScopeIndex];
1671
1672             lAddress = IPAddress::MakeIPv6PrefixMulticast(lScope, lPrefixLength, lPrefix, lGroup);
1673
1674             CheckAddress(inSuite, *lCurrent, lAddress);
1675
1676             ++lCurrent;
1677         }
1678     }
1679 }
1680
1681 /**
1682  *  Test IPPrefix.
1683  */
1684 void CheckIPPrefix(nlTestSuite * inSuite, void * inContext)
1685 {
1686     const struct TestContext * lContext       = static_cast<const struct TestContext *>(inContext);
1687     IPAddressExpandedContextIterator lCurrent = lContext->mIPAddressExpandedContextRange.mBegin;
1688     IPAddressExpandedContextIterator lEnd     = lContext->mIPAddressExpandedContextRange.mEnd;
1689     size_t i                                  = 0;
1690
1691     while (lCurrent != lEnd)
1692     {
1693         IPPrefix ipprefix_1, ipprefix_2;
1694         IPAddress test_addr_1;
1695
1696         SetupIPAddress(test_addr_1, lCurrent);
1697
1698         ipprefix_1.IPAddr = test_addr_1;
1699         ipprefix_1.Length = 128 - (i++ % 128);
1700         ipprefix_2        = ipprefix_1;
1701
1702         NL_TEST_ASSERT(inSuite, !ipprefix_1.IsZero());
1703         NL_TEST_ASSERT(inSuite, !ipprefix_2.IsZero());
1704         NL_TEST_ASSERT(inSuite, ipprefix_1 == ipprefix_2);
1705         NL_TEST_ASSERT(inSuite, !(ipprefix_1 != ipprefix_2));
1706 #if !CHIP_SYSTEM_CONFIG_USE_LWIP
1707         NL_TEST_ASSERT(inSuite, ipprefix_1.MatchAddress(test_addr_1));
1708 #endif
1709         ++lCurrent;
1710     }
1711 }
1712
1713 /**
1714  *   Test Suite. It lists all the test functions.
1715  */
1716
1717 // clang-format off
1718 const nlTest sTests[] =
1719 {
1720     NL_TEST_DEF("Address Type",                                CheckType),
1721     NL_TEST_DEF("Any Address Global",                          CheckAnyAddress),
1722     NL_TEST_DEF("Address Encoding (Writing)",                  CheckEncoding),
1723     NL_TEST_DEF("Address Decoding (Reading)",                  CheckDecoding),
1724     NL_TEST_DEF("Address Encode / Decode Symmetricity",        CheckEcodeDecodeSymmetricity),
1725     NL_TEST_DEF("From String Conversion",                      CheckFromString),
1726     NL_TEST_DEF("To String Conversion",                        CheckToString),
1727 #if INET_CONFIG_ENABLE_IPV4
1728     NL_TEST_DEF("IPv4 Detection",                              CheckIsIPv4),
1729     NL_TEST_DEF("IPv4 Multicast Detection",                    CheckIsIPv4Multicast),
1730     NL_TEST_DEF("IPv4 Broadcast Detection",                    CheckIsIPv4Broadcast),
1731     NL_TEST_DEF("Convert IPv4 to IPAddress",                   CheckFromIPv4),
1732     NL_TEST_DEF("Convert IPAddress to IPv4",                   CheckToIPv4),
1733 #endif // INET_CONFIG_ENABLE_IPV4
1734     NL_TEST_DEF("IPv6 ULA Detection",                          CheckIsIPv6ULA),
1735     NL_TEST_DEF("IPv6 Link Local Detection",                   CheckIsIPv6LLA),
1736     NL_TEST_DEF("IPv6 Multicast Detection",                    CheckIsIPv6Multicast),
1737     NL_TEST_DEF("Multicast Detection",                         CheckIsMulticast),
1738     NL_TEST_DEF("Equivalence Operator",                        CheckOperatorEqual),
1739     NL_TEST_DEF("Non-Equivalence Operator",                    CheckOperatorNotEqual),
1740     NL_TEST_DEF("Assign Operator",                             CheckOperatorAssign),
1741     NL_TEST_DEF("Convert IPv6 to IPAddress",                   CheckFromIPv6),
1742     NL_TEST_DEF("Convert IPAddress to IPv6",                   CheckToIPv6),
1743     NL_TEST_DEF("Assign address from socket",                  CheckFromSocket),
1744     NL_TEST_DEF("Address Interface ID",                        CheckInterface),
1745     NL_TEST_DEF("Address Subnet",                              CheckSubnet),
1746     NL_TEST_DEF("Address Global ID",                           CheckGlobal),
1747     NL_TEST_DEF("Assemble IPv6 ULA address",                   CheckMakeULA),
1748     NL_TEST_DEF("Assemble IPv6 LLA address",                   CheckMakeLLA),
1749     NL_TEST_DEF("Assemble IPv6 Well-known Multicast address",  CheckMakeIPv6WellKnownMulticast),
1750     NL_TEST_DEF("Assemble IPv6 Transient Multicast address",   CheckMakeIPv6TransientMulticast),
1751     NL_TEST_DEF("Assemble IPv6 Prefix Multicast address",      CheckMakeIPv6PrefixMulticast),
1752     NL_TEST_DEF("IPPrefix test",                               CheckIPPrefix),
1753     NL_TEST_SENTINEL()
1754 };
1755 // clang-format on
1756
1757 /**
1758  *  Set up the test suite.
1759  */
1760 int TestSetup(void * inContext)
1761 {
1762     return (SUCCESS);
1763 }
1764
1765 /**
1766  *  Tear down the test suite.
1767  */
1768 int TestTeardown(void * inContext)
1769 {
1770     return (SUCCESS);
1771 }
1772
1773 } // namespace
1774
1775 int TestInetAddress(void)
1776 {
1777     // clang-format off
1778     nlTestSuite theSuite = {
1779         "inet-address",
1780         &sTests[0],
1781         TestSetup,
1782         TestTeardown
1783     };
1784     // clang-format on
1785
1786     // Run test suit againt one context.
1787     nlTestRunner(&theSuite, const_cast<TestContext *>(&sTestContext));
1788
1789     return (nlTestRunnerStats(&theSuite));
1790 }
1791
1792 CHIP_REGISTER_TEST_SUITE(TestInetAddress)