1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "platform/base/ip_address.h"
6
7 #include "gmock/gmock.h"
8 #include "gtest/gtest.h"
9 #include "platform/base/error.h"
10
11 namespace openscreen {
12
13 using ::testing::ElementsAreArray;
14
TEST(IPAddressTest,V4Constructors)15 TEST(IPAddressTest, V4Constructors) {
16 uint8_t bytes[4] = {};
17 IPAddress address1(std::array<uint8_t, 4>{{1, 2, 3, 4}});
18 address1.CopyToV4(bytes);
19 EXPECT_THAT(bytes, ElementsAreArray({1, 2, 3, 4}));
20
21 uint8_t x[] = {4, 3, 2, 1};
22 IPAddress address2(x);
23 address2.CopyToV4(bytes);
24 EXPECT_THAT(bytes, ElementsAreArray(x));
25
26 const auto b = address2.bytes();
27 const uint8_t raw_bytes[4]{b[0], b[1], b[2], b[3]};
28 EXPECT_THAT(raw_bytes, ElementsAreArray(x));
29
30 IPAddress address3(IPAddress::Version::kV4, &x[0]);
31 address3.CopyToV4(bytes);
32 EXPECT_THAT(bytes, ElementsAreArray(x));
33
34 IPAddress address4(6, 5, 7, 9);
35 address4.CopyToV4(bytes);
36 EXPECT_THAT(bytes, ElementsAreArray({6, 5, 7, 9}));
37
38 IPAddress address5(address4);
39 address5.CopyToV4(bytes);
40 EXPECT_THAT(bytes, ElementsAreArray({6, 5, 7, 9}));
41
42 address5 = address1;
43 address5.CopyToV4(bytes);
44 EXPECT_THAT(bytes, ElementsAreArray({1, 2, 3, 4}));
45 }
46
TEST(IPAddressTest,V4ComparisonAndBoolean)47 TEST(IPAddressTest, V4ComparisonAndBoolean) {
48 IPAddress address1;
49 EXPECT_EQ(address1, address1);
50 EXPECT_FALSE(address1);
51
52 uint8_t x[] = {4, 3, 2, 1};
53 IPAddress address2(x);
54 EXPECT_NE(address1, address2);
55 EXPECT_TRUE(address2);
56
57 IPAddress address3(x);
58 EXPECT_EQ(address2, address3);
59 EXPECT_TRUE(address3);
60
61 address2 = address1;
62 EXPECT_EQ(address1, address2);
63 EXPECT_FALSE(address2);
64 }
65
TEST(IPAddressTest,V4Parse)66 TEST(IPAddressTest, V4Parse) {
67 uint8_t bytes[4] = {};
68
69 ErrorOr<IPAddress> address = IPAddress::Parse("192.168.0.1");
70 ASSERT_TRUE(address);
71 address.value().CopyToV4(bytes);
72 EXPECT_THAT(bytes, ElementsAreArray({192, 168, 0, 1}));
73 }
74
TEST(IPAddressTest,V4ParseFailures)75 TEST(IPAddressTest, V4ParseFailures) {
76 EXPECT_FALSE(IPAddress::Parse("192..0.1"))
77 << "empty value should fail to parse";
78 EXPECT_FALSE(IPAddress::Parse(".192.168.0.1"))
79 << "leading dot should fail to parse";
80 EXPECT_FALSE(IPAddress::Parse(".192.168.1"))
81 << "leading dot should fail to parse";
82 EXPECT_FALSE(IPAddress::Parse("..192.168.0.1"))
83 << "leading dot should fail to parse";
84 EXPECT_FALSE(IPAddress::Parse("..192.1"))
85 << "leading dot should fail to parse";
86 EXPECT_FALSE(IPAddress::Parse("192.168.0.1."))
87 << "trailing dot should fail to parse";
88 EXPECT_FALSE(IPAddress::Parse("192.168.1."))
89 << "trailing dot should fail to parse";
90 EXPECT_FALSE(IPAddress::Parse("192.168.1.."))
91 << "trailing dot should fail to parse";
92 EXPECT_FALSE(IPAddress::Parse("192.168.."))
93 << "trailing dot should fail to parse";
94 EXPECT_FALSE(IPAddress::Parse("192.x3.0.1"))
95 << "non-digit character should fail to parse";
96 EXPECT_FALSE(IPAddress::Parse("192.3.1"))
97 << "too few values should fail to parse";
98 EXPECT_FALSE(IPAddress::Parse("192.3.2.0.1"))
99 << "too many values should fail to parse";
100 EXPECT_FALSE(IPAddress::Parse("1920.3.2.1"))
101 << "value > 255 should fail to parse";
102 }
103
TEST(IPAddressTest,V6Constructors)104 TEST(IPAddressTest, V6Constructors) {
105 uint8_t bytes[16] = {};
106 IPAddress address1(std::array<uint16_t, 8>{
107 {0x0102, 0x0304, 0x0506, 0x0708, 0x090a, 0x0b0c, 0x0d0e, 0x0f10}});
108 address1.CopyToV6(bytes);
109 EXPECT_THAT(bytes, ElementsAreArray({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
110 13, 14, 15, 16}));
111
112 const uint8_t x[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
113 const uint16_t hextets[] = {0x0102, 0x0304, 0x0506, 0x0708,
114 0x090a, 0x0b0c, 0x0d0e, 0x0f10};
115 IPAddress address2(hextets);
116 address2.CopyToV6(bytes);
117 EXPECT_THAT(bytes, ElementsAreArray(x));
118
119 IPAddress address3(IPAddress::Version::kV6, &x[0]);
120 address3.CopyToV6(bytes);
121 EXPECT_THAT(bytes, ElementsAreArray(x));
122
123 IPAddress address4(0x100f, 0x0e0d, 0x0c0b, 0x0a09, 0x0807, 0x0605, 0x0403,
124 0x0201);
125 address4.CopyToV6(bytes);
126 EXPECT_THAT(bytes, ElementsAreArray({16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6,
127 5, 4, 3, 2, 1}));
128
129 IPAddress address5(address4);
130 address5.CopyToV6(bytes);
131 EXPECT_THAT(bytes, ElementsAreArray({16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6,
132 5, 4, 3, 2, 1}));
133 }
134
TEST(IPAddressTest,V6ComparisonAndBoolean)135 TEST(IPAddressTest, V6ComparisonAndBoolean) {
136 IPAddress address1;
137 EXPECT_EQ(address1, address1);
138 EXPECT_FALSE(address1);
139
140 uint8_t x[] = {16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
141 IPAddress address2(IPAddress::Version::kV6, x);
142 EXPECT_NE(address1, address2);
143 EXPECT_TRUE(address2);
144
145 IPAddress address3(IPAddress::Version::kV6, x);
146 EXPECT_EQ(address2, address3);
147 EXPECT_TRUE(address3);
148
149 address2 = address1;
150 EXPECT_EQ(address1, address2);
151 EXPECT_FALSE(address2);
152 }
153
TEST(IPAddressTest,V6ParseBasic)154 TEST(IPAddressTest, V6ParseBasic) {
155 uint8_t bytes[16] = {};
156 ErrorOr<IPAddress> address =
157 IPAddress::Parse("abcd:ef01:2345:6789:9876:5432:10FE:DBCA");
158 ASSERT_TRUE(address);
159 address.value().CopyToV6(bytes);
160 EXPECT_THAT(bytes, ElementsAreArray({0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67,
161 0x89, 0x98, 0x76, 0x54, 0x32, 0x10, 0xfe,
162 0xdb, 0xca}));
163 }
164
TEST(IPAddressTest,V6ParseDoubleColon)165 TEST(IPAddressTest, V6ParseDoubleColon) {
166 uint8_t bytes[16] = {};
167 ErrorOr<IPAddress> address1 =
168 IPAddress::Parse("abcd:ef01:2345:6789:9876:5432::dbca");
169 ASSERT_TRUE(address1);
170 address1.value().CopyToV6(bytes);
171 EXPECT_THAT(bytes, ElementsAreArray({0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67,
172 0x89, 0x98, 0x76, 0x54, 0x32, 0x00, 0x00,
173 0xdb, 0xca}));
174 ErrorOr<IPAddress> address2 = IPAddress::Parse("abcd::10fe:dbca");
175 ASSERT_TRUE(address2);
176 address2.value().CopyToV6(bytes);
177 EXPECT_THAT(bytes, ElementsAreArray({0xab, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00,
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xfe,
179 0xdb, 0xca}));
180
181 ErrorOr<IPAddress> address3 = IPAddress::Parse("::10fe:dbca");
182 ASSERT_TRUE(address3);
183 address3.value().CopyToV6(bytes);
184 EXPECT_THAT(bytes, ElementsAreArray({0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
185 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xfe,
186 0xdb, 0xca}));
187
188 ErrorOr<IPAddress> address4 = IPAddress::Parse("10fe:dbca::");
189 ASSERT_TRUE(address4);
190 address4.value().CopyToV6(bytes);
191 EXPECT_THAT(bytes, ElementsAreArray({0x10, 0xfe, 0xdb, 0xca, 0x00, 0x00, 0x00,
192 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
193 0x00, 0x00}));
194 }
195
TEST(IPAddressTest,V6SmallValues)196 TEST(IPAddressTest, V6SmallValues) {
197 uint8_t bytes[16] = {};
198 ErrorOr<IPAddress> address1 = IPAddress::Parse("::");
199 ASSERT_TRUE(address1);
200 address1.value().CopyToV6(bytes);
201 EXPECT_THAT(bytes, ElementsAreArray({0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
202 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203 0x00, 0x00}));
204
205 ErrorOr<IPAddress> address2 = IPAddress::Parse("::1");
206 ASSERT_TRUE(address2);
207 address2.value().CopyToV6(bytes);
208 EXPECT_THAT(bytes, ElementsAreArray({0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210 0x00, 0x01}));
211
212 ErrorOr<IPAddress> address3 = IPAddress::Parse("::2:1");
213 ASSERT_TRUE(address3);
214 address3.value().CopyToV6(bytes);
215 EXPECT_THAT(bytes, ElementsAreArray({0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
216 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
217 0x00, 0x01}));
218 }
219
TEST(IPAddressTest,V6ParseFailures)220 TEST(IPAddressTest, V6ParseFailures) {
221 EXPECT_FALSE(IPAddress::Parse(":abcd::dbca"))
222 << "leading colon should fail to parse";
223 EXPECT_FALSE(IPAddress::Parse("abcd::dbca:"))
224 << "trailing colon should fail to parse";
225 EXPECT_FALSE(IPAddress::Parse("abxd::1234"))
226 << "non-hex digit should fail to parse";
227 EXPECT_FALSE(IPAddress::Parse("abcd:1234"))
228 << "too few values should fail to parse";
229 EXPECT_FALSE(IPAddress::Parse("a:b:c:d:e:f:0:1:2:3:4:5:6:7:8:9:a"))
230 << "too many values should fail to parse";
231 EXPECT_FALSE(IPAddress::Parse("1:2:3:4:5:6:7::8"))
232 << "too many values around double-colon should fail to parse";
233 EXPECT_FALSE(IPAddress::Parse("1:2:3:4:5:6:7:8::"))
234 << "too many values before double-colon should fail to parse";
235 EXPECT_FALSE(IPAddress::Parse("::1:2:3:4:5:6:7:8"))
236 << "too many values after double-colon should fail to parse";
237 EXPECT_FALSE(IPAddress::Parse("abcd1::dbca"))
238 << "value > 0xffff should fail to parse";
239 EXPECT_FALSE(IPAddress::Parse("::abcd::dbca"))
240 << "multiple double colon should fail to parse";
241
242 EXPECT_FALSE(IPAddress::Parse(":::abcd::dbca"))
243 << "leading triple colon should fail to parse";
244 EXPECT_FALSE(IPAddress::Parse("abcd:::dbca"))
245 << "triple colon should fail to parse";
246 EXPECT_FALSE(IPAddress::Parse("abcd:dbca:::"))
247 << "trailing triple colon should fail to parse";
248 }
249
TEST(IPAddressTest,V6ParseThreeDigitValue)250 TEST(IPAddressTest, V6ParseThreeDigitValue) {
251 uint8_t bytes[16] = {};
252 ErrorOr<IPAddress> address = IPAddress::Parse("::123");
253 ASSERT_TRUE(address);
254 address.value().CopyToV6(bytes);
255 EXPECT_THAT(bytes, ElementsAreArray({0x0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
256 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
257 0x01, 0x23}));
258 }
259
TEST(IPAddressTest,IPEndpointBoolOperator)260 TEST(IPAddressTest, IPEndpointBoolOperator) {
261 IPEndpoint endpoint;
262 ASSERT_FALSE((endpoint));
263 ASSERT_TRUE((IPEndpoint{{192, 168, 0, 1}, 80}));
264 ASSERT_TRUE((IPEndpoint{{192, 168, 0, 1}, 0}));
265 ASSERT_TRUE((IPEndpoint{{}, 80}));
266 }
267
TEST(IPAddressTest,IPEndpointParse)268 TEST(IPAddressTest, IPEndpointParse) {
269 IPEndpoint expected{IPAddress(std::array<uint8_t, 4>{{1, 2, 3, 4}}), 5678};
270 ErrorOr<IPEndpoint> result = IPEndpoint::Parse("1.2.3.4:5678");
271 ASSERT_TRUE(result.is_value()) << result.error();
272 EXPECT_EQ(expected, result.value());
273
274 expected = IPEndpoint{
275 IPAddress(std::array<uint16_t, 8>{{0xabcd, 0, 0, 0, 0, 0, 0, 1}}), 99};
276 result = IPEndpoint::Parse("[abcd::1]:99");
277 ASSERT_TRUE(result.is_value()) << result.error();
278 EXPECT_EQ(expected, result.value());
279
280 expected = IPEndpoint{
281 IPAddress(std::array<uint16_t, 8>{{0, 0, 0, 0, 0, 0, 0, 0}}), 5791};
282 result = IPEndpoint::Parse("[::]:5791");
283 ASSERT_TRUE(result.is_value()) << result.error();
284 EXPECT_EQ(expected, result.value());
285
286 EXPECT_FALSE(IPEndpoint::Parse("")); // Empty string.
287 EXPECT_FALSE(IPEndpoint::Parse("beef")); // Random word.
288 EXPECT_FALSE(IPEndpoint::Parse("localhost:99")); // We don't do DNS.
289 EXPECT_FALSE(IPEndpoint::Parse(":80")); // Missing address.
290 EXPECT_FALSE(IPEndpoint::Parse("[]:22")); // Missing address.
291 EXPECT_FALSE(IPEndpoint::Parse("1.2.3.4")); // Missing port after IPv4.
292 EXPECT_FALSE(IPEndpoint::Parse("[abcd::1]")); // Missing port after IPv6.
293 EXPECT_FALSE(IPEndpoint::Parse("abcd::1:8080")); // Missing square brackets.
294
295 // No extra whitespace is allowed.
296 EXPECT_FALSE(IPEndpoint::Parse(" 1.2.3.4:5678"));
297 EXPECT_FALSE(IPEndpoint::Parse("1.2.3.4 :5678"));
298 EXPECT_FALSE(IPEndpoint::Parse("1.2.3.4: 5678"));
299 EXPECT_FALSE(IPEndpoint::Parse("1.2.3.4:5678 "));
300 EXPECT_FALSE(IPEndpoint::Parse(" [abcd::1]:99"));
301 EXPECT_FALSE(IPEndpoint::Parse("[abcd::1] :99"));
302 EXPECT_FALSE(IPEndpoint::Parse("[abcd::1]: 99"));
303 EXPECT_FALSE(IPEndpoint::Parse("[abcd::1]:99 "));
304 }
305
TEST(IPAddressTest,IPAddressComparisons)306 TEST(IPAddressTest, IPAddressComparisons) {
307 const IPAddress kV4Low{192, 168, 0, 1};
308 const IPAddress kV4High{192, 168, 0, 2};
309 const IPAddress kV6Low{0, 0, 0, 0, 0, 0, 0, 1};
310 const IPAddress kV6High{0, 0, 1, 0, 0, 0, 0, 0};
311
312 EXPECT_TRUE(kV4Low == kV4Low);
313 EXPECT_TRUE(kV4High == kV4High);
314 EXPECT_TRUE(kV6Low == kV6Low);
315 EXPECT_TRUE(kV6High == kV6High);
316 EXPECT_FALSE(kV4Low == kV4High);
317 EXPECT_FALSE(kV4High == kV4Low);
318 EXPECT_FALSE(kV6Low == kV6High);
319 EXPECT_FALSE(kV6High == kV6Low);
320
321 EXPECT_FALSE(kV4Low != kV4Low);
322 EXPECT_FALSE(kV4High != kV4High);
323 EXPECT_FALSE(kV6Low != kV6Low);
324 EXPECT_FALSE(kV6High != kV6High);
325 EXPECT_TRUE(kV4Low != kV4High);
326 EXPECT_TRUE(kV4High != kV4Low);
327 EXPECT_TRUE(kV6Low != kV6High);
328 EXPECT_TRUE(kV6High != kV6Low);
329
330 EXPECT_TRUE(kV4Low < kV4High);
331 EXPECT_TRUE(kV4High < kV6Low);
332 EXPECT_TRUE(kV6Low < kV6High);
333 EXPECT_FALSE(kV6High < kV6Low);
334 EXPECT_FALSE(kV6Low < kV4High);
335 EXPECT_FALSE(kV4High < kV4Low);
336
337 EXPECT_FALSE(kV4Low > kV4High);
338 EXPECT_FALSE(kV4High > kV6Low);
339 EXPECT_FALSE(kV6Low > kV6High);
340 EXPECT_TRUE(kV6High > kV6Low);
341 EXPECT_TRUE(kV6Low > kV4High);
342 EXPECT_TRUE(kV4High > kV4Low);
343
344 EXPECT_TRUE(kV4Low <= kV4High);
345 EXPECT_TRUE(kV4High <= kV6Low);
346 EXPECT_TRUE(kV6Low <= kV6High);
347 EXPECT_TRUE(kV4Low <= kV4Low);
348 EXPECT_TRUE(kV4High <= kV4High);
349 EXPECT_TRUE(kV6Low <= kV6Low);
350 EXPECT_TRUE(kV6High <= kV6High);
351 EXPECT_FALSE(kV6High <= kV6Low);
352 EXPECT_FALSE(kV6Low <= kV4High);
353 EXPECT_FALSE(kV4High <= kV4Low);
354
355 EXPECT_FALSE(kV4Low >= kV4High);
356 EXPECT_FALSE(kV4High >= kV6Low);
357 EXPECT_FALSE(kV6Low >= kV6High);
358 EXPECT_TRUE(kV4Low >= kV4Low);
359 EXPECT_TRUE(kV4High >= kV4High);
360 EXPECT_TRUE(kV6Low >= kV6Low);
361 EXPECT_TRUE(kV6High >= kV6High);
362 EXPECT_TRUE(kV6High >= kV6Low);
363 EXPECT_TRUE(kV6Low >= kV4High);
364 EXPECT_TRUE(kV4High >= kV4Low);
365 }
366
TEST(IPAddressTest,IPEndpointComparisons)367 TEST(IPAddressTest, IPEndpointComparisons) {
368 const IPEndpoint kV4LowHighPort{{192, 168, 0, 1}, 1000};
369 const IPEndpoint kV4LowLowPort{{192, 168, 0, 1}, 1};
370 const IPEndpoint kV4High{{192, 168, 0, 2}, 22};
371 const IPEndpoint kV6Low{{0, 0, 0, 0, 0, 0, 0, 1}, 22};
372 const IPEndpoint kV6High{{0, 0, 1, 0, 0, 0, 0, 0}, 22};
373
374 EXPECT_TRUE(kV4LowHighPort == kV4LowHighPort);
375 EXPECT_TRUE(kV4High == kV4High);
376 EXPECT_TRUE(kV6Low == kV6Low);
377 EXPECT_TRUE(kV6High == kV6High);
378
379 EXPECT_TRUE(kV4LowLowPort != kV4LowHighPort);
380 EXPECT_TRUE(kV4LowLowPort != kV4High);
381 EXPECT_TRUE(kV4High != kV6Low);
382 EXPECT_TRUE(kV6Low != kV6High);
383
384 EXPECT_TRUE(kV4LowLowPort < kV4LowHighPort);
385 EXPECT_TRUE(kV4LowLowPort < kV4High);
386 EXPECT_TRUE(kV4High < kV6Low);
387 EXPECT_TRUE(kV6Low < kV6High);
388
389 EXPECT_TRUE(kV4LowHighPort > kV4LowLowPort);
390 EXPECT_TRUE(kV4High > kV4LowLowPort);
391 EXPECT_TRUE(kV6Low > kV4High);
392 EXPECT_TRUE(kV6High > kV6Low);
393
394 EXPECT_TRUE(kV4LowLowPort <= kV4LowHighPort);
395 EXPECT_TRUE(kV4LowLowPort <= kV4High);
396 EXPECT_TRUE(kV4High <= kV6Low);
397 EXPECT_TRUE(kV6Low <= kV6High);
398 EXPECT_TRUE(kV4LowLowPort <= kV4LowHighPort);
399 EXPECT_TRUE(kV4LowLowPort <= kV4High);
400 EXPECT_TRUE(kV4High <= kV6Low);
401 EXPECT_TRUE(kV6Low <= kV6High);
402
403 EXPECT_FALSE(kV4LowLowPort >= kV4LowHighPort);
404 EXPECT_FALSE(kV4LowLowPort >= kV4High);
405 EXPECT_FALSE(kV4High >= kV6Low);
406 EXPECT_FALSE(kV6Low >= kV6High);
407 EXPECT_TRUE(kV4LowHighPort >= kV4LowLowPort);
408 EXPECT_TRUE(kV4High >= kV4LowLowPort);
409 EXPECT_TRUE(kV6Low >= kV4High);
410 EXPECT_TRUE(kV6High >= kV6Low);
411 EXPECT_TRUE(kV4LowHighPort >= kV4LowLowPort);
412 EXPECT_TRUE(kV4High >= kV4LowLowPort);
413 EXPECT_TRUE(kV6Low >= kV4High);
414 EXPECT_TRUE(kV6High >= kV6Low);
415 }
416
TEST(IPAddressTest,OstreamOperatorForIPv4)417 TEST(IPAddressTest, OstreamOperatorForIPv4) {
418 std::ostringstream oss;
419 oss << IPAddress{192, 168, 1, 2};
420 EXPECT_EQ("192.168.1.2", oss.str());
421
422 oss.str("");
423 oss << IPAddress{192, 168, 0, 2};
424 EXPECT_EQ("192.168.0.2", oss.str());
425
426 oss.str("");
427 oss << IPAddress{23, 45, 67, 89};
428 EXPECT_EQ("23.45.67.89", oss.str());
429 }
430
431 } // namespace openscreen
432