dns: add reverse DNS IPv6 entries to dnsmasq
https://bugzilla.gnome.org/show_bug.cgi?id=767174
This commit is contained in:
@@ -219,6 +219,8 @@ add_ip6_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP6Config *ip6,
|
|||||||
nnameservers = nm_ip6_config_get_num_nameservers (ip6);
|
nnameservers = nm_ip6_config_get_num_nameservers (ip6);
|
||||||
|
|
||||||
if (split) {
|
if (split) {
|
||||||
|
char **domains, **iter;
|
||||||
|
|
||||||
if (nnameservers == 0)
|
if (nnameservers == 0)
|
||||||
return FALSE;
|
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);
|
g_free (buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -57,5 +57,36 @@ nm_dns_utils_get_ip4_rdns_domains (NMIP4Config *ip4)
|
|||||||
strv = (char **) g_ptr_array_free (domains, (domains->len == 1));
|
strv = (char **) g_ptr_array_free (domains, (domains->len == 1));
|
||||||
|
|
||||||
return _nm_utils_strv_cleanup (strv, FALSE, FALSE, TRUE);
|
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);
|
||||||
}
|
}
|
||||||
|
@@ -21,8 +21,10 @@
|
|||||||
#define __NETWORKMANAGER_DNS_UTILS_H__
|
#define __NETWORKMANAGER_DNS_UTILS_H__
|
||||||
|
|
||||||
#include "nm-ip4-config.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_ip4_rdns_domains (NMIP4Config *ip4);
|
||||||
|
char **nm_dns_utils_get_ip6_rdns_domains (NMIP6Config *ip6);
|
||||||
|
|
||||||
#endif /* NM_DNS_UTILS_H */
|
#endif /* NM_DNS_UTILS_H */
|
||||||
|
|
||||||
|
@@ -3318,3 +3318,60 @@ nm_utils_get_reverse_dns_domains_ip4 (guint32 addr, guint8 plen, GPtrArray *doma
|
|||||||
ip2 += 1 << ((32 - plen) & ~7);
|
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
|
||||||
|
}
|
||||||
|
@@ -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);
|
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_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__ */
|
#endif /* __NM_CORE_UTILS_H__ */
|
||||||
|
@@ -1361,8 +1361,6 @@ test_duplicate_decl_specifier (void)
|
|||||||
v_result[0] = TEST_MAX (v_const[0], nmtst_get_rand_int () % 5) + v2;
|
v_result[0] = TEST_MAX (v_const[0], nmtst_get_rand_int () % 5) + v2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_reverse_dns_ip4 (void)
|
test_reverse_dns_ip4 (void)
|
||||||
{
|
{
|
||||||
@@ -1427,6 +1425,60 @@ test_reverse_dns_ip4 (void)
|
|||||||
g_ptr_array_unref (domains);
|
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 ();
|
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/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/ip4", test_reverse_dns_ip4);
|
||||||
|
g_test_add_func ("/general/reverse_dns/ip6", test_reverse_dns_ip6);
|
||||||
|
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user