xref: /aosp_15_r20/external/openthread/tests/unit/test_ip_address.cpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker  *  Copyright (c) 2019-2022, The OpenThread Authors.
3*cfb92d14SAndroid Build Coastguard Worker  *  All rights reserved.
4*cfb92d14SAndroid Build Coastguard Worker  *
5*cfb92d14SAndroid Build Coastguard Worker  *  Redistribution and use in source and binary forms, with or without
6*cfb92d14SAndroid Build Coastguard Worker  *  modification, are permitted provided that the following conditions are met:
7*cfb92d14SAndroid Build Coastguard Worker  *  1. Redistributions of source code must retain the above copyright
8*cfb92d14SAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer.
9*cfb92d14SAndroid Build Coastguard Worker  *  2. Redistributions in binary form must reproduce the above copyright
10*cfb92d14SAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer in the
11*cfb92d14SAndroid Build Coastguard Worker  *     documentation and/or other materials provided with the distribution.
12*cfb92d14SAndroid Build Coastguard Worker  *  3. Neither the name of the copyright holder nor the
13*cfb92d14SAndroid Build Coastguard Worker  *     names of its contributors may be used to endorse or promote products
14*cfb92d14SAndroid Build Coastguard Worker  *     derived from this software without specific prior written permission.
15*cfb92d14SAndroid Build Coastguard Worker  *
16*cfb92d14SAndroid Build Coastguard Worker  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*cfb92d14SAndroid Build Coastguard Worker  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*cfb92d14SAndroid Build Coastguard Worker  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*cfb92d14SAndroid Build Coastguard Worker  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*cfb92d14SAndroid Build Coastguard Worker  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*cfb92d14SAndroid Build Coastguard Worker  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*cfb92d14SAndroid Build Coastguard Worker  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*cfb92d14SAndroid Build Coastguard Worker  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*cfb92d14SAndroid Build Coastguard Worker  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*cfb92d14SAndroid Build Coastguard Worker  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*cfb92d14SAndroid Build Coastguard Worker  *  POSSIBILITY OF SUCH DAMAGE.
27*cfb92d14SAndroid Build Coastguard Worker  */
28*cfb92d14SAndroid Build Coastguard Worker 
29*cfb92d14SAndroid Build Coastguard Worker #include "common/array.hpp"
30*cfb92d14SAndroid Build Coastguard Worker #include "common/encoding.hpp"
31*cfb92d14SAndroid Build Coastguard Worker #include "common/string.hpp"
32*cfb92d14SAndroid Build Coastguard Worker #include "net/ip4_types.hpp"
33*cfb92d14SAndroid Build Coastguard Worker #include "net/ip6_address.hpp"
34*cfb92d14SAndroid Build Coastguard Worker 
35*cfb92d14SAndroid Build Coastguard Worker #include "test_util.h"
36*cfb92d14SAndroid Build Coastguard Worker 
37*cfb92d14SAndroid Build Coastguard Worker namespace ot {
38*cfb92d14SAndroid Build Coastguard Worker 
39*cfb92d14SAndroid Build Coastguard Worker template <typename AddressType> struct TestVector
40*cfb92d14SAndroid Build Coastguard Worker {
41*cfb92d14SAndroid Build Coastguard Worker     const char   *mString;
42*cfb92d14SAndroid Build Coastguard Worker     const uint8_t mAddr[sizeof(AddressType)];
43*cfb92d14SAndroid Build Coastguard Worker     Error         mError;
44*cfb92d14SAndroid Build Coastguard Worker };
45*cfb92d14SAndroid Build Coastguard Worker 
checkAddressFromString(TestVector<AddressType> * aTestVector)46*cfb92d14SAndroid Build Coastguard Worker template <typename AddressType> static void checkAddressFromString(TestVector<AddressType> *aTestVector)
47*cfb92d14SAndroid Build Coastguard Worker {
48*cfb92d14SAndroid Build Coastguard Worker     Error       error;
49*cfb92d14SAndroid Build Coastguard Worker     AddressType address;
50*cfb92d14SAndroid Build Coastguard Worker 
51*cfb92d14SAndroid Build Coastguard Worker     address.Clear();
52*cfb92d14SAndroid Build Coastguard Worker 
53*cfb92d14SAndroid Build Coastguard Worker     error = address.FromString(aTestVector->mString);
54*cfb92d14SAndroid Build Coastguard Worker 
55*cfb92d14SAndroid Build Coastguard Worker     printf("%-42s -> %-42s\n", aTestVector->mString,
56*cfb92d14SAndroid Build Coastguard Worker            (error == kErrorNone) ? address.ToString().AsCString() : "(parse error)");
57*cfb92d14SAndroid Build Coastguard Worker 
58*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(error == aTestVector->mError, "Address::FromString returned unexpected error code");
59*cfb92d14SAndroid Build Coastguard Worker 
60*cfb92d14SAndroid Build Coastguard Worker     if (error == kErrorNone)
61*cfb92d14SAndroid Build Coastguard Worker     {
62*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(0 == memcmp(address.GetBytes(), aTestVector->mAddr, sizeof(AddressType)),
63*cfb92d14SAndroid Build Coastguard Worker                      "Address::FromString parsing failed");
64*cfb92d14SAndroid Build Coastguard Worker     }
65*cfb92d14SAndroid Build Coastguard Worker }
66*cfb92d14SAndroid Build Coastguard Worker 
TestIp6AddressFromString(void)67*cfb92d14SAndroid Build Coastguard Worker void TestIp6AddressFromString(void)
68*cfb92d14SAndroid Build Coastguard Worker {
69*cfb92d14SAndroid Build Coastguard Worker     typedef TestVector<Ip6::Address> Ip6AddressTestVector;
70*cfb92d14SAndroid Build Coastguard Worker 
71*cfb92d14SAndroid Build Coastguard Worker     Ip6AddressTestVector testVectors[] = {
72*cfb92d14SAndroid Build Coastguard Worker         // Valid full IPv6 address.
73*cfb92d14SAndroid Build Coastguard Worker         {"0102:0304:0506:0708:090a:0b0c:0d0e:0f00",
74*cfb92d14SAndroid Build Coastguard Worker          {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00},
75*cfb92d14SAndroid Build Coastguard Worker          kErrorNone},
76*cfb92d14SAndroid Build Coastguard Worker 
77*cfb92d14SAndroid Build Coastguard Worker         // Valid full address using capital letters.
78*cfb92d14SAndroid Build Coastguard Worker         {"0102:0304:0506:0708:090A:0B0C:0D0E:0F00",
79*cfb92d14SAndroid Build Coastguard Worker          {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00},
80*cfb92d14SAndroid Build Coastguard Worker          kErrorNone},
81*cfb92d14SAndroid Build Coastguard Worker 
82*cfb92d14SAndroid Build Coastguard Worker         // Valid full IPv6 address with mixed capital and small letters.
83*cfb92d14SAndroid Build Coastguard Worker         {"0102:0304:0506:0708:090a:0B0C:0d0E:0F00",
84*cfb92d14SAndroid Build Coastguard Worker          {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00},
85*cfb92d14SAndroid Build Coastguard Worker          kErrorNone},
86*cfb92d14SAndroid Build Coastguard Worker 
87*cfb92d14SAndroid Build Coastguard Worker         // Short prefix and full IID.
88*cfb92d14SAndroid Build Coastguard Worker         {"fd11::abcd:e0e0:d10e:0001",
89*cfb92d14SAndroid Build Coastguard Worker          {0xfd, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0xcd, 0xe0, 0xe0, 0xd1, 0x0e, 0x00, 0x01},
90*cfb92d14SAndroid Build Coastguard Worker          kErrorNone},
91*cfb92d14SAndroid Build Coastguard Worker 
92*cfb92d14SAndroid Build Coastguard Worker         // Valid IPv6 address with unnecessary :: symbol.
93*cfb92d14SAndroid Build Coastguard Worker         {"fd11:1234:5678:abcd::abcd:e0e0:d10e:1000",
94*cfb92d14SAndroid Build Coastguard Worker          {0xfd, 0x11, 0x12, 0x34, 0x56, 0x78, 0xab, 0xcd, 0xab, 0xcd, 0xe0, 0xe0, 0xd1, 0x0e, 0x10, 0x00},
95*cfb92d14SAndroid Build Coastguard Worker          kErrorNone},
96*cfb92d14SAndroid Build Coastguard Worker 
97*cfb92d14SAndroid Build Coastguard Worker         // Short multicast address.
98*cfb92d14SAndroid Build Coastguard Worker         {"ff03::0b",
99*cfb92d14SAndroid Build Coastguard Worker          {0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b},
100*cfb92d14SAndroid Build Coastguard Worker          kErrorNone},
101*cfb92d14SAndroid Build Coastguard Worker 
102*cfb92d14SAndroid Build Coastguard Worker         // Unspecified address.
103*cfb92d14SAndroid Build Coastguard Worker         {"::", {0}, kErrorNone},
104*cfb92d14SAndroid Build Coastguard Worker 
105*cfb92d14SAndroid Build Coastguard Worker         // Starts with ::
106*cfb92d14SAndroid Build Coastguard Worker         {"::1:2:3:4",
107*cfb92d14SAndroid Build Coastguard Worker          {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04},
108*cfb92d14SAndroid Build Coastguard Worker          kErrorNone},
109*cfb92d14SAndroid Build Coastguard Worker 
110*cfb92d14SAndroid Build Coastguard Worker         // Ends with ::
111*cfb92d14SAndroid Build Coastguard Worker         {"1001:2002:3003:4004::",
112*cfb92d14SAndroid Build Coastguard Worker          {0x10, 0x01, 0x20, 0x02, 0x30, 0x03, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
113*cfb92d14SAndroid Build Coastguard Worker          kErrorNone},
114*cfb92d14SAndroid Build Coastguard Worker 
115*cfb92d14SAndroid Build Coastguard Worker         // Valid embedded IPv4 address.
116*cfb92d14SAndroid Build Coastguard Worker         {"64:ff9b::100.200.15.4",
117*cfb92d14SAndroid Build Coastguard Worker          {0x00, 0x64, 0xff, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0xc8, 0x0f, 0x04},
118*cfb92d14SAndroid Build Coastguard Worker          kErrorNone},
119*cfb92d14SAndroid Build Coastguard Worker 
120*cfb92d14SAndroid Build Coastguard Worker         // Valid embedded IPv4 address.
121*cfb92d14SAndroid Build Coastguard Worker         {"2001:db8::abc:def1:127.0.0.1",
122*cfb92d14SAndroid Build Coastguard Worker          {0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xbc, 0xde, 0xf1, 0x7f, 0x00, 0x00, 0x01},
123*cfb92d14SAndroid Build Coastguard Worker          kErrorNone},
124*cfb92d14SAndroid Build Coastguard Worker 
125*cfb92d14SAndroid Build Coastguard Worker         // Valid embedded IPv4 address.
126*cfb92d14SAndroid Build Coastguard Worker         {"1:2:3:4:5:6:127.1.2.3",
127*cfb92d14SAndroid Build Coastguard Worker          {0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x7f, 0x01, 0x02, 0x03},
128*cfb92d14SAndroid Build Coastguard Worker          kErrorNone},
129*cfb92d14SAndroid Build Coastguard Worker 
130*cfb92d14SAndroid Build Coastguard Worker         // Two :: should cause a parse error.
131*cfb92d14SAndroid Build Coastguard Worker         {"2001:db8::a::b", {0}, kErrorParse},
132*cfb92d14SAndroid Build Coastguard Worker 
133*cfb92d14SAndroid Build Coastguard Worker         // The "g" and "h" are not the hex characters.
134*cfb92d14SAndroid Build Coastguard Worker         {"2001:db8::abcd:efgh", {0}, kErrorParse},
135*cfb92d14SAndroid Build Coastguard Worker 
136*cfb92d14SAndroid Build Coastguard Worker         // Too many colons.
137*cfb92d14SAndroid Build Coastguard Worker         {"1:2:3:4:5:6:7:8:9", {0}, kErrorParse},
138*cfb92d14SAndroid Build Coastguard Worker 
139*cfb92d14SAndroid Build Coastguard Worker         // Too many characters in a single part.
140*cfb92d14SAndroid Build Coastguard Worker         {"2001:db8::abc:def12:1:2", {0}, kErrorParse},
141*cfb92d14SAndroid Build Coastguard Worker 
142*cfb92d14SAndroid Build Coastguard Worker         // Invalid embedded IPv4 address.
143*cfb92d14SAndroid Build Coastguard Worker         {"64:ff9b::123.231.0.257", {0}, kErrorParse},
144*cfb92d14SAndroid Build Coastguard Worker 
145*cfb92d14SAndroid Build Coastguard Worker         // Invalid embedded IPv4 address.
146*cfb92d14SAndroid Build Coastguard Worker         {"64:ff9b::1.22.33", {0}, kErrorParse},
147*cfb92d14SAndroid Build Coastguard Worker 
148*cfb92d14SAndroid Build Coastguard Worker         // Invalid embedded IPv4 address.
149*cfb92d14SAndroid Build Coastguard Worker         {"64:ff9b::1.22.33.44.5", {0}, kErrorParse},
150*cfb92d14SAndroid Build Coastguard Worker 
151*cfb92d14SAndroid Build Coastguard Worker         // Too long with embedded IPv4 address.
152*cfb92d14SAndroid Build Coastguard Worker         {"1:2:3:4:5:6:7:127.1.2.3", {0}, kErrorParse},
153*cfb92d14SAndroid Build Coastguard Worker 
154*cfb92d14SAndroid Build Coastguard Worker         // Invalid embedded IPv4 address.
155*cfb92d14SAndroid Build Coastguard Worker         {".", {0}, kErrorParse},
156*cfb92d14SAndroid Build Coastguard Worker 
157*cfb92d14SAndroid Build Coastguard Worker         // Invalid embedded IPv4 address.
158*cfb92d14SAndroid Build Coastguard Worker         {":.", {0}, kErrorParse},
159*cfb92d14SAndroid Build Coastguard Worker 
160*cfb92d14SAndroid Build Coastguard Worker         // Invalid embedded IPv4 address.
161*cfb92d14SAndroid Build Coastguard Worker         {"::.", {0}, kErrorParse},
162*cfb92d14SAndroid Build Coastguard Worker 
163*cfb92d14SAndroid Build Coastguard Worker         // Invalid embedded IPv4 address.
164*cfb92d14SAndroid Build Coastguard Worker         {":f:0:0:c:0:f:f:.", {0}, kErrorParse},
165*cfb92d14SAndroid Build Coastguard Worker     };
166*cfb92d14SAndroid Build Coastguard Worker 
167*cfb92d14SAndroid Build Coastguard Worker     for (Ip6AddressTestVector &testVector : testVectors)
168*cfb92d14SAndroid Build Coastguard Worker     {
169*cfb92d14SAndroid Build Coastguard Worker         checkAddressFromString(&testVector);
170*cfb92d14SAndroid Build Coastguard Worker     }
171*cfb92d14SAndroid Build Coastguard Worker 
172*cfb92d14SAndroid Build Coastguard Worker     // Validate parsing all test vectors now as an IPv6 prefix.
173*cfb92d14SAndroid Build Coastguard Worker 
174*cfb92d14SAndroid Build Coastguard Worker     for (Ip6AddressTestVector &testVector : testVectors)
175*cfb92d14SAndroid Build Coastguard Worker     {
176*cfb92d14SAndroid Build Coastguard Worker         constexpr uint16_t kMaxString = 80;
177*cfb92d14SAndroid Build Coastguard Worker 
178*cfb92d14SAndroid Build Coastguard Worker         Ip6::Prefix prefix;
179*cfb92d14SAndroid Build Coastguard Worker         char        string[kMaxString];
180*cfb92d14SAndroid Build Coastguard Worker         uint16_t    length;
181*cfb92d14SAndroid Build Coastguard Worker 
182*cfb92d14SAndroid Build Coastguard Worker         length = StringLength(testVector.mString, kMaxString);
183*cfb92d14SAndroid Build Coastguard Worker         memcpy(string, testVector.mString, length);
184*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(length + sizeof("/128") <= kMaxString);
185*cfb92d14SAndroid Build Coastguard Worker         strcpy(&string[length], "/128");
186*cfb92d14SAndroid Build Coastguard Worker 
187*cfb92d14SAndroid Build Coastguard Worker         printf("%s\n", string);
188*cfb92d14SAndroid Build Coastguard Worker 
189*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(prefix.FromString(string) == testVector.mError);
190*cfb92d14SAndroid Build Coastguard Worker 
191*cfb92d14SAndroid Build Coastguard Worker         if (testVector.mError == kErrorNone)
192*cfb92d14SAndroid Build Coastguard Worker         {
193*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(memcmp(prefix.GetBytes(), testVector.mAddr, sizeof(Ip6::Address)) == 0);
194*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(prefix.GetLength() == 128);
195*cfb92d14SAndroid Build Coastguard Worker         }
196*cfb92d14SAndroid Build Coastguard Worker     }
197*cfb92d14SAndroid Build Coastguard Worker }
198*cfb92d14SAndroid Build Coastguard Worker 
TestIp6PrefixFromString(void)199*cfb92d14SAndroid Build Coastguard Worker void TestIp6PrefixFromString(void)
200*cfb92d14SAndroid Build Coastguard Worker {
201*cfb92d14SAndroid Build Coastguard Worker     Ip6::Prefix prefix;
202*cfb92d14SAndroid Build Coastguard Worker 
203*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(prefix.FromString("::/128"));
204*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(prefix.GetLength() == 128);
205*cfb92d14SAndroid Build Coastguard Worker 
206*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(prefix.FromString("::/0128"));
207*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(prefix.GetLength() == 128);
208*cfb92d14SAndroid Build Coastguard Worker 
209*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(prefix.FromString("::/5"));
210*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(prefix.GetLength() == 5);
211*cfb92d14SAndroid Build Coastguard Worker 
212*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(prefix.FromString("::/0"));
213*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(prefix.GetLength() == 0);
214*cfb92d14SAndroid Build Coastguard Worker 
215*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(prefix.FromString("::") == kErrorParse);
216*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(prefix.FromString("::/") == kErrorParse);
217*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(prefix.FromString("::/129") == kErrorParse);
218*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(prefix.FromString(":: /12") == kErrorParse);
219*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(prefix.FromString("::/a1") == kErrorParse);
220*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(prefix.FromString("::/12 ") == kErrorParse);
221*cfb92d14SAndroid Build Coastguard Worker }
222*cfb92d14SAndroid Build Coastguard Worker 
TestIp4AddressFromString(void)223*cfb92d14SAndroid Build Coastguard Worker void TestIp4AddressFromString(void)
224*cfb92d14SAndroid Build Coastguard Worker {
225*cfb92d14SAndroid Build Coastguard Worker     typedef TestVector<Ip4::Address> Ip4AddressTestVector;
226*cfb92d14SAndroid Build Coastguard Worker 
227*cfb92d14SAndroid Build Coastguard Worker     Ip4AddressTestVector testVectors[] = {
228*cfb92d14SAndroid Build Coastguard Worker         {"0.0.0.0", {0, 0, 0, 0}, kErrorNone},
229*cfb92d14SAndroid Build Coastguard Worker         {"255.255.255.255", {255, 255, 255, 255}, kErrorNone},
230*cfb92d14SAndroid Build Coastguard Worker         {"127.0.0.1", {127, 0, 0, 1}, kErrorNone},
231*cfb92d14SAndroid Build Coastguard Worker         {"1.2.3.4", {1, 2, 3, 4}, kErrorNone},
232*cfb92d14SAndroid Build Coastguard Worker         {"001.002.003.004", {1, 2, 3, 4}, kErrorNone},
233*cfb92d14SAndroid Build Coastguard Worker         {"00000127.000.000.000001", {127, 0, 0, 1}, kErrorNone},
234*cfb92d14SAndroid Build Coastguard Worker         {"123.231.0.256", {0}, kErrorParse},    // Invalid byte value.
235*cfb92d14SAndroid Build Coastguard Worker         {"100123.231.0.256", {0}, kErrorParse}, // Invalid byte value.
236*cfb92d14SAndroid Build Coastguard Worker         {"1.22.33", {0}, kErrorParse},          // Too few bytes.
237*cfb92d14SAndroid Build Coastguard Worker         {"1.22.33.44.5", {0}, kErrorParse},     // Too many bytes.
238*cfb92d14SAndroid Build Coastguard Worker         {"a.b.c.d", {0}, kErrorParse},          // Wrong digit char.
239*cfb92d14SAndroid Build Coastguard Worker         {"123.23.45 .12", {0}, kErrorParse},    // Extra space.
240*cfb92d14SAndroid Build Coastguard Worker         {".", {0}, kErrorParse},                // Invalid.
241*cfb92d14SAndroid Build Coastguard Worker     };
242*cfb92d14SAndroid Build Coastguard Worker 
243*cfb92d14SAndroid Build Coastguard Worker     for (Ip4AddressTestVector &testVector : testVectors)
244*cfb92d14SAndroid Build Coastguard Worker     {
245*cfb92d14SAndroid Build Coastguard Worker         checkAddressFromString(&testVector);
246*cfb92d14SAndroid Build Coastguard Worker     }
247*cfb92d14SAndroid Build Coastguard Worker }
248*cfb92d14SAndroid Build Coastguard Worker 
249*cfb92d14SAndroid Build Coastguard Worker struct CidrTestVector
250*cfb92d14SAndroid Build Coastguard Worker {
251*cfb92d14SAndroid Build Coastguard Worker     const char   *mString;
252*cfb92d14SAndroid Build Coastguard Worker     const uint8_t mAddr[sizeof(otIp4Address)];
253*cfb92d14SAndroid Build Coastguard Worker     const uint8_t mLength;
254*cfb92d14SAndroid Build Coastguard Worker     Error         mError;
255*cfb92d14SAndroid Build Coastguard Worker };
256*cfb92d14SAndroid Build Coastguard Worker 
checkCidrFromString(CidrTestVector * aTestVector)257*cfb92d14SAndroid Build Coastguard Worker static void checkCidrFromString(CidrTestVector *aTestVector)
258*cfb92d14SAndroid Build Coastguard Worker {
259*cfb92d14SAndroid Build Coastguard Worker     Error     error;
260*cfb92d14SAndroid Build Coastguard Worker     Ip4::Cidr cidr;
261*cfb92d14SAndroid Build Coastguard Worker 
262*cfb92d14SAndroid Build Coastguard Worker     cidr.Clear();
263*cfb92d14SAndroid Build Coastguard Worker 
264*cfb92d14SAndroid Build Coastguard Worker     error = cidr.FromString(aTestVector->mString);
265*cfb92d14SAndroid Build Coastguard Worker 
266*cfb92d14SAndroid Build Coastguard Worker     printf("%-42s -> %-42s\n", aTestVector->mString,
267*cfb92d14SAndroid Build Coastguard Worker            (error == kErrorNone) ? cidr.ToString().AsCString() : "(parse error)");
268*cfb92d14SAndroid Build Coastguard Worker 
269*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(error == aTestVector->mError, "Address::FromString returned unexpected error code");
270*cfb92d14SAndroid Build Coastguard Worker 
271*cfb92d14SAndroid Build Coastguard Worker     if (error == kErrorNone)
272*cfb92d14SAndroid Build Coastguard Worker     {
273*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(0 == memcmp(cidr.GetBytes(), aTestVector->mAddr, sizeof(aTestVector->mAddr)),
274*cfb92d14SAndroid Build Coastguard Worker                      "Cidr::FromString parsing failed");
275*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(cidr.mLength == aTestVector->mLength, "Cidr::FromString parsing failed");
276*cfb92d14SAndroid Build Coastguard Worker     }
277*cfb92d14SAndroid Build Coastguard Worker }
278*cfb92d14SAndroid Build Coastguard Worker 
TestIp4CidrFromString(void)279*cfb92d14SAndroid Build Coastguard Worker void TestIp4CidrFromString(void)
280*cfb92d14SAndroid Build Coastguard Worker {
281*cfb92d14SAndroid Build Coastguard Worker     CidrTestVector testVectors[] = {
282*cfb92d14SAndroid Build Coastguard Worker         {"0.0.0.0/0", {0, 0, 0, 0}, 0, kErrorNone},
283*cfb92d14SAndroid Build Coastguard Worker         {"255.255.255.255/32", {255, 255, 255, 255}, 32, kErrorNone},
284*cfb92d14SAndroid Build Coastguard Worker         {"127.0.0.1/8", {127, 0, 0, 1}, 8, kErrorNone},
285*cfb92d14SAndroid Build Coastguard Worker         {"1.2.3.4/24", {1, 2, 3, 4}, 24, kErrorNone},
286*cfb92d14SAndroid Build Coastguard Worker         {"001.002.003.004/20", {1, 2, 3, 4}, 20, kErrorNone},
287*cfb92d14SAndroid Build Coastguard Worker         {"00000127.000.000.000001/8", {127, 0, 0, 1}, 8, kErrorNone},
288*cfb92d14SAndroid Build Coastguard Worker         // Valid suffix, invalid address
289*cfb92d14SAndroid Build Coastguard Worker         {"123.231.0.256/4", {0}, 0, kErrorParse},    // Invalid byte value.
290*cfb92d14SAndroid Build Coastguard Worker         {"100123.231.0.256/4", {0}, 0, kErrorParse}, // Invalid byte value.
291*cfb92d14SAndroid Build Coastguard Worker         {"1.22.33/4", {0}, 0, kErrorParse},          // Too few bytes.
292*cfb92d14SAndroid Build Coastguard Worker         {"1.22.33.44.5/4", {0}, 0, kErrorParse},     // Too many bytes.
293*cfb92d14SAndroid Build Coastguard Worker         {"a.b.c.d/4", {0}, 0, kErrorParse},          // Wrong digit char.
294*cfb92d14SAndroid Build Coastguard Worker         {"123.23.45 .12/4", {0}, 0, kErrorParse},    // Extra space.
295*cfb92d14SAndroid Build Coastguard Worker         {"./4", {0}, 0, kErrorParse},                // Invalid.
296*cfb92d14SAndroid Build Coastguard Worker         // valid address, invalid suffix
297*cfb92d14SAndroid Build Coastguard Worker         {"1.2.3.4/33", {0}, 0, kErrorParse},       // Prefix length too large
298*cfb92d14SAndroid Build Coastguard Worker         {"1.2.3.4/12345678", {0}, 0, kErrorParse}, // Prefix length too large?
299*cfb92d14SAndroid Build Coastguard Worker         {"1.2.3.4/12a", {0}, 0, kErrorParse},      // Extra char after prefix length.
300*cfb92d14SAndroid Build Coastguard Worker         {"1.2.3.4/-1", {0}, 0, kErrorParse},       // Not even a non-negative integer.
301*cfb92d14SAndroid Build Coastguard Worker         {"1.2.3.4/3.14", {0}, 0, kErrorParse},     // Not even a integer.
302*cfb92d14SAndroid Build Coastguard Worker         {"1.2.3.4/abcd", {0}, 0, kErrorParse},     // Not even a number.
303*cfb92d14SAndroid Build Coastguard Worker         {"1.2.3.4/", {0}, 0, kErrorParse},         // Where is the suffix?
304*cfb92d14SAndroid Build Coastguard Worker         {"1.2.3.4", {0}, 0, kErrorParse},          // Where is the suffix?
305*cfb92d14SAndroid Build Coastguard Worker         // invalid address and invalid suffix
306*cfb92d14SAndroid Build Coastguard Worker         {"123.231.0.256/41", {0}, 0, kErrorParse},     // Invalid byte value.
307*cfb92d14SAndroid Build Coastguard Worker         {"100123.231.0.256/abc", {0}, 0, kErrorParse}, // Invalid byte value.
308*cfb92d14SAndroid Build Coastguard Worker         {"1.22.33", {0}, 0, kErrorParse},              // Too few bytes.
309*cfb92d14SAndroid Build Coastguard Worker         {"1.22.33.44.5/36", {0}, 0, kErrorParse},      // Too many bytes.
310*cfb92d14SAndroid Build Coastguard Worker         {"a.b.c.d/99", {0}, 0, kErrorParse},           // Wrong digit char.
311*cfb92d14SAndroid Build Coastguard Worker         {"123.23.45 .12", {0}, 0, kErrorParse},        // Extra space.
312*cfb92d14SAndroid Build Coastguard Worker         {".", {0}, 0, kErrorParse},                    // Invalid.
313*cfb92d14SAndroid Build Coastguard Worker     };
314*cfb92d14SAndroid Build Coastguard Worker 
315*cfb92d14SAndroid Build Coastguard Worker     for (CidrTestVector &testVector : testVectors)
316*cfb92d14SAndroid Build Coastguard Worker     {
317*cfb92d14SAndroid Build Coastguard Worker         checkCidrFromString(&testVector);
318*cfb92d14SAndroid Build Coastguard Worker     }
319*cfb92d14SAndroid Build Coastguard Worker }
320*cfb92d14SAndroid Build Coastguard Worker 
CheckPrefix(const Ip6::Address & aAddress,const uint8_t * aPrefix,uint8_t aPrefixLength)321*cfb92d14SAndroid Build Coastguard Worker bool CheckPrefix(const Ip6::Address &aAddress, const uint8_t *aPrefix, uint8_t aPrefixLength)
322*cfb92d14SAndroid Build Coastguard Worker {
323*cfb92d14SAndroid Build Coastguard Worker     // Check the first aPrefixLength bits of aAddress to match the given aPrefix.
324*cfb92d14SAndroid Build Coastguard Worker 
325*cfb92d14SAndroid Build Coastguard Worker     bool matches = true;
326*cfb92d14SAndroid Build Coastguard Worker 
327*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t bit = 0; bit < aPrefixLength; bit++)
328*cfb92d14SAndroid Build Coastguard Worker     {
329*cfb92d14SAndroid Build Coastguard Worker         uint8_t index = bit / kBitsPerByte;
330*cfb92d14SAndroid Build Coastguard Worker         uint8_t mask  = (0x80 >> (bit % kBitsPerByte));
331*cfb92d14SAndroid Build Coastguard Worker 
332*cfb92d14SAndroid Build Coastguard Worker         if ((aAddress.mFields.m8[index] & mask) != (aPrefix[index] & mask))
333*cfb92d14SAndroid Build Coastguard Worker         {
334*cfb92d14SAndroid Build Coastguard Worker             matches = false;
335*cfb92d14SAndroid Build Coastguard Worker             break;
336*cfb92d14SAndroid Build Coastguard Worker         }
337*cfb92d14SAndroid Build Coastguard Worker     }
338*cfb92d14SAndroid Build Coastguard Worker 
339*cfb92d14SAndroid Build Coastguard Worker     return matches;
340*cfb92d14SAndroid Build Coastguard Worker }
341*cfb92d14SAndroid Build Coastguard Worker 
CheckPrefixInIid(const Ip6::InterfaceIdentifier & aIid,const uint8_t * aPrefix,uint8_t aPrefixLength)342*cfb92d14SAndroid Build Coastguard Worker bool CheckPrefixInIid(const Ip6::InterfaceIdentifier &aIid, const uint8_t *aPrefix, uint8_t aPrefixLength)
343*cfb92d14SAndroid Build Coastguard Worker {
344*cfb92d14SAndroid Build Coastguard Worker     // Check the IID to contain the prefix bits (applicable when prefix length is longer than 64).
345*cfb92d14SAndroid Build Coastguard Worker 
346*cfb92d14SAndroid Build Coastguard Worker     bool matches = true;
347*cfb92d14SAndroid Build Coastguard Worker 
348*cfb92d14SAndroid Build Coastguard Worker     for (uint8_t bit = 64; bit < aPrefixLength; bit++)
349*cfb92d14SAndroid Build Coastguard Worker     {
350*cfb92d14SAndroid Build Coastguard Worker         uint8_t index = bit / kBitsPerByte;
351*cfb92d14SAndroid Build Coastguard Worker         uint8_t mask  = (0x80 >> (bit % kBitsPerByte));
352*cfb92d14SAndroid Build Coastguard Worker 
353*cfb92d14SAndroid Build Coastguard Worker         if ((aIid.mFields.m8[index - 8] & mask) != (aPrefix[index] & mask))
354*cfb92d14SAndroid Build Coastguard Worker         {
355*cfb92d14SAndroid Build Coastguard Worker             matches = false;
356*cfb92d14SAndroid Build Coastguard Worker             break;
357*cfb92d14SAndroid Build Coastguard Worker         }
358*cfb92d14SAndroid Build Coastguard Worker     }
359*cfb92d14SAndroid Build Coastguard Worker 
360*cfb92d14SAndroid Build Coastguard Worker     return matches;
361*cfb92d14SAndroid Build Coastguard Worker }
362*cfb92d14SAndroid Build Coastguard Worker 
CheckInterfaceId(const Ip6::Address & aAddress1,const Ip6::Address & aAddress2,uint8_t aPrefixLength)363*cfb92d14SAndroid Build Coastguard Worker bool CheckInterfaceId(const Ip6::Address &aAddress1, const Ip6::Address &aAddress2, uint8_t aPrefixLength)
364*cfb92d14SAndroid Build Coastguard Worker {
365*cfb92d14SAndroid Build Coastguard Worker     // Check whether all the bits after aPrefixLength of the two given IPv6 Address match or not.
366*cfb92d14SAndroid Build Coastguard Worker 
367*cfb92d14SAndroid Build Coastguard Worker     bool matches = true;
368*cfb92d14SAndroid Build Coastguard Worker 
369*cfb92d14SAndroid Build Coastguard Worker     for (size_t bit = aPrefixLength; bit < sizeof(Ip6::Address) * kBitsPerByte; bit++)
370*cfb92d14SAndroid Build Coastguard Worker     {
371*cfb92d14SAndroid Build Coastguard Worker         uint8_t index = bit / kBitsPerByte;
372*cfb92d14SAndroid Build Coastguard Worker         uint8_t mask  = (0x80 >> (bit % kBitsPerByte));
373*cfb92d14SAndroid Build Coastguard Worker 
374*cfb92d14SAndroid Build Coastguard Worker         if ((aAddress1.mFields.m8[index] & mask) != (aAddress2.mFields.m8[index] & mask))
375*cfb92d14SAndroid Build Coastguard Worker         {
376*cfb92d14SAndroid Build Coastguard Worker             matches = false;
377*cfb92d14SAndroid Build Coastguard Worker             break;
378*cfb92d14SAndroid Build Coastguard Worker         }
379*cfb92d14SAndroid Build Coastguard Worker     }
380*cfb92d14SAndroid Build Coastguard Worker 
381*cfb92d14SAndroid Build Coastguard Worker     return matches;
382*cfb92d14SAndroid Build Coastguard Worker }
383*cfb92d14SAndroid Build Coastguard Worker 
TestIp6AddressSetPrefix(void)384*cfb92d14SAndroid Build Coastguard Worker void TestIp6AddressSetPrefix(void)
385*cfb92d14SAndroid Build Coastguard Worker {
386*cfb92d14SAndroid Build Coastguard Worker     const uint8_t kPrefixes[][OT_IP6_ADDRESS_SIZE] = {
387*cfb92d14SAndroid Build Coastguard Worker         {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
388*cfb92d14SAndroid Build Coastguard Worker         {0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55},
389*cfb92d14SAndroid Build Coastguard Worker         {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
390*cfb92d14SAndroid Build Coastguard Worker         {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
391*cfb92d14SAndroid Build Coastguard Worker     };
392*cfb92d14SAndroid Build Coastguard Worker 
393*cfb92d14SAndroid Build Coastguard Worker     Ip6::Address address;
394*cfb92d14SAndroid Build Coastguard Worker     Ip6::Address allZeroAddress;
395*cfb92d14SAndroid Build Coastguard Worker     Ip6::Address allOneAddress;
396*cfb92d14SAndroid Build Coastguard Worker     Ip6::Prefix  ip6Prefix;
397*cfb92d14SAndroid Build Coastguard Worker 
398*cfb92d14SAndroid Build Coastguard Worker     allZeroAddress.Clear();
399*cfb92d14SAndroid Build Coastguard Worker     memset(&allOneAddress, 0xff, sizeof(allOneAddress));
400*cfb92d14SAndroid Build Coastguard Worker 
401*cfb92d14SAndroid Build Coastguard Worker     for (auto prefix : kPrefixes)
402*cfb92d14SAndroid Build Coastguard Worker     {
403*cfb92d14SAndroid Build Coastguard Worker         memcpy(address.mFields.m8, prefix, sizeof(address));
404*cfb92d14SAndroid Build Coastguard Worker         printf("Prefix is %s\n", address.ToString().AsCString());
405*cfb92d14SAndroid Build Coastguard Worker 
406*cfb92d14SAndroid Build Coastguard Worker         for (size_t prefixLength = 0; prefixLength <= sizeof(Ip6::Address) * kBitsPerByte; prefixLength++)
407*cfb92d14SAndroid Build Coastguard Worker         {
408*cfb92d14SAndroid Build Coastguard Worker             ip6Prefix.Clear();
409*cfb92d14SAndroid Build Coastguard Worker             ip6Prefix.Set(prefix, prefixLength);
410*cfb92d14SAndroid Build Coastguard Worker 
411*cfb92d14SAndroid Build Coastguard Worker             address = allZeroAddress;
412*cfb92d14SAndroid Build Coastguard Worker             address.SetPrefix(ip6Prefix);
413*cfb92d14SAndroid Build Coastguard Worker             printf("   prefix-len:%-3zu --> %s\n", prefixLength, address.ToString().AsCString());
414*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(CheckPrefix(address, prefix, prefixLength), "Prefix does not match after SetPrefix()");
415*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(CheckInterfaceId(address, allZeroAddress, prefixLength),
416*cfb92d14SAndroid Build Coastguard Worker                          "SetPrefix changed bits beyond the prefix length");
417*cfb92d14SAndroid Build Coastguard Worker 
418*cfb92d14SAndroid Build Coastguard Worker             address = allOneAddress;
419*cfb92d14SAndroid Build Coastguard Worker             address.SetPrefix(ip6Prefix);
420*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(CheckPrefix(address, prefix, prefixLength), "Prefix does not match after SetPrefix()");
421*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(CheckInterfaceId(address, allOneAddress, prefixLength),
422*cfb92d14SAndroid Build Coastguard Worker                          "SetPrefix changed bits beyond the prefix length");
423*cfb92d14SAndroid Build Coastguard Worker 
424*cfb92d14SAndroid Build Coastguard Worker             address = allZeroAddress;
425*cfb92d14SAndroid Build Coastguard Worker             address.GetIid().ApplyPrefix(ip6Prefix);
426*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(CheckPrefixInIid(address.GetIid(), prefix, prefixLength), "IID is not correct");
427*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(CheckInterfaceId(address, allZeroAddress, prefixLength),
428*cfb92d14SAndroid Build Coastguard Worker                          "Iid:ApplyPrefrix() changed bits beyond the prefix length");
429*cfb92d14SAndroid Build Coastguard Worker 
430*cfb92d14SAndroid Build Coastguard Worker             address = allOneAddress;
431*cfb92d14SAndroid Build Coastguard Worker             address.GetIid().ApplyPrefix(ip6Prefix);
432*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(CheckPrefixInIid(address.GetIid(), prefix, prefixLength), "IID is not correct");
433*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(CheckInterfaceId(address, allOneAddress, prefixLength),
434*cfb92d14SAndroid Build Coastguard Worker                          "Iid:ApplyPrefrix() changed bits beyond the prefix length");
435*cfb92d14SAndroid Build Coastguard Worker         }
436*cfb92d14SAndroid Build Coastguard Worker     }
437*cfb92d14SAndroid Build Coastguard Worker }
438*cfb92d14SAndroid Build Coastguard Worker 
PrefixFrom(const char * aAddressString,uint8_t aPrefixLength)439*cfb92d14SAndroid Build Coastguard Worker Ip6::Prefix PrefixFrom(const char *aAddressString, uint8_t aPrefixLength)
440*cfb92d14SAndroid Build Coastguard Worker {
441*cfb92d14SAndroid Build Coastguard Worker     Ip6::Prefix  prefix;
442*cfb92d14SAndroid Build Coastguard Worker     Ip6::Address address;
443*cfb92d14SAndroid Build Coastguard Worker 
444*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(address.FromString(aAddressString));
445*cfb92d14SAndroid Build Coastguard Worker     prefix.Set(address.GetBytes(), aPrefixLength);
446*cfb92d14SAndroid Build Coastguard Worker 
447*cfb92d14SAndroid Build Coastguard Worker     return prefix;
448*cfb92d14SAndroid Build Coastguard Worker }
449*cfb92d14SAndroid Build Coastguard Worker 
TestIp6Prefix(void)450*cfb92d14SAndroid Build Coastguard Worker void TestIp6Prefix(void)
451*cfb92d14SAndroid Build Coastguard Worker {
452*cfb92d14SAndroid Build Coastguard Worker     const uint8_t kPrefixes[][OT_IP6_ADDRESS_SIZE] = {
453*cfb92d14SAndroid Build Coastguard Worker         {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
454*cfb92d14SAndroid Build Coastguard Worker         {0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55},
455*cfb92d14SAndroid Build Coastguard Worker         {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
456*cfb92d14SAndroid Build Coastguard Worker     };
457*cfb92d14SAndroid Build Coastguard Worker 
458*cfb92d14SAndroid Build Coastguard Worker     Ip6::Prefix  prefix;
459*cfb92d14SAndroid Build Coastguard Worker     Ip6::Address address1, address2;
460*cfb92d14SAndroid Build Coastguard Worker 
461*cfb92d14SAndroid Build Coastguard Worker     for (auto prefixBytes : kPrefixes)
462*cfb92d14SAndroid Build Coastguard Worker     {
463*cfb92d14SAndroid Build Coastguard Worker         memcpy(address1.mFields.m8, prefixBytes, sizeof(address1));
464*cfb92d14SAndroid Build Coastguard Worker         address2 = address1;
465*cfb92d14SAndroid Build Coastguard Worker         address2.mFields.m8[0] ^= 0x80; // Change first bit.
466*cfb92d14SAndroid Build Coastguard Worker 
467*cfb92d14SAndroid Build Coastguard Worker         for (uint8_t prefixLength = 1; prefixLength <= Ip6::Prefix::kMaxLength; prefixLength++)
468*cfb92d14SAndroid Build Coastguard Worker         {
469*cfb92d14SAndroid Build Coastguard Worker             prefix.Set(prefixBytes, prefixLength);
470*cfb92d14SAndroid Build Coastguard Worker 
471*cfb92d14SAndroid Build Coastguard Worker             printf("Prefix %s\n", prefix.ToString().AsCString());
472*cfb92d14SAndroid Build Coastguard Worker 
473*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(prefix.GetLength() == prefixLength);
474*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(prefix.IsValid());
475*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(prefix.IsEqual(prefixBytes, prefixLength));
476*cfb92d14SAndroid Build Coastguard Worker 
477*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(address1.MatchesPrefix(prefix));
478*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(!address2.MatchesPrefix(prefix));
479*cfb92d14SAndroid Build Coastguard Worker 
480*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(prefix == prefix);
481*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(!(prefix < prefix));
482*cfb92d14SAndroid Build Coastguard Worker 
483*cfb92d14SAndroid Build Coastguard Worker             for (uint8_t subPrefixLength = 1; subPrefixLength <= prefixLength; subPrefixLength++)
484*cfb92d14SAndroid Build Coastguard Worker             {
485*cfb92d14SAndroid Build Coastguard Worker                 Ip6::Prefix subPrefix;
486*cfb92d14SAndroid Build Coastguard Worker 
487*cfb92d14SAndroid Build Coastguard Worker                 subPrefix.Set(prefixBytes, subPrefixLength);
488*cfb92d14SAndroid Build Coastguard Worker 
489*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrQuit(prefix.ContainsPrefix(subPrefix));
490*cfb92d14SAndroid Build Coastguard Worker 
491*cfb92d14SAndroid Build Coastguard Worker                 if (prefixLength == subPrefixLength)
492*cfb92d14SAndroid Build Coastguard Worker                 {
493*cfb92d14SAndroid Build Coastguard Worker                     VerifyOrQuit(prefix == subPrefix);
494*cfb92d14SAndroid Build Coastguard Worker                     VerifyOrQuit(prefix.IsEqual(subPrefix.GetBytes(), subPrefix.GetLength()));
495*cfb92d14SAndroid Build Coastguard Worker                     VerifyOrQuit(!(subPrefix < prefix));
496*cfb92d14SAndroid Build Coastguard Worker                 }
497*cfb92d14SAndroid Build Coastguard Worker                 else
498*cfb92d14SAndroid Build Coastguard Worker                 {
499*cfb92d14SAndroid Build Coastguard Worker                     VerifyOrQuit(prefix != subPrefix);
500*cfb92d14SAndroid Build Coastguard Worker                     VerifyOrQuit(!prefix.IsEqual(subPrefix.GetBytes(), subPrefix.GetLength()));
501*cfb92d14SAndroid Build Coastguard Worker                     VerifyOrQuit(subPrefix < prefix);
502*cfb92d14SAndroid Build Coastguard Worker                 }
503*cfb92d14SAndroid Build Coastguard Worker             }
504*cfb92d14SAndroid Build Coastguard Worker 
505*cfb92d14SAndroid Build Coastguard Worker             for (uint8_t bitNumber = 0; bitNumber < prefixLength; bitNumber++)
506*cfb92d14SAndroid Build Coastguard Worker             {
507*cfb92d14SAndroid Build Coastguard Worker                 Ip6::Prefix prefix2;
508*cfb92d14SAndroid Build Coastguard Worker                 uint8_t     mask  = static_cast<uint8_t>(1U << (7 - (bitNumber & 7)));
509*cfb92d14SAndroid Build Coastguard Worker                 uint8_t     index = (bitNumber / 8);
510*cfb92d14SAndroid Build Coastguard Worker                 bool        isPrefixSmaller;
511*cfb92d14SAndroid Build Coastguard Worker 
512*cfb92d14SAndroid Build Coastguard Worker                 prefix2 = prefix;
513*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrQuit(prefix == prefix2);
514*cfb92d14SAndroid Build Coastguard Worker 
515*cfb92d14SAndroid Build Coastguard Worker                 // Flip the `bitNumber` bit between `prefix` and `prefix2`
516*cfb92d14SAndroid Build Coastguard Worker 
517*cfb92d14SAndroid Build Coastguard Worker                 prefix2.mPrefix.mFields.m8[index] ^= mask;
518*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrQuit(prefix != prefix2);
519*cfb92d14SAndroid Build Coastguard Worker 
520*cfb92d14SAndroid Build Coastguard Worker                 isPrefixSmaller = ((prefix.GetBytes()[index] & mask) == 0);
521*cfb92d14SAndroid Build Coastguard Worker 
522*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrQuit((prefix < prefix2) == isPrefixSmaller);
523*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrQuit((prefix2 < prefix) == !isPrefixSmaller);
524*cfb92d14SAndroid Build Coastguard Worker             }
525*cfb92d14SAndroid Build Coastguard Worker         }
526*cfb92d14SAndroid Build Coastguard Worker     }
527*cfb92d14SAndroid Build Coastguard Worker 
528*cfb92d14SAndroid Build Coastguard Worker     {
529*cfb92d14SAndroid Build Coastguard Worker         struct TestCase
530*cfb92d14SAndroid Build Coastguard Worker         {
531*cfb92d14SAndroid Build Coastguard Worker             Ip6::Prefix mPrefixA;
532*cfb92d14SAndroid Build Coastguard Worker             Ip6::Prefix mPrefixB;
533*cfb92d14SAndroid Build Coastguard Worker         };
534*cfb92d14SAndroid Build Coastguard Worker 
535*cfb92d14SAndroid Build Coastguard Worker         TestCase kTestCases[] = {
536*cfb92d14SAndroid Build Coastguard Worker             {PrefixFrom("fd00::", 16), PrefixFrom("fd01::", 16)},
537*cfb92d14SAndroid Build Coastguard Worker             {PrefixFrom("fc00::", 16), PrefixFrom("fd00::", 16)},
538*cfb92d14SAndroid Build Coastguard Worker             {PrefixFrom("fd00::", 15), PrefixFrom("fd00::", 16)},
539*cfb92d14SAndroid Build Coastguard Worker             {PrefixFrom("fd00::", 16), PrefixFrom("fd00:0::", 32)},
540*cfb92d14SAndroid Build Coastguard Worker             {PrefixFrom("2001:0:0:0::", 64), PrefixFrom("fd00::", 8)},
541*cfb92d14SAndroid Build Coastguard Worker             {PrefixFrom("2001:dba::", 32), PrefixFrom("fd12:3456:1234:abcd::", 64)},
542*cfb92d14SAndroid Build Coastguard Worker             {PrefixFrom("910b:1000:0::", 48), PrefixFrom("910b:2000::", 32)},
543*cfb92d14SAndroid Build Coastguard Worker             {PrefixFrom("::", 0), PrefixFrom("fd00::", 8)},
544*cfb92d14SAndroid Build Coastguard Worker             {PrefixFrom("::", 0), PrefixFrom("::", 16)},
545*cfb92d14SAndroid Build Coastguard Worker             {PrefixFrom("fd00:2:2::", 33), PrefixFrom("fd00:2:2::", 35)},
546*cfb92d14SAndroid Build Coastguard Worker             {PrefixFrom("1:2:3:ffff::", 62), PrefixFrom("1:2:3:ffff::", 63)},
547*cfb92d14SAndroid Build Coastguard Worker         };
548*cfb92d14SAndroid Build Coastguard Worker 
549*cfb92d14SAndroid Build Coastguard Worker         printf("\nCompare Prefixes:\n");
550*cfb92d14SAndroid Build Coastguard Worker 
551*cfb92d14SAndroid Build Coastguard Worker         for (const TestCase &testCase : kTestCases)
552*cfb92d14SAndroid Build Coastguard Worker         {
553*cfb92d14SAndroid Build Coastguard Worker             printf(" %26s  <  %s\n", testCase.mPrefixA.ToString().AsCString(),
554*cfb92d14SAndroid Build Coastguard Worker                    testCase.mPrefixB.ToString().AsCString());
555*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(testCase.mPrefixA < testCase.mPrefixB);
556*cfb92d14SAndroid Build Coastguard Worker             VerifyOrQuit(!(testCase.mPrefixB < testCase.mPrefixA));
557*cfb92d14SAndroid Build Coastguard Worker         }
558*cfb92d14SAndroid Build Coastguard Worker     }
559*cfb92d14SAndroid Build Coastguard Worker 
560*cfb92d14SAndroid Build Coastguard Worker     // `IsLinkLocal()` - should contain `fe80::/10`.
561*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(PrefixFrom("fe80::", 10).IsLinkLocal());
562*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(PrefixFrom("fe80::", 11).IsLinkLocal());
563*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(PrefixFrom("fea0::", 16).IsLinkLocal());
564*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!PrefixFrom("fe80::", 9).IsLinkLocal());
565*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!PrefixFrom("ff80::", 10).IsLinkLocal());
566*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!PrefixFrom("fe00::", 10).IsLinkLocal());
567*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!PrefixFrom("fec0::", 10).IsLinkLocal());
568*cfb92d14SAndroid Build Coastguard Worker 
569*cfb92d14SAndroid Build Coastguard Worker     // `IsMulticast()` - should contain `ff00::/8`.
570*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(PrefixFrom("ff00::", 8).IsMulticast());
571*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(PrefixFrom("ff80::", 9).IsMulticast());
572*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(PrefixFrom("ffff::", 16).IsMulticast());
573*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!PrefixFrom("ff00::", 7).IsMulticast());
574*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!PrefixFrom("fe00::", 8).IsMulticast());
575*cfb92d14SAndroid Build Coastguard Worker 
576*cfb92d14SAndroid Build Coastguard Worker     // `IsUniqueLocal()` - should contain `fc00::/7`.
577*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(PrefixFrom("fc00::", 7).IsUniqueLocal());
578*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(PrefixFrom("fd00::", 8).IsUniqueLocal());
579*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(PrefixFrom("fc10::", 16).IsUniqueLocal());
580*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!PrefixFrom("fc00::", 6).IsUniqueLocal());
581*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!PrefixFrom("f800::", 7).IsUniqueLocal());
582*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(!PrefixFrom("fe00::", 7).IsUniqueLocal());
583*cfb92d14SAndroid Build Coastguard Worker }
584*cfb92d14SAndroid Build Coastguard Worker 
TestIp6PrefixTidy(void)585*cfb92d14SAndroid Build Coastguard Worker void TestIp6PrefixTidy(void)
586*cfb92d14SAndroid Build Coastguard Worker {
587*cfb92d14SAndroid Build Coastguard Worker     struct TestVector
588*cfb92d14SAndroid Build Coastguard Worker     {
589*cfb92d14SAndroid Build Coastguard Worker         uint8_t     originalPrefix[OT_IP6_ADDRESS_SIZE];
590*cfb92d14SAndroid Build Coastguard Worker         const char *prefixStringAfterTidy[129];
591*cfb92d14SAndroid Build Coastguard Worker     };
592*cfb92d14SAndroid Build Coastguard Worker     const TestVector kPrefixes[] = {
593*cfb92d14SAndroid Build Coastguard Worker         {
594*cfb92d14SAndroid Build Coastguard Worker             .originalPrefix = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
595*cfb92d14SAndroid Build Coastguard Worker                                0xff},
596*cfb92d14SAndroid Build Coastguard Worker             .prefixStringAfterTidy =
597*cfb92d14SAndroid Build Coastguard Worker                 {
598*cfb92d14SAndroid Build Coastguard Worker                     "::/0",
599*cfb92d14SAndroid Build Coastguard Worker                     "8000::/1",
600*cfb92d14SAndroid Build Coastguard Worker                     "c000::/2",
601*cfb92d14SAndroid Build Coastguard Worker                     "e000::/3",
602*cfb92d14SAndroid Build Coastguard Worker                     "f000::/4",
603*cfb92d14SAndroid Build Coastguard Worker                     "f800::/5",
604*cfb92d14SAndroid Build Coastguard Worker                     "fc00::/6",
605*cfb92d14SAndroid Build Coastguard Worker                     "fe00::/7",
606*cfb92d14SAndroid Build Coastguard Worker                     "ff00::/8",
607*cfb92d14SAndroid Build Coastguard Worker                     "ff80::/9",
608*cfb92d14SAndroid Build Coastguard Worker                     "ffc0::/10",
609*cfb92d14SAndroid Build Coastguard Worker                     "ffe0::/11",
610*cfb92d14SAndroid Build Coastguard Worker                     "fff0::/12",
611*cfb92d14SAndroid Build Coastguard Worker                     "fff8::/13",
612*cfb92d14SAndroid Build Coastguard Worker                     "fffc::/14",
613*cfb92d14SAndroid Build Coastguard Worker                     "fffe::/15",
614*cfb92d14SAndroid Build Coastguard Worker                     "ffff::/16",
615*cfb92d14SAndroid Build Coastguard Worker                     "ffff:8000::/17",
616*cfb92d14SAndroid Build Coastguard Worker                     "ffff:c000::/18",
617*cfb92d14SAndroid Build Coastguard Worker                     "ffff:e000::/19",
618*cfb92d14SAndroid Build Coastguard Worker                     "ffff:f000::/20",
619*cfb92d14SAndroid Build Coastguard Worker                     "ffff:f800::/21",
620*cfb92d14SAndroid Build Coastguard Worker                     "ffff:fc00::/22",
621*cfb92d14SAndroid Build Coastguard Worker                     "ffff:fe00::/23",
622*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ff00::/24",
623*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ff80::/25",
624*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffc0::/26",
625*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffe0::/27",
626*cfb92d14SAndroid Build Coastguard Worker                     "ffff:fff0::/28",
627*cfb92d14SAndroid Build Coastguard Worker                     "ffff:fff8::/29",
628*cfb92d14SAndroid Build Coastguard Worker                     "ffff:fffc::/30",
629*cfb92d14SAndroid Build Coastguard Worker                     "ffff:fffe::/31",
630*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff::/32",
631*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:8000::/33",
632*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:c000::/34",
633*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:e000::/35",
634*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:f000::/36",
635*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:f800::/37",
636*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:fc00::/38",
637*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:fe00::/39",
638*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ff00::/40",
639*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ff80::/41",
640*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffc0::/42",
641*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffe0::/43",
642*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:fff0::/44",
643*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:fff8::/45",
644*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:fffc::/46",
645*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:fffe::/47",
646*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff::/48",
647*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:8000::/49",
648*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:c000::/50",
649*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:e000::/51",
650*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:f000::/52",
651*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:f800::/53",
652*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:fc00::/54",
653*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:fe00::/55",
654*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ff00::/56",
655*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ff80::/57",
656*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffc0::/58",
657*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffe0::/59",
658*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:fff0::/60",
659*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:fff8::/61",
660*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:fffc::/62",
661*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:fffe::/63",
662*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff::/64",
663*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:8000::/65",
664*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:c000::/66",
665*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:e000::/67",
666*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:f000::/68",
667*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:f800::/69",
668*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:fc00::/70",
669*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:fe00::/71",
670*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ff00::/72",
671*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ff80::/73",
672*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffc0::/74",
673*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffe0::/75",
674*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:fff0::/76",
675*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:fff8::/77",
676*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:fffc::/78",
677*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:fffe::/79",
678*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff::/80",
679*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:8000::/81",
680*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:c000::/82",
681*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:e000::/83",
682*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:f000::/84",
683*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:f800::/85",
684*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:fc00::/86",
685*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:fe00::/87",
686*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ff00::/88",
687*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ff80::/89",
688*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffc0::/90",
689*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffe0::/91",
690*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:fff0::/92",
691*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:fff8::/93",
692*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:fffc::/94",
693*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:fffe::/95",
694*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff::/96",
695*cfb92d14SAndroid Build Coastguard Worker                     // Note: The result of /97 to /112 does not meet RFC requirements:
696*cfb92d14SAndroid Build Coastguard Worker                     // 4.2.2.  Handling One 16-Bit 0 Field
697*cfb92d14SAndroid Build Coastguard Worker                     // The symbol "::" MUST NOT be used to shorten just one 16-bit 0 field.
698*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:8000::/97",
699*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:c000::/98",
700*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:e000::/99",
701*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:f000::/100",
702*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:f800::/101",
703*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:fc00::/102",
704*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:fe00::/103",
705*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:ff00::/104",
706*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:ff80::/105",
707*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:ffc0::/106",
708*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:ffe0::/107",
709*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:fff0::/108",
710*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:fff8::/109",
711*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:fffc::/110",
712*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:fffe::/111",
713*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:ffff::/112",
714*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:ffff:8000/113",
715*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:ffff:c000/114",
716*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:ffff:e000/115",
717*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:ffff:f000/116",
718*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:ffff:f800/117",
719*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fc00/118",
720*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fe00/119",
721*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00/120",
722*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff80/121",
723*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffc0/122",
724*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffe0/123",
725*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0/124",
726*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff8/125",
727*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffc/126",
728*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe/127",
729*cfb92d14SAndroid Build Coastguard Worker                     "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128",
730*cfb92d14SAndroid Build Coastguard Worker                 },
731*cfb92d14SAndroid Build Coastguard Worker         },
732*cfb92d14SAndroid Build Coastguard Worker     };
733*cfb92d14SAndroid Build Coastguard Worker 
734*cfb92d14SAndroid Build Coastguard Worker     printf("Tidy Prefixes:\n");
735*cfb92d14SAndroid Build Coastguard Worker 
736*cfb92d14SAndroid Build Coastguard Worker     for (auto test : kPrefixes)
737*cfb92d14SAndroid Build Coastguard Worker     {
738*cfb92d14SAndroid Build Coastguard Worker         for (uint16_t i = 0; i < GetArrayLength(test.prefixStringAfterTidy); i++)
739*cfb92d14SAndroid Build Coastguard Worker         {
740*cfb92d14SAndroid Build Coastguard Worker             Ip6::Prefix prefix, answer;
741*cfb92d14SAndroid Build Coastguard Worker 
742*cfb92d14SAndroid Build Coastguard Worker             SuccessOrQuit(answer.FromString(test.prefixStringAfterTidy[i]));
743*cfb92d14SAndroid Build Coastguard Worker             prefix.Set(test.originalPrefix, i);
744*cfb92d14SAndroid Build Coastguard Worker             prefix.Tidy();
745*cfb92d14SAndroid Build Coastguard Worker 
746*cfb92d14SAndroid Build Coastguard Worker             {
747*cfb92d14SAndroid Build Coastguard Worker                 Ip6::Prefix::InfoString prefixString = prefix.ToString();
748*cfb92d14SAndroid Build Coastguard Worker 
749*cfb92d14SAndroid Build Coastguard Worker                 printf("Prefix: %-36s  TidyResult: %-36s\n", test.prefixStringAfterTidy[i],
750*cfb92d14SAndroid Build Coastguard Worker                        prefix.ToString().AsCString());
751*cfb92d14SAndroid Build Coastguard Worker 
752*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrQuit(memcmp(answer.mPrefix.mFields.m8, prefix.mPrefix.mFields.m8,
753*cfb92d14SAndroid Build Coastguard Worker                                     sizeof(answer.mPrefix.mFields.m8)) == 0);
754*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrQuit(prefix.mLength == answer.mLength);
755*cfb92d14SAndroid Build Coastguard Worker                 VerifyOrQuit(strcmp(test.prefixStringAfterTidy[i], prefixString.AsCString()) == 0);
756*cfb92d14SAndroid Build Coastguard Worker             }
757*cfb92d14SAndroid Build Coastguard Worker         }
758*cfb92d14SAndroid Build Coastguard Worker     }
759*cfb92d14SAndroid Build Coastguard Worker }
760*cfb92d14SAndroid Build Coastguard Worker 
TestIp4MappedIp6Address(void)761*cfb92d14SAndroid Build Coastguard Worker void TestIp4MappedIp6Address(void)
762*cfb92d14SAndroid Build Coastguard Worker {
763*cfb92d14SAndroid Build Coastguard Worker     const uint8_t kIp4Address[] = {192, 0, 2, 33};
764*cfb92d14SAndroid Build Coastguard Worker 
765*cfb92d14SAndroid Build Coastguard Worker     const char *kInvalidIp4MappedFormats[] = {
766*cfb92d14SAndroid Build Coastguard Worker         "8000::ffff:192.0.2.23",     "0:400::ffff:192.0.2.23", "0:0:1::ffff:192.0.2.23", "0:0:0:4:0:ffff:192.0.2.23",
767*cfb92d14SAndroid Build Coastguard Worker         "0:0:0:0:1:ffff:192.0.2.23", "::fffe:192.0.2.23",      "::efff:192.0.2.23",
768*cfb92d14SAndroid Build Coastguard Worker     };
769*cfb92d14SAndroid Build Coastguard Worker 
770*cfb92d14SAndroid Build Coastguard Worker     Ip4::Address expectedIp4Address;
771*cfb92d14SAndroid Build Coastguard Worker     Ip4::Address ip4Address;
772*cfb92d14SAndroid Build Coastguard Worker     Ip6::Address expectedIp6Address;
773*cfb92d14SAndroid Build Coastguard Worker     Ip6::Address ip6Address;
774*cfb92d14SAndroid Build Coastguard Worker 
775*cfb92d14SAndroid Build Coastguard Worker     printf("\nTestIp4MappedIp6Address()\n");
776*cfb92d14SAndroid Build Coastguard Worker 
777*cfb92d14SAndroid Build Coastguard Worker     expectedIp4Address.SetBytes(kIp4Address);
778*cfb92d14SAndroid Build Coastguard Worker 
779*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(expectedIp6Address.FromString("::ffff:192.0.2.33"));
780*cfb92d14SAndroid Build Coastguard Worker     ip6Address.SetToIp4Mapped(expectedIp4Address);
781*cfb92d14SAndroid Build Coastguard Worker 
782*cfb92d14SAndroid Build Coastguard Worker     printf("IPv4-mapped IPv6 address: %s\n", ip6Address.ToString().AsCString());
783*cfb92d14SAndroid Build Coastguard Worker 
784*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ip6Address.IsIp4Mapped());
785*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ip6Address == expectedIp6Address);
786*cfb92d14SAndroid Build Coastguard Worker 
787*cfb92d14SAndroid Build Coastguard Worker     SuccessOrQuit(ip4Address.ExtractFromIp4MappedIp6Address(ip6Address));
788*cfb92d14SAndroid Build Coastguard Worker     VerifyOrQuit(ip4Address == expectedIp4Address);
789*cfb92d14SAndroid Build Coastguard Worker 
790*cfb92d14SAndroid Build Coastguard Worker     for (const char *invalidIp4MappedAddr : kInvalidIp4MappedFormats)
791*cfb92d14SAndroid Build Coastguard Worker     {
792*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(ip6Address.FromString(invalidIp4MappedAddr));
793*cfb92d14SAndroid Build Coastguard Worker         printf("Invalid IPv4-mapped IPv6 address: %s -> %s\n", invalidIp4MappedAddr, ip6Address.ToString().AsCString());
794*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(!ip6Address.IsIp4Mapped());
795*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(ip4Address.ExtractFromIp4MappedIp6Address(ip6Address) != kErrorNone);
796*cfb92d14SAndroid Build Coastguard Worker     }
797*cfb92d14SAndroid Build Coastguard Worker }
798*cfb92d14SAndroid Build Coastguard Worker 
TestIp4Ip6Translation(void)799*cfb92d14SAndroid Build Coastguard Worker void TestIp4Ip6Translation(void)
800*cfb92d14SAndroid Build Coastguard Worker {
801*cfb92d14SAndroid Build Coastguard Worker     struct TestCase
802*cfb92d14SAndroid Build Coastguard Worker     {
803*cfb92d14SAndroid Build Coastguard Worker         const char *mPrefix;     // NAT64 prefix
804*cfb92d14SAndroid Build Coastguard Worker         uint8_t     mLength;     // Prefix length in bits
805*cfb92d14SAndroid Build Coastguard Worker         const char *mIp6Address; // Expected IPv6 address (with embedded IPv4 "192.0.2.33").
806*cfb92d14SAndroid Build Coastguard Worker     };
807*cfb92d14SAndroid Build Coastguard Worker 
808*cfb92d14SAndroid Build Coastguard Worker     // The test cases are from RFC 6052 - section 2.4
809*cfb92d14SAndroid Build Coastguard Worker 
810*cfb92d14SAndroid Build Coastguard Worker     const TestCase kTestCases[] = {
811*cfb92d14SAndroid Build Coastguard Worker         {"2001:db8::", 32, "2001:db8:c000:221::"},
812*cfb92d14SAndroid Build Coastguard Worker         {"2001:db8:100::", 40, "2001:db8:1c0:2:21::"},
813*cfb92d14SAndroid Build Coastguard Worker         {"2001:db8:122::", 48, "2001:db8:122:c000:2:2100::"},
814*cfb92d14SAndroid Build Coastguard Worker         {"2001:db8:122:300::", 56, "2001:db8:122:3c0:0:221::"},
815*cfb92d14SAndroid Build Coastguard Worker         {"2001:db8:122:344::", 64, "2001:db8:122:344:c0:2:2100::"},
816*cfb92d14SAndroid Build Coastguard Worker         {"2001:db8:122:344::", 96, "2001:db8:122:344::192.0.2.33"},
817*cfb92d14SAndroid Build Coastguard Worker         {"64:ff9b::", 96, "64:ff9b::192.0.2.33"},
818*cfb92d14SAndroid Build Coastguard Worker     };
819*cfb92d14SAndroid Build Coastguard Worker 
820*cfb92d14SAndroid Build Coastguard Worker     const uint8_t kIp4Address[] = {192, 0, 2, 33};
821*cfb92d14SAndroid Build Coastguard Worker 
822*cfb92d14SAndroid Build Coastguard Worker     Ip4::Address ip4Address;
823*cfb92d14SAndroid Build Coastguard Worker 
824*cfb92d14SAndroid Build Coastguard Worker     printf("\nTestIp4Ip6Translation()\n");
825*cfb92d14SAndroid Build Coastguard Worker 
826*cfb92d14SAndroid Build Coastguard Worker     ip4Address.SetBytes(kIp4Address);
827*cfb92d14SAndroid Build Coastguard Worker 
828*cfb92d14SAndroid Build Coastguard Worker     for (const TestCase &testCase : kTestCases)
829*cfb92d14SAndroid Build Coastguard Worker     {
830*cfb92d14SAndroid Build Coastguard Worker         Ip6::Prefix  prefix;
831*cfb92d14SAndroid Build Coastguard Worker         Ip6::Address address;
832*cfb92d14SAndroid Build Coastguard Worker         Ip6::Address expectedAddress;
833*cfb92d14SAndroid Build Coastguard Worker 
834*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(address.FromString(testCase.mPrefix));
835*cfb92d14SAndroid Build Coastguard Worker         prefix.Set(address.GetBytes(), testCase.mLength);
836*cfb92d14SAndroid Build Coastguard Worker 
837*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(expectedAddress.FromString(testCase.mIp6Address));
838*cfb92d14SAndroid Build Coastguard Worker 
839*cfb92d14SAndroid Build Coastguard Worker         address.SynthesizeFromIp4Address(prefix, ip4Address);
840*cfb92d14SAndroid Build Coastguard Worker 
841*cfb92d14SAndroid Build Coastguard Worker         printf("Prefix: %-26s IPv4Addr: %-12s Ipv6Address: %-36s Expected: %s (%s)\n", prefix.ToString().AsCString(),
842*cfb92d14SAndroid Build Coastguard Worker                ip4Address.ToString().AsCString(), address.ToString().AsCString(), testCase.mIp6Address,
843*cfb92d14SAndroid Build Coastguard Worker                expectedAddress.ToString().AsCString());
844*cfb92d14SAndroid Build Coastguard Worker 
845*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(address == expectedAddress, "Ip6::SynthesizeFromIp4Address() failed");
846*cfb92d14SAndroid Build Coastguard Worker     }
847*cfb92d14SAndroid Build Coastguard Worker 
848*cfb92d14SAndroid Build Coastguard Worker     for (const TestCase &testCase : kTestCases)
849*cfb92d14SAndroid Build Coastguard Worker     {
850*cfb92d14SAndroid Build Coastguard Worker         const Ip4::Address expectedAddress = ip4Address;
851*cfb92d14SAndroid Build Coastguard Worker         Ip4::Address       address;
852*cfb92d14SAndroid Build Coastguard Worker         Ip6::Address       ip6Address;
853*cfb92d14SAndroid Build Coastguard Worker 
854*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(ip6Address.FromString(testCase.mIp6Address));
855*cfb92d14SAndroid Build Coastguard Worker 
856*cfb92d14SAndroid Build Coastguard Worker         address.ExtractFromIp6Address(testCase.mLength, ip6Address);
857*cfb92d14SAndroid Build Coastguard Worker 
858*cfb92d14SAndroid Build Coastguard Worker         printf("Ipv6Address: %-36s IPv4Addr: %-12s Expected: %s\n", testCase.mIp6Address,
859*cfb92d14SAndroid Build Coastguard Worker                address.ToString().AsCString(), expectedAddress.ToString().AsCString());
860*cfb92d14SAndroid Build Coastguard Worker 
861*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(address == expectedAddress, "Ip4::ExtractFromIp6Address() failed");
862*cfb92d14SAndroid Build Coastguard Worker     }
863*cfb92d14SAndroid Build Coastguard Worker }
864*cfb92d14SAndroid Build Coastguard Worker 
TestIp4Cidr(void)865*cfb92d14SAndroid Build Coastguard Worker void TestIp4Cidr(void)
866*cfb92d14SAndroid Build Coastguard Worker {
867*cfb92d14SAndroid Build Coastguard Worker     struct TestCase
868*cfb92d14SAndroid Build Coastguard Worker     {
869*cfb92d14SAndroid Build Coastguard Worker         const char    *mNetwork;
870*cfb92d14SAndroid Build Coastguard Worker         const uint8_t  mLength;
871*cfb92d14SAndroid Build Coastguard Worker         const uint32_t mHost;
872*cfb92d14SAndroid Build Coastguard Worker         const char    *mOutcome;
873*cfb92d14SAndroid Build Coastguard Worker     };
874*cfb92d14SAndroid Build Coastguard Worker 
875*cfb92d14SAndroid Build Coastguard Worker     const TestCase kTestCases[] = {
876*cfb92d14SAndroid Build Coastguard Worker         {"172.16.12.34", 32, 0x12345678, "172.16.12.34"},  {"172.16.12.34", 31, 0x12345678, "172.16.12.34"},
877*cfb92d14SAndroid Build Coastguard Worker         {"172.16.12.34", 30, 0x12345678, "172.16.12.32"},  {"172.16.12.34", 29, 0x12345678, "172.16.12.32"},
878*cfb92d14SAndroid Build Coastguard Worker         {"172.16.12.34", 28, 0x12345678, "172.16.12.40"},  {"172.16.12.34", 27, 0x12345678, "172.16.12.56"},
879*cfb92d14SAndroid Build Coastguard Worker         {"172.16.12.34", 26, 0x12345678, "172.16.12.56"},  {"172.16.12.34", 25, 0x12345678, "172.16.12.120"},
880*cfb92d14SAndroid Build Coastguard Worker         {"172.16.12.34", 24, 0x12345678, "172.16.12.120"}, {"172.16.12.34", 23, 0x12345678, "172.16.12.120"},
881*cfb92d14SAndroid Build Coastguard Worker         {"172.16.12.34", 22, 0x12345678, "172.16.14.120"}, {"172.16.12.34", 21, 0x12345678, "172.16.14.120"},
882*cfb92d14SAndroid Build Coastguard Worker         {"172.16.12.34", 20, 0x12345678, "172.16.6.120"},  {"172.16.12.34", 19, 0x12345678, "172.16.22.120"},
883*cfb92d14SAndroid Build Coastguard Worker         {"172.16.12.34", 18, 0x12345678, "172.16.22.120"}, {"172.16.12.34", 17, 0x12345678, "172.16.86.120"},
884*cfb92d14SAndroid Build Coastguard Worker         {"172.16.12.34", 16, 0x12345678, "172.16.86.120"}, {"172.16.12.34", 15, 0x12345678, "172.16.86.120"},
885*cfb92d14SAndroid Build Coastguard Worker         {"172.16.12.34", 14, 0x12345678, "172.16.86.120"}, {"172.16.12.34", 13, 0x12345678, "172.20.86.120"},
886*cfb92d14SAndroid Build Coastguard Worker         {"172.16.12.34", 12, 0x12345678, "172.20.86.120"}, {"172.16.12.34", 11, 0x12345678, "172.20.86.120"},
887*cfb92d14SAndroid Build Coastguard Worker         {"172.16.12.34", 10, 0x12345678, "172.52.86.120"}, {"172.16.12.34", 9, 0x12345678, "172.52.86.120"},
888*cfb92d14SAndroid Build Coastguard Worker         {"172.16.12.34", 8, 0x12345678, "172.52.86.120"},  {"172.16.12.34", 7, 0x12345678, "172.52.86.120"},
889*cfb92d14SAndroid Build Coastguard Worker         {"172.16.12.34", 6, 0x12345678, "174.52.86.120"},  {"172.16.12.34", 5, 0x12345678, "170.52.86.120"},
890*cfb92d14SAndroid Build Coastguard Worker         {"172.16.12.34", 4, 0x12345678, "162.52.86.120"},  {"172.16.12.34", 3, 0x12345678, "178.52.86.120"},
891*cfb92d14SAndroid Build Coastguard Worker         {"172.16.12.34", 2, 0x12345678, "146.52.86.120"},  {"172.16.12.34", 1, 0x12345678, "146.52.86.120"},
892*cfb92d14SAndroid Build Coastguard Worker         {"172.16.12.34", 0, 0x12345678, "18.52.86.120"},
893*cfb92d14SAndroid Build Coastguard Worker     };
894*cfb92d14SAndroid Build Coastguard Worker 
895*cfb92d14SAndroid Build Coastguard Worker     for (const TestCase &testCase : kTestCases)
896*cfb92d14SAndroid Build Coastguard Worker     {
897*cfb92d14SAndroid Build Coastguard Worker         Ip4::Address network;
898*cfb92d14SAndroid Build Coastguard Worker         Ip4::Cidr    cidr;
899*cfb92d14SAndroid Build Coastguard Worker         Ip4::Address generated;
900*cfb92d14SAndroid Build Coastguard Worker 
901*cfb92d14SAndroid Build Coastguard Worker         SuccessOrQuit(network.FromString(testCase.mNetwork));
902*cfb92d14SAndroid Build Coastguard Worker         cidr.mAddress = network;
903*cfb92d14SAndroid Build Coastguard Worker         cidr.mLength  = testCase.mLength;
904*cfb92d14SAndroid Build Coastguard Worker 
905*cfb92d14SAndroid Build Coastguard Worker         generated.SynthesizeFromCidrAndHost(cidr, testCase.mHost);
906*cfb92d14SAndroid Build Coastguard Worker 
907*cfb92d14SAndroid Build Coastguard Worker         printf("CIDR: %-18s HostID: %-8x Host: %-14s Expected: %s\n", cidr.ToString().AsCString(), testCase.mHost,
908*cfb92d14SAndroid Build Coastguard Worker                generated.ToString().AsCString(), testCase.mOutcome);
909*cfb92d14SAndroid Build Coastguard Worker 
910*cfb92d14SAndroid Build Coastguard Worker         VerifyOrQuit(strcmp(generated.ToString().AsCString(), testCase.mOutcome) == 0,
911*cfb92d14SAndroid Build Coastguard Worker                      "Ip4::Address::SynthesizeFromCidrAndHost() failed");
912*cfb92d14SAndroid Build Coastguard Worker     }
913*cfb92d14SAndroid Build Coastguard Worker }
914*cfb92d14SAndroid Build Coastguard Worker 
915*cfb92d14SAndroid Build Coastguard Worker } // namespace ot
916*cfb92d14SAndroid Build Coastguard Worker 
main(void)917*cfb92d14SAndroid Build Coastguard Worker int main(void)
918*cfb92d14SAndroid Build Coastguard Worker {
919*cfb92d14SAndroid Build Coastguard Worker     ot::TestIp6AddressSetPrefix();
920*cfb92d14SAndroid Build Coastguard Worker     ot::TestIp4AddressFromString();
921*cfb92d14SAndroid Build Coastguard Worker     ot::TestIp6AddressFromString();
922*cfb92d14SAndroid Build Coastguard Worker     ot::TestIp6PrefixFromString();
923*cfb92d14SAndroid Build Coastguard Worker     ot::TestIp6Prefix();
924*cfb92d14SAndroid Build Coastguard Worker     ot::TestIp6PrefixTidy();
925*cfb92d14SAndroid Build Coastguard Worker     ot::TestIp4MappedIp6Address();
926*cfb92d14SAndroid Build Coastguard Worker     ot::TestIp4Ip6Translation();
927*cfb92d14SAndroid Build Coastguard Worker     ot::TestIp4Cidr();
928*cfb92d14SAndroid Build Coastguard Worker     ot::TestIp4CidrFromString();
929*cfb92d14SAndroid Build Coastguard Worker 
930*cfb92d14SAndroid Build Coastguard Worker     printf("All tests passed\n");
931*cfb92d14SAndroid Build Coastguard Worker     return 0;
932*cfb92d14SAndroid Build Coastguard Worker }
933