2 * Copyright 2014-present Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 #include <sys/types.h>
20 #include <folly/Format.h>
21 #include <folly/IPAddress.h>
22 #include <folly/MacAddress.h>
23 #include <folly/String.h>
24 #include <folly/container/BitIterator.h>
25 #include <folly/detail/IPAddressSource.h>
26 #include <folly/lang/Bits.h>
27 #include <folly/portability/GMock.h>
28 #include <folly/portability/GTest.h>
30 using namespace folly;
32 using namespace testing;
34 typedef std::vector<uint8_t> ByteVector;
42 const std::string& address,
43 const ByteVector& bytes,
45 : address(address), bytes(bytes), version(version) {}
46 AddressData(const std::string& address, uint8_t version)
47 : address(address), bytes(), version(version) {}
48 explicit AddressData(const std::string& address)
49 : address(address), bytes(), version(0) {}
50 AddressData() : address(""), bytes(), version(0) {}
52 static in_addr parseAddress4(const std::string& src) {
54 inet_pton(AF_INET, src.c_str(), &addr);
58 static in6_addr parseAddress6(const std::string& src) {
60 inet_pton(AF_INET6, src.c_str(), &addr);
70 static const uint8_t IS_LOCAL = 1 << 0;
71 static const uint8_t IS_NONROUTABLE = 1 << 1;
72 static const uint8_t IS_PRIVATE = 1 << 2;
73 static const uint8_t IS_ZERO = 1 << 3;
74 static const uint8_t IS_LINK_LOCAL = 1 << 4;
75 static const uint8_t IS_MULTICAST = 1 << 5;
76 static const uint8_t IS_LINK_LOCAL_BROADCAST = 1 << 6;
78 AddressFlags(const std::string& addr, uint8_t version, uint8_t flags)
79 : address(addr), flags(flags), version(version) {}
81 bool isLoopback() const {
82 return (flags & IS_LOCAL);
84 bool isNonroutable() const {
85 return (flags & IS_NONROUTABLE);
87 bool isPrivate() const {
88 return (flags & IS_PRIVATE);
91 return (flags & IS_ZERO);
93 bool isLinkLocal() const {
94 return (flags & IS_LINK_LOCAL);
96 bool isLinkLocalBroadcast() const {
97 return (flags & IS_LINK_LOCAL_BROADCAST);
105 MaskData(const std::string& addr, uint8_t mask, const std::string& subnet)
106 : address(addr), mask(mask), subnet(subnet) {}
109 struct MaskBoundaryData : MaskData {
112 const std::string& addr,
114 const std::string& subnet,
116 : MaskData(addr, mask, subnet), inSubnet(inSubnet) {}
119 struct SerializeData {
123 SerializeData(const std::string& addr, const ByteVector& bytes)
124 : address(addr), bytes(bytes) {}
127 struct IPAddressTest : TestWithParam<AddressData> {
128 void ExpectIsValid(const IPAddress& addr) {
129 AddressData param = GetParam();
130 EXPECT_EQ(param.version, addr.version());
131 EXPECT_EQ(param.address, addr.str());
132 if (param.version == 4) {
133 in_addr v4addr = AddressData::parseAddress4(param.address);
134 EXPECT_EQ(0, memcmp(&v4addr, addr.asV4().toByteArray().data(), 4));
135 EXPECT_TRUE(addr.isV4());
136 EXPECT_FALSE(addr.isV6());
138 in6_addr v6addr = AddressData::parseAddress6(param.address);
139 EXPECT_EQ(0, memcmp(&v6addr, addr.asV6().toByteArray().data(), 16));
140 EXPECT_TRUE(addr.isV6());
141 EXPECT_FALSE(addr.isV4());
145 struct IPAddressFlagTest : TestWithParam<AddressFlags> {};
146 struct IPAddressCtorTest : TestWithParam<std::string> {};
147 struct IPAddressCtorBinaryTest : TestWithParam<ByteVector> {};
148 struct IPAddressMappedTest
149 : TestWithParam<std::pair<std::string, std::string>> {};
150 struct IPAddressMaskTest : TestWithParam<MaskData> {};
151 struct IPAddressMaskBoundaryTest : TestWithParam<MaskBoundaryData> {};
152 struct IPAddressSerializeTest : TestWithParam<SerializeData> {};
153 struct IPAddressByteAccessorTest : TestWithParam<AddressData> {};
154 struct IPAddressBitAccessorTest : TestWithParam<AddressData> {};
156 struct StringTestParam {
158 folly::Optional<std::string> out;
159 folly::Optional<std::string> out4;
160 folly::Optional<std::string> out6;
163 struct TryFromStringTest : TestWithParam<StringTestParam> {
164 static std::vector<StringTestParam> ipInOutProvider() {
165 const std::string lo6{"::1"};
166 const std::string lo6brackets{"[::1]"};
167 const std::string ip6{"1234::abcd"};
168 const std::string invalid6{"[::aaaR]"};
170 const std::string lo4{"127.0.0.1"};
171 const std::string ip4{"192.168.0.1"};
172 const std::string invalid4{"127.0.0.256"};
174 const static std::vector<StringTestParam> ret = {
175 {lo6, lo6, none, lo6},
176 {lo6brackets, lo6, none, lo6},
177 {ip6, ip6, none, ip6},
178 {invalid6, none, none, none},
179 {lo4, lo4, lo4, none},
180 {ip4, ip4, ip4, none},
181 {invalid4, none, none, none},
188 // tests code example
189 TEST(IPAddress, CodeExample) {
190 EXPECT_EQ(4, sizeof(IPAddressV4));
191 EXPECT_EQ(20, sizeof(IPAddressV6));
192 EXPECT_EQ(24, sizeof(IPAddress));
193 IPAddress uninitaddr;
194 IPAddress v4addr("192.0.2.129");
195 IPAddress v6map("::ffff:192.0.2.129");
196 ASSERT_TRUE(uninitaddr.empty());
197 ASSERT_FALSE(v4addr.empty());
198 ASSERT_FALSE(v6map.empty());
199 EXPECT_TRUE(v4addr.inSubnet("192.0.2.0/24"));
200 EXPECT_TRUE(v4addr.inSubnet(IPAddress("192.0.2.0"), 24));
201 EXPECT_TRUE(v4addr.inSubnet("192.0.2.128/30"));
202 EXPECT_FALSE(v4addr.inSubnet("192.0.2.128/32"));
203 EXPECT_EQ(2164392128, v4addr.asV4().toLong());
204 EXPECT_EQ(3221226113, v4addr.asV4().toLongHBO());
205 ASSERT_FALSE(uninitaddr.isV4());
206 ASSERT_FALSE(uninitaddr.isV6());
207 ASSERT_TRUE(v4addr.isV4());
208 ASSERT_TRUE(v6map.isV6());
209 EXPECT_TRUE(v4addr == v6map);
210 ASSERT_TRUE(v6map.isIPv4Mapped());
211 EXPECT_TRUE(v4addr.asV4() == IPAddress::createIPv4(v6map));
212 EXPECT_TRUE(IPAddress::createIPv6(v4addr) == v6map.asV6());
215 TEST(IPAddress, Scope) {
216 // Test that link-local scope is saved
217 auto str = "fe80::62eb:69ff:fe9b:ba60%eth0";
219 EXPECT_EQ(str, a2.str());
221 sockaddr_in6 sock = a2.toSockAddr();
222 EXPECT_NE(0, sock.sin6_scope_id);
225 EXPECT_EQ(str, a1.str());
230 EXPECT_TRUE(a2 < a1);
233 TEST(IPAddress, ScopeNumeric) {
234 // it's very unlikely that the host running these
235 // tests will have 42 network interfaces
236 auto str = "fe80::62eb:69ff:fe9b:ba60%42";
238 EXPECT_EQ(str, a2.str());
240 sockaddr_in6 sock = a2.toSockAddr();
241 EXPECT_NE(0, sock.sin6_scope_id);
244 EXPECT_EQ(str, a1.str());
249 EXPECT_TRUE(a2 < a1);
252 TEST(IPAddress, Ordering) {
253 IPAddress a1("0.1.1.1");
254 IPAddress a2("1.1.1.0");
255 EXPECT_TRUE(a1 < a2);
257 IPAddress b1("::ffff:0.1.1.1");
258 IPAddress b2("::ffff:1.1.1.0");
259 EXPECT_TRUE(b1 < b2);
262 TEST(IPAddress, InvalidAddressFamilyExceptions) {
266 EXPECT_THROW(addr.asV4(), InvalidAddressFamilyException);
271 EXPECT_THROW(addr.asV6(), InvalidAddressFamilyException);
277 addr.sin_family = AF_UNSPEC;
279 EXPECT_THROW(IPAddress((sockaddr*)&addr), InvalidAddressFamilyException);
283 TEST(IPAddress, TryCreateNetwork) {
284 // test valid IPv4 network
286 auto net = IPAddress::tryCreateNetwork("192.168.0.1/24").value();
287 ASSERT_TRUE(net.first.isV4());
288 EXPECT_EQ("192.168.0.0", net.first.str());
289 EXPECT_EQ(24, net.second);
290 EXPECT_EQ("192.168.0.0/24", IPAddress::networkToString(net));
292 // test valid IPv4 network without applying mask
294 auto net = IPAddress::tryCreateNetwork("192.168.0.1/24", -1, false).value();
295 ASSERT_TRUE(net.first.isV4());
296 EXPECT_EQ("192.168.0.1", net.first.str());
297 EXPECT_EQ(24, net.second);
298 EXPECT_EQ("192.168.0.1/24", IPAddress::networkToString(net));
300 // test valid IPv6 network
302 auto net = IPAddress::tryCreateNetwork("1999::1/24").value();
303 ASSERT_TRUE(net.first.isV6());
304 EXPECT_EQ("1999::", net.first.str());
305 EXPECT_EQ(24, net.second);
306 EXPECT_EQ("1999::/24", IPAddress::networkToString(net));
308 // test valid IPv6 network without applying mask
310 auto net = IPAddress::tryCreateNetwork("1999::1/24", -1, false).value();
311 ASSERT_TRUE(net.first.isV6());
312 EXPECT_EQ("1999::1", net.first.str());
313 EXPECT_EQ(24, net.second);
314 EXPECT_EQ("1999::1/24", IPAddress::networkToString(net));
317 // test invalid default CIDR
319 CIDRNetworkError::INVALID_DEFAULT_CIDR,
320 IPAddress::tryCreateNetwork("192.168.1.1", 300).error());
324 CIDRNetworkError::INVALID_IP, IPAddress::tryCreateNetwork("").error());
326 // test multi slash string
328 CIDRNetworkError::INVALID_IP_SLASH_CIDR,
329 IPAddress::tryCreateNetwork("192.168.0.1/24/36").error());
331 // test no slash string with default IPv4
333 auto net = IPAddress::tryCreateNetwork("192.168.0.1").value();
334 ASSERT_TRUE(net.first.isV4());
335 EXPECT_EQ("192.168.0.1", net.first.str());
336 EXPECT_EQ(32, net.second); // auto-detected
337 net = IPAddress::createNetwork("192.168.0.1", -1, false);
338 ASSERT_TRUE(net.first.isV4());
339 EXPECT_EQ("192.168.0.1", net.first.str());
340 EXPECT_EQ(32, net.second);
342 // test no slash string with default IPv6
344 auto net = IPAddress::tryCreateNetwork("1999::1").value();
345 ASSERT_TRUE(net.first.isV6());
346 EXPECT_EQ("1999::1", net.first.str());
347 EXPECT_EQ(128, net.second);
349 // test no slash string with invalid default
351 CIDRNetworkError::CIDR_MISMATCH,
352 IPAddress::tryCreateNetwork("192.168.0.1", 33).error());
355 // test that throwing version actually throws
356 TEST(IPAddress, CreateNetworkExceptions) {
357 // test invalid default CIDR
358 EXPECT_THROW(IPAddress::createNetwork("192.168.0.1", 300), std::range_error);
360 EXPECT_THROW(IPAddress::createNetwork(""), IPAddressFormatException);
361 // test multi slash string
363 IPAddress::createNetwork("192.168.0.1/24/36"), IPAddressFormatException);
364 // test no slash string with invalid default
366 IPAddress::createNetwork("192.168.0.1", 33), IPAddressFormatException);
369 // test assignment operators
370 TEST(IPAddress, Assignment) {
371 static const string kIPv4Addr = "69.63.189.16";
372 static const string kIPv6Addr = "2620:0:1cfe:face:b00c::3";
374 // Test assigning IPAddressV6 addr to IPAddress (was V4)
376 IPAddress addr(kIPv4Addr);
377 IPAddressV6 addrV6 = IPAddress(kIPv6Addr).asV6();
378 EXPECT_TRUE(addr.isV4());
379 EXPECT_EQ(kIPv4Addr, addr.str());
381 EXPECT_TRUE(addr.isV6());
382 EXPECT_EQ(kIPv6Addr, addr.str());
384 // Test assigning IPAddressV4 addr to IPAddress (was V6)
386 IPAddress addr(kIPv6Addr);
387 IPAddressV4 addrV4 = IPAddress(kIPv4Addr).asV4();
388 EXPECT_TRUE(addr.isV6());
389 EXPECT_EQ(kIPv6Addr, addr.str());
391 EXPECT_TRUE(addr.isV4());
392 EXPECT_EQ(kIPv4Addr, addr.str());
394 // Test assigning IPAddress(v6) to IPAddress (was v4)
396 IPAddress addr(kIPv4Addr);
397 IPAddress addrV6 = IPAddress(kIPv6Addr);
398 EXPECT_TRUE(addr.isV4());
399 EXPECT_EQ(kIPv4Addr, addr.str());
401 EXPECT_TRUE(addr.isV6());
402 EXPECT_EQ(kIPv6Addr, addr.str());
404 // Test assigning IPAddress(v4) to IPAddress (was v6)
406 IPAddress addr(kIPv6Addr);
407 IPAddress addrV4 = IPAddress(kIPv4Addr);
408 EXPECT_TRUE(addr.isV6());
409 EXPECT_EQ(kIPv6Addr, addr.str());
411 EXPECT_TRUE(addr.isV4());
412 EXPECT_EQ(kIPv4Addr, addr.str());
416 // Test the default constructors
417 TEST(IPAddress, CtorDefault) {
419 EXPECT_EQ(IPAddressV4("0.0.0.0"), v4);
421 EXPECT_EQ(IPAddressV6("::0"), v6);
424 TEST(IPAddressV4, validate) {
425 EXPECT_TRUE(IPAddressV4::validate("0.0.0.0"));
426 EXPECT_FALSE(IPAddressV4::validate("0.0.0."));
427 EXPECT_TRUE(IPAddressV4::validate("127.127.127.127"));
430 TEST(IPAddressV6, validate) {
431 EXPECT_TRUE(IPAddressV6::validate("2620:0:1cfe:face:b00c::3"));
432 EXPECT_FALSE(IPAddressV6::validate("0.0.0.0"));
433 EXPECT_TRUE(IPAddressV6::validate("[2620:0:1cfe:face:b00c::3]"));
434 EXPECT_TRUE(IPAddressV6::validate("::ffff:0.1.1.1"));
435 EXPECT_TRUE(IPAddressV6::validate("2620:0000:1cfe:face:b00c:0000:0000:0003"));
437 IPAddressV6::validate("2620:0000:1cfe:face:b00c:0000:127.127.127.127"));
440 TEST(IPAddress, validate) {
441 EXPECT_TRUE(IPAddress::validate("0.0.0.0"));
442 EXPECT_TRUE(IPAddress::validate("::"));
443 EXPECT_FALSE(IPAddress::validate("asdf"));
446 // Test addresses constructed using a in[6]_addr value
447 TEST_P(IPAddressTest, CtorAddress) {
448 AddressData param = GetParam();
449 IPAddress strAddr(param.address);
452 if (param.version == 4) {
453 in_addr v4addr = detail::Bytes::mkAddress4(¶m.bytes[0]);
454 address = IPAddress(v4addr);
456 in6_addr v6addr = detail::Bytes::mkAddress6(¶m.bytes[0]);
457 address = IPAddress(v6addr);
459 ExpectIsValid(address);
460 EXPECT_EQ(strAddr, address);
463 // Test addresses constructed using a binary address
464 TEST_P(IPAddressTest, CtorBinary) {
465 AddressData param = GetParam();
468 if (param.version == 4) {
469 in_addr v4addr = AddressData::parseAddress4(param.address);
470 address = IPAddress::fromBinary(ByteRange((unsigned char*)&v4addr, 4));
472 in6_addr v6addr = AddressData::parseAddress6(param.address);
473 address = IPAddress::fromBinary(ByteRange((unsigned char*)&v6addr, 16));
476 ExpectIsValid(address);
477 EXPECT_EQ(IPAddress(param.address), address);
480 // Test addresses constructed using a string
481 TEST_P(IPAddressTest, CtorString) {
482 AddressData param = GetParam();
483 IPAddress address(param.address);
485 ExpectIsValid(address);
487 // Test the direct version-specific constructor
488 if (param.version == 4) {
489 IPAddressV4 v4(param.address);
490 ExpectIsValid(IPAddress(v4));
491 EXPECT_THROW(IPAddressV6 v6(param.address), IPAddressFormatException);
492 } else if (param.version == 6) {
493 IPAddressV6 v6(param.address);
494 ExpectIsValid(IPAddress(v6));
495 EXPECT_THROW(IPAddressV4 v4(param.address), IPAddressFormatException);
499 TEST(IPAddress, CtorSockaddr) {
505 sin_addr.s_addr = htonl(2122547223);
506 addr.sin_family = AF_INET;
507 addr.sin_addr = sin_addr;
509 IPAddress ipAddr((sockaddr*)&addr);
510 EXPECT_TRUE(ipAddr.isV4());
511 EXPECT_EQ("126.131.128.23", ipAddr.str());
517 memset(&addr, 0, sizeof(addr));
519 // 2620:0:1cfe:face:b00c::3
521 {38, 32, 0, 0, 28, 254, 250, 206, 176, 12, 0, 0, 0, 0, 0, 3}};
522 std::memcpy(sin_addr.s6_addr, sec.data(), 16);
523 addr.sin6_family = AF_INET6;
524 addr.sin6_addr = sin_addr;
526 IPAddress ipAddr((sockaddr*)&addr);
527 EXPECT_TRUE(ipAddr.isV6());
528 EXPECT_EQ("2620:0:1cfe:face:b00c::3", ipAddr.str());
530 // test nullptr exception
532 sockaddr* addr = nullptr;
533 EXPECT_THROW(IPAddress((const sockaddr*)addr), IPAddressFormatException);
535 // test invalid family exception
540 sin_addr.s_addr = htonl(2122547223);
541 addr.sin_family = AF_UNSPEC;
542 addr.sin_addr = sin_addr;
544 EXPECT_THROW(IPAddress((sockaddr*)&addr), IPAddressFormatException);
548 TEST(IPAddress, ToSockaddrStorage) {
551 string strAddr("126.131.128.23");
552 IPAddress addr(strAddr);
553 sockaddr_storage out;
555 ASSERT_TRUE(addr.isV4()); // test invariant
556 EXPECT_GT(addr.toSockaddrStorage(&out), 0);
558 IPAddress sockAddr((sockaddr*)&out);
559 ASSERT_TRUE(sockAddr.isV4());
560 EXPECT_EQ(strAddr, sockAddr.str());
564 string strAddr("2620:0:1cfe:face:b00c::3");
565 IPAddress addr(strAddr);
566 sockaddr_storage out;
568 ASSERT_TRUE(addr.isV6()); // test invariant
569 EXPECT_GT(addr.toSockaddrStorage(&out), 0);
571 IPAddress sockAddr((sockaddr*)&out);
572 ASSERT_TRUE(sockAddr.isV6());
573 EXPECT_EQ(strAddr, sockAddr.str());
575 // test nullptr exception
577 sockaddr_storage* out = nullptr;
578 IPAddress addr("127.0.0.1");
579 EXPECT_THROW(addr.toSockaddrStorage(out), IPAddressFormatException);
581 // test invalid family exception
584 sockaddr_storage out;
585 ASSERT_EQ(AF_UNSPEC, addr.family());
586 EXPECT_THROW(addr.toSockaddrStorage(&out), InvalidAddressFamilyException);
590 TEST_P(TryFromStringTest, IPAddress) {
591 auto param = GetParam();
592 auto maybeIp = IPAddress::tryFromString(param.in);
594 EXPECT_TRUE(maybeIp.hasValue());
595 EXPECT_EQ(param.out, maybeIp.value().str());
597 EXPECT_TRUE(maybeIp.hasError());
599 IPAddressFormatError::INVALID_IP == maybeIp.error() ||
600 IPAddressFormatError::UNSUPPORTED_ADDR_FAMILY == maybeIp.error());
604 TEST_P(TryFromStringTest, IPAddressV4) {
605 auto param = GetParam();
606 auto maybeIp = IPAddressV4::tryFromString(param.in);
608 EXPECT_TRUE(maybeIp.hasValue());
609 EXPECT_EQ(param.out4, maybeIp.value().str());
611 EXPECT_TRUE(maybeIp.hasError());
612 EXPECT_EQ(IPAddressFormatError::INVALID_IP, maybeIp.error());
616 TEST_P(TryFromStringTest, IPAddressV6) {
617 auto param = GetParam();
618 auto maybeIp = IPAddressV6::tryFromString(param.in);
620 EXPECT_TRUE(maybeIp.hasValue());
621 EXPECT_EQ(param.out6, maybeIp.value().str());
623 EXPECT_TRUE(maybeIp.hasError());
624 EXPECT_EQ(IPAddressFormatError::INVALID_IP, maybeIp.error());
628 TEST(IPAddress, ToString) {
629 // Test with IPAddressV4
630 IPAddressV4 addr_10_0_0_1("10.0.0.1");
631 EXPECT_EQ("10.0.0.1", folly::to<string>(addr_10_0_0_1));
632 // Test with IPAddressV6
633 IPAddressV6 addr_1("::1");
634 EXPECT_EQ("::1", folly::to<string>(addr_1));
635 // Test with IPAddress, both V4 and V6
636 IPAddress addr_10_1_2_3("10.1.2.3");
637 EXPECT_EQ("10.1.2.3", folly::to<string>(addr_10_1_2_3));
638 IPAddress addr_1_2_3("1:2::3");
639 EXPECT_EQ("1:2::3", folly::to<string>(addr_1_2_3));
641 // Test a combination of all the above arguments
643 "1:2::3 - 10.0.0.1 - ::1 - 10.1.2.3",
654 TEST(IPaddress, toInverseArpaName) {
655 IPAddressV4 addr_ipv4("10.0.0.1");
656 EXPECT_EQ("1.0.0.10.in-addr.arpa", addr_ipv4.toInverseArpaName());
657 IPAddressV6 addr_ipv6("2620:0000:1cfe:face:b00c:0000:0000:0003");
661 "3.0.0.0.0.0.0.0.0.0.0.0.c.0.0.b.e.c.a.f.e.f.c.1.0.0.0.0.0.2.6.2"),
662 addr_ipv6.toInverseArpaName());
665 TEST(IPaddress, fromInverseArpaName) {
667 IPAddressV4("10.0.0.1"),
668 IPAddressV4::fromInverseArpaName("1.0.0.10.in-addr.arpa"));
670 IPAddressV6("2620:0000:1cfe:face:b00c:0000:0000:0003"),
671 IPAddressV6::fromInverseArpaName(sformat(
673 "3.0.0.0.0.0.0.0.0.0.0.0.c.0.0.b.e.c.a.f.e.f.c.1.0.0.0.0.0.2.6.2")));
676 // Test that invalid string values are killed
677 TEST_P(IPAddressCtorTest, InvalidCreation) {
678 string addr = GetParam();
679 EXPECT_THROW(IPAddress((const string)addr), IPAddressFormatException)
680 << "IPAddress(" << addr << ") "
681 << "should have thrown an IPAddressFormatException";
684 // Test that invalid binary values throw or return an exception
685 TEST_P(IPAddressCtorBinaryTest, InvalidBinary) {
686 auto bin = GetParam();
687 auto byteRange = ByteRange(&bin[0], bin.size());
688 // Throwing versions.
689 EXPECT_THROW(IPAddress::fromBinary(byteRange), IPAddressFormatException);
690 EXPECT_THROW(IPAddressV4::fromBinary(byteRange), IPAddressFormatException);
691 EXPECT_THROW(IPAddressV6::fromBinary(byteRange), IPAddressFormatException);
692 // Non-throwing versions.
693 EXPECT_TRUE(IPAddress::tryFromBinary(byteRange).hasError());
694 EXPECT_TRUE(IPAddressV4::tryFromBinary(byteRange).hasError());
695 EXPECT_TRUE(IPAddressV6::tryFromBinary(byteRange).hasError());
698 TEST(IPAddressSource, ToHex) {
699 vector<std::uint8_t> data = {{0xff, 0x20, 0x45}};
700 EXPECT_EQ(detail::Bytes::toHex(data.data(), 0), "");
701 EXPECT_EQ(detail::Bytes::toHex(data.data(), 1), "ff");
702 EXPECT_EQ(detail::Bytes::toHex(data.data(), 2), "ff20");
703 EXPECT_EQ(detail::Bytes::toHex(data.data(), 3), "ff2045");
706 // Test toFullyQualified()
707 TEST(IPAddress, ToFullyQualifiedFb) {
708 IPAddress ip("2620:0:1cfe:face:b00c::3");
709 EXPECT_EQ("2620:0000:1cfe:face:b00c:0000:0000:0003", ip.toFullyQualified())
712 TEST(IPAddress, ToFullyQualifiedLocal) {
714 EXPECT_EQ("0000:0000:0000:0000:0000:0000:0000:0001", ip.toFullyQualified())
717 TEST(IPAddress, ToFullyQualifiedAppendV6) {
718 IPAddress ip("2620:0:1cfe:face:b00c::3");
720 ip.toFullyQualifiedAppend(result);
721 EXPECT_EQ("2620:0000:1cfe:face:b00c:0000:0000:0003", result) << ip;
723 TEST(IPAddress, ToFullyQualifiedAppendV4) {
724 IPAddress ip("127.0.0.1");
726 ip.toFullyQualifiedAppend(result);
727 EXPECT_EQ("127.0.0.1", result) << ip;
729 TEST(IPAddress, ToFullyQualifiedSizeV6) {
730 auto actual = IPAddressV6::kToFullyQualifiedSize;
731 auto expected = IPAddress("::").toFullyQualified().size();
732 EXPECT_EQ(expected, actual);
734 TEST(IPAddress, MaxToFullyQualifiedSizeV4) {
735 auto actual = IPAddressV4::kMaxToFullyQualifiedSize;
736 auto expected = IPAddress("255.255.255.255").toFullyQualified().size();
737 EXPECT_EQ(expected, actual);
740 // test v4-v6 mapped addresses
741 TEST_P(IPAddressMappedTest, MappedEqual) {
742 auto param = GetParam();
743 string mappedIp = param.first;
744 string otherIp = param.second;
746 auto mapped = IPAddress(mappedIp);
747 auto expected = IPAddress(otherIp);
749 EXPECT_EQ(expected, mapped);
753 v6addr = mapped.asV4().createIPv6();
754 } else if (expected.isV4()) {
755 v6addr = expected.asV4().createIPv6();
757 EXPECT_TRUE(v6addr.isV6());
758 EXPECT_TRUE(mapped == v6addr);
759 EXPECT_TRUE(expected == v6addr);
762 // Test subnet mask calculations
763 TEST_P(IPAddressMaskTest, Masks) {
764 auto param = GetParam();
766 IPAddress ip(param.address);
767 IPAddress masked = ip.mask(param.mask);
768 EXPECT_EQ(param.subnet, masked.str())
769 << param.address << "/" << folly::to<std::string>(param.mask) << " -> "
773 // Test inSubnet calculations
774 TEST_P(IPAddressMaskTest, InSubnet) {
775 auto param = GetParam();
777 IPAddress ip(param.address);
778 IPAddress subnet(param.subnet);
779 EXPECT_TRUE(ip.inSubnet(subnet, param.mask));
782 // Test boundary conditions for subnet calculations
783 TEST_P(IPAddressMaskBoundaryTest, NonMaskedSubnet) {
784 auto param = GetParam();
785 IPAddress ip(param.address);
786 IPAddress subnet(param.subnet);
787 EXPECT_EQ(param.inSubnet, ip.inSubnet(subnet, param.mask));
790 TEST(IPAddress, UnitializedEqual) {
792 IPAddress ip4("127.0.0.1");
793 EXPECT_FALSE(addrEmpty == ip4);
794 EXPECT_FALSE(ip4 == addrEmpty);
795 IPAddress ip6("::1");
796 EXPECT_FALSE(addrEmpty == ip6);
797 EXPECT_FALSE(ip6 == addrEmpty);
798 IPAddress ip6Map("::ffff:192.0.2.129");
799 EXPECT_FALSE(addrEmpty == ip6Map);
800 EXPECT_FALSE(ip6Map == addrEmpty);
801 IPAddress ip4Zero("0.0.0.0");
802 EXPECT_FALSE(addrEmpty == ip4Zero);
803 EXPECT_FALSE(ip4Zero == addrEmpty);
804 IPAddress ip6Zero("::");
805 EXPECT_FALSE(addrEmpty == ip6Zero);
806 EXPECT_FALSE(ip6Zero == addrEmpty);
807 EXPECT_EQ(addrEmpty, addrEmpty);
810 // Test subnet calcs with 6to4 addresses
811 TEST(IPAddress, InSubnetWith6to4) {
812 auto ip = IPAddress("2002:c000:022a::"); // 192.0.2.42
813 auto subnet = IPAddress("192.0.0.0");
814 EXPECT_TRUE(ip.inSubnet(subnet, 16));
816 auto ip2 = IPAddress("192.0.0.1");
817 auto subnet2 = IPAddress("2002:c000:0000::"); // 192.0.0.0
818 EXPECT_TRUE(ip2.inSubnet(subnet2, 14));
820 auto ip3 = IPAddress("2002:c000:022a::"); // 192.0.2.42
821 auto subnet3 = IPAddress("2002:c000:0000::"); // 192.0.0.0
822 EXPECT_TRUE(ip3.inSubnet(subnet3, 16));
825 static const vector<string> ipv4Strs = {
830 TEST(IPAddress, getIPv6For6To4) {
831 for (auto ipv4Str : ipv4Strs) {
832 auto ip = IPAddress(ipv4Str);
833 EXPECT_TRUE(ip.isV4());
834 IPAddressV4 ipv4 = ip.asV4();
835 auto ipv6 = ipv4.getIPv6For6To4();
836 EXPECT_EQ(ipv6.type(), IPAddressV6::Type::T6TO4);
837 auto ipv4New = ipv6.getIPv4For6To4();
838 EXPECT_TRUE(ipv4Str.compare(ipv4New.str()) == 0);
842 static const vector<pair<string, uint8_t>> invalidMasks = {
846 TEST(IPAddress, InvalidMask) {
847 for (auto& tc : invalidMasks) {
848 auto ip = IPAddress(tc.first);
849 EXPECT_THROW(ip.mask(tc.second), IPAddressFormatException);
853 static const vector<pair<string, IPAddressV6::Type>> v6types = {
854 {"::1", IPAddressV6::Type::NORMAL},
855 {"2620:0:1cfe:face:b00c::3", IPAddressV6::Type::NORMAL},
856 {"2001:0000:4136:e378:8000:63bf:3fff:fdd2", IPAddressV6::Type::TEREDO},
857 {"2002:c000:022a::", IPAddressV6::Type::T6TO4},
859 TEST(IPAddress, V6Types) {
860 auto mkName = [&](const IPAddressV6::Type t) -> string {
862 case IPAddressV6::Type::TEREDO:
864 case IPAddressV6::Type::T6TO4:
871 for (auto& tc : v6types) {
872 auto ip = IPAddress(tc.first);
873 EXPECT_TRUE(ip.isV6());
874 IPAddressV6 ipv6 = ip.asV6();
875 EXPECT_EQ(tc.second, ipv6.type())
876 << "expected " << mkName(tc.second) << ", got " << mkName(ipv6.type());
878 case IPAddressV6::Type::TEREDO:
879 EXPECT_TRUE(ipv6.isTeredo()) << "isTeredo was false";
880 EXPECT_FALSE(ipv6.is6To4()) << "is6To4 was true";
882 case IPAddressV6::Type::T6TO4:
883 EXPECT_TRUE(ipv6.is6To4()) << "is6To4 was false";
884 EXPECT_FALSE(ipv6.isTeredo()) << "isTeredo was true";
886 case IPAddressV6::Type::NORMAL:
887 EXPECT_FALSE(ipv6.is6To4()) << "is6To4 was true";
888 EXPECT_FALSE(ipv6.isTeredo()) << "isTeredo was true";
891 FAIL() << "Invalid expected type: " << to<std::string>(tc.second);
896 static const vector<pair<string, uint32_t>> provideToLong = {
898 {"10.0.0.0", 167772160},
899 {"126.131.128.23", 2122547223},
900 {"192.168.0.0", 3232235520},
902 TEST(IPAddress, ToLong) {
903 for (auto& tc : provideToLong) {
904 auto ip = IPAddress(tc.first);
905 EXPECT_TRUE(ip.isV4());
906 IPAddressV4 ipv4 = ip.asV4();
907 EXPECT_EQ(tc.second, ipv4.toLongHBO());
909 auto ip2 = IPAddress::fromLongHBO(tc.second);
910 EXPECT_TRUE(ip2.isV4());
911 EXPECT_TRUE(tc.first.compare(ip2.str()) == 0);
912 EXPECT_EQ(tc.second, ip2.asV4().toLongHBO());
914 auto nla = htonl(tc.second);
915 auto ip3 = IPAddress::fromLong(nla);
916 EXPECT_TRUE(ip3.isV4());
917 EXPECT_TRUE(tc.first.compare(ip3.str()) == 0);
918 EXPECT_EQ(nla, ip3.asV4().toLong());
922 TEST(IPAddress, fromBinaryV4) {
923 for (auto& tc : provideToLong) {
924 SCOPED_TRACE(tc.first);
929 data.u32 = Endian::big(tc.second);
930 ByteRange bytes(data.u8, 4);
932 auto fromBin = IPAddressV4::fromBinary(bytes);
933 IPAddressV4 fromStr(tc.first);
934 EXPECT_EQ(fromStr, fromBin);
936 IPAddressV4 addr2("0.0.0.0");
937 addr2 = IPAddressV4::fromBinary(bytes);
938 EXPECT_EQ(fromStr, addr2);
940 auto maybeAddr3 = IPAddressV4::tryFromBinary(bytes);
941 EXPECT_TRUE(maybeAddr3.hasValue());
942 EXPECT_EQ(fromStr, maybeAddr3.value());
944 IPAddress genericAddr = IPAddress::fromBinary(bytes);
945 ASSERT_TRUE(genericAddr.isV4());
946 EXPECT_EQ(fromStr, genericAddr.asV4());
947 EXPECT_EQ(ByteRange(genericAddr.bytes(), genericAddr.byteCount()), bytes);
952 IPAddressV4::fromBinary(ByteRange(data, 3)), IPAddressFormatException);
954 IPAddressV4::fromBinary(ByteRange(data, 16)), IPAddressFormatException);
956 IPAddressV4::fromBinary(ByteRange(data, 20)), IPAddressFormatException);
959 TEST(IPAddress, toBinaryV4) {
960 for (auto& tc : provideToLong) {
961 SCOPED_TRACE(tc.first);
966 data.u32 = Endian::big(tc.second);
967 ByteRange bytes(data.u8, 4);
969 auto fromBin = IPAddressV4::fromBinary(bytes);
970 auto toBin = fromBin.toBinary();
971 EXPECT_EQ(bytes, toBin);
975 using ByteArray8 = std::array<uint8_t, 8>;
977 static auto join8 = [](std::array<ByteArray8, 2> parts) {
979 std::memcpy(_return.data(), parts.data(), _return.size());
983 static const vector<pair<string, ByteArray16>> provideBinary16Bytes = {
987 ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
988 ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
993 ByteArray8{{0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
994 ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}},
997 "fe80::0012:34ff:fe56:78ab",
999 {{ByteArray8{{0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1000 ByteArray8{{0x00, 0x12, 0x34, 0xff, 0xfe, 0x56, 0x78, 0xab}}}})),
1002 "2001:db8:1234:5678:90ab:cdef:8765:4321",
1004 ByteArray8{{0x20, 0x01, 0x0d, 0xb8, 0x12, 0x34, 0x56, 0x78}},
1005 ByteArray8{{0x90, 0xab, 0xcd, 0xef, 0x87, 0x65, 0x43, 0x21}},
1010 ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1011 ByteArray8{{0xff, 0xff, 0x00, 0x00, 0xc0, 0xa8, 0x00, 0x01}},
1015 TEST(IPAddress, fromBinaryV6) {
1016 for (auto& tc : provideBinary16Bytes) {
1017 SCOPED_TRACE(tc.first);
1018 ByteRange bytes(&tc.second.front(), tc.second.size());
1020 auto fromBin = IPAddressV6::fromBinary(bytes);
1021 IPAddressV6 fromStr(tc.first);
1022 EXPECT_EQ(fromStr, fromBin);
1024 IPAddressV6 addr2("::0");
1025 addr2 = IPAddressV6::fromBinary(bytes);
1026 EXPECT_EQ(fromStr, addr2);
1028 auto maybeAddr3 = IPAddressV6::tryFromBinary(bytes);
1029 EXPECT_TRUE(maybeAddr3.hasValue());
1030 EXPECT_EQ(fromStr, maybeAddr3.value());
1032 IPAddress genericAddr = IPAddress::fromBinary(bytes);
1033 ASSERT_TRUE(genericAddr.isV6());
1034 EXPECT_EQ(fromStr, genericAddr.asV6());
1035 EXPECT_EQ(ByteRange(genericAddr.bytes(), genericAddr.byteCount()), bytes);
1040 IPAddressV6::fromBinary(ByteRange(data, 3)), IPAddressFormatException);
1042 IPAddressV6::fromBinary(ByteRange(data, 4)), IPAddressFormatException);
1044 IPAddressV6::fromBinary(ByteRange(data, 20)), IPAddressFormatException);
1047 TEST(IPAddress, toBinaryV6) {
1048 for (auto& tc : provideBinary16Bytes) {
1049 SCOPED_TRACE(tc.first);
1050 ByteRange bytes(&tc.second.front(), tc.second.size());
1052 auto fromBin = IPAddressV6::fromBinary(bytes);
1053 auto toBin = fromBin.toBinary();
1054 EXPECT_EQ(bytes, toBin);
1058 TEST_P(IPAddressFlagTest, IsLoopback) {
1059 AddressFlags param = GetParam();
1060 IPAddress addr(param.address);
1062 EXPECT_EQ(param.version, addr.version());
1063 EXPECT_EQ(param.isLoopback(), addr.isLoopback());
1066 TEST_P(IPAddressFlagTest, IsPrivate) {
1067 AddressFlags param = GetParam();
1068 IPAddress addr(param.address);
1070 EXPECT_EQ(param.version, addr.version());
1071 EXPECT_EQ(param.isPrivate(), addr.isPrivate()) << addr;
1074 TEST_P(IPAddressFlagTest, IsNonroutable) {
1075 AddressFlags param = GetParam();
1076 IPAddress addr(param.address);
1078 EXPECT_EQ(param.version, addr.version());
1079 EXPECT_EQ(param.isNonroutable(), addr.isNonroutable()) << addr;
1082 TEST_P(IPAddressFlagTest, IsZero) {
1083 AddressFlags param = GetParam();
1084 IPAddress addr(param.address);
1086 EXPECT_EQ(param.version, addr.version());
1087 EXPECT_EQ(param.isZero(), addr.isZero()) << addr;
1090 TEST_P(IPAddressFlagTest, IsLinkLocal) {
1091 AddressFlags param = GetParam();
1092 IPAddress addr(param.address);
1093 EXPECT_EQ(param.isLinkLocal(), addr.isLinkLocal()) << addr;
1096 TEST(IPAddress, CreateLinkLocal) {
1097 IPAddressV6 addr(IPAddressV6::LINK_LOCAL, MacAddress("00:05:73:f9:46:fc"));
1098 EXPECT_EQ(IPAddressV6("fe80::0205:73ff:fef9:46fc"), addr);
1100 addr = IPAddressV6(IPAddressV6::LINK_LOCAL, MacAddress("02:00:00:12:34:56"));
1101 EXPECT_EQ(IPAddressV6("fe80::ff:fe12:3456"), addr);
1104 TEST_P(IPAddressFlagTest, IsLinkLocalBroadcast) {
1105 AddressFlags param = GetParam();
1106 IPAddress addr(param.address);
1107 EXPECT_EQ(param.version, addr.version());
1108 EXPECT_EQ(param.isLinkLocalBroadcast(), addr.isLinkLocalBroadcast());
1111 TEST(IPAddress, SolicitedNodeAddress) {
1112 // An example from RFC 4291 section 2.7.1
1114 IPAddressV6("ff02::1:ff0e:8c6c"),
1115 IPAddressV6("4037::01:800:200e:8c6c").getSolicitedNodeAddress());
1117 // An example from wikipedia
1118 // (http://en.wikipedia.org/wiki/Solicited-node_multicast_address)
1120 IPAddressV6("ff02::1:ff28:9c5a"),
1121 IPAddressV6("fe80::2aa:ff:fe28:9c5a").getSolicitedNodeAddress());
1124 TEST_P(IPAddressByteAccessorTest, CheckBytes) {
1125 auto addrData = GetParam();
1126 IPAddress ip(addrData.address);
1128 for (auto byitr = addrData.bytes.begin(); i < ip.byteCount(); ++i, ++byitr) {
1129 EXPECT_EQ(*byitr, ip.getNthMSByte(i));
1132 ip.isV4() ? ip.asV4().getNthMSByte(i) : ip.asV6().getNthMSByte(i));
1135 for (auto byritr = addrData.bytes.rbegin(); i < ip.byteCount();
1137 EXPECT_EQ(*byritr, ip.getNthLSByte(i));
1140 ip.isV4() ? ip.asV4().getNthLSByte(i) : ip.asV6().getNthLSByte(i));
1144 TEST_P(IPAddressBitAccessorTest, CheckBits) {
1145 auto addrData = GetParam();
1146 auto littleEndianAddrData = addrData.bytes;
1147 // IPAddress stores address data in n/w byte order.
1148 reverse(littleEndianAddrData.begin(), littleEndianAddrData.end());
1149 // Bit iterator goes from LSBit to MSBit
1150 // We will traverse the IPAddress bits from 0 to bitCount -1
1151 auto bitr = folly::makeBitIterator(littleEndianAddrData.begin());
1152 IPAddress ip(addrData.address);
1153 for (size_t i = 0; i < ip.bitCount(); ++i) {
1154 auto msbIndex = ip.bitCount() - i - 1;
1155 EXPECT_EQ(*bitr, ip.getNthMSBit(msbIndex));
1158 ip.isV4() ? ip.asV4().getNthMSBit(msbIndex)
1159 : ip.asV6().getNthMSBit(msbIndex));
1160 EXPECT_EQ(*bitr, ip.getNthLSBit(i));
1162 *bitr, ip.isV4() ? ip.asV4().getNthLSBit(i) : ip.asV6().getNthLSBit(i));
1167 TEST(IPAddress, InvalidByteAccess) {
1168 IPAddress ip4("10.10.10.10");
1169 // MSByte, LSByte accessors are 0 indexed
1170 EXPECT_THROW(ip4.getNthMSByte(ip4.byteCount()), std::invalid_argument);
1171 EXPECT_THROW(ip4.getNthLSByte(ip4.byteCount()), std::invalid_argument);
1172 EXPECT_THROW(ip4.getNthMSByte(-1), std::invalid_argument);
1173 EXPECT_THROW(ip4.getNthLSByte(-1), std::invalid_argument);
1174 auto asV4 = ip4.asV4();
1175 EXPECT_THROW(asV4.getNthMSByte(asV4.byteCount()), std::invalid_argument);
1176 EXPECT_THROW(asV4.getNthLSByte(asV4.byteCount()), std::invalid_argument);
1177 EXPECT_THROW(asV4.getNthMSByte(-1), std::invalid_argument);
1178 EXPECT_THROW(asV4.getNthLSByte(-1), std::invalid_argument);
1180 IPAddress ip6("2620:0:1cfe:face:b00c::3");
1181 EXPECT_THROW(ip6.getNthMSByte(ip6.byteCount()), std::invalid_argument);
1182 EXPECT_THROW(ip6.getNthLSByte(ip6.byteCount()), std::invalid_argument);
1183 EXPECT_THROW(ip6.getNthMSByte(-1), std::invalid_argument);
1184 EXPECT_THROW(ip6.getNthLSByte(-1), std::invalid_argument);
1185 auto asV6 = ip6.asV6();
1186 EXPECT_THROW(asV6.getNthMSByte(asV6.byteCount()), std::invalid_argument);
1187 EXPECT_THROW(asV6.getNthLSByte(asV6.byteCount()), std::invalid_argument);
1188 EXPECT_THROW(asV6.getNthMSByte(-1), std::invalid_argument);
1189 EXPECT_THROW(asV6.getNthLSByte(-1), std::invalid_argument);
1192 TEST(IPAddress, InvalidBBitAccess) {
1193 IPAddress ip4("10.10.10.10");
1194 // MSByte, LSByte accessors are 0 indexed
1195 EXPECT_THROW(ip4.getNthMSBit(ip4.bitCount()), std::invalid_argument);
1196 EXPECT_THROW(ip4.getNthLSBit(ip4.bitCount()), std::invalid_argument);
1197 EXPECT_THROW(ip4.getNthMSBit(-1), std::invalid_argument);
1198 EXPECT_THROW(ip4.getNthLSBit(-1), std::invalid_argument);
1199 auto asV4 = ip4.asV4();
1200 EXPECT_THROW(asV4.getNthMSBit(asV4.bitCount()), std::invalid_argument);
1201 EXPECT_THROW(asV4.getNthLSBit(asV4.bitCount()), std::invalid_argument);
1202 EXPECT_THROW(asV4.getNthMSBit(-1), std::invalid_argument);
1203 EXPECT_THROW(asV4.getNthLSBit(-1), std::invalid_argument);
1205 IPAddress ip6("2620:0:1cfe:face:b00c::3");
1206 EXPECT_THROW(ip6.getNthMSBit(ip6.bitCount()), std::invalid_argument);
1207 EXPECT_THROW(ip6.getNthLSBit(ip6.bitCount()), std::invalid_argument);
1208 EXPECT_THROW(ip6.getNthMSBit(-1), std::invalid_argument);
1209 EXPECT_THROW(ip6.getNthLSBit(-1), std::invalid_argument);
1210 auto asV6 = ip6.asV6();
1211 EXPECT_THROW(asV6.getNthMSBit(asV6.bitCount()), std::invalid_argument);
1212 EXPECT_THROW(asV6.getNthLSBit(asV6.bitCount()), std::invalid_argument);
1213 EXPECT_THROW(asV6.getNthMSBit(-1), std::invalid_argument);
1214 EXPECT_THROW(asV6.getNthLSBit(-1), std::invalid_argument);
1217 TEST(IPAddress, StringFormat) {
1219 for (int i = 0; i < 8; ++i) {
1220 auto t = htons(0x0123 + ((i % 4) * 0x4444));
1224 a6.s6_addr16[i] = t;
1228 "0123:4567:89ab:cdef:0123:4567:89ab:cdef", detail::fastIpv6ToString(a6));
1231 a4.s_addr = htonl(0x01020304);
1232 EXPECT_EQ("1.2.3.4", detail::fastIpv4ToString(a4));
1235 TEST(IPAddress, getMacAddressFromLinkLocal) {
1236 IPAddressV6 ip6("fe80::f652:14ff:fec5:74d8");
1237 EXPECT_TRUE(ip6.getMacAddressFromLinkLocal().hasValue());
1238 EXPECT_EQ("f4:52:14:c5:74:d8", ip6.getMacAddressFromLinkLocal()->toString());
1241 TEST(IPAddress, getMacAddressFromLinkLocal_Negative) {
1242 IPAddressV6 no_link_local_ip6("2803:6082:a2:4447::1");
1243 EXPECT_FALSE(no_link_local_ip6.getMacAddressFromLinkLocal().hasValue());
1244 no_link_local_ip6 = IPAddressV6("fe80::f652:14ff:ccc5:74d8");
1245 EXPECT_FALSE(no_link_local_ip6.getMacAddressFromLinkLocal().hasValue());
1246 no_link_local_ip6 = IPAddressV6("fe80::f652:14ff:ffc5:74d8");
1247 EXPECT_FALSE(no_link_local_ip6.getMacAddressFromLinkLocal().hasValue());
1248 no_link_local_ip6 = IPAddressV6("fe81::f652:14ff:ffc5:74d8");
1249 EXPECT_FALSE(no_link_local_ip6.getMacAddressFromLinkLocal().hasValue());
1252 TEST(IPAddress, getMacAddressFromEUI64) {
1253 IPAddressV6 ip6("2401:db00:3020:51dc:4a57:ddff:fe04:5643");
1254 EXPECT_TRUE(ip6.getMacAddressFromEUI64().hasValue());
1255 EXPECT_EQ("48:57:dd:04:56:43", ip6.getMacAddressFromEUI64()->toString());
1256 ip6 = IPAddressV6("fe80::4a57:ddff:fe04:5643");
1257 EXPECT_TRUE(ip6.getMacAddressFromEUI64().hasValue());
1258 EXPECT_EQ("48:57:dd:04:56:43", ip6.getMacAddressFromEUI64()->toString());
1261 TEST(IPAddress, getMacAddressFromEUI64_Negative) {
1262 IPAddressV6 not_eui64_ip6("2401:db00:3020:51dc:face:0000:009a:0000");
1263 EXPECT_FALSE(not_eui64_ip6.getMacAddressFromEUI64().hasValue());
1266 TEST(IPAddress, LongestCommonPrefix) {
1267 IPAddress ip10("10.0.0.0");
1268 IPAddress ip11("11.0.0.0");
1269 IPAddress ip12("12.0.0.0");
1270 IPAddress ip128("128.0.0.0");
1271 IPAddress ip10dot10("10.10.0.0");
1272 auto prefix = IPAddress::longestCommonPrefix({ip10, 8}, {ip128, 8});
1274 IPAddressV4::longestCommonPrefix({ip10.asV4(), 8}, {ip128.asV4(), 8});
1275 // No bits match b/w 128/8 and 10/8
1276 EXPECT_EQ(IPAddress("0.0.0.0"), prefix.first);
1277 EXPECT_EQ(0, prefix.second);
1278 EXPECT_EQ(IPAddressV4("0.0.0.0"), prefix4.first);
1279 EXPECT_EQ(0, prefix4.second);
1281 prefix = IPAddress::longestCommonPrefix({ip10, 8}, {ip10dot10, 16});
1282 prefix4 = IPAddressV4::longestCommonPrefix(
1283 {ip10.asV4(), 8}, {ip10dot10.asV4(), 16});
1284 // Between 10/8 and 10.10/16, 10/8 is the longest common match
1285 EXPECT_EQ(ip10, prefix.first);
1286 EXPECT_EQ(8, prefix.second);
1287 EXPECT_EQ(ip10.asV4(), prefix4.first);
1288 EXPECT_EQ(8, prefix4.second);
1290 prefix = IPAddress::longestCommonPrefix({ip11, 8}, {ip12, 8});
1292 IPAddressV4::longestCommonPrefix({ip11.asV4(), 8}, {ip12.asV4(), 8});
1293 // 12 = 1100, 11 = 1011, longest match - 1000 = 8
1294 EXPECT_EQ(IPAddress("8.0.0.0"), prefix.first);
1295 EXPECT_EQ(5, prefix.second);
1296 EXPECT_EQ(IPAddressV4("8.0.0.0"), prefix4.first);
1297 EXPECT_EQ(5, prefix4.second);
1299 // Between 128/1 and 128/2, longest match 128/1
1300 prefix = IPAddress::longestCommonPrefix({ip128, 1}, {ip128, 2});
1302 IPAddressV4::longestCommonPrefix({ip128.asV4(), 1}, {ip128.asV4(), 2});
1303 EXPECT_EQ(ip128, prefix.first);
1304 EXPECT_EQ(1, prefix.second);
1305 EXPECT_EQ(ip128.asV4(), prefix4.first);
1306 EXPECT_EQ(1, prefix4.second);
1308 IPAddress ip6("2620:0:1cfe:face:b00c::3");
1309 prefix = IPAddress::longestCommonPrefix(
1310 {ip6, ip6.bitCount()}, {ip6, ip6.bitCount()});
1311 auto prefix6 = IPAddressV6::longestCommonPrefix(
1312 {ip6.asV6(), IPAddressV6::bitCount()},
1313 {ip6.asV6(), IPAddressV6::bitCount()});
1314 // Longest common b/w me and myself is myself
1315 EXPECT_EQ(ip6, prefix.first);
1316 EXPECT_EQ(ip6.bitCount(), prefix.second);
1317 EXPECT_EQ(ip6.asV6(), prefix6.first);
1318 EXPECT_EQ(ip6.asV6().bitCount(), prefix6.second);
1320 IPAddress ip6Zero("::");
1321 prefix = IPAddress::longestCommonPrefix({ip6, ip6.bitCount()}, {ip6Zero, 0});
1322 prefix6 = IPAddressV6::longestCommonPrefix(
1323 {ip6.asV6(), IPAddressV6::bitCount()}, {ip6Zero.asV6(), 0});
1324 // Longest common b/w :: (ipv6 equivalent of 0/0) is ::
1325 EXPECT_EQ(ip6Zero, prefix.first);
1326 EXPECT_EQ(0, prefix.second);
1328 // Exceptional cases
1330 IPAddress::longestCommonPrefix({ip10, 8}, {ip6, 128}),
1331 std::invalid_argument);
1333 IPAddress::longestCommonPrefix({ip10, ip10.bitCount() + 1}, {ip10, 8}),
1334 std::invalid_argument);
1336 IPAddressV4::longestCommonPrefix(
1337 {ip10.asV4(), IPAddressV4::bitCount() + 1}, {ip10.asV4(), 8}),
1338 std::invalid_argument);
1340 IPAddress::longestCommonPrefix(
1341 {ip6, ip6.bitCount() + 1}, {ip6, ip6.bitCount()}),
1342 std::invalid_argument);
1344 IPAddressV6::longestCommonPrefix(
1345 {ip6.asV6(), IPAddressV6::bitCount() + 1},
1346 {ip6.asV6(), IPAddressV6::bitCount()}),
1347 std::invalid_argument);
1350 static const vector<AddressData> validAddressProvider = {
1351 AddressData("127.0.0.1", {127, 0, 0, 1}, 4),
1352 AddressData("69.63.189.16", {69, 63, 189, 16}, 4),
1353 AddressData("0.0.0.0", {0, 0, 0, 0}, 4),
1354 AddressData("::1", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, 6),
1356 "2620:0:1cfe:face:b00c::3",
1357 {38, 32, 0, 0, 28, 254, 250, 206, 176, 12, 0, 0, 0, 0, 0, 3},
1361 static const vector<string> invalidAddressProvider = {
1367 "127.0.0.1,127.0.0.1",
1371 static const vector<ByteVector> invalidBinaryProvider = {
1372 {0x31, 0x32, 0x37, 0x2e, 0x30, 0x30, 0x2e, 0x30, 0x2e, 0x31},
1378 {0x00, 0x00, 0x00, 0x00, 0x00},
1382 static const uint8_t IS_LOCAL = AddressFlags::IS_LOCAL;
1383 static const uint8_t IS_NONROUTABLE = AddressFlags::IS_NONROUTABLE;
1384 static const uint8_t IS_PRIVATE = AddressFlags::IS_PRIVATE;
1385 static const uint8_t IS_ZERO = AddressFlags::IS_ZERO;
1386 static const uint8_t IS_LINK_LOCAL =
1387 AddressFlags::IS_LINK_LOCAL | IS_NONROUTABLE;
1388 static const uint8_t IS_PVT_NONROUTE = IS_NONROUTABLE | IS_PRIVATE;
1389 static const uint8_t IS_MULTICAST = AddressFlags::IS_MULTICAST;
1390 static const uint8_t IS_LINK_LOCAL_BROADCAST =
1391 AddressFlags::IS_LINK_LOCAL_BROADCAST;
1393 static vector<AddressFlags> flagProvider = {
1395 AddressFlags("69.63.176.1", 4, 0),
1396 AddressFlags("128.12.65.3", 4, 0),
1397 AddressFlags("192.0.1.0", 4, 0),
1398 AddressFlags("198.51.101.0", 4, 0),
1399 AddressFlags("203.0.114.0", 4, 0),
1400 AddressFlags("128.12.64.115", 4, 0),
1403 AddressFlags("2620:0:1cfe:face:b00c::3", 6, 0),
1406 AddressFlags("127.0.0.1", 4, IS_LOCAL | IS_PVT_NONROUTE),
1407 AddressFlags("::1", 6, IS_LOCAL | IS_PVT_NONROUTE),
1410 AddressFlags("169.254.0.1", 4, IS_LINK_LOCAL | IS_PVT_NONROUTE),
1413 AddressFlags("10.0.0.0", 4, IS_PVT_NONROUTE),
1414 AddressFlags("10.11.12.13", 4, IS_PVT_NONROUTE),
1415 AddressFlags("10.255.255.255", 4, IS_PVT_NONROUTE),
1416 AddressFlags("127.128.129.200", 4, IS_LOCAL | IS_PVT_NONROUTE),
1417 AddressFlags("127.255.255.255", 4, IS_LOCAL | IS_PVT_NONROUTE),
1418 AddressFlags("169.254.0.0", 4, IS_LINK_LOCAL | IS_PVT_NONROUTE),
1419 AddressFlags("192.168.0.0", 4, IS_PVT_NONROUTE),
1420 AddressFlags("192.168.200.255", 4, IS_PVT_NONROUTE),
1421 AddressFlags("192.168.255.255", 4, IS_PVT_NONROUTE),
1424 AddressFlags("fd01:1637:1c56:66af::", 6, IS_PVT_NONROUTE),
1427 AddressFlags("0.0.0.0", 4, IS_NONROUTABLE | IS_ZERO),
1428 AddressFlags("0.255.255.255", 4, IS_NONROUTABLE),
1429 AddressFlags("192.0.0.0", 4, IS_NONROUTABLE),
1430 AddressFlags("192.0.2.0", 4, IS_NONROUTABLE),
1431 AddressFlags("198.18.0.0", 4, IS_NONROUTABLE),
1432 AddressFlags("198.19.255.255", 4, IS_NONROUTABLE),
1433 AddressFlags("198.51.100.0", 4, IS_NONROUTABLE),
1434 AddressFlags("198.51.100.255", 4, IS_NONROUTABLE),
1435 AddressFlags("203.0.113.0", 4, IS_NONROUTABLE),
1436 AddressFlags("203.0.113.255", 4, IS_NONROUTABLE),
1437 AddressFlags("224.0.0.0", 4, IS_NONROUTABLE | IS_MULTICAST),
1438 AddressFlags("240.0.0.0", 4, IS_NONROUTABLE),
1439 AddressFlags("224.0.0.0", 4, IS_NONROUTABLE),
1440 // v4 link local broadcast
1444 IS_NONROUTABLE | IS_LINK_LOCAL_BROADCAST),
1447 AddressFlags("1999::1", 6, IS_NONROUTABLE),
1448 AddressFlags("0::0", 6, IS_NONROUTABLE | IS_ZERO),
1449 AddressFlags("0::0:0", 6, IS_NONROUTABLE | IS_ZERO),
1450 AddressFlags("0:0:0::0", 6, IS_NONROUTABLE | IS_ZERO),
1453 AddressFlags("fe80::0205:73ff:fef9:46fc", 6, IS_LINK_LOCAL),
1454 AddressFlags("fe80::0012:34ff:fe56:7890", 6, IS_LINK_LOCAL),
1457 AddressFlags("224.0.0.1", 4, IS_MULTICAST | IS_NONROUTABLE),
1458 AddressFlags("224.0.0.251", 4, IS_MULTICAST | IS_NONROUTABLE),
1459 AddressFlags("239.12.34.56", 4, IS_MULTICAST | IS_NONROUTABLE),
1462 AddressFlags("ff00::", 6, IS_MULTICAST | IS_NONROUTABLE),
1463 AddressFlags("ff02:ffff::1", 6, IS_MULTICAST | IS_NONROUTABLE),
1464 AddressFlags("ff02::101", 6, IS_MULTICAST | IS_NONROUTABLE),
1465 AddressFlags("ff0e::101", 6, IS_MULTICAST),
1466 // v6 link local broadcast
1467 AddressFlags("ff02::1", 6, IS_NONROUTABLE | IS_LINK_LOCAL_BROADCAST),
1470 static const vector<pair<string, string>> mapProvider = {
1471 {"::ffff:192.0.2.128", "192.0.2.128"},
1472 {"192.0.2.128", "::ffff:192.0.2.128"},
1473 {"::FFFF:129.144.52.38", "129.144.52.38"},
1474 {"129.144.52.38", "::FFFF:129.144.52.38"},
1475 {"0:0:0:0:0:FFFF:222.1.41.90", "222.1.41.90"},
1476 {"::FFFF:222.1.41.90", "222.1.41.90"},
1479 static const vector<MaskData> masksProvider = {
1480 MaskData("255.255.255.255", 1, "128.0.0.0"),
1481 MaskData("255.255.255.255", 2, "192.0.0.0"),
1482 MaskData("192.0.2.42", 16, "192.0.0.0"),
1483 MaskData("255.255.255.255", 24, "255.255.255.0"),
1484 MaskData("255.255.255.255", 32, "255.255.255.255"),
1485 MaskData("10.10.10.10", 0, "0.0.0.0"),
1486 MaskData("::1", 64, "::"),
1487 MaskData("2620:0:1cfe:face:b00c::3", 1, "::"),
1488 MaskData("2620:0:1cfe:face:b00c::3", 3, "2000::"),
1489 MaskData("2620:0:1cfe:face:b00c::3", 6, "2400::"),
1490 MaskData("2620:0:1cfe:face:b00c::3", 7, "2600::"),
1491 MaskData("2620:0:1cfe:face:b00c::3", 11, "2620::"),
1492 MaskData("2620:0:1cfe:face:b00c::3", 36, "2620:0:1000::"),
1493 MaskData("2620:0:1cfe:face:b00c::3", 37, "2620:0:1800::"),
1494 MaskData("2620:0:1cfe:face:b00c::3", 38, "2620:0:1c00::"),
1495 MaskData("2620:0:1cfe:face:b00c::3", 41, "2620:0:1c80::"),
1496 MaskData("2620:0:1cfe:face:b00c::3", 42, "2620:0:1cc0::"),
1497 MaskData("2620:0:1cfe:face:b00c::3", 43, "2620:0:1ce0::"),
1498 MaskData("2620:0:1cfe:face:b00c::3", 44, "2620:0:1cf0::"),
1499 MaskData("2620:0:1cfe:face:b00c::3", 45, "2620:0:1cf8::"),
1500 MaskData("2620:0:1cfe:face:b00c::3", 46, "2620:0:1cfc::"),
1501 MaskData("2620:0:1cfe:face:b00c::3", 47, "2620:0:1cfe::"),
1502 MaskData("2620:0:1cfe:face:b00c::3", 49, "2620:0:1cfe:8000::"),
1503 MaskData("2620:0:1cfe:face:b00c::3", 50, "2620:0:1cfe:c000::"),
1504 MaskData("2620:0:1cfe:face:b00c::3", 51, "2620:0:1cfe:e000::"),
1505 MaskData("2620:0:1cfe:face:b00c::3", 52, "2620:0:1cfe:f000::"),
1506 MaskData("2620:0:1cfe:face:b00c::3", 53, "2620:0:1cfe:f800::"),
1507 MaskData("2620:0:1cfe:face:b00c::3", 55, "2620:0:1cfe:fa00::"),
1508 MaskData("2620:0:1cfe:face:b00c::3", 57, "2620:0:1cfe:fa80::"),
1509 MaskData("2620:0:1cfe:face:b00c::3", 58, "2620:0:1cfe:fac0::"),
1510 MaskData("2620:0:1cfe:face:b00c::3", 61, "2620:0:1cfe:fac8::"),
1511 MaskData("2620:0:1cfe:face:b00c::3", 62, "2620:0:1cfe:facc::"),
1512 MaskData("2620:0:1cfe:face:b00c::3", 63, "2620:0:1cfe:face::"),
1513 MaskData("2620:0:1cfe:face:b00c::3", 65, "2620:0:1cfe:face:8000::"),
1514 MaskData("2620:0:1cfe:face:b00c::3", 67, "2620:0:1cfe:face:a000::"),
1515 MaskData("2620:0:1cfe:face:b00c::3", 68, "2620:0:1cfe:face:b000::"),
1516 MaskData("2620:0:1cfe:face:b00c::3", 77, "2620:0:1cfe:face:b008::"),
1517 MaskData("2620:0:1cfe:face:b00c::3", 78, "2620:0:1cfe:face:b00c::"),
1518 MaskData("2620:0:1cfe:face:b00c::3", 127, "2620:0:1cfe:face:b00c::2"),
1519 MaskData("2620:0:1cfe:face:b00c::3", 128, "2620:0:1cfe:face:b00c::3"),
1520 MaskData("2620:0:1cfe:face:b00c::3", 0, "::"),
1523 static const vector<MaskBoundaryData> maskBoundaryProvider = {
1524 MaskBoundaryData("10.1.1.1", 24, "10.1.1.1", true),
1525 MaskBoundaryData("10.1.1.1", 8, "10.1.2.3", true),
1526 MaskBoundaryData("2620:0:1cfe:face:b00c::1", 48, "2620:0:1cfe::", true),
1527 // addresses that are NOT in the same subnet once mask is applied
1528 MaskBoundaryData("10.1.1.1", 24, "10.1.2.1", false),
1529 MaskBoundaryData("10.1.1.1", 16, "10.2.3.4", false),
1530 MaskBoundaryData("2620:0:1cfe:face:b00c::1", 48, "2620:0:1cfc::", false),
1533 INSTANTIATE_TEST_CASE_P(
1536 ::testing::ValuesIn(validAddressProvider));
1537 INSTANTIATE_TEST_CASE_P(
1540 ::testing::ValuesIn(flagProvider));
1541 INSTANTIATE_TEST_CASE_P(
1543 IPAddressMappedTest,
1544 ::testing::ValuesIn(mapProvider));
1545 INSTANTIATE_TEST_CASE_P(
1548 ::testing::ValuesIn(invalidAddressProvider));
1549 INSTANTIATE_TEST_CASE_P(
1551 IPAddressCtorBinaryTest,
1552 ::testing::ValuesIn(invalidBinaryProvider));
1553 INSTANTIATE_TEST_CASE_P(
1556 ::testing::ValuesIn(masksProvider));
1557 INSTANTIATE_TEST_CASE_P(
1559 IPAddressMaskBoundaryTest,
1560 ::testing::ValuesIn(maskBoundaryProvider));
1561 INSTANTIATE_TEST_CASE_P(
1563 IPAddressByteAccessorTest,
1564 ::testing::ValuesIn(validAddressProvider));
1565 INSTANTIATE_TEST_CASE_P(
1567 IPAddressBitAccessorTest,
1568 ::testing::ValuesIn(validAddressProvider));
1569 INSTANTIATE_TEST_CASE_P(
1572 ::testing::ValuesIn(TryFromStringTest::ipInOutProvider()));
1574 TEST(IPAddressV4, fetchMask) {
1575 struct X : private IPAddressV4 {
1576 using IPAddressV4::fetchMask;
1581 ::testing::ElementsAreArray(ByteArray4{{0x00, 0x00, 0x00, 0x00}}));
1585 ::testing::ElementsAreArray(ByteArray4{{0x80, 0x00, 0x00, 0x00}}));
1589 ::testing::ElementsAreArray(ByteArray4{{0xff, 0xff, 0xff, 0xfe}}));
1593 ::testing::ElementsAreArray(ByteArray4{{0xff, 0xff, 0xff, 0xff}}));
1596 TEST(IPAddressV6, fetchMask) {
1597 struct X : private IPAddressV6 {
1598 using IPAddressV6::fetchMask;
1603 ::testing::ElementsAreArray(join8({{
1604 ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1605 ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1610 ::testing::ElementsAreArray(join8({{
1611 ByteArray8{{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1612 ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1617 ::testing::ElementsAreArray(join8({{
1618 ByteArray8{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}},
1619 ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1624 ::testing::ElementsAreArray(join8({{
1625 ByteArray8{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
1626 ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1631 ::testing::ElementsAreArray(join8({{
1632 ByteArray8{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
1633 ByteArray8{{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1638 ::testing::ElementsAreArray(join8({{
1639 ByteArray8{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
1640 ByteArray8{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}},
1645 ::testing::ElementsAreArray(join8({{
1646 ByteArray8{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
1647 ByteArray8{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},