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