cmake: build as many source files as possible
[folly.git] / folly / test / IPAddressTest.cpp
1 /*
2  * Copyright 2014-present Facebook, Inc.
3  *
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
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 #include <sys/types.h>
17
18 #include <string>
19
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>
29
30 using namespace folly;
31 using namespace std;
32 using namespace testing;
33
34 typedef std::vector<uint8_t> ByteVector;
35
36 struct AddressData {
37   std::string address;
38   ByteVector bytes;
39   uint8_t version;
40
41   AddressData(
42       const std::string& address,
43       const ByteVector& bytes,
44       uint8_t version)
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) {}
51
52   static in_addr parseAddress4(const std::string& src) {
53     in_addr addr;
54     inet_pton(AF_INET, src.c_str(), &addr);
55     return addr;
56   }
57
58   static in6_addr parseAddress6(const std::string& src) {
59     in6_addr addr;
60     inet_pton(AF_INET6, src.c_str(), &addr);
61     return addr;
62   }
63 };
64
65 struct AddressFlags {
66   std::string address;
67   uint8_t flags;
68   uint8_t version;
69
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;
77
78   AddressFlags(const std::string& addr, uint8_t version, uint8_t flags)
79       : address(addr), flags(flags), version(version) {}
80
81   bool isLoopback() const {
82     return (flags & IS_LOCAL);
83   }
84   bool isNonroutable() const {
85     return (flags & IS_NONROUTABLE);
86   }
87   bool isPrivate() const {
88     return (flags & IS_PRIVATE);
89   }
90   bool isZero() const {
91     return (flags & IS_ZERO);
92   }
93   bool isLinkLocal() const {
94     return (flags & IS_LINK_LOCAL);
95   }
96   bool isLinkLocalBroadcast() const {
97     return (flags & IS_LINK_LOCAL_BROADCAST);
98   }
99 };
100
101 struct MaskData {
102   std::string address;
103   uint8_t mask;
104   std::string subnet;
105   MaskData(const std::string& addr, uint8_t mask, const std::string& subnet)
106       : address(addr), mask(mask), subnet(subnet) {}
107 };
108
109 struct MaskBoundaryData : MaskData {
110   bool inSubnet;
111   MaskBoundaryData(
112       const std::string& addr,
113       uint8_t mask,
114       const std::string& subnet,
115       bool inSubnet)
116       : MaskData(addr, mask, subnet), inSubnet(inSubnet) {}
117 };
118
119 struct SerializeData {
120   std::string address;
121   ByteVector bytes;
122
123   SerializeData(const std::string& addr, const ByteVector& bytes)
124       : address(addr), bytes(bytes) {}
125 };
126
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());
137     } else {
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());
142     }
143   }
144 };
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> {};
155
156 struct StringTestParam {
157   std::string in;
158   folly::Optional<std::string> out;
159   folly::Optional<std::string> out4;
160   folly::Optional<std::string> out6;
161 };
162
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]"};
169
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"};
173
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},
182     };
183
184     return ret;
185   }
186 };
187
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());
213 }
214
215 TEST(IPAddress, Scope) {
216   // Test that link-local scope is saved
217   auto str = "fe80::62eb:69ff:fe9b:ba60%eth0";
218   IPAddressV6 a2(str);
219   EXPECT_EQ(str, a2.str());
220
221   sockaddr_in6 sock = a2.toSockAddr();
222   EXPECT_NE(0, sock.sin6_scope_id);
223
224   IPAddress a1(str);
225   EXPECT_EQ(str, a1.str());
226
227   a2.setScopeId(0);
228   EXPECT_NE(a1, a2);
229
230   EXPECT_TRUE(a2 < a1);
231 }
232
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";
237   IPAddressV6 a2(str);
238   EXPECT_EQ(str, a2.str());
239
240   sockaddr_in6 sock = a2.toSockAddr();
241   EXPECT_NE(0, sock.sin6_scope_id);
242
243   IPAddress a1(str);
244   EXPECT_EQ(str, a1.str());
245
246   a2.setScopeId(0);
247   EXPECT_NE(a1, a2);
248
249   EXPECT_TRUE(a2 < a1);
250 }
251
252 TEST(IPAddress, Ordering) {
253   IPAddress a1("0.1.1.1");
254   IPAddress a2("1.1.1.0");
255   EXPECT_TRUE(a1 < a2);
256
257   IPAddress b1("::ffff:0.1.1.1");
258   IPAddress b2("::ffff:1.1.1.0");
259   EXPECT_TRUE(b1 < b2);
260 }
261
262 TEST(IPAddress, InvalidAddressFamilyExceptions) {
263   // asV4
264   {
265     IPAddress addr;
266     EXPECT_THROW(addr.asV4(), InvalidAddressFamilyException);
267   }
268   // asV6
269   {
270     IPAddress addr;
271     EXPECT_THROW(addr.asV6(), InvalidAddressFamilyException);
272   }
273   // sockaddr ctor
274   {
275     // setup
276     sockaddr_in addr;
277     addr.sin_family = AF_UNSPEC;
278
279     EXPECT_THROW(IPAddress((sockaddr*)&addr), InvalidAddressFamilyException);
280   }
281 }
282
283 TEST(IPAddress, TryCreateNetwork) {
284   // test valid IPv4 network
285   {
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));
291   }
292   // test valid IPv4 network without applying mask
293   {
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));
299   }
300   // test valid IPv6 network
301   {
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));
307   }
308   // test valid IPv6 network without applying mask
309   {
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));
315   }
316
317   // test invalid default CIDR
318   EXPECT_EQ(
319       CIDRNetworkError::INVALID_DEFAULT_CIDR,
320       IPAddress::tryCreateNetwork("192.168.1.1", 300).error());
321
322   // test empty string
323   EXPECT_EQ(
324       CIDRNetworkError::INVALID_IP, IPAddress::tryCreateNetwork("").error());
325
326   // test multi slash string
327   EXPECT_EQ(
328       CIDRNetworkError::INVALID_IP_SLASH_CIDR,
329       IPAddress::tryCreateNetwork("192.168.0.1/24/36").error());
330
331   // test no slash string with default IPv4
332   {
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);
341   }
342   // test no slash string with default IPv6
343   {
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);
348   }
349   // test no slash string with invalid default
350   EXPECT_EQ(
351       CIDRNetworkError::CIDR_MISMATCH,
352       IPAddress::tryCreateNetwork("192.168.0.1", 33).error());
353 }
354
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);
359   // test empty string
360   EXPECT_THROW(IPAddress::createNetwork(""), IPAddressFormatException);
361   // test multi slash string
362   EXPECT_THROW(
363       IPAddress::createNetwork("192.168.0.1/24/36"), IPAddressFormatException);
364   // test no slash string with invalid default
365   EXPECT_THROW(
366       IPAddress::createNetwork("192.168.0.1", 33), IPAddressFormatException);
367 }
368
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";
373
374   // Test assigning IPAddressV6 addr to IPAddress (was V4)
375   {
376     IPAddress addr(kIPv4Addr);
377     IPAddressV6 addrV6 = IPAddress(kIPv6Addr).asV6();
378     EXPECT_TRUE(addr.isV4());
379     EXPECT_EQ(kIPv4Addr, addr.str());
380     addr = addrV6;
381     EXPECT_TRUE(addr.isV6());
382     EXPECT_EQ(kIPv6Addr, addr.str());
383   }
384   // Test assigning IPAddressV4 addr to IPAddress (was V6)
385   {
386     IPAddress addr(kIPv6Addr);
387     IPAddressV4 addrV4 = IPAddress(kIPv4Addr).asV4();
388     EXPECT_TRUE(addr.isV6());
389     EXPECT_EQ(kIPv6Addr, addr.str());
390     addr = addrV4;
391     EXPECT_TRUE(addr.isV4());
392     EXPECT_EQ(kIPv4Addr, addr.str());
393   }
394   // Test assigning IPAddress(v6) to IPAddress (was v4)
395   {
396     IPAddress addr(kIPv4Addr);
397     IPAddress addrV6 = IPAddress(kIPv6Addr);
398     EXPECT_TRUE(addr.isV4());
399     EXPECT_EQ(kIPv4Addr, addr.str());
400     addr = addrV6;
401     EXPECT_TRUE(addr.isV6());
402     EXPECT_EQ(kIPv6Addr, addr.str());
403   }
404   // Test assigning IPAddress(v4) to IPAddress (was v6)
405   {
406     IPAddress addr(kIPv6Addr);
407     IPAddress addrV4 = IPAddress(kIPv4Addr);
408     EXPECT_TRUE(addr.isV6());
409     EXPECT_EQ(kIPv6Addr, addr.str());
410     addr = addrV4;
411     EXPECT_TRUE(addr.isV4());
412     EXPECT_EQ(kIPv4Addr, addr.str());
413   }
414 }
415
416 // Test the default constructors
417 TEST(IPAddress, CtorDefault) {
418   IPAddressV4 v4;
419   EXPECT_EQ(IPAddressV4("0.0.0.0"), v4);
420   IPAddressV6 v6;
421   EXPECT_EQ(IPAddressV6("::0"), v6);
422 }
423
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"));
428 }
429
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"));
436   EXPECT_TRUE(
437       IPAddressV6::validate("2620:0000:1cfe:face:b00c:0000:127.127.127.127"));
438 }
439
440 TEST(IPAddress, validate) {
441   EXPECT_TRUE(IPAddress::validate("0.0.0.0"));
442   EXPECT_TRUE(IPAddress::validate("::"));
443   EXPECT_FALSE(IPAddress::validate("asdf"));
444 }
445
446 // Test addresses constructed using a in[6]_addr value
447 TEST_P(IPAddressTest, CtorAddress) {
448   AddressData param = GetParam();
449   IPAddress strAddr(param.address);
450   IPAddress address;
451
452   if (param.version == 4) {
453     in_addr v4addr = detail::Bytes::mkAddress4(&param.bytes[0]);
454     address = IPAddress(v4addr);
455   } else {
456     in6_addr v6addr = detail::Bytes::mkAddress6(&param.bytes[0]);
457     address = IPAddress(v6addr);
458   }
459   ExpectIsValid(address);
460   EXPECT_EQ(strAddr, address);
461 }
462
463 // Test addresses constructed using a binary address
464 TEST_P(IPAddressTest, CtorBinary) {
465   AddressData param = GetParam();
466   IPAddress address;
467
468   if (param.version == 4) {
469     in_addr v4addr = AddressData::parseAddress4(param.address);
470     address = IPAddress::fromBinary(ByteRange((unsigned char*)&v4addr, 4));
471   } else {
472     in6_addr v6addr = AddressData::parseAddress6(param.address);
473     address = IPAddress::fromBinary(ByteRange((unsigned char*)&v6addr, 16));
474   }
475
476   ExpectIsValid(address);
477   EXPECT_EQ(IPAddress(param.address), address);
478 }
479
480 // Test addresses constructed using a string
481 TEST_P(IPAddressTest, CtorString) {
482   AddressData param = GetParam();
483   IPAddress address(param.address);
484
485   ExpectIsValid(address);
486
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);
496   }
497 }
498
499 TEST(IPAddress, CtorSockaddr) {
500   // test v4 address
501   {
502     // setup
503     sockaddr_in addr;
504     in_addr sin_addr;
505     sin_addr.s_addr = htonl(2122547223);
506     addr.sin_family = AF_INET;
507     addr.sin_addr = sin_addr;
508
509     IPAddress ipAddr((sockaddr*)&addr);
510     EXPECT_TRUE(ipAddr.isV4());
511     EXPECT_EQ("126.131.128.23", ipAddr.str());
512   }
513   // test v6 address
514   {
515     // setup
516     sockaddr_in6 addr;
517     memset(&addr, 0, sizeof(addr));
518     in6_addr sin_addr;
519     // 2620:0:1cfe:face:b00c::3
520     ByteArray16 sec{
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;
525
526     IPAddress ipAddr((sockaddr*)&addr);
527     EXPECT_TRUE(ipAddr.isV6());
528     EXPECT_EQ("2620:0:1cfe:face:b00c::3", ipAddr.str());
529   }
530   // test nullptr exception
531   {
532     sockaddr* addr = nullptr;
533     EXPECT_THROW(IPAddress((const sockaddr*)addr), IPAddressFormatException);
534   }
535   // test invalid family exception
536   {
537     // setup
538     sockaddr_in addr;
539     in_addr sin_addr;
540     sin_addr.s_addr = htonl(2122547223);
541     addr.sin_family = AF_UNSPEC;
542     addr.sin_addr = sin_addr;
543
544     EXPECT_THROW(IPAddress((sockaddr*)&addr), IPAddressFormatException);
545   }
546 }
547
548 TEST(IPAddress, ToSockaddrStorage) {
549   // test v4 address
550   {
551     string strAddr("126.131.128.23");
552     IPAddress addr(strAddr);
553     sockaddr_storage out;
554
555     ASSERT_TRUE(addr.isV4()); // test invariant
556     EXPECT_GT(addr.toSockaddrStorage(&out), 0);
557
558     IPAddress sockAddr((sockaddr*)&out);
559     ASSERT_TRUE(sockAddr.isV4());
560     EXPECT_EQ(strAddr, sockAddr.str());
561   }
562   // test v6 address
563   {
564     string strAddr("2620:0:1cfe:face:b00c::3");
565     IPAddress addr(strAddr);
566     sockaddr_storage out;
567
568     ASSERT_TRUE(addr.isV6()); // test invariant
569     EXPECT_GT(addr.toSockaddrStorage(&out), 0);
570
571     IPAddress sockAddr((sockaddr*)&out);
572     ASSERT_TRUE(sockAddr.isV6());
573     EXPECT_EQ(strAddr, sockAddr.str());
574   }
575   // test nullptr exception
576   {
577     sockaddr_storage* out = nullptr;
578     IPAddress addr("127.0.0.1");
579     EXPECT_THROW(addr.toSockaddrStorage(out), IPAddressFormatException);
580   }
581   // test invalid family exception
582   {
583     IPAddress addr;
584     sockaddr_storage out;
585     ASSERT_EQ(AF_UNSPEC, addr.family());
586     EXPECT_THROW(addr.toSockaddrStorage(&out), InvalidAddressFamilyException);
587   }
588 }
589
590 TEST_P(TryFromStringTest, IPAddress) {
591   auto param = GetParam();
592   auto maybeIp = IPAddress::tryFromString(param.in);
593   if (param.out) {
594     EXPECT_TRUE(maybeIp.hasValue());
595     EXPECT_EQ(param.out, maybeIp.value().str());
596   } else {
597     EXPECT_TRUE(maybeIp.hasError());
598     EXPECT_TRUE(
599         IPAddressFormatError::INVALID_IP == maybeIp.error() ||
600         IPAddressFormatError::UNSUPPORTED_ADDR_FAMILY == maybeIp.error());
601   }
602 }
603
604 TEST_P(TryFromStringTest, IPAddressV4) {
605   auto param = GetParam();
606   auto maybeIp = IPAddressV4::tryFromString(param.in);
607   if (param.out4) {
608     EXPECT_TRUE(maybeIp.hasValue());
609     EXPECT_EQ(param.out4, maybeIp.value().str());
610   } else {
611     EXPECT_TRUE(maybeIp.hasError());
612     EXPECT_EQ(IPAddressFormatError::INVALID_IP, maybeIp.error());
613   }
614 }
615
616 TEST_P(TryFromStringTest, IPAddressV6) {
617   auto param = GetParam();
618   auto maybeIp = IPAddressV6::tryFromString(param.in);
619   if (param.out6) {
620     EXPECT_TRUE(maybeIp.hasValue());
621     EXPECT_EQ(param.out6, maybeIp.value().str());
622   } else {
623     EXPECT_TRUE(maybeIp.hasError());
624     EXPECT_EQ(IPAddressFormatError::INVALID_IP, maybeIp.error());
625   }
626 }
627
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));
640
641   // Test a combination of all the above arguments
642   EXPECT_EQ(
643       "1:2::3 - 10.0.0.1 - ::1 - 10.1.2.3",
644       folly::to<string>(
645           addr_1_2_3,
646           " - ",
647           addr_10_0_0_1,
648           " - ",
649           addr_1,
650           " - ",
651           addr_10_1_2_3));
652 }
653
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");
658   EXPECT_EQ(
659       sformat(
660           "{}.ip6.arpa",
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());
663 }
664
665 TEST(IPaddress, fromInverseArpaName) {
666   EXPECT_EQ(
667       IPAddressV4("10.0.0.1"),
668       IPAddressV4::fromInverseArpaName("1.0.0.10.in-addr.arpa"));
669   EXPECT_EQ(
670       IPAddressV6("2620:0000:1cfe:face:b00c:0000:0000:0003"),
671       IPAddressV6::fromInverseArpaName(sformat(
672           "{}.ip6.arpa",
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")));
674 }
675
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";
682 }
683
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());
696 }
697
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");
704 }
705
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())
710       << ip;
711 }
712 TEST(IPAddress, ToFullyQualifiedLocal) {
713   IPAddress ip("::1");
714   EXPECT_EQ("0000:0000:0000:0000:0000:0000:0000:0001", ip.toFullyQualified())
715       << ip;
716 }
717 TEST(IPAddress, ToFullyQualifiedAppendV6) {
718   IPAddress ip("2620:0:1cfe:face:b00c::3");
719   std::string result;
720   ip.toFullyQualifiedAppend(result);
721   EXPECT_EQ("2620:0000:1cfe:face:b00c:0000:0000:0003", result) << ip;
722 }
723 TEST(IPAddress, ToFullyQualifiedAppendV4) {
724   IPAddress ip("127.0.0.1");
725   std::string result;
726   ip.toFullyQualifiedAppend(result);
727   EXPECT_EQ("127.0.0.1", result) << ip;
728 }
729 TEST(IPAddress, ToFullyQualifiedSizeV6) {
730   auto actual = IPAddressV6::kToFullyQualifiedSize;
731   auto expected = IPAddress("::").toFullyQualified().size();
732   EXPECT_EQ(expected, actual);
733 }
734 TEST(IPAddress, MaxToFullyQualifiedSizeV4) {
735   auto actual = IPAddressV4::kMaxToFullyQualifiedSize;
736   auto expected = IPAddress("255.255.255.255").toFullyQualified().size();
737   EXPECT_EQ(expected, actual);
738 }
739
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;
745
746   auto mapped = IPAddress(mappedIp);
747   auto expected = IPAddress(otherIp);
748
749   EXPECT_EQ(expected, mapped);
750
751   IPAddress v6addr;
752   if (mapped.isV4()) {
753     v6addr = mapped.asV4().createIPv6();
754   } else if (expected.isV4()) {
755     v6addr = expected.asV4().createIPv6();
756   }
757   EXPECT_TRUE(v6addr.isV6());
758   EXPECT_TRUE(mapped == v6addr);
759   EXPECT_TRUE(expected == v6addr);
760 }
761
762 // Test subnet mask calculations
763 TEST_P(IPAddressMaskTest, Masks) {
764   auto param = GetParam();
765
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) << " -> "
770       << param.subnet;
771 }
772
773 // Test inSubnet calculations
774 TEST_P(IPAddressMaskTest, InSubnet) {
775   auto param = GetParam();
776
777   IPAddress ip(param.address);
778   IPAddress subnet(param.subnet);
779   EXPECT_TRUE(ip.inSubnet(subnet, param.mask));
780 }
781
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));
788 }
789
790 TEST(IPAddress, UnitializedEqual) {
791   IPAddress addrEmpty;
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);
808 }
809
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));
815
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));
819
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));
823 }
824
825 static const vector<string> ipv4Strs = {
826     "127.0.0.1",
827     "198.168.0.1",
828     "8.8.0.0",
829 };
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);
839   }
840 }
841
842 static const vector<pair<string, uint8_t>> invalidMasks = {
843     {"127.0.0.1", 33},
844     {"::1", 129},
845 };
846 TEST(IPAddress, InvalidMask) {
847   for (auto& tc : invalidMasks) {
848     auto ip = IPAddress(tc.first);
849     EXPECT_THROW(ip.mask(tc.second), IPAddressFormatException);
850   }
851 }
852
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},
858 };
859 TEST(IPAddress, V6Types) {
860   auto mkName = [&](const IPAddressV6::Type t) -> string {
861     switch (t) {
862       case IPAddressV6::Type::TEREDO:
863         return "teredo";
864       case IPAddressV6::Type::T6TO4:
865         return "6to4";
866       default:
867         return "default";
868     }
869   };
870
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());
877     switch (tc.second) {
878       case IPAddressV6::Type::TEREDO:
879         EXPECT_TRUE(ipv6.isTeredo()) << "isTeredo was false";
880         EXPECT_FALSE(ipv6.is6To4()) << "is6To4 was true";
881         break;
882       case IPAddressV6::Type::T6TO4:
883         EXPECT_TRUE(ipv6.is6To4()) << "is6To4 was false";
884         EXPECT_FALSE(ipv6.isTeredo()) << "isTeredo was true";
885         break;
886       case IPAddressV6::Type::NORMAL:
887         EXPECT_FALSE(ipv6.is6To4()) << "is6To4 was true";
888         EXPECT_FALSE(ipv6.isTeredo()) << "isTeredo was true";
889         break;
890       default:
891         FAIL() << "Invalid expected type: " << to<std::string>(tc.second);
892     }
893   }
894 }
895
896 static const vector<pair<string, uint32_t>> provideToLong = {
897     {"0.0.0.0", 0},
898     {"10.0.0.0", 167772160},
899     {"126.131.128.23", 2122547223},
900     {"192.168.0.0", 3232235520},
901 };
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());
908
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());
913
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());
919   }
920 }
921
922 TEST(IPAddress, fromBinaryV4) {
923   for (auto& tc : provideToLong) {
924     SCOPED_TRACE(tc.first);
925     union {
926       uint8_t u8[4];
927       uint32_t u32;
928     } data;
929     data.u32 = Endian::big(tc.second);
930     ByteRange bytes(data.u8, 4);
931
932     auto fromBin = IPAddressV4::fromBinary(bytes);
933     IPAddressV4 fromStr(tc.first);
934     EXPECT_EQ(fromStr, fromBin);
935
936     IPAddressV4 addr2("0.0.0.0");
937     addr2 = IPAddressV4::fromBinary(bytes);
938     EXPECT_EQ(fromStr, addr2);
939
940     auto maybeAddr3 = IPAddressV4::tryFromBinary(bytes);
941     EXPECT_TRUE(maybeAddr3.hasValue());
942     EXPECT_EQ(fromStr, maybeAddr3.value());
943
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);
948   }
949
950   uint8_t data[20];
951   EXPECT_THROW(
952       IPAddressV4::fromBinary(ByteRange(data, 3)), IPAddressFormatException);
953   EXPECT_THROW(
954       IPAddressV4::fromBinary(ByteRange(data, 16)), IPAddressFormatException);
955   EXPECT_THROW(
956       IPAddressV4::fromBinary(ByteRange(data, 20)), IPAddressFormatException);
957 }
958
959 TEST(IPAddress, toBinaryV4) {
960   for (auto& tc : provideToLong) {
961     SCOPED_TRACE(tc.first);
962     union {
963       uint8_t u8[4];
964       uint32_t u32;
965     } data;
966     data.u32 = Endian::big(tc.second);
967     ByteRange bytes(data.u8, 4);
968
969     auto fromBin = IPAddressV4::fromBinary(bytes);
970     auto toBin = fromBin.toBinary();
971     EXPECT_EQ(bytes, toBin);
972   }
973 }
974
975 using ByteArray8 = std::array<uint8_t, 8>;
976
977 static auto join8 = [](std::array<ByteArray8, 2> parts) {
978   ByteArray16 _return;
979   std::memcpy(_return.data(), parts.data(), _return.size());
980   return _return;
981 };
982
983 static const vector<pair<string, ByteArray16>> provideBinary16Bytes = {
984     make_pair(
985         "::0",
986         join8({{
987             ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
988             ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
989         }})),
990     make_pair(
991         "1::2",
992         join8({{
993             ByteArray8{{0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
994             ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}},
995         }})),
996     make_pair(
997         "fe80::0012:34ff:fe56:78ab",
998         join8(
999             {{ByteArray8{{0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1000               ByteArray8{{0x00, 0x12, 0x34, 0xff, 0xfe, 0x56, 0x78, 0xab}}}})),
1001     make_pair(
1002         "2001:db8:1234:5678:90ab:cdef:8765:4321",
1003         join8({{
1004             ByteArray8{{0x20, 0x01, 0x0d, 0xb8, 0x12, 0x34, 0x56, 0x78}},
1005             ByteArray8{{0x90, 0xab, 0xcd, 0xef, 0x87, 0x65, 0x43, 0x21}},
1006         }})),
1007     make_pair(
1008         "::ffff:0:c0a8:1",
1009         join8({{
1010             ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1011             ByteArray8{{0xff, 0xff, 0x00, 0x00, 0xc0, 0xa8, 0x00, 0x01}},
1012         }})),
1013 };
1014
1015 TEST(IPAddress, fromBinaryV6) {
1016   for (auto& tc : provideBinary16Bytes) {
1017     SCOPED_TRACE(tc.first);
1018     ByteRange bytes(&tc.second.front(), tc.second.size());
1019
1020     auto fromBin = IPAddressV6::fromBinary(bytes);
1021     IPAddressV6 fromStr(tc.first);
1022     EXPECT_EQ(fromStr, fromBin);
1023
1024     IPAddressV6 addr2("::0");
1025     addr2 = IPAddressV6::fromBinary(bytes);
1026     EXPECT_EQ(fromStr, addr2);
1027
1028     auto maybeAddr3 = IPAddressV6::tryFromBinary(bytes);
1029     EXPECT_TRUE(maybeAddr3.hasValue());
1030     EXPECT_EQ(fromStr, maybeAddr3.value());
1031
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);
1036   }
1037
1038   uint8_t data[20];
1039   EXPECT_THROW(
1040       IPAddressV6::fromBinary(ByteRange(data, 3)), IPAddressFormatException);
1041   EXPECT_THROW(
1042       IPAddressV6::fromBinary(ByteRange(data, 4)), IPAddressFormatException);
1043   EXPECT_THROW(
1044       IPAddressV6::fromBinary(ByteRange(data, 20)), IPAddressFormatException);
1045 }
1046
1047 TEST(IPAddress, toBinaryV6) {
1048   for (auto& tc : provideBinary16Bytes) {
1049     SCOPED_TRACE(tc.first);
1050     ByteRange bytes(&tc.second.front(), tc.second.size());
1051
1052     auto fromBin = IPAddressV6::fromBinary(bytes);
1053     auto toBin = fromBin.toBinary();
1054     EXPECT_EQ(bytes, toBin);
1055   }
1056 }
1057
1058 TEST_P(IPAddressFlagTest, IsLoopback) {
1059   AddressFlags param = GetParam();
1060   IPAddress addr(param.address);
1061
1062   EXPECT_EQ(param.version, addr.version());
1063   EXPECT_EQ(param.isLoopback(), addr.isLoopback());
1064 }
1065
1066 TEST_P(IPAddressFlagTest, IsPrivate) {
1067   AddressFlags param = GetParam();
1068   IPAddress addr(param.address);
1069
1070   EXPECT_EQ(param.version, addr.version());
1071   EXPECT_EQ(param.isPrivate(), addr.isPrivate()) << addr;
1072 }
1073
1074 TEST_P(IPAddressFlagTest, IsNonroutable) {
1075   AddressFlags param = GetParam();
1076   IPAddress addr(param.address);
1077
1078   EXPECT_EQ(param.version, addr.version());
1079   EXPECT_EQ(param.isNonroutable(), addr.isNonroutable()) << addr;
1080 }
1081
1082 TEST_P(IPAddressFlagTest, IsZero) {
1083   AddressFlags param = GetParam();
1084   IPAddress addr(param.address);
1085
1086   EXPECT_EQ(param.version, addr.version());
1087   EXPECT_EQ(param.isZero(), addr.isZero()) << addr;
1088 }
1089
1090 TEST_P(IPAddressFlagTest, IsLinkLocal) {
1091   AddressFlags param = GetParam();
1092   IPAddress addr(param.address);
1093   EXPECT_EQ(param.isLinkLocal(), addr.isLinkLocal()) << addr;
1094 }
1095
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);
1099
1100   addr = IPAddressV6(IPAddressV6::LINK_LOCAL, MacAddress("02:00:00:12:34:56"));
1101   EXPECT_EQ(IPAddressV6("fe80::ff:fe12:3456"), addr);
1102 }
1103
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());
1109 }
1110
1111 TEST(IPAddress, SolicitedNodeAddress) {
1112   // An example from RFC 4291 section 2.7.1
1113   EXPECT_EQ(
1114       IPAddressV6("ff02::1:ff0e:8c6c"),
1115       IPAddressV6("4037::01:800:200e:8c6c").getSolicitedNodeAddress());
1116
1117   // An example from wikipedia
1118   // (http://en.wikipedia.org/wiki/Solicited-node_multicast_address)
1119   EXPECT_EQ(
1120       IPAddressV6("ff02::1:ff28:9c5a"),
1121       IPAddressV6("fe80::2aa:ff:fe28:9c5a").getSolicitedNodeAddress());
1122 }
1123
1124 TEST_P(IPAddressByteAccessorTest, CheckBytes) {
1125   auto addrData = GetParam();
1126   IPAddress ip(addrData.address);
1127   size_t i = 0;
1128   for (auto byitr = addrData.bytes.begin(); i < ip.byteCount(); ++i, ++byitr) {
1129     EXPECT_EQ(*byitr, ip.getNthMSByte(i));
1130     EXPECT_EQ(
1131         *byitr,
1132         ip.isV4() ? ip.asV4().getNthMSByte(i) : ip.asV6().getNthMSByte(i));
1133   }
1134   i = 0;
1135   for (auto byritr = addrData.bytes.rbegin(); i < ip.byteCount();
1136        ++i, ++byritr) {
1137     EXPECT_EQ(*byritr, ip.getNthLSByte(i));
1138     EXPECT_EQ(
1139         *byritr,
1140         ip.isV4() ? ip.asV4().getNthLSByte(i) : ip.asV6().getNthLSByte(i));
1141   }
1142 }
1143
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));
1156     EXPECT_EQ(
1157         *bitr,
1158         ip.isV4() ? ip.asV4().getNthMSBit(msbIndex)
1159                   : ip.asV6().getNthMSBit(msbIndex));
1160     EXPECT_EQ(*bitr, ip.getNthLSBit(i));
1161     EXPECT_EQ(
1162         *bitr, ip.isV4() ? ip.asV4().getNthLSBit(i) : ip.asV6().getNthLSBit(i));
1163     ++bitr;
1164   }
1165 }
1166
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);
1179
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);
1190 }
1191
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);
1204
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);
1215 }
1216
1217 TEST(IPAddress, StringFormat) {
1218   in6_addr a6;
1219   for (int i = 0; i < 8; ++i) {
1220     auto t = htons(0x0123 + ((i % 4) * 0x4444));
1221 #ifdef _WIN32
1222     a6.u.Word[i] = t;
1223 #else
1224     a6.s6_addr16[i] = t;
1225 #endif
1226   }
1227   EXPECT_EQ(
1228       "0123:4567:89ab:cdef:0123:4567:89ab:cdef", detail::fastIpv6ToString(a6));
1229
1230   in_addr a4;
1231   a4.s_addr = htonl(0x01020304);
1232   EXPECT_EQ("1.2.3.4", detail::fastIpv4ToString(a4));
1233 }
1234
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());
1239 }
1240
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());
1250 }
1251
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());
1259 }
1260
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());
1264 }
1265
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});
1273   auto prefix4 =
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);
1280
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);
1289
1290   prefix = IPAddress::longestCommonPrefix({ip11, 8}, {ip12, 8});
1291   prefix4 =
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);
1298
1299   // Between 128/1 and 128/2, longest match 128/1
1300   prefix = IPAddress::longestCommonPrefix({ip128, 1}, {ip128, 2});
1301   prefix4 =
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);
1307
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);
1319
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);
1327
1328   // Exceptional cases
1329   EXPECT_THROW(
1330       IPAddress::longestCommonPrefix({ip10, 8}, {ip6, 128}),
1331       std::invalid_argument);
1332   EXPECT_THROW(
1333       IPAddress::longestCommonPrefix({ip10, ip10.bitCount() + 1}, {ip10, 8}),
1334       std::invalid_argument);
1335   EXPECT_THROW(
1336       IPAddressV4::longestCommonPrefix(
1337           {ip10.asV4(), IPAddressV4::bitCount() + 1}, {ip10.asV4(), 8}),
1338       std::invalid_argument);
1339   EXPECT_THROW(
1340       IPAddress::longestCommonPrefix(
1341           {ip6, ip6.bitCount() + 1}, {ip6, ip6.bitCount()}),
1342       std::invalid_argument);
1343   EXPECT_THROW(
1344       IPAddressV6::longestCommonPrefix(
1345           {ip6.asV6(), IPAddressV6::bitCount() + 1},
1346           {ip6.asV6(), IPAddressV6::bitCount()}),
1347       std::invalid_argument);
1348 }
1349
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),
1355     AddressData(
1356         "2620:0:1cfe:face:b00c::3",
1357         {38, 32, 0, 0, 28, 254, 250, 206, 176, 12, 0, 0, 0, 0, 0, 3},
1358         6),
1359 };
1360
1361 static const vector<string> invalidAddressProvider = {
1362     "",
1363     "foo",
1364     "1.1.1.256",
1365     "1",
1366     ":1",
1367     "127.0.0.1,127.0.0.1",
1368     "[1234]",
1369 };
1370
1371 static const vector<ByteVector> invalidBinaryProvider = {
1372     {0x31, 0x32, 0x37, 0x2e, 0x30, 0x30, 0x2e, 0x30, 0x2e, 0x31},
1373     // foo
1374     {0x66, 0x6f, 0x6f},
1375     {0x00},
1376     {0x00, 0x00},
1377     {0x00, 0x00, 0x00},
1378     {0x00, 0x00, 0x00, 0x00, 0x00},
1379     {0xff},
1380 };
1381
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;
1392
1393 static vector<AddressFlags> flagProvider = {
1394     // public v4
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),
1401
1402     // public v6
1403     AddressFlags("2620:0:1cfe:face:b00c::3", 6, 0),
1404
1405     // localhost
1406     AddressFlags("127.0.0.1", 4, IS_LOCAL | IS_PVT_NONROUTE),
1407     AddressFlags("::1", 6, IS_LOCAL | IS_PVT_NONROUTE),
1408
1409     // link-local v4
1410     AddressFlags("169.254.0.1", 4, IS_LINK_LOCAL | IS_PVT_NONROUTE),
1411
1412     // private v4
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),
1422
1423     // private v6
1424     AddressFlags("fd01:1637:1c56:66af::", 6, IS_PVT_NONROUTE),
1425
1426     // non routable v4
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
1441     AddressFlags(
1442         "255.255.255.255",
1443         4,
1444         IS_NONROUTABLE | IS_LINK_LOCAL_BROADCAST),
1445
1446     // non routable v6
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),
1451
1452     // link-local v6
1453     AddressFlags("fe80::0205:73ff:fef9:46fc", 6, IS_LINK_LOCAL),
1454     AddressFlags("fe80::0012:34ff:fe56:7890", 6, IS_LINK_LOCAL),
1455
1456     // multicast v4
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),
1460
1461     // multicast v6
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),
1468 };
1469
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"},
1477 };
1478
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, "::"),
1521 };
1522
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),
1531 };
1532
1533 INSTANTIATE_TEST_CASE_P(
1534     IPAddress,
1535     IPAddressTest,
1536     ::testing::ValuesIn(validAddressProvider));
1537 INSTANTIATE_TEST_CASE_P(
1538     IPAddress,
1539     IPAddressFlagTest,
1540     ::testing::ValuesIn(flagProvider));
1541 INSTANTIATE_TEST_CASE_P(
1542     IPAddress,
1543     IPAddressMappedTest,
1544     ::testing::ValuesIn(mapProvider));
1545 INSTANTIATE_TEST_CASE_P(
1546     IPAddress,
1547     IPAddressCtorTest,
1548     ::testing::ValuesIn(invalidAddressProvider));
1549 INSTANTIATE_TEST_CASE_P(
1550     IPAddress,
1551     IPAddressCtorBinaryTest,
1552     ::testing::ValuesIn(invalidBinaryProvider));
1553 INSTANTIATE_TEST_CASE_P(
1554     IPAddress,
1555     IPAddressMaskTest,
1556     ::testing::ValuesIn(masksProvider));
1557 INSTANTIATE_TEST_CASE_P(
1558     IPAddress,
1559     IPAddressMaskBoundaryTest,
1560     ::testing::ValuesIn(maskBoundaryProvider));
1561 INSTANTIATE_TEST_CASE_P(
1562     IPAddress,
1563     IPAddressByteAccessorTest,
1564     ::testing::ValuesIn(validAddressProvider));
1565 INSTANTIATE_TEST_CASE_P(
1566     IPAddress,
1567     IPAddressBitAccessorTest,
1568     ::testing::ValuesIn(validAddressProvider));
1569 INSTANTIATE_TEST_CASE_P(
1570     IPAddress,
1571     TryFromStringTest,
1572     ::testing::ValuesIn(TryFromStringTest::ipInOutProvider()));
1573
1574 TEST(IPAddressV4, fetchMask) {
1575   struct X : private IPAddressV4 {
1576     using IPAddressV4::fetchMask;
1577   };
1578
1579   EXPECT_THAT(
1580       X::fetchMask(0),
1581       ::testing::ElementsAreArray(ByteArray4{{0x00, 0x00, 0x00, 0x00}}));
1582
1583   EXPECT_THAT(
1584       X::fetchMask(1),
1585       ::testing::ElementsAreArray(ByteArray4{{0x80, 0x00, 0x00, 0x00}}));
1586
1587   EXPECT_THAT(
1588       X::fetchMask(31),
1589       ::testing::ElementsAreArray(ByteArray4{{0xff, 0xff, 0xff, 0xfe}}));
1590
1591   EXPECT_THAT(
1592       X::fetchMask(32),
1593       ::testing::ElementsAreArray(ByteArray4{{0xff, 0xff, 0xff, 0xff}}));
1594 }
1595
1596 TEST(IPAddressV6, fetchMask) {
1597   struct X : private IPAddressV6 {
1598     using IPAddressV6::fetchMask;
1599   };
1600
1601   EXPECT_THAT(
1602       X::fetchMask(0),
1603       ::testing::ElementsAreArray(join8({{
1604           ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1605           ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1606       }})));
1607
1608   EXPECT_THAT(
1609       X::fetchMask(1),
1610       ::testing::ElementsAreArray(join8({{
1611           ByteArray8{{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1612           ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1613       }})));
1614
1615   EXPECT_THAT(
1616       X::fetchMask(63),
1617       ::testing::ElementsAreArray(join8({{
1618           ByteArray8{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}},
1619           ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1620       }})));
1621
1622   EXPECT_THAT(
1623       X::fetchMask(64),
1624       ::testing::ElementsAreArray(join8({{
1625           ByteArray8{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
1626           ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1627       }})));
1628
1629   EXPECT_THAT(
1630       X::fetchMask(65),
1631       ::testing::ElementsAreArray(join8({{
1632           ByteArray8{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
1633           ByteArray8{{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1634       }})));
1635
1636   EXPECT_THAT(
1637       X::fetchMask(127),
1638       ::testing::ElementsAreArray(join8({{
1639           ByteArray8{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
1640           ByteArray8{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}},
1641       }})));
1642
1643   EXPECT_THAT(
1644       X::fetchMask(128),
1645       ::testing::ElementsAreArray(join8({{
1646           ByteArray8{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
1647           ByteArray8{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
1648       }})));
1649 }