Пример #1
0
static gboolean
add_ip6_config (GString *str, NMIP6Config *ip6, gboolean split)
{
	const struct in6_addr *addr;
	char *buf = NULL;
	int nnameservers, i_nameserver, n, i;
	gboolean added = FALSE;
	const char *iface;

	nnameservers = nm_ip6_config_get_num_nameservers (ip6);

	iface = g_object_get_data (G_OBJECT (ip6), IP_CONFIG_IFACE_TAG);
	g_assert (iface);

	if (split) {
		if (nnameservers == 0)
			return FALSE;

		for (i_nameserver = 0; i_nameserver < nnameservers; i_nameserver++) {
			addr = nm_ip6_config_get_nameserver (ip6, i_nameserver);
			buf = ip6_addr_to_string (addr, iface);

			/* searches are preferred over domains */
			n = nm_ip6_config_get_num_searches (ip6);
			for (i = 0; i < n; i++) {
				g_string_append_printf (str, "server=/%s/%s\n",
				                        nm_ip6_config_get_search (ip6, i),
				                        buf);
				added = TRUE;
			}

			if (n == 0) {
				/* If not searches, use any domains */
				n = nm_ip6_config_get_num_domains (ip6);
				for (i = 0; i < n; i++) {
					g_string_append_printf (str, "server=/%s/%s\n",
					                        nm_ip6_config_get_domain (ip6, i),
					                        buf);
					added = TRUE;
				}
			}

			g_free (buf);
		}
	}

	/* If no searches or domains, just add the namservers */
	if (!added) {
		for (i = 0; i < nnameservers; i++) {
			addr = nm_ip6_config_get_nameserver (ip6, i);
			buf = ip6_addr_to_string (addr, iface);
			if (buf) {
				g_string_append_printf (str, "server=%s\n", buf);
				g_free (buf);
			}
		}
	}

	return TRUE;
}
Пример #2
0
static gboolean
add_ip6_config (GString *str, NMIP6Config *ip6, gboolean split, const char *iface)
{
	const struct in6_addr *addr;
	char *buf;
	int n, i;
	gboolean added = FALSE;

	if (split) {
		/* FIXME: it appears that dnsmasq can only handle one nameserver
		 * per domain (at the manpage seems to indicate that) so only use
		 * the first nameserver here.
		 */
		addr = nm_ip6_config_get_nameserver (ip6, 0);
		buf = ip6_addr_to_string (addr, iface);
		if (!buf)
			return FALSE;

		/* searches are preferred over domains */
		n = nm_ip6_config_get_num_searches (ip6);
		for (i = 0; i < n; i++) {
			g_string_append_printf (str, "server=/%s/%s\n",
				                    nm_ip6_config_get_search (ip6, i),
				                    buf);
			added = TRUE;
		}

		if (n == 0) {
			/* If not searches, use any domains */
			n = nm_ip6_config_get_num_domains (ip6);
			for (i = 0; i < n; i++) {
				g_string_append_printf (str, "server=/%s/%s\n",
							            nm_ip6_config_get_domain (ip6, i),
							            buf);
				added = TRUE;
			}
		}

		g_free (buf);
	}

	/* If no searches or domains, just add the namservers */
	if (!added) {
		n = nm_ip6_config_get_num_nameservers (ip6);
		for (i = 0; i < n; i++) {
			addr = nm_ip6_config_get_nameserver (ip6, i);
			buf = ip6_addr_to_string (addr, iface);
			if (buf) {
				g_string_append_printf (str, "server=%s\n", buf);
				g_free (buf);
			}
		}
	}

	return TRUE;
}
Пример #3
0
void
nm_ip6_config_hash (NMIP6Config *config, GChecksum *sum, gboolean dns_only)
{
	guint32 i;
	const struct in6_addr *in6a;
	const char *s;

	g_return_if_fail (config != NULL);
	g_return_if_fail (sum != NULL);

	if (dns_only == FALSE) {
		for (i = 0; i < nm_ip6_config_get_num_addresses (config); i++) {
			NMIP6Address *a = nm_ip6_config_get_address (config, i);

			hash_in6addr (sum, nm_ip6_address_get_address (a));
			hash_u32 (sum, nm_ip6_address_get_prefix (a));
			hash_in6addr (sum, nm_ip6_address_get_gateway (a));
		}

		for (i = 0; i < nm_ip6_config_get_num_routes (config); i++) {
			NMIP6Route *r = nm_ip6_config_get_route (config, i);

			hash_in6addr (sum, nm_ip6_route_get_dest (r));
			hash_u32 (sum, nm_ip6_route_get_prefix (r));
			hash_in6addr (sum, nm_ip6_route_get_next_hop (r));
			hash_u32 (sum, nm_ip6_route_get_metric (r));
		}

		in6a = nm_ip6_config_get_ptp_address (config);
		if (in6a)
			hash_in6addr (sum, in6a);
	}

	for (i = 0; i < nm_ip6_config_get_num_nameservers (config); i++)
		hash_in6addr (sum, nm_ip6_config_get_nameserver (config, i));

	for (i = 0; i < nm_ip6_config_get_num_domains (config); i++) {
		s = nm_ip6_config_get_domain (config, i);
		g_checksum_update (sum, (const guint8 *) s, strlen (s));
	}

	for (i = 0; i < nm_ip6_config_get_num_searches (config); i++) {
		s = nm_ip6_config_get_search (config, i);
		g_checksum_update (sum, (const guint8 *) s, strlen (s));
	}
}
Пример #4
0
static void
merge_one_ip6_config (NMResolvConfData *rc, NMIP6Config *src, const char *iface)
{
    guint32 num, i;

    num = nm_ip6_config_get_num_nameservers (src);
    for (i = 0; i < num; i++) {
        const struct in6_addr *addr;
        char buf[INET6_ADDRSTRLEN];

        addr = nm_ip6_config_get_nameserver (src, i);

        /* inet_ntop is probably supposed to do this for us, but it doesn't */
        if (IN6_IS_ADDR_V4MAPPED (addr)) {
            if (inet_ntop (AF_INET, &(addr->s6_addr32[3]), buf, INET_ADDRSTRLEN) > 0)
                add_string_item (rc->nameservers, buf);
        } else {
            if (inet_ntop (AF_INET6, addr, buf, INET6_ADDRSTRLEN) > 0) {
                if (IN6_IS_ADDR_LINKLOCAL (addr) && strchr (buf, '%') == NULL) {
                    char *tmp;
                    tmp = g_strdup_printf ("%s%%%s", buf, iface);
                    add_string_item (rc->nameservers, tmp);
                    g_free (tmp);
                } else
                    add_string_item (rc->nameservers, buf);
            }
        }
    }

    num = nm_ip6_config_get_num_domains (src);
    for (i = 0; i < num; i++) {
        const char *domain;

        domain = nm_ip6_config_get_domain (src, i);
        if (!rc->domain)
            rc->domain = domain;
        add_string_item (rc->searches, domain);
    }

    num = nm_ip6_config_get_num_searches (src);
    for (i = 0; i < num; i++)
        add_string_item (rc->searches, nm_ip6_config_get_search (src, i));
}
Пример #5
0
/* This is exactly identical to nm_utils_merge_ip4_config, with s/4/6/,
 * except that we can't compare addresses with ==.
 */
