]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
common/ipaddr: add network_contains() helper
authorSage Weil <sage@redhat.com>
Thu, 9 Aug 2018 18:20:07 +0000 (13:20 -0500)
committerSage Weil <sage@redhat.com>
Sun, 12 Aug 2018 22:01:05 +0000 (17:01 -0500)
Signed-off-by: Sage Weil <sage@redhat.com>
src/common/ipaddr.cc
src/include/ipaddr.h
src/test/test_ipaddr.cc

index 3d03aef6b54cc33aba0b96ba32b104e727f44546..7e4112fbe56731de2b26a69cd833436690f82558 100644 (file)
@@ -178,3 +178,40 @@ bool parse_network(const char *s,
   }
   return ret;
 }
+
+bool network_contains(
+  const struct entity_addr_t& network,
+  unsigned int prefix_len,
+  const struct entity_addr_t& addr)
+{
+  if (addr.get_family() != network.get_family()) {
+    return false;
+  }
+  switch (network.get_family()) {
+  case AF_INET:
+    {
+      struct in_addr a, b;
+      netmask_ipv4(
+       &((const sockaddr_in*)network.get_sockaddr())->sin_addr, prefix_len, &a);
+      netmask_ipv4(
+       &((const sockaddr_in*)addr.get_sockaddr())->sin_addr, prefix_len, &b);
+      if (memcmp(&a, &b, sizeof(a)) == 0) {
+       return true;
+      }
+    }
+    break;
+  case AF_INET6:
+    {
+      struct in6_addr a, b;
+      netmask_ipv6(
+       &((const sockaddr_in6*)network.get_sockaddr())->sin6_addr, prefix_len, &a);
+      netmask_ipv6(
+       &((const sockaddr_in6*)addr.get_sockaddr())->sin6_addr, prefix_len, &b);
+      if (memcmp(&a, &b, sizeof(a)) == 0) {
+       return true;
+      }
+    }
+    break;
+  }
+  return false;
+}
index 3ec822534f0d439500fec91c59bb5a0fd9cf4137..2f72f40ef4b8dcea597de50a6713a31e91fe9dd3 100644 (file)
@@ -38,4 +38,10 @@ void netmask_ipv6(const struct in6_addr *addr,
 void netmask_ipv4(const struct in_addr *addr,
                  unsigned int prefix_len,
                  struct in_addr *out);
+
+bool network_contains(
+       const struct entity_addr_t& network,
+       unsigned int prefix_len,
+       const struct entity_addr_t& addr);
+
 #endif
index ffd7b7911350af068c4efcf6a1e6d3dc277e0440..e8e61c17ff033318513356a7922275ac6c925bd7 100644 (file)
@@ -542,6 +542,42 @@ TEST(CommonIPAddr, ParseNetwork_IPv6_9000)
   ASSERT_EQ(0, memcmp(want.sin6_addr.s6_addr, network.sin6_addr.s6_addr, sizeof(network.sin6_addr.s6_addr)));
 }
 
+TEST(CommonIPAddr, network_contains)
+{
+  entity_addr_t network, addr;
+  unsigned int prefix;
+  bool ok;
+
+  ok = parse_network("2001:1234:5678:90ab::dead:beef/32", &network, &prefix);
+  ASSERT_TRUE(ok);
+  ASSERT_EQ(32U, prefix);
+  ok = addr.parse("2001:1234:5678:90ab::dead:beef", nullptr);
+  ASSERT_TRUE(ok);
+  ASSERT_TRUE(network_contains(network, prefix, addr));
+  ok = addr.parse("2001:1334:5678:90ab::dead:beef", nullptr);
+  ASSERT_TRUE(ok);
+  ASSERT_FALSE(network_contains(network, prefix, addr));
+  ok = addr.parse("127.0.0.1", nullptr);
+  ASSERT_TRUE(ok);
+  ASSERT_FALSE(network_contains(network, prefix, addr));
+
+  ok = parse_network("10.1.2.3/16", &network, &prefix);
+  ASSERT_TRUE(ok);
+  ASSERT_EQ(16U, prefix);
+  ok = addr.parse("2001:1234:5678:90ab::dead:beef", nullptr);
+  ASSERT_TRUE(ok);
+  ASSERT_FALSE(network_contains(network, prefix, addr));
+  ok = addr.parse("1.2.3.4", nullptr);
+  ASSERT_TRUE(ok);
+  ASSERT_FALSE(network_contains(network, prefix, addr));
+  ok = addr.parse("10.1.22.44", nullptr);
+  ASSERT_TRUE(ok);
+  ASSERT_TRUE(network_contains(network, prefix, addr));
+  ok = addr.parse("10.2.22.44", nullptr);
+  ASSERT_TRUE(ok);
+  ASSERT_FALSE(network_contains(network, prefix, addr));
+}
+
 TEST(pick_address, find_ip_in_subnet_list)
 {
   struct ifaddrs one, two, three;