summaryrefslogtreecommitdiffstats
path: root/net/base
diff options
context:
space:
mode:
Diffstat (limited to 'net/base')
-rw-r--r--net/base/net_util.cc34
-rw-r--r--net/base/net_util.h8
-rw-r--r--net/base/net_util_unittest.cc28
3 files changed, 70 insertions, 0 deletions
diff --git a/net/base/net_util.cc b/net/base/net_util.cc
index a850eb8..959ee29 100644
--- a/net/base/net_util.cc
+++ b/net/base/net_util.cc
@@ -2111,6 +2111,40 @@ int GetPortFromSockaddr(const struct sockaddr* address, socklen_t address_len) {
return ntohs(*port_field);
}
+bool IsLocalhost(const std::string& host) {
+ if (host == "localhost" ||
+ host == "localhost.localdomain" ||
+ host == "localhost6" ||
+ host == "localhost6.localdomain6")
+ return true;
+
+ IPAddressNumber ip_number;
+ if (ParseIPLiteralToNumber(host, &ip_number)) {
+ size_t size = ip_number.size();
+ switch (size) {
+ case kIPv4AddressSize: {
+ IPAddressNumber localhost_prefix;
+ localhost_prefix.push_back(127);
+ for (int i = 0; i < 3; ++i) {
+ localhost_prefix.push_back(0);
+ }
+ return IPNumberMatchesPrefix(ip_number, localhost_prefix, 8);
+ }
+
+ case kIPv6AddressSize: {
+ struct in6_addr sin6_addr;
+ memcpy(&sin6_addr, &ip_number[0], kIPv6AddressSize);
+ return IN6_IS_ADDR_LOOPBACK(&sin6_addr) != FALSE;
+ }
+
+ default:
+ NOTREACHED();
+ }
+ }
+
+ return false;
+}
+
NetworkInterface::NetworkInterface() {
}
diff --git a/net/base/net_util.h b/net/base/net_util.h
index 4e1d07e..bae27c3 100644
--- a/net/base/net_util.h
+++ b/net/base/net_util.h
@@ -427,6 +427,14 @@ const uint16* GetPortFieldFromSockaddr(const struct sockaddr* address,
int GetPortFromSockaddr(const struct sockaddr* address,
socklen_t address_len);
+// Returns true if |host| is one of the names (e.g. "localhost") or IP
+// addresses (IPv4 127.0.0.0/8 or IPv6 ::1) that indicate a loopback.
+//
+// Note that this function does not check for IP addresses other than
+// the above, although other IP addresses may point to the local
+// machine.
+bool IsLocalhost(const std::string& host);
+
// struct that is used by GetNetworkList() to represent a network
// interface.
struct NetworkInterface {
diff --git a/net/base/net_util_unittest.cc b/net/base/net_util_unittest.cc
index 9f15bc5..292d416 100644
--- a/net/base/net_util_unittest.cc
+++ b/net/base/net_util_unittest.cc
@@ -2166,6 +2166,34 @@ TEST(NetUtilTest, IPNumberMatchesPrefix) {
}
}
+TEST(NetUtilTest, IsLocalhost) {
+ EXPECT_TRUE(net::IsLocalhost("localhost"));
+ EXPECT_TRUE(net::IsLocalhost("localhost.localdomain"));
+ EXPECT_TRUE(net::IsLocalhost("localhost6"));
+ EXPECT_TRUE(net::IsLocalhost("localhost6.localdomain6"));
+ EXPECT_TRUE(net::IsLocalhost("127.0.0.1"));
+ EXPECT_TRUE(net::IsLocalhost("127.0.1.0"));
+ EXPECT_TRUE(net::IsLocalhost("127.1.0.0"));
+ EXPECT_TRUE(net::IsLocalhost("127.0.0.255"));
+ EXPECT_TRUE(net::IsLocalhost("127.0.255.0"));
+ EXPECT_TRUE(net::IsLocalhost("127.255.0.0"));
+ EXPECT_TRUE(net::IsLocalhost("::1"));
+ EXPECT_TRUE(net::IsLocalhost("0:0:0:0:0:0:0:1"));
+
+ EXPECT_FALSE(net::IsLocalhost("localhostx"));
+ EXPECT_FALSE(net::IsLocalhost("foo.localdomain"));
+ EXPECT_FALSE(net::IsLocalhost("localhost6x"));
+ EXPECT_FALSE(net::IsLocalhost("localhost.localdomain6"));
+ EXPECT_FALSE(net::IsLocalhost("localhost6.localdomain"));
+ EXPECT_FALSE(net::IsLocalhost("127.0.0.1.1"));
+ EXPECT_FALSE(net::IsLocalhost(".127.0.0.255"));
+ EXPECT_FALSE(net::IsLocalhost("::2"));
+ EXPECT_FALSE(net::IsLocalhost("::1:1"));
+ EXPECT_FALSE(net::IsLocalhost("0:0:0:0:1:0:0:1"));
+ EXPECT_FALSE(net::IsLocalhost("::1:1"));
+ EXPECT_FALSE(net::IsLocalhost("0:0:0:0:0:0:0:0:1"));
+}
+
// Verify GetNetworkList().
TEST(NetUtilTest, GetNetworkList) {
NetworkInterfaceList list;