memcpy(&addr_.inAddr_.s_addr, bytes.data(), sizeof(in_addr));
}
+// static
+IPAddressV4 IPAddressV4::fromInverseArpaName(const std::string& arpaname) {
+ auto piece = StringPiece(arpaname);
+ // input must be something like 1.0.168.192.in-addr.arpa
+ if (!piece.removeSuffix(".in-addr.arpa")) {
+ throw IPAddressFormatException(
+ sformat("input does not end with '.in-addr.arpa': '{}'", arpaname));
+ }
+ std::vector<StringPiece> pieces;
+ split(".", piece, pieces);
+ if (pieces.size() != 4) {
+ throw IPAddressFormatException(sformat("Invalid input. Got {}", piece));
+ }
+ // reverse 1.0.168.192 -> 192.168.0.1
+ return IPAddressV4(join(".", pieces.rbegin(), pieces.rend()));
+}
+
// public
IPAddressV6 IPAddressV4::createIPv6() const {
ByteArray16 ba{};
return ByteRange((const unsigned char *) &addr_.inAddr_.s_addr, 4);
}
+ /**
+ * Create a new IPAddress instance from the in-addr.arpa representation.
+ * @throws IPAddressFormatException if the input is not a valid in-addr.arpa
+ * representation
+ */
+ static IPAddressV4 fromInverseArpaName(const std::string& arpaname);
+
/**
* Convert a IPv4 address string to a long in network byte order.
* @param [in] ip the address to convert
scope_ = 0;
}
+// static
+IPAddressV6 IPAddressV6::fromInverseArpaName(const std::string& arpaname) {
+ auto piece = StringPiece(arpaname);
+ if (!piece.removeSuffix(".ip6.arpa")) {
+ throw IPAddressFormatException(sformat(
+ "Invalid input. Should end with 'ip6.arpa'. Got '{}'", arpaname));
+ }
+ std::vector<StringPiece> pieces;
+ split(".", piece, pieces);
+ if (pieces.size() != 32) {
+ throw IPAddressFormatException(sformat("Invalid input. Got '{}'", piece));
+ }
+ std::array<char, IPAddressV6::kToFullyQualifiedSize> ip;
+ int pos = 0;
+ int count = 0;
+ for (int p = pieces.size() - 1; p >= 0; p--) {
+ ip[pos] = pieces[p][0];
+ pos++;
+ count++;
+ // add ':' every 4 chars
+ if (count == 4) {
+ ip[pos++] = ':';
+ count = 0;
+ }
+ }
+ return IPAddressV6(folly::range(ip));
+}
+
// public
IPAddressV4 IPAddressV6::createIPv4() const {
if (!isIPv4Mapped()) {
return addr;
}
+ /**
+ * Create a new IPAddress instance from the ip6.arpa representation.
+ * @throws IPAddressFormatException if the input is not a valid ip6.arpa
+ * representation
+ */
+ static IPAddressV6 fromInverseArpaName(const std::string& arpaname);
+
/**
* Returns the address as a Range.
*/
addr_ipv6.toInverseArpaName());
}
+TEST(IPaddress, fromInverseArpaName) {
+ EXPECT_EQ(
+ IPAddressV4("10.0.0.1"),
+ IPAddressV4::fromInverseArpaName("1.0.0.10.in-addr.arpa"));
+ EXPECT_EQ(
+ IPAddressV6("2620:0000:1cfe:face:b00c:0000:0000:0003"),
+ IPAddressV6::fromInverseArpaName(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")));
+}
+
// Test that invalid string values are killed
TEST_P(IPAddressCtorTest, InvalidCreation) {
string addr = GetParam();