void
nm_utils_merge_ip6_config (NMIP6Config *ip6_config, NMSettingIP6Config *setting)
{
	int i, j;

	if (!setting)
		return; /* Defaults are just fine */

	if (nm_setting_ip6_config_get_ignore_auto_dns (setting)) {
		nm_ip6_config_reset_nameservers (ip6_config);
		nm_ip6_config_reset_domains (ip6_config);
		nm_ip6_config_reset_searches (ip6_config);
	}

	if (nm_setting_ip6_config_get_ignore_auto_routes (setting))
		nm_ip6_config_reset_routes (ip6_config);

	for (i = 0; i < nm_setting_ip6_config_get_num_dns (setting); i++) {
		const struct in6_addr *ns;
		gboolean found = FALSE;

		/* Avoid dupes */
		ns = nm_setting_ip6_config_get_dns (setting, i);
		for (j = 0; j < nm_ip6_config_get_num_nameservers (ip6_config); j++) {
			if (ip6_addresses_equal (nm_ip6_config_get_nameserver (ip6_config, j), ns)) {
				found = TRUE;
				break;
			}
		}

		if (!found)
			nm_ip6_config_add_nameserver (ip6_config, ns);
	}

	/* DNS search domains */
	for (i = 0; i < nm_setting_ip6_config_get_num_dns_searches (setting); i++) {
		const char *search = nm_setting_ip6_config_get_dns_search (setting, i);
		gboolean found = FALSE;

		/* Avoid dupes */
		for (j = 0; j < nm_ip6_config_get_num_searches (ip6_config); j++) {
			if (!strcmp (search, nm_ip6_config_get_search (ip6_config, j))) {
				found = TRUE;
				break;
			}
		}

		if (!found)
			nm_ip6_config_add_search (ip6_config, search);
	}

	/* IPv6 addresses */
	for (i = 0; i < nm_setting_ip6_config_get_num_addresses (setting); i++) {
		NMIP6Address *setting_addr = nm_setting_ip6_config_get_address (setting, i);
		guint32 num;

		num = nm_ip6_config_get_num_addresses (ip6_config);
		for (j = 0; j < num; j++) {
			NMIP6Address *cfg_addr = nm_ip6_config_get_address (ip6_config, j);

			/* Dupe, override with user-specified address */
			if (ip6_addresses_equal (nm_ip6_address_get_address (cfg_addr), nm_ip6_address_get_address (setting_addr))) {
				nm_ip6_config_replace_address (ip6_config, j, setting_addr);
				break;
			}
		}

		if (j == num)
			nm_ip6_config_add_address (ip6_config, setting_addr);
	}

	/* IPv6 routes */
	for (i = 0; i < nm_setting_ip6_config_get_num_routes (setting); i++) {
		NMIP6Route *setting_route = nm_setting_ip6_config_get_route (setting, i);
		guint32 num;

		num = nm_ip6_config_get_num_routes (ip6_config);
		for (j = 0; j < num; j++) {
			NMIP6Route *cfg_route = nm_ip6_config_get_route (ip6_config, j);

			/* Dupe, override with user-specified route */
			if (   ip6_addresses_equal (nm_ip6_route_get_dest (cfg_route), nm_ip6_route_get_dest (setting_route))
			    && (nm_ip6_route_get_prefix (cfg_route) == nm_ip6_route_get_prefix (setting_route))
				&& ip6_addresses_equal (nm_ip6_route_get_next_hop (cfg_route), nm_ip6_route_get_next_hop (setting_route))) {
				nm_ip6_config_replace_route (ip6_config, j, setting_route);
				break;
			}
		}

		if (j == num)
			nm_ip6_config_add_route (ip6_config, setting_route);
	}

	if (nm_setting_ip6_config_get_never_default (setting))
		nm_ip6_config_set_never_default (ip6_config, TRUE);
}
Пример #6
0
static gboolean
add_ip6_config (NMDnsDnsmasq *self, GVariantBuilder *servers, NMIP6Config *ip6,
                const char *iface, gboolean split)
{
	const struct in6_addr *addr;
	char *buf = NULL;
	int nnameservers, i_nameserver, n, i;
	gboolean added = FALSE;

	g_return_val_if_fail (iface, FALSE);
	nnameservers = nm_ip6_config_get_num_nameservers (ip6);

	if (split) {
		char **domains, **iter;

		if (nnameservers == 0)
			return FALSE;

		for (i_nameserver = 0; i_nameserver < nnameservers; i_nameserver++) {
			addr = nm_ip6_config_get_nameserver (ip6, i_nameserver);
			buf = ip6_addr_to_string (addr, iface);

			/* searches are preferred over domains */
			n = nm_ip6_config_get_num_searches (ip6);
			for (i = 0; i < n; i++) {
				add_dnsmasq_nameserver (self,
				                        servers,
				                        buf,
				                        nm_ip6_config_get_search (ip6, i));
				added = TRUE;
			}

			if (n == 0) {
				/* If not searches, use any domains */
				n = nm_ip6_config_get_num_domains (ip6);
				for (i = 0; i < n; i++) {
					add_dnsmasq_nameserver (self,
					                        servers,
					                        buf,
					                        nm_ip6_config_get_domain (ip6, i));
					added = TRUE;
				}
			}

			/* Ensure reverse-DNS works by directing queries for ip6.arpa
			 * domains to the split domain's nameserver.
			 */
			domains = 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);
		}
	}

	/* If no searches or domains, just add the nameservers */
	if (!added) {
		for (i = 0; i < nnameservers; i++) {
			addr = nm_ip6_config_get_nameserver (ip6, i);
			buf = ip6_addr_to_string (addr, iface);
			if (buf) {
				add_dnsmasq_nameserver (self, servers, buf, NULL);
				g_free (buf);
			}
		}
	}

	return TRUE;
}