/*
- * Copyright 2015 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <folly/test/IPAddressTest.h>
-#include <gtest/gtest.h>
-
#include <folly/Bits.h>
#include <folly/Format.h>
-#include <folly/String.h>
#include <folly/MacAddress.h>
+#include <folly/String.h>
+#include <folly/detail/IPAddressSource.h>
+#include <folly/portability/GTest.h>
using namespace folly;
using namespace std;
EXPECT_EQ(IPAddressV6("::0"), v6);
}
+TEST(IPAddressV4, validate) {
+ EXPECT_TRUE(IPAddressV4::validate("0.0.0.0"));
+ EXPECT_FALSE(IPAddressV4::validate("0.0.0."));
+ EXPECT_TRUE(IPAddressV4::validate("127.127.127.127"));
+}
+
+TEST(IPAddressV6, validate) {
+ EXPECT_TRUE(IPAddressV6::validate("2620:0:1cfe:face:b00c::3"));
+ EXPECT_FALSE(IPAddressV6::validate("0.0.0.0"));
+ EXPECT_TRUE(IPAddressV6::validate("[2620:0:1cfe:face:b00c::3]"));
+ EXPECT_TRUE(IPAddressV6::validate("::ffff:0.1.1.1"));
+ EXPECT_TRUE(IPAddressV6::validate("2620:0000:1cfe:face:b00c:0000:0000:0003"));
+ EXPECT_TRUE(
+ IPAddressV6::validate("2620:0000:1cfe:face:b00c:0000:127.127.127.127"));
+}
+
+TEST(IPAddress, validate) {
+ EXPECT_TRUE(IPAddress::validate("0.0.0.0"));
+ EXPECT_TRUE(IPAddress::validate("::"));
+ EXPECT_FALSE(IPAddress::validate("asdf"));
+}
+
// Test addresses constructed using a in[6]_addr value
TEST_P(IPAddressTest, CtorAddress) {
AddressData param = GetParam();
" - ", addr_1, " - ", addr_10_1_2_3));
}
+TEST(IPaddress, toInverseArpaName) {
+ IPAddressV4 addr_ipv4("10.0.0.1");
+ EXPECT_EQ("1.0.0.10.in-addr.arpa", addr_ipv4.toInverseArpaName());
+ IPAddressV6 addr_ipv6("2620:0000:1cfe:face:b00c:0000:0000:0003");
+ EXPECT_EQ(
+ sformat(
+ "{}.ip6.arpa",
+ "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"),
+ addr_ipv6.toInverseArpaName());
+}
+
// Test that invalid string values are killed
TEST_P(IPAddressCtorTest, InvalidCreation) {
string addr = GetParam();
IPAddressFormatException);
}
+TEST(IPAddressSource, ToHex) {
+ vector<std::uint8_t> data = {{0xff, 0x20, 0x45}};
+ EXPECT_EQ(detail::Bytes::toHex(data.data(), 0), "");
+ EXPECT_EQ(detail::Bytes::toHex(data.data(), 1), "ff");
+ EXPECT_EQ(detail::Bytes::toHex(data.data(), 2), "ff20");
+ EXPECT_EQ(detail::Bytes::toHex(data.data(), 3), "ff2045");
+}
+
// Test toFullyQualified()
TEST(IPAddress, ToFullyQualifiedFb) {
IPAddress ip("2620:0:1cfe:face:b00c::3");
IPAddress ip(param.address);
IPAddress masked = ip.mask(param.mask);
EXPECT_EQ(param.subnet, masked.str())
- << param.address << "/" << to_string(param.mask)
- << " -> " << param.subnet;
+ << param.address << "/" << folly::to<std::string>(param.mask) << " -> "
+ << param.subnet;
}
// Test inSubnet calculations
EXPECT_TRUE(ip3.inSubnet(subnet3, 16));
}
-static vector<pair<string, uint8_t> > invalidMasks = {
+static const vector<string> ipv4Strs = {
+ "127.0.0.1",
+ "198.168.0.1",
+ "8.8.0.0",
+};
+TEST(IPAddress, getIPv6For6To4) {
+ for (auto ipv4Str : ipv4Strs) {
+ auto ip = IPAddress(ipv4Str);
+ EXPECT_TRUE(ip.isV4());
+ IPAddressV4 ipv4 = ip.asV4();
+ auto ipv6 = ipv4.getIPv6For6To4();
+ EXPECT_EQ(ipv6.type(), IPAddressV6::Type::T6TO4);
+ auto ipv4New = ipv6.getIPv4For6To4();
+ EXPECT_TRUE(ipv4Str.compare(ipv4New.str()) == 0);
+ }
+}
+
+static const vector<pair<string, uint8_t> > invalidMasks = {
{"127.0.0.1", 33},
{"::1", 129},
};
TEST(IPAddress, InvalidMask) {
for (auto& tc : invalidMasks) {
- uint8_t mask = tc.second;
auto ip = IPAddress(tc.first);
EXPECT_THROW(ip.mask(tc.second), IPAddressFormatException);
}
}
-static vector<pair<string, IPAddressV6::Type> > v6types = {
+static const vector<pair<string, IPAddressV6::Type> > v6types = {
{"::1", IPAddressV6::Type::NORMAL},
{"2620:0:1cfe:face:b00c::3", IPAddressV6::Type::NORMAL},
{"2001:0000:4136:e378:8000:63bf:3fff:fdd2", IPAddressV6::Type::TEREDO},
break;
default:
throw std::range_error("Invalid expected type: " +
- to_string(tc.second));
+ folly::to<std::string>(tc.second));
}
}
}
-static vector<pair<string, uint32_t> > provideToLong = {
+static const vector<pair<string, uint32_t> > provideToLong = {
{"0.0.0.0", 0},
{"10.0.0.0", 167772160},
{"126.131.128.23", 2122547223},
IPAddressFormatException);
}
-static vector<pair<string, vector<uint8_t> > > provideBinary16Bytes = {
+TEST(IPAddress, toBinaryV4) {
+ for (auto& tc : provideToLong) {
+ SCOPED_TRACE(tc.first);
+ union {
+ uint8_t u8[4];
+ uint32_t u32;
+ } data;
+ data.u32 = Endian::big(tc.second);
+ ByteRange bytes(data.u8, 4);
+
+ auto fromBin = IPAddressV4::fromBinary(bytes);
+ auto toBin = fromBin.toBinary();
+ EXPECT_EQ(bytes, toBin);
+ }
+}
+
+static const vector<pair<string, vector<uint8_t> > > provideBinary16Bytes = {
{"::0",
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
IPAddressFormatException);
}
+TEST(IPAddress, toBinaryV6) {
+ for (auto& tc : provideBinary16Bytes) {
+ SCOPED_TRACE(tc.first);
+ ByteRange bytes(&tc.second.front(), tc.second.size());
+
+ auto fromBin = IPAddressV6::fromBinary(bytes);
+ auto toBin = fromBin.toBinary();
+ EXPECT_EQ(bytes, toBin);
+ }
+}
+
TEST_P(IPAddressFlagTest, IsLoopback) {
AddressFlags param = GetParam();
IPAddress addr(param.address);
EXPECT_THROW(asV6.getNthLSBit(-1), std::invalid_argument);
}
+TEST(IPAddress, StringFormat) {
+ in6_addr a6;
+ for (int i = 0; i < 8; ++i) {
+ auto t = htons(0x0123 + ((i % 4) * 0x4444));
+#ifdef _WIN32
+ a6.u.Word[i] = t;
+#else
+ a6.s6_addr16[i] = t;
+#endif
+ }
+ EXPECT_EQ("0123:4567:89ab:cdef:0123:4567:89ab:cdef",
+ detail::fastIpv6ToString(a6));
+
+ in_addr a4;
+ a4.s_addr = htonl(0x01020304);
+ EXPECT_EQ("1.2.3.4", detail::fastIpv4ToString(a4));
+}
+
+TEST(IPAddress, getMacAddressFromLinkLocal) {
+ IPAddressV6 ip6("fe80::f652:14ff:fec5:74d8");
+ EXPECT_TRUE(ip6.getMacAddressFromLinkLocal().hasValue());
+ EXPECT_EQ("f4:52:14:c5:74:d8", ip6.getMacAddressFromLinkLocal()->toString());
+}
+
+TEST(IPAddress, getMacAddressFromLinkLocal_Negative) {
+ IPAddressV6 no_link_local_ip6("2803:6082:a2:4447::1");
+ EXPECT_FALSE(no_link_local_ip6.getMacAddressFromLinkLocal().hasValue());
+ no_link_local_ip6 = IPAddressV6("fe80::f652:14ff:ccc5:74d8");
+ EXPECT_FALSE(no_link_local_ip6.getMacAddressFromLinkLocal().hasValue());
+ no_link_local_ip6 = IPAddressV6("fe80::f652:14ff:ffc5:74d8");
+ EXPECT_FALSE(no_link_local_ip6.getMacAddressFromLinkLocal().hasValue());
+ no_link_local_ip6 = IPAddressV6("fe81::f652:14ff:ffc5:74d8");
+ EXPECT_FALSE(no_link_local_ip6.getMacAddressFromLinkLocal().hasValue());
+}
+
TEST(IPAddress, LongestCommonPrefix) {
IPAddress ip10("10.0.0.0");
IPAddress ip11("11.0.0.0");
}
-static vector<AddressData> validAddressProvider = {
+static const vector<AddressData> validAddressProvider = {
AddressData("127.0.0.1", {127,0,0,1}, 4),
AddressData("69.63.189.16", {69,63,189,16}, 4),
AddressData("0.0.0.0", {0,0,0,0}, 4),
{38,32,0,0,28,254,250,206,176,12,0,0,0,0,0,3}, 6),
};
-static vector<string> invalidAddressProvider = {
+static const vector<string> invalidAddressProvider = {
"",
"foo",
"1.1.1.256",
"[1234]",
};
-static vector<ByteVector> invalidBinaryProvider = {
+static const vector<ByteVector> invalidBinaryProvider = {
{0x31, 0x32, 0x37, 0x2e, 0x30, 0x30, 0x2e, 0x30, 0x2e, 0x31},
// foo
{0x66, 0x6f, 0x6f},
AddressFlags("ff02::1", 6, IS_NONROUTABLE | IS_LINK_LOCAL_BROADCAST),
};
-static vector<pair<string, string> > mapProvider = {
+static const vector<pair<string, string> > mapProvider = {
{"::ffff:192.0.2.128", "192.0.2.128"},
{"192.0.2.128", "::ffff:192.0.2.128"},
{"::FFFF:129.144.52.38", "129.144.52.38"},
{"::FFFF:222.1.41.90", "222.1.41.90"},
};
-static vector<MaskData> masksProvider = {
+static const vector<MaskData> masksProvider = {
MaskData("255.255.255.255", 1, "128.0.0.0"),
MaskData("255.255.255.255", 2, "192.0.0.0"),
MaskData("192.0.2.42", 16, "192.0.0.0"),
MaskData("2620:0:1cfe:face:b00c::3", 0, "::")
};
-static vector<MaskBoundaryData> maskBoundaryProvider = {
+static const vector<MaskBoundaryData> maskBoundaryProvider = {
MaskBoundaryData("10.1.1.1", 24, "10.1.1.1", true),
MaskBoundaryData("10.1.1.1", 8, "10.1.2.3", true),
MaskBoundaryData("2620:0:1cfe:face:b00c::1", 48, "2620:0:1cfe::", true),