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; }
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; }
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)); } }
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)); }
static void dump_ip6_to_props (NMIP6Config *ip6, GVariantBuilder *builder) { GVariantBuilder int_builder; guint n, i; const NMPlatformIP6Address *addr; const struct in6_addr *gw_bytes; const NMPlatformIP6Route *route; GVariant *ip, *gw; /* Addresses */ g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("a(ayuay)")); n = nm_ip6_config_get_num_addresses (ip6); for (i = 0; i < n; i++) { addr = nm_ip6_config_get_address (ip6, i); gw_bytes = nm_ip6_config_get_gateway (ip6); ip = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, &addr->address, sizeof (struct in6_addr), 1); gw = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, (i == 0 && gw_bytes) ? gw_bytes : &in6addr_any, sizeof (struct in6_addr), 1); g_variant_builder_add (&int_builder, "(@ayu@ay)", ip, addr->plen, gw); } g_variant_builder_add (builder, "{sv}", "addresses", g_variant_builder_end (&int_builder)); /* DNS servers */ g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("aay")); n = nm_ip6_config_get_num_nameservers (ip6); for (i = 0; i < n; i++) { ip = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, nm_ip6_config_get_nameserver (ip6, i), sizeof (struct in6_addr), 1); g_variant_builder_add (&int_builder, "@ay", ip); } g_variant_builder_add (builder, "{sv}", "nameservers", g_variant_builder_end (&int_builder)); /* Search domains */ g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("as")); n = nm_ip6_config_get_num_domains (ip6); for (i = 0; i < n; i++) g_variant_builder_add (&int_builder, "s", nm_ip6_config_get_domain (ip6, i)); g_variant_builder_add (builder, "{sv}", "domains", g_variant_builder_end (&int_builder)); /* Static routes */ g_variant_builder_init (&int_builder, G_VARIANT_TYPE ("a(ayuayu)")); n = nm_ip6_config_get_num_routes (ip6); for (i = 0; i < n; i++) { route = nm_ip6_config_get_route (ip6, i); ip = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, &route->network, sizeof (struct in6_addr), 1); gw = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, &route->gateway, sizeof (struct in6_addr), 1); g_variant_builder_add (&int_builder, "(@ayu@ayu)", ip, route->plen, gw, route->metric); } g_variant_builder_add (builder, "{sv}", "routes", g_variant_builder_end (&int_builder)); }
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; }