summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2016-06-03 22:07:42 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2016-06-07 11:20:09 +0200
commitae763642d885dc8d8edc3890a2087bfddbaae635 (patch)
tree5a47b71a40850020db724d1a481190dc63888106
parent4d1e7dc23c3cad10aacee1f585f33ca159e5724a (diff)
downloadNetworkManager-ae763642d885dc8d8edc3890a2087bfddbaae635.tar.gz
dns: add reverse DNS IPv6 entries to dnsmasq
https://bugzilla.gnome.org/show_bug.cgi?id=767174
-rw-r--r--src/dns-manager/nm-dns-dnsmasq.c12
-rw-r--r--src/dns-manager/nm-dns-utils.c31
-rw-r--r--src/dns-manager/nm-dns-utils.h2
-rw-r--r--src/nm-core-utils.c57
-rw-r--r--src/nm-core-utils.h1
-rw-r--r--src/tests/test-general.c57
6 files changed, 158 insertions, 2 deletions
diff --git a/src/dns-manager/nm-dns-dnsmasq.c b/src/dns-manager/nm-dns-dnsmasq.c
index 79fc7d6cb8..bde3427355 100644
--- a/src/dns-manager/nm-dns-dnsmasq.c
+++ b/src/dns-manager/nm-dns-dnsmasq.c
@@ -219,6 +219,8 @@ add_ip6_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP6Config *ip6,
nnameservers = nm_ip6_config_get_num_nameservers (ip6);
if (split) {
+ char **domains, **iter;
+
if (nnameservers == 0)
return FALSE;
@@ -248,6 +250,16 @@ add_ip6_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP6Config *ip6,
}
}
+ /* Ensure reverse-DNS works by directing queries for ip6.arpa
+ * domains to the split domain's nameserver.
+ */
+ domains = nm_dns_utils_get_ip6_rdns_domains (ip6);
+ if (domains) {
+ for (iter = domains; iter && *iter; iter++)
+ add_dnsmasq_nameserver (self, servers, buf, *iter);
+ g_strfreev (domains);
+ }
+
g_free (buf);
}
}
diff --git a/src/dns-manager/nm-dns-utils.c b/src/dns-manager/nm-dns-utils.c
index d864aa9619..f9bb79b65f 100644
--- a/src/dns-manager/nm-dns-utils.c
+++ b/src/dns-manager/nm-dns-utils.c
@@ -57,5 +57,36 @@ nm_dns_utils_get_ip4_rdns_domains (NMIP4Config *ip4)
strv = (char **) g_ptr_array_free (domains, (domains->len == 1));
return _nm_utils_strv_cleanup (strv, FALSE, FALSE, TRUE);
+}
+
+char **
+nm_dns_utils_get_ip6_rdns_domains (NMIP6Config *ip6)
+{
+ char **strv;
+ GPtrArray *domains = NULL;
+ int i;
+
+ g_return_val_if_fail (ip6 != NULL, NULL);
+
+ domains = g_ptr_array_sized_new (5);
+
+ for (i = 0; i < nm_ip6_config_get_num_addresses (ip6); i++) {
+ const NMPlatformIP6Address *address = nm_ip6_config_get_address (ip6, i);
+ nm_utils_get_reverse_dns_domains_ip6 (&address->address, address->plen, domains);
+ }
+
+ for (i = 0; i < nm_ip6_config_get_num_routes (ip6); i++) {
+ const NMPlatformIP6Route *route = nm_ip6_config_get_route (ip6, i);
+
+ nm_utils_get_reverse_dns_domains_ip6 (&route->network, route->plen, domains);
+ }
+
+ /* Terminating NULL so we can use g_strfreev() to free it */
+ g_ptr_array_add (domains, NULL);
+
+ /* Free the array and return NULL if the only element was the ending NULL */
+ strv = (char **) g_ptr_array_free (domains, (domains->len == 1));
+
+ return _nm_utils_strv_cleanup (strv, FALSE, FALSE, TRUE);
}
diff --git a/src/dns-manager/nm-dns-utils.h b/src/dns-manager/nm-dns-utils.h
index 75c6b0608f..2c484ac341 100644
--- a/src/dns-manager/nm-dns-utils.h
+++ b/src/dns-manager/nm-dns-utils.h
@@ -21,8 +21,10 @@
#define __NETWORKMANAGER_DNS_UTILS_H__
#include "nm-ip4-config.h"
+#include "nm-ip6-config.h"
char **nm_dns_utils_get_ip4_rdns_domains (NMIP4Config *ip4);
+char **nm_dns_utils_get_ip6_rdns_domains (NMIP6Config *ip6);
#endif /* NM_DNS_UTILS_H */
diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c
index 1258a75f1e..b20653838d 100644
--- a/src/nm-core-utils.c
+++ b/src/nm-core-utils.c
@@ -3318,3 +3318,60 @@ nm_utils_get_reverse_dns_domains_ip4 (guint32 addr, guint8 plen, GPtrArray *doma
ip2 += 1 << ((32 - plen) & ~7);
}
}
+
+/**
+ * nm_utils_get_reverse_dns_domains_ip6:
+ * @addr: IPv6 address
+ * @plen: prefix length
+ * @domains: array for results
+ *
+ * Creates reverse DNS domains for the given address and prefix length, and
+ * append them to @domains.
+ */
+void
+nm_utils_get_reverse_dns_domains_ip6 (const struct in6_addr *ip, guint8 plen, GPtrArray *domains)
+{
+ struct in6_addr addr;
+ guint nibbles, bits, entries;
+ int i, j;
+ gsize len0, len;
+ char *str, *s;
+
+ g_return_if_fail (domains);
+ g_return_if_fail (plen <= 128);
+
+ if (!plen)
+ return;
+
+ memcpy (&addr, ip, sizeof (struct in6_addr));
+ nm_utils_ip6_address_clear_host_address (&addr, &addr, plen);
+
+ /* Number of nibbles to include in domains */
+ nibbles = (plen - 1) / 4 + 1;
+ /* Prefix length in nibble */
+ bits = plen - ((plen - 1) / 4 * 4);
+ /* Number of domains */
+ entries = 1 << (4 - bits);
+
+ len0 = NM_STRLEN ("ip6.arpa") + (2 * nibbles) + 1;
+
+#define N_SHIFT(x) ((x) % 2 ? 0 : 4)
+
+ for (i = 0; i < entries; i++) {
+ len = len0;
+ str = s = g_malloc (len);
+
+ for (j = nibbles - 1; j >= 0; j--)
+ nm_utils_strbuf_append (&s,
+ &len,
+ "%x.",
+ (addr.s6_addr[j / 2] >> N_SHIFT (j)) & 0xf);
+ nm_utils_strbuf_append_str (&s, &len, "ip6.arpa");
+
+ g_ptr_array_add (domains, str);
+
+ addr.s6_addr[(nibbles - 1) / 2] += 1 << N_SHIFT (nibbles - 1);
+ }
+
+#undef N_SHIFT
+}
diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h
index 8b278f725b..ce22439b1b 100644
--- a/src/nm-core-utils.h
+++ b/src/nm-core-utils.h
@@ -407,5 +407,6 @@ gboolean nm_utils_ip4_address_is_link_local (in_addr_t addr);
const char *nm_utils_dnsmasq_status_to_string (int status, char *dest, gsize size);
void nm_utils_get_reverse_dns_domains_ip4 (guint32 ip, guint8 plen, GPtrArray *domains);
+void nm_utils_get_reverse_dns_domains_ip6 (const struct in6_addr *ip, guint8 plen, GPtrArray *domains);
#endif /* __NM_CORE_UTILS_H__ */
diff --git a/src/tests/test-general.c b/src/tests/test-general.c
index 34e928811d..9769ead11b 100644
--- a/src/tests/test-general.c
+++ b/src/tests/test-general.c
@@ -1361,8 +1361,6 @@ test_duplicate_decl_specifier (void)
v_result[0] = TEST_MAX (v_const[0], nmtst_get_rand_int () % 5) + v2;
}
-/*****************************************************************************/
-
static void
test_reverse_dns_ip4 (void)
{
@@ -1427,6 +1425,60 @@ test_reverse_dns_ip4 (void)
g_ptr_array_unref (domains);
}
+static void
+test_reverse_dns_ip6 (void)
+{
+ struct in6_addr addr;
+ GPtrArray *domains = g_ptr_array_new_full (8, g_free);
+
+ inet_pton (AF_INET6, "1234::56", &addr);
+ nm_utils_get_reverse_dns_domains_ip6 (&addr, 16, domains);
+ g_assert_cmpuint (domains->len, ==, 1);
+ g_assert_cmpstr (domains->pdata[0], ==, "4.3.2.1.ip6.arpa");
+
+ g_ptr_array_set_size (domains, 0);
+
+ inet_pton (AF_INET6, "1234::56", &addr);
+ nm_utils_get_reverse_dns_domains_ip6 (&addr, 17, domains);
+ g_assert_cmpuint (domains->len, ==, 8);
+ g_assert_cmpstr (domains->pdata[0], ==, "0.4.3.2.1.ip6.arpa");
+ g_assert_cmpstr (domains->pdata[1], ==, "1.4.3.2.1.ip6.arpa");
+ g_assert_cmpstr (domains->pdata[7], ==, "7.4.3.2.1.ip6.arpa");
+
+ g_ptr_array_set_size (domains, 0);
+
+ inet_pton (AF_INET6, "2001:db8::", &addr);
+ nm_utils_get_reverse_dns_domains_ip6 (&addr, 29, domains);
+ g_assert_cmpuint (domains->len, ==, 8);
+ g_assert_cmpstr (domains->pdata[0], ==, "8.b.d.0.1.0.0.2.ip6.arpa");
+ g_assert_cmpstr (domains->pdata[1], ==, "9.b.d.0.1.0.0.2.ip6.arpa");
+ g_assert_cmpstr (domains->pdata[7], ==, "f.b.d.0.1.0.0.2.ip6.arpa");
+
+ g_ptr_array_set_size (domains, 0);
+
+ inet_pton (AF_INET6, "0123:4567:89ab:cdef::", &addr);
+ nm_utils_get_reverse_dns_domains_ip6 (&addr, 63, domains);
+ g_assert_cmpuint (domains->len, ==, 2);
+ g_assert_cmpstr (domains->pdata[0], ==, "e.e.d.c.b.a.9.8.7.6.5.4.3.2.1.0.ip6.arpa");
+ g_assert_cmpstr (domains->pdata[1], ==, "f.e.d.c.b.a.9.8.7.6.5.4.3.2.1.0.ip6.arpa");
+
+ g_ptr_array_set_size (domains, 0);
+
+ inet_pton (AF_INET6, "fec0:1234:5678:9ab0::", &addr);
+ nm_utils_get_reverse_dns_domains_ip6 (&addr, 61, domains);
+ g_assert_cmpuint (domains->len, ==, 8);
+ g_assert_cmpstr (domains->pdata[0], ==, "0.b.a.9.8.7.6.5.4.3.2.1.0.c.e.f.ip6.arpa");
+ g_assert_cmpstr (domains->pdata[7], ==, "7.b.a.9.8.7.6.5.4.3.2.1.0.c.e.f.ip6.arpa");
+
+ g_ptr_array_set_size (domains, 0);
+
+ inet_pton (AF_INET6, "0123:4567:89ab:cdee::", &addr);
+ nm_utils_get_reverse_dns_domains_ip6 (&addr, 0, domains);
+ g_assert_cmpuint (domains->len, ==, 0);
+
+ g_ptr_array_unref (domains);
+}
+
/*****************************************************************************/
NMTST_DEFINE ();
@@ -1464,6 +1516,7 @@ main (int argc, char **argv)
g_test_add_func ("/general/duplicate_decl_specifier", test_duplicate_decl_specifier);
g_test_add_func ("/general/reverse_dns/ip4", test_reverse_dns_ip4);
+ g_test_add_func ("/general/reverse_dns/ip6", test_reverse_dns_ip6);
return g_test_run ();
}