diff options
Diffstat (limited to 'libnm-core/nm-utils.c')
-rw-r--r-- | libnm-core/nm-utils.c | 1302 |
1 files changed, 563 insertions, 739 deletions
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 7e0e52815e..e991ce0b68 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -29,7 +29,6 @@ #include "nm-utils.h" #include "nm-utils-private.h" #include "nm-glib-compat.h" -#include "nm-dbus-glib-types.h" #include "nm-setting-private.h" #include "crypto.h" @@ -221,8 +220,6 @@ nm_utils_init (GError **error) if (!crypto_init (error)) return FALSE; - - _nm_value_transforms_register (); } return TRUE; } @@ -522,46 +519,72 @@ done: return valid; } -void -_nm_utils_strdict_to_dbus (const GValue *prop_value, - GValue *dbus_value) +GVariant * +_nm_utils_strdict_to_dbus (const GValue *prop_value) { - g_value_set_boxed (dbus_value, g_value_get_boxed (prop_value)); + GHashTable *hash; + GHashTableIter iter; + gpointer key, value; + GVariantBuilder builder; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + hash = g_value_get_boxed (prop_value); + if (hash) { + g_hash_table_iter_init (&iter, hash); + while (g_hash_table_iter_next (&iter, &key, &value)) + g_variant_builder_add (&builder, "{ss}", key, value); + } + + return g_variant_builder_end (&builder); } void -_nm_utils_strdict_from_dbus (const GValue *dbus_value, +_nm_utils_strdict_from_dbus (GVariant *dbus_value, GValue *prop_value) { - g_value_set_boxed (prop_value, g_value_get_boxed (dbus_value)); + GVariantIter iter; + const char *key, *value; + GHashTable *hash; + + hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + g_variant_iter_init (&iter, g_value_get_variant (prop_value)); + while (g_variant_iter_next (&iter, "{&s&s}", &key, &value)) + g_hash_table_insert (hash, g_strdup (key), g_strdup (value)); + + g_value_take_boxed (prop_value, hash); } -void -_nm_utils_bytes_to_dbus (const GValue *prop_value, - GValue *dbus_value) +GVariant * +_nm_utils_bytes_to_dbus (const GValue *prop_value) { GBytes *bytes = g_value_get_boxed (prop_value); - GByteArray *ba = NULL; if (bytes) { - ba = g_byte_array_new (); - g_byte_array_append (ba, - g_bytes_get_data (bytes, NULL), - g_bytes_get_size (bytes)); + return g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + g_bytes_get_data (bytes, NULL), + g_bytes_get_size (bytes), + 1); + } else { + return g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + NULL, 0, + 1); } - - g_value_take_boxed (dbus_value, ba); } void -_nm_utils_bytes_from_dbus (const GValue *dbus_value, +_nm_utils_bytes_from_dbus (GVariant *dbus_value, GValue *prop_value) { - GByteArray *ba = g_value_dup_boxed (dbus_value); - GBytes *bytes = NULL; + GBytes *bytes; - if (ba) - bytes = g_byte_array_free_to_bytes (ba); + if (g_variant_n_children (dbus_value)) { + gconstpointer data; + gsize length; + + data = g_variant_get_fixed_array (dbus_value, &length, 1); + bytes = g_bytes_new (data, length); + } else + bytes = NULL; g_value_take_boxed (prop_value, bytes); } @@ -927,357 +950,265 @@ nm_utils_wpa_psk_valid (const char *psk) return TRUE; } -void -_nm_utils_ip4_dns_to_dbus (const GValue *prop_value, - GValue *dbus_value) -{ - char **dns; - int i; - GArray *array; - - dns = g_value_get_boxed (prop_value); - array = g_array_new (FALSE, FALSE, sizeof (guint32)); - - if (dns) { - for (i = 0; dns[i]; i++) { - guint32 ip = 0; - - inet_pton (AF_INET, dns[i], &ip); - g_array_append_val (array, ip); - } - } - - g_value_take_boxed (dbus_value, array); -} - -void -_nm_utils_ip4_dns_from_dbus (const GValue *dbus_value, - GValue *prop_value) +/** + * nm_utils_ip4_dns_from_variant: (skip) + * @variant: a #GVariant + * + * Converts a #GVariant containing an "au" of IP4 DNS into an array of + * IP address strings. + * + * Returns: a %NULL-terminated array of IP4 address strings. + */ +char ** +nm_utils_ip4_dns_from_variant (GVariant *variant) { - GArray *array; + const guint32 *array; + gsize length; GPtrArray *dns; int i; - array = g_value_get_boxed (dbus_value); + array = g_variant_get_fixed_array (variant, &length, sizeof (guint32)); dns = g_ptr_array_new (); - if (array) { - for (i = 0; i < array->len; i++) { - guint32 ip = g_array_index (array, guint32, i); - const char *str; + for (i = 0; i < length; i++) { + guint32 ip = array[i]; + const char *str; - str = nm_utils_inet4_ntop (ip, NULL); - g_ptr_array_add (dns, g_strdup (str)); - } + str = nm_utils_inet4_ntop (ip, NULL); + g_ptr_array_add (dns, g_strdup (str)); } g_ptr_array_add (dns, NULL); - g_value_take_boxed (prop_value, g_ptr_array_free (dns, FALSE)); -} - -void -_nm_utils_ip4_addresses_to_dbus (const GValue *prop_value, - GValue *dbus_value) -{ - GPtrArray *addresses, *dbus_addresses; - int i; - - addresses = g_value_get_boxed (prop_value); - dbus_addresses = g_ptr_array_new (); - - if (addresses) { - for (i = 0; i < addresses->len; i++) { - NMIP4Address *addr = addresses->pdata[i]; - GArray *array; - guint32 tmp; - - array = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3); - - tmp = nm_ip4_address_get_address (addr); - g_array_append_val (array, tmp); - - tmp = nm_ip4_address_get_prefix (addr); - g_array_append_val (array, tmp); - - tmp = nm_ip4_address_get_gateway (addr); - g_array_append_val (array, tmp); - - g_ptr_array_add (dbus_addresses, array); - } - } - - g_value_take_boxed (dbus_value, dbus_addresses); -} - -void -_nm_utils_ip4_addresses_from_dbus (const GValue *dbus_value, - GValue *prop_value) -{ - GPtrArray *dbus_addresses; - GPtrArray *addresses; - int i; - - dbus_addresses = g_value_get_boxed (dbus_value); - addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip4_address_unref); - - if (dbus_addresses) { - for (i = 0; i < dbus_addresses->len; i++) { - GArray *array = dbus_addresses->pdata[i]; - NMIP4Address *addr; - - if (array->len < 3) { - g_warning ("Ignoring invalid IP4 address"); - continue; - } - - addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, g_array_index (array, guint32, 0)); - nm_ip4_address_set_prefix (addr, g_array_index (array, guint32, 1)); - nm_ip4_address_set_gateway (addr, g_array_index (array, guint32, 2)); - - g_ptr_array_add (addresses, addr); - } - } - - g_value_take_boxed (prop_value, addresses); -} - -void -_nm_utils_ip4_routes_to_dbus (const GValue *prop_value, - GValue *dbus_value) -{ - GPtrArray *routes, *dbus_routes; - int i; - - routes = g_value_get_boxed (prop_value); - dbus_routes = g_ptr_array_new (); - - if (routes) { - for (i = 0; i < routes->len; i++) { - NMIP4Route *route = routes->pdata[i]; - GArray *array; - guint32 tmp; - - array = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3); - - tmp = nm_ip4_route_get_dest (route); - g_array_append_val (array, tmp); - - tmp = nm_ip4_route_get_prefix (route); - g_array_append_val (array, tmp); - - tmp = nm_ip4_route_get_next_hop (route); - g_array_append_val (array, tmp); - - tmp = nm_ip4_route_get_metric (route); - g_array_append_val (array, tmp); - - g_ptr_array_add (dbus_routes, array); - } - } - - g_value_take_boxed (dbus_value, dbus_routes); + return (char **) g_ptr_array_free (dns, FALSE); } -void -_nm_utils_ip4_routes_from_dbus (const GValue *dbus_value, - GValue *prop_value) +/** + * nm_utils_ip4_dns_to_variant: (skip) + * @dns: a %NULL-termianted array of IP address strings + * + * Utility function to convert an array of IPv4 address strings into an "au" + * variant representing each server's IPv4 addresses in network byte order. + */ +GVariant * +nm_utils_ip4_dns_to_variant (char **dns) { - GPtrArray *dbus_routes, *routes; + GVariantBuilder builder; int i; - dbus_routes = g_value_get_boxed (dbus_value); - routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip4_route_unref); - - if (dbus_routes) { - for (i = 0; i < dbus_routes->len; i++) { - GArray *array = dbus_routes->pdata[i]; - NMIP4Route *route; - - if (array->len < 4) { - g_warning ("Ignoring invalid IP4 route"); - continue; - } + g_variant_builder_init (&builder, G_VARIANT_TYPE ("au")); - route = nm_ip4_route_new (); - nm_ip4_route_set_dest (route, g_array_index (array, guint32, 0)); - nm_ip4_route_set_prefix (route, g_array_index (array, guint32, 1)); - nm_ip4_route_set_next_hop (route, g_array_index (array, guint32, 2)); - nm_ip4_route_set_metric (route, g_array_index (array, guint32, 3)); + if (dns) { + for (i = 0; dns[i]; i++) { + guint32 ip = 0; - g_ptr_array_add (routes, route); + inet_pton (AF_INET, dns[i], &ip); + g_variant_builder_add (&builder, "u", ip); } } - g_value_take_boxed (prop_value, routes); + return g_variant_builder_end (&builder); } /** - * nm_utils_ip4_addresses_from_gvalue: - * @value: #GValue containing a #GPtrArray of #GArrays of #guint32s + * nm_utils_ip4_addresses_from_variant: + * @variant: #GVariant containing an "a(uuu)" * - * Utility function to convert a #GPtrArray of #GArrays of #guint32s representing - * a list of NetworkManager IPv4 addresses (which is a tuple of address, gateway, - * and prefix) into a #GSList of #NMIP4Address objects. The specific format of - * this serialization is not guaranteed to be stable and the #GArray may be - * extended in the future. + * Utility function to convert an "a(uuu)" (array of tuples of address, prefix, + * and gateway) into a #GPtrArray of #NMIP4Address objects. * - * Returns: (transfer full) (element-type NMIP4Address): a newly allocated #GSList of #NMIP4Address objects + * Returns: (transfer full) (element-type NMIP4Address): an array of + * #NMIP4Address objects **/ -GSList * -nm_utils_ip4_addresses_from_gvalue (const GValue *value) +GPtrArray * +nm_utils_ip4_addresses_from_variant (GVariant *variant) { + GVariantIter iter; + GVariant *addr_var; GPtrArray *addresses; - int i; - GSList *list = NULL; - addresses = (GPtrArray *) g_value_get_boxed (value); - for (i = 0; addresses && (i < addresses->len); i++) { - GArray *array = (GArray *) g_ptr_array_index (addresses, i); + g_variant_iter_init (&iter, variant); + addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip4_address_unref); + + while (g_variant_iter_next (&iter, "au", &addr_var)) { + const guint32 *addr_array; NMIP4Address *addr; - if (array->len < 3) { + if (g_variant_n_children (addr_var) != 3) { g_warning ("Ignoring invalid IP4 address"); + g_variant_unref (addr_var); continue; } + addr_array = g_variant_get_fixed_array (addr_var, NULL, sizeof (guint32)); addr = nm_ip4_address_new (); - nm_ip4_address_set_address (addr, g_array_index (array, guint32, 0)); - nm_ip4_address_set_prefix (addr, g_array_index (array, guint32, 1)); - nm_ip4_address_set_gateway (addr, g_array_index (array, guint32, 2)); - list = g_slist_prepend (list, addr); + nm_ip4_address_set_address (addr, addr_array[0]); + nm_ip4_address_set_prefix (addr, addr_array[1]); + nm_ip4_address_set_gateway (addr, addr_array[2]); + + g_ptr_array_add (addresses, addr); + g_variant_unref (addr_var); } - return g_slist_reverse (list); + return addresses; } /** - * nm_utils_ip4_addresses_to_gvalue: - * @list: (element-type NMIP4Address): a list of #NMIP4Address objects - * @value: a pointer to a #GValue into which to place the converted addresses, - * which should be unset by the caller (when no longer needed) with - * g_value_unset(). - * - * Utility function to convert a #GSList of #NMIP4Address objects into a - * #GPtrArray of #GArrays of #guint32s representing a list of NetworkManager IPv4 - * addresses (which is a tuple of address, gateway, and prefix). The specific - * format of this serialization is not guaranteed to be stable and may be - * extended in the future. + * nm_utils_ip4_addresses_to_variant: + * @addresses: (element-type NMIP4Address): an array of #NMIP4Address objects + * + * Utility function to convert a #GPtrArray of #NMIP4Address objects into an + * "a(uuu)" variant representing a list of NetworkManager IPv4 addresses (which + * is a tuple of address, prefix, and gateway). + * + * Return value: (transfer none): a new floating #GVariant containing the + * addresses **/ -void -nm_utils_ip4_addresses_to_gvalue (GSList *list, GValue *value) +GVariant * +nm_utils_ip4_addresses_to_variant (GPtrArray *addresses) { - GPtrArray *addresses; - GSList *iter; - - addresses = g_ptr_array_new (); - - for (iter = list; iter; iter = iter->next) { - NMIP4Address *addr = (NMIP4Address *) iter->data; - GArray *array; - guint32 tmp; - - array = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3); + GVariantBuilder builder; + int i; - tmp = nm_ip4_address_get_address (addr); - g_array_append_val (array, tmp); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("aau")); - tmp = nm_ip4_address_get_prefix (addr); - g_array_append_val (array, tmp); + if (addresses) { + for (i = 0; i < addresses->len; i++) { + NMIP4Address *addr = addresses->pdata[i]; + guint32 array[3]; - tmp = nm_ip4_address_get_gateway (addr); - g_array_append_val (array, tmp); + array[0] = nm_ip4_address_get_address (addr); + array[1] = nm_ip4_address_get_prefix (addr); + array[2] = nm_ip4_address_get_gateway (addr); - g_ptr_array_add (addresses, array); + g_variant_builder_add (&builder, "au", + g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + array, 3, sizeof (guint32))); + } } - g_value_take_boxed (value, addresses); + return g_variant_builder_end (&builder); } /** - * nm_utils_ip4_routes_from_gvalue: - * @value: #GValue containing a #GPtrArray of #GArrays of #guint32s + * nm_utils_ip4_routes_from_variant: + * @variant: #GVariant containing an "a(uuuu)" * - * Utility function to convert a #GPtrArray of #GArrays of #guint32s representing - * a list of NetworkManager IPv4 routes (which is a tuple of route, next hop, - * prefix, and metric) into a #GSList of #NMIP4Route objects. The specific - * format of this serialization is not guaranteed to be stable and may be - * extended in the future. + * Utility function to convert an "a(uuuu)" representing a list of NetworkManager + * IPv4 routes (which is a tuple of destination, prefix, next hop, and metric) into a + * #GPtrArray of #NMIP4Route objects. * - * Returns: (transfer full) (element-type NMIP4Route): a newly allocated #GSList of #NMIP4Route objects + * Returns: (transfer full) (element-type NMIP4Route): an array of #NMIP4Route + * objects **/ -GSList * -nm_utils_ip4_routes_from_gvalue (const GValue *value) +GPtrArray * +nm_utils_ip4_routes_from_variant (GVariant *variant) { + GVariantIter iter; + GVariant *route_var; GPtrArray *routes; - int i; - GSList *list = NULL; - routes = (GPtrArray *) g_value_get_boxed (value); - for (i = 0; routes && (i < routes->len); i++) { - GArray *array = (GArray *) g_ptr_array_index (routes, i); + g_variant_iter_init (&iter, variant); + routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip4_route_unref); + + while (g_variant_iter_next (&iter, "au", &route_var)) { + const guint32 *route_array; NMIP4Route *route; - if (array->len < 4) { + if (g_variant_n_children (route_var) != 4) { g_warning ("Ignoring invalid IP4 route"); + g_variant_unref (route_var); continue; } + route_array = g_variant_get_fixed_array (route_var, NULL, sizeof (guint32)); route = nm_ip4_route_new (); - nm_ip4_route_set_dest (route, g_array_index (array, guint32, 0)); - nm_ip4_route_set_prefix (route, g_array_index (array, guint32, 1)); - nm_ip4_route_set_next_hop (route, g_array_index (array, guint32, 2)); - nm_ip4_route_set_metric (route, g_array_index (array, guint32, 3)); - list = g_slist_prepend (list, route); + nm_ip4_route_set_dest (route, route_array[0]); + nm_ip4_route_set_prefix (route, route_array[1]); + nm_ip4_route_set_next_hop (route, route_array[2]); + nm_ip4_route_set_metric (route, route_array[3]); + + g_ptr_array_add (routes, route); + g_variant_unref (route_var); } - return g_slist_reverse (list); + return routes; } /** - * nm_utils_ip4_routes_to_gvalue: - * @list: (element-type NMIP4Route): a list of #NMIP4Route objects - * @value: a pointer to a #GValue into which to place the converted routes, - * which should be unset by the caller (when no longer needed) with - * g_value_unset(). - * - * Utility function to convert a #GSList of #NMIP4Route objects into a - * #GPtrArray of #GArrays of #guint32s representing a list of NetworkManager IPv4 - * routes (which is a tuple of route, next hop, prefix, and metric). The - * specific format of this serialization is not guaranteed to be stable and may - * be extended in the future. + * nm_utils_ip4_routes_to_variant: + * @routes: (element-type NMIP4Route): an array of #NMIP4Route objects + * + * Utility function to convert an array of #NMIP4Route objects into an + * "a(uuuu)" variant representing a list of NetworkManager IPv4 + * routes (which is a tuple of destination, prefix, next hop, and metric). + * + * Return value: (transfer none): a new floating #GVariant containing the + * routes **/ -void -nm_utils_ip4_routes_to_gvalue (GSList *list, GValue *value) +GVariant * +nm_utils_ip4_routes_to_variant (GPtrArray *routes) { - GPtrArray *routes; - GSList *iter; + GVariantBuilder builder; + int i; - routes = g_ptr_array_new (); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("aau")); - for (iter = list; iter; iter = iter->next) { - NMIP4Route *route = (NMIP4Route *) iter->data; - GArray *array; - guint32 tmp; + if (routes) { + for (i = 0; i < routes->len; i++) { + NMIP4Route *route = routes->pdata[i]; + guint32 array[4]; - array = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3); + array[0] = nm_ip4_route_get_dest (route); + array[1] = nm_ip4_route_get_prefix (route); + array[2] = nm_ip4_route_get_next_hop (route); + array[3] = nm_ip4_route_get_metric (route); - tmp = nm_ip4_route_get_dest (route); - g_array_append_val (array, tmp); + g_variant_builder_add (&builder, "au", + g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + array, 4, sizeof (guint32))); + } + } - tmp = nm_ip4_route_get_prefix (route); - g_array_append_val (array, tmp); + return g_variant_builder_end (&builder); +} - tmp = nm_ip4_route_get_next_hop (route); - g_array_append_val (array, tmp); +GVariant * +_nm_utils_ip4_dns_to_dbus (const GValue *prop_value) +{ + return nm_utils_ip4_dns_to_variant (g_value_get_boxed (prop_value)); +} - tmp = nm_ip4_route_get_metric (route); - g_array_append_val (array, tmp); +void +_nm_utils_ip4_dns_from_dbus (GVariant *dbus_value, + GValue *prop_value) +{ + g_value_take_boxed (prop_value, nm_utils_ip4_dns_from_variant (dbus_value)); +} - g_ptr_array_add (routes, array); - } +GVariant * +_nm_utils_ip4_addresses_to_dbus (const GValue *prop_value) +{ + return nm_utils_ip4_addresses_to_variant (g_value_get_boxed (prop_value)); +} + +void +_nm_utils_ip4_addresses_from_dbus (GVariant *dbus_value, + GValue *prop_value) +{ + g_value_take_boxed (prop_value, nm_utils_ip4_addresses_from_variant (dbus_value)); +} + +GVariant * +_nm_utils_ip4_routes_to_dbus (const GValue *prop_value) +{ + return nm_utils_ip4_routes_to_variant (g_value_get_boxed (prop_value)); +} - g_value_take_boxed (value, routes); +void +_nm_utils_ip4_routes_from_dbus (GVariant *dbus_value, + GValue *prop_value) +{ + g_value_take_boxed (prop_value, nm_utils_ip4_routes_from_variant (dbus_value)); } /** @@ -1351,618 +1282,503 @@ nm_utils_ip4_get_default_prefix (guint32 ip) return 24; /* Class C - 255.255.255.0 */ } -void -_nm_utils_ip6_dns_to_dbus (const GValue *prop_value, - GValue *dbus_value) +GVariant * +_nm_utils_ip6_dns_to_dbus (const GValue *prop_value) { + GVariantBuilder builder; char **dns; - GPtrArray *dbus_dns; int i; dns = g_value_get_boxed (prop_value); - dbus_dns = g_ptr_array_new (); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("aay")); if (dns) { for (i = 0; dns[i]; i++) { - GByteArray *bytearray; + struct in6_addr ip; - bytearray = g_byte_array_new (); - g_byte_array_set_size (bytearray, 16); - inet_pton (AF_INET6, dns[i], bytearray->data); - g_ptr_array_add (dbus_dns, bytearray); + inet_pton (AF_INET6, dns[i], &ip); + g_variant_builder_add (&builder, "ay", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + &ip, sizeof (ip), 1)); } } - g_value_take_boxed (dbus_value, dbus_dns); + return g_variant_builder_end (&builder); } void -_nm_utils_ip6_dns_from_dbus (const GValue *dbus_value, +_nm_utils_ip6_dns_from_dbus (GVariant *dbus_value, GValue *prop_value) { - GPtrArray *dbus_dns, *dns; - int i; + GVariantIter iter; + GVariant *ip_var; + GPtrArray *dns; - dbus_dns = g_value_get_boxed (dbus_value); dns = g_ptr_array_new (); - if (dbus_dns) { - for (i = 0; i < dbus_dns->len; i++) { - GByteArray *bytearray = dbus_dns->pdata[i]; - const char *str; - - if (bytearray->len != 16) { - g_warning ("%s: ignoring invalid IP6 address of length %d", - __func__, bytearray->len); - continue; - } + g_variant_iter_init (&iter, dbus_value); + while (g_variant_iter_next (&iter, "ay", &ip_var)) { + gsize length; + const struct in6_addr *ip = g_variant_get_fixed_array (ip_var, &length, 1); + const char *str; - str = nm_utils_inet6_ntop ((struct in6_addr *) bytearray->data, NULL); - g_ptr_array_add (dns, g_strdup (str)); + if (length != sizeof (struct in6_addr)) { + g_warning ("%s: ignoring invalid IP6 address of length %d", + __func__, (int) length); + g_variant_unref (ip_var); + continue; } + + str = nm_utils_inet6_ntop (ip, NULL); + g_ptr_array_add (dns, g_strdup (str)); + g_variant_unref (ip_var); } g_ptr_array_add (dns, NULL); g_value_take_boxed (prop_value, g_ptr_array_free (dns, FALSE)); } -void -_nm_utils_ip6_addresses_to_dbus (const GValue *prop_value, - GValue *dbus_value) +GVariant * +_nm_utils_ip6_addresses_to_dbus (const GValue *prop_value) { - GPtrArray *addresses, *dbus_addresses; + GVariantBuilder builder; + GPtrArray *addresses; int i; addresses = g_value_get_boxed (prop_value); - dbus_addresses = g_ptr_array_new (); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayuay)")); if (addresses) { for (i = 0; i < addresses->len; i++) { NMIP6Address *addr = addresses->pdata[i]; - GValueArray *array; - GValue element = G_VALUE_INIT; - GByteArray *ba; - - array = g_value_array_new (3); - - /* IP address */ - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - ba = g_byte_array_new (); - g_byte_array_append (ba, (guint8 *) nm_ip6_address_get_address (addr), 16); - g_value_take_boxed (&element, ba); - g_value_array_append (array, &element); - g_value_unset (&element); - - /* Prefix */ - g_value_init (&element, G_TYPE_UINT); - g_value_set_uint (&element, nm_ip6_address_get_prefix (addr)); - g_value_array_append (array, &element); - g_value_unset (&element); - - /* Gateway */ - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - ba = g_byte_array_new (); - g_byte_array_append (ba, (guint8 *) nm_ip6_address_get_gateway (addr), 16); - g_value_take_boxed (&element, ba); - g_value_array_append (array, &element); - g_value_unset (&element); - - g_ptr_array_add (dbus_addresses, array); + GVariant *ip, *gateway; + guint32 prefix; + + ip = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + nm_ip6_address_get_address (addr), + 16, 1); + prefix = nm_ip6_address_get_prefix (addr); + gateway = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + nm_ip6_address_get_gateway (addr), + 16, 1); + + g_variant_builder_add (&builder, "(@au@a)", ip, prefix, gateway); } } - g_value_take_boxed (dbus_value, dbus_addresses); + return g_variant_builder_end (&builder); } void -_nm_utils_ip6_addresses_from_dbus (const GValue *dbus_value, +_nm_utils_ip6_addresses_from_dbus (GVariant *dbus_value, GValue *prop_value) { - GPtrArray *addresses, *dbus_addresses; - int i; + GVariantIter iter; + GVariant *dest_var, *gateway_var; + guint32 prefix, metric; + GPtrArray *addresses; - dbus_addresses = g_value_get_boxed (dbus_value); + g_variant_iter_init (&iter, dbus_value); addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip6_address_unref); - if (dbus_addresses) { - for (i = 0; i < dbus_addresses->len; i++) { - GValueArray *elements = dbus_addresses->pdata[i]; - GValue *tmp; - GByteArray *ba_addr; - GByteArray *ba_gw = NULL; - NMIP6Address *addr; - guint32 prefix; - - if (elements->n_values < 2 || elements->n_values > 3) { - g_warning ("%s: ignoring invalid IP6 address structure", __func__); - continue; - } - - /* Third element (gateway) is optional */ - if ( !_nm_utils_gvalue_array_validate (elements, 2, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT) - && !_nm_utils_gvalue_array_validate (elements, 3, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, DBUS_TYPE_G_UCHAR_ARRAY)) { - g_warning ("%s: ignoring invalid IP6 address structure", __func__); - continue; - } - - tmp = g_value_array_get_nth (elements, 0); - ba_addr = g_value_get_boxed (tmp); - if (ba_addr->len != 16) { - g_warning ("%s: ignoring invalid IP6 address of length %d", - __func__, ba_addr->len); - continue; - } + while (g_variant_iter_next (&iter, "ayuayu", &dest_var, &prefix, &gateway_var, &metric)) { + NMIP6Address *addr; + const struct in6_addr *dest, *gateway; + gsize dest_len, gateway_len; - tmp = g_value_array_get_nth (elements, 1); - prefix = g_value_get_uint (tmp); - if (prefix > 128) { - g_warning ("%s: ignoring invalid IP6 prefix %d", - __func__, prefix); - continue; - } + if ( !g_variant_is_of_type (dest_var, G_VARIANT_TYPE_BYTESTRING) + || !g_variant_is_of_type (gateway_var, G_VARIANT_TYPE_BYTESTRING)) { + g_warning ("%s: ignoring invalid IP6 address structure", __func__); + goto next; + } - if (elements->n_values == 3) { - tmp = g_value_array_get_nth (elements, 2); - ba_gw = g_value_get_boxed (tmp); - if (ba_gw->len != 16) { - g_warning ("%s: ignoring invalid IP6 gateway address of length %d", - __func__, ba_gw->len); - continue; - } - } + dest = g_variant_get_fixed_array (dest_var, &dest_len, 1); + if (dest_len != 16) { + g_warning ("%s: ignoring invalid IP6 address of length %d", + __func__, (int) dest_len); + goto next; + } + if (prefix > 128) { + g_warning ("%s: ignoring invalid IP6 prefix %d", + __func__, prefix); + goto next; + } + gateway = g_variant_get_fixed_array (gateway_var, &gateway_len, 1); + if (gateway_len != 16) { + g_warning ("%s: ignoring invalid IP6 address of length %d", + __func__, (int) gateway_len); + goto next; + } - addr = nm_ip6_address_new (); - nm_ip6_address_set_prefix (addr, prefix); - nm_ip6_address_set_address (addr, (const struct in6_addr *) ba_addr->data); - if (ba_gw) - nm_ip6_address_set_gateway (addr, (const struct in6_addr *) ba_gw->data); + addr = nm_ip6_address_new (); + nm_ip6_address_set_address (addr, dest); + nm_ip6_address_set_prefix (addr, prefix); + nm_ip6_address_set_gateway (addr, gateway); + g_ptr_array_add (addresses, addr); - g_ptr_array_add (addresses, addr); - } + next: + g_variant_unref (dest_var); + g_variant_unref (gateway_var); } g_value_take_boxed (prop_value, addresses); } -void -_nm_utils_ip6_routes_to_dbus (const GValue *prop_value, - GValue *dbus_value) +GVariant * +_nm_utils_ip6_routes_to_dbus (const GValue *prop_value) { - GPtrArray *routes, *dbus_routes; + GPtrArray *routes; + GVariantBuilder builder; int i; routes = g_value_get_boxed (prop_value); - dbus_routes = g_ptr_array_new (); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayuayu)")); if (routes) { for (i = 0; i < routes->len; i++) { NMIP6Route *route = routes->pdata[i]; - GValueArray *array; - const struct in6_addr *addr; - GByteArray *ba; - GValue element = G_VALUE_INIT; - - array = g_value_array_new (4); - - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - addr = nm_ip6_route_get_dest (route); - ba = g_byte_array_new (); - g_byte_array_append (ba, (guchar *)addr, sizeof (*addr)); - g_value_take_boxed (&element, ba); - g_value_array_append (array, &element); - g_value_unset (&element); - - g_value_init (&element, G_TYPE_UINT); - g_value_set_uint (&element, nm_ip6_route_get_prefix (route)); - g_value_array_append (array, &element); - g_value_unset (&element); - - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - addr = nm_ip6_route_get_next_hop (route); - ba = g_byte_array_new (); - g_byte_array_append (ba, (guchar *)addr, sizeof (*addr)); - g_value_take_boxed (&element, ba); - g_value_array_append (array, &element); - g_value_unset (&element); - - g_value_init (&element, G_TYPE_UINT); - g_value_set_uint (&element, nm_ip6_route_get_metric (route)); - g_value_array_append (array, &element); - g_value_unset (&element); - - g_ptr_array_add (dbus_routes, array); + GVariant *dest, *next_hop; + guint32 prefix, metric; + + dest = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + nm_ip6_route_get_dest (route), + 16, 1); + prefix = nm_ip6_route_get_prefix (route); + next_hop = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + nm_ip6_route_get_next_hop (route), + 16, 1); + metric = nm_ip6_route_get_metric (route); + + g_variant_builder_add (&builder, "(@au@au)", dest, prefix, next_hop, metric); } } - g_value_take_boxed (dbus_value, dbus_routes); + return g_variant_builder_end (&builder); } void -_nm_utils_ip6_routes_from_dbus (const GValue *dbus_value, +_nm_utils_ip6_routes_from_dbus (GVariant *dbus_value, GValue *prop_value) { - GPtrArray *routes, *dbus_routes; - int i; + GPtrArray *routes; + GVariantIter iter; + GVariant *dest_var, *next_hop_var; + const struct in6_addr *dest, *next_hop; + gsize dest_len, next_hop_len; + guint32 prefix, metric; - dbus_routes = g_value_get_boxed (dbus_value); routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip6_route_unref); - if (dbus_routes) { - for (i = 0; i < dbus_routes->len; i++) { - GValueArray *route_values = dbus_routes->pdata[i]; - GByteArray *dest, *next_hop; - guint prefix, metric; - NMIP6Route *route; - - if (!_nm_utils_gvalue_array_validate (route_values, 4, - DBUS_TYPE_G_UCHAR_ARRAY, - G_TYPE_UINT, - DBUS_TYPE_G_UCHAR_ARRAY, - G_TYPE_UINT)) { - g_warning ("Ignoring invalid IP6 route"); - continue; - } - - dest = g_value_get_boxed (g_value_array_get_nth (route_values, 0)); - if (dest->len != 16) { - g_warning ("%s: ignoring invalid IP6 dest address of length %d", - __func__, dest->len); - continue; - } - - prefix = g_value_get_uint (g_value_array_get_nth (route_values, 1)); + g_variant_iter_init (&iter, dbus_value); + while (g_variant_iter_next (&iter, "(@au@au)", &dest_var, &prefix, &next_hop_var, &metric)) { + NMIP6Route *route; - next_hop = g_value_get_boxed (g_value_array_get_nth (route_values, 2)); - if (next_hop->len != 16) { - g_warning ("%s: ignoring invalid IP6 next_hop address of length %d", - __func__, next_hop->len); - continue; - } + if ( !g_variant_is_of_type (dest_var, G_VARIANT_TYPE_BYTESTRING) + || !g_variant_is_of_type (next_hop_var, G_VARIANT_TYPE_BYTESTRING)) { + g_warning ("%s: ignoring invalid IP6 address structure", __func__); + goto next; + } - metric = g_value_get_uint (g_value_array_get_nth (route_values, 3)); + dest = g_variant_get_fixed_array (dest_var, &dest_len, 1); + if (dest_len != 16) { + g_warning ("%s: ignoring invalid IP6 address of length %d", + __func__, (int) dest_len); + goto next; + } + next_hop = g_variant_get_fixed_array (next_hop_var, &next_hop_len, 1); + if (next_hop_len != 16) { + g_warning ("%s: ignoring invalid IP6 address of length %d", + __func__, (int) next_hop_len); + goto next; + } - route = nm_ip6_route_new (); - nm_ip6_route_set_dest (route, (struct in6_addr *)dest->data); - nm_ip6_route_set_prefix (route, prefix); - nm_ip6_route_set_next_hop (route, (struct in6_addr *)next_hop->data); - nm_ip6_route_set_metric (route, metric); + route = nm_ip6_route_new (); + nm_ip6_route_set_dest (route, dest); + nm_ip6_route_set_prefix (route, prefix); + nm_ip6_route_set_next_hop (route, next_hop); + nm_ip6_route_set_metric (route, metric); + g_ptr_array_add (routes, route); - g_ptr_array_add (routes, route); - } + next: + g_variant_unref (dest_var); + g_variant_unref (next_hop_var); } g_value_take_boxed (prop_value, routes); } /** - * nm_utils_ip6_addresses_from_gvalue: - * @value: gvalue containing a GPtrArray of GValueArrays of (GArray of guchars) and #guint32 + * nm_utils_ip6_addresses_from_variant: + * @variant: #GVariant containing an "a(ayuay)" * - * Utility function to convert a #GPtrArray of #GValueArrays of (#GArray of guchars) and #guint32 - * representing a list of NetworkManager IPv6 addresses (which is a tuple of address, - * prefix, and gateway), into a #GSList of #NMIP6Address objects. The specific format of - * this serialization is not guaranteed to be stable and the #GValueArray may be - * extended in the future. + * Utility function to convert an "a(ayuay)" (array of tuples of address, prefix, + * and gateway), into a #GSList of #NMIP6Address objects. * - * Returns: (transfer full) (element-type NMIP6Address): a newly allocated #GSList of #NMIP6Address objects + * Returns: (transfer full) (element-type NMIP6Address): a newly allocated #GSList of + * #NMIP6Address objects **/ -GSList * -nm_utils_ip6_addresses_from_gvalue (const GValue *value) +GPtrArray * +nm_utils_ip6_addresses_from_variant (GVariant *variant) { + GVariantIter iter; + GVariant *ip_var, *gateway_var; + const struct in6_addr *ip, *gateway; + gsize ip_len, gateway_len; + guint32 prefix; GPtrArray *addresses; - int i; - GSList *list = NULL; - addresses = (GPtrArray *) g_value_get_boxed (value); - - for (i = 0; addresses && (i < addresses->len); i++) { - GValueArray *elements = (GValueArray *) g_ptr_array_index (addresses, i); - GValue *tmp; - GByteArray *ba_addr; - GByteArray *ba_gw = NULL; + addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip6_address_unref); + g_variant_iter_init (&iter, variant); + while (g_variant_iter_next (&iter, "(@au@a)", &ip_var, &prefix, &gateway_var)) { NMIP6Address *addr; - guint32 prefix; - - if (elements->n_values < 2 || elements->n_values > 3) { - g_warning ("%s: ignoring invalid IP6 address structure", __func__); - continue; - } - /* Third element (gateway) is optional */ - if ( !_nm_utils_gvalue_array_validate (elements, 2, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT) - && !_nm_utils_gvalue_array_validate (elements, 3, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, DBUS_TYPE_G_UCHAR_ARRAY)) { + if ( !g_variant_is_of_type (ip_var, G_VARIANT_TYPE_BYTESTRING) + || !g_variant_is_of_type (gateway_var, G_VARIANT_TYPE_BYTESTRING)) { g_warning ("%s: ignoring invalid IP6 address structure", __func__); - continue; + goto next; } - tmp = g_value_array_get_nth (elements, 0); - ba_addr = g_value_get_boxed (tmp); - if (ba_addr->len != 16) { + ip = g_variant_get_fixed_array (ip_var, &ip_len, 1); + if (ip_len != 16) { g_warning ("%s: ignoring invalid IP6 address of length %d", - __func__, ba_addr->len); - continue; + __func__, (int) ip_len); + goto next; } - - tmp = g_value_array_get_nth (elements, 1); - prefix = g_value_get_uint (tmp); if (prefix > 128) { g_warning ("%s: ignoring invalid IP6 prefix %d", __func__, prefix); - continue; + goto next; } - - if (elements->n_values == 3) { - tmp = g_value_array_get_nth (elements, 2); - ba_gw = g_value_get_boxed (tmp); - if (ba_gw->len != 16) { - g_warning ("%s: ignoring invalid IP6 gateway address of length %d", - __func__, ba_gw->len); - continue; - } + gateway = g_variant_get_fixed_array (gateway_var, &gateway_len, 1); + if (gateway_len != 16) { + g_warning ("%s: ignoring invalid IP6 address of length %d", + __func__, (int) gateway_len); + goto next; } addr = nm_ip6_address_new (); + nm_ip6_address_set_address (addr, ip); nm_ip6_address_set_prefix (addr, prefix); - nm_ip6_address_set_address (addr, (const struct in6_addr *) ba_addr->data); - if (ba_gw) - nm_ip6_address_set_gateway (addr, (const struct in6_addr *) ba_gw->data); + nm_ip6_address_set_gateway (addr, gateway); + g_ptr_array_add (addresses, addr); - list = g_slist_prepend (list, addr); + next: + g_variant_unref (ip_var); + g_variant_unref (gateway_var); } - return g_slist_reverse (list); + return addresses; } /** - * nm_utils_ip6_addresses_to_gvalue: - * @list: (element-type NMIP6Address): a list of #NMIP6Address objects - * @value: a pointer to a #GValue into which to place the converted addresses, - * which should be unset by the caller (when no longer needed) with - * g_value_unset(). - * - * Utility function to convert a #GSList of #NMIP6Address objects into a - * #GPtrArray of #GValueArrays representing a list of NetworkManager IPv6 addresses - * (which is a tuple of address, prefix, and gateway). The specific format of - * this serialization is not guaranteed to be stable and may be extended in the - * future. + * nm_utils_ip6_addresses_to_variant: + * @addresses: (element-type NMIP6Address): an array of #NMIP6Address objects + * + * Utility function to convert a #GSList of #NMIP6Address objects into an + * "a(ayuay)" variant representing a list of NetworkManager IPv6 addresses (which + * is a tuple of address, prefix, and gateway). + * + * Return value: (transfer none): a new floating #GVariant containing the + * addresses **/ -void -nm_utils_ip6_addresses_to_gvalue (GSList *list, GValue *value) +GVariant * +nm_utils_ip6_addresses_to_variant (GPtrArray *addresses) { - GPtrArray *addresses; - GSList *iter; - - addresses = g_ptr_array_new (); - - for (iter = list; iter; iter = iter->next) { - NMIP6Address *addr = (NMIP6Address *) iter->data; - GValueArray *array; - GValue element = G_VALUE_INIT; - GByteArray *ba; - - array = g_value_array_new (3); + GVariantBuilder builder; + int i; - /* IP address */ - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - ba = g_byte_array_new (); - g_byte_array_append (ba, (guint8 *) nm_ip6_address_get_address (addr), 16); - g_value_take_boxed (&element, ba); - g_value_array_append (array, &element); - g_value_unset (&element); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayuay)")); - /* Prefix */ - g_value_init (&element, G_TYPE_UINT); - g_value_set_uint (&element, nm_ip6_address_get_prefix (addr)); - g_value_array_append (array, &element); - g_value_unset (&element); + for (i = 0; i < addresses->len; i++) { + NMIP6Address *addr = (NMIP6Address *) addresses->pdata[i]; + GVariant *ip, *gateway; + guint32 prefix; - /* Gateway */ - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - ba = g_byte_array_new (); - g_byte_array_append (ba, (guint8 *) nm_ip6_address_get_gateway (addr), 16); - g_value_take_boxed (&element, ba); - g_value_array_append (array, &element); - g_value_unset (&element); + ip = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + nm_ip6_address_get_address (addr), + 16, 1); + prefix = nm_ip6_address_get_prefix (addr); + gateway = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + nm_ip6_address_get_gateway (addr), + 16, 1); - g_ptr_array_add (addresses, array); + g_variant_builder_add (&builder, "(@au@a)", ip, prefix, gateway); } - g_value_take_boxed (value, addresses); + return g_variant_builder_end (&builder); } /** - * nm_utils_ip6_routes_from_gvalue: - * @value: #GValue containing a #GPtrArray of #GValueArrays of (#GArray of #guchars), #guint32, - * (#GArray of #guchars), and #guint32 + * nm_utils_ip6_routes_from_variant: + * @variant: #GVariant containing an "a(ayuayu)" * - * Utility function #GPtrArray of #GValueArrays of (#GArray of #guchars), #guint32, - * (#GArray of #guchars), and #guint32 representing a list of NetworkManager IPv6 - * routes (which is a tuple of destination, prefix, next hop, and metric) - * into a #GSList of #NMIP6Route objects. The specific format of this serialization - * is not guaranteed to be stable and may be extended in the future. + * Utility function to convert an "a(ayuayu)" representing a list of NetworkManager + * IPv6 routes (which is a tuple of destination, prefix, next hop, and metric) into a + * #GSList of #NMIP6Route objects. * - * Returns: (transfer full) (element-type NMIP6Route): a newly allocated #GSList of #NMIP6Route objects + * Returns: (transfer full) (element-type NMIP6Route): a newly allocated #GSList of + * #NMIP6Route objects **/ -GSList * -nm_utils_ip6_routes_from_gvalue (const GValue *value) -{ +GPtrArray * +nm_utils_ip6_routes_from_variant (GVariant *variant) +{ + GVariantIter iter; + GVariant *dest_var, *next_hop_var; + const struct in6_addr *dest, *next_hop; + gsize dest_len, next_hop_len; + guint32 prefix, metric; GPtrArray *routes; - int i; - GSList *list = NULL; - routes = (GPtrArray *) g_value_get_boxed (value); - for (i = 0; routes && (i < routes->len); i++) { - GValueArray *route_values = (GValueArray *) g_ptr_array_index (routes, i); - GByteArray *dest, *next_hop; - guint prefix, metric; + routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip6_route_unref); + g_variant_iter_init (&iter, variant); + while (g_variant_iter_next (&iter, "(@au@au)", &dest_var, &prefix, &next_hop_var, &metric)) { NMIP6Route *route; - if (!_nm_utils_gvalue_array_validate (route_values, 4, - DBUS_TYPE_G_UCHAR_ARRAY, - G_TYPE_UINT, - DBUS_TYPE_G_UCHAR_ARRAY, - G_TYPE_UINT)) { - g_warning ("Ignoring invalid IP6 route"); - continue; + if ( !g_variant_is_of_type (dest_var, G_VARIANT_TYPE_BYTESTRING) + || !g_variant_is_of_type (next_hop_var, G_VARIANT_TYPE_BYTESTRING)) { + g_warning ("%s: ignoring invalid IP6 address structure", __func__); + goto next; } - dest = g_value_get_boxed (g_value_array_get_nth (route_values, 0)); - if (dest->len != 16) { - g_warning ("%s: ignoring invalid IP6 dest address of length %d", - __func__, dest->len); - continue; + dest = g_variant_get_fixed_array (dest_var, &dest_len, 1); + if (dest_len != 16) { + g_warning ("%s: ignoring invalid IP6 address of length %d", + __func__, (int) dest_len); + goto next; } - - prefix = g_value_get_uint (g_value_array_get_nth (route_values, 1)); - - next_hop = g_value_get_boxed (g_value_array_get_nth (route_values, 2)); - if (next_hop->len != 16) { - g_warning ("%s: ignoring invalid IP6 next_hop address of length %d", - __func__, next_hop->len); - continue; + next_hop = g_variant_get_fixed_array (next_hop_var, &next_hop_len, 1); + if (next_hop_len != 16) { + g_warning ("%s: ignoring invalid IP6 address of length %d", + __func__, (int) next_hop_len); + goto next; } - metric = g_value_get_uint (g_value_array_get_nth (route_values, 3)); - route = nm_ip6_route_new (); - nm_ip6_route_set_dest (route, (struct in6_addr *)dest->data); + nm_ip6_route_set_dest (route, dest); nm_ip6_route_set_prefix (route, prefix); - nm_ip6_route_set_next_hop (route, (struct in6_addr *)next_hop->data); + nm_ip6_route_set_next_hop (route, next_hop); nm_ip6_route_set_metric (route, metric); - list = g_slist_prepend (list, route); + g_ptr_array_add (routes, route); + + next: + g_variant_unref (dest_var); + g_variant_unref (next_hop_var); } - return g_slist_reverse (list); + return routes; } /** - * nm_utils_ip6_routes_to_gvalue: - * @list: (element-type NMIP6Route): a list of #NMIP6Route objects - * @value: a pointer to a #GValue into which to place the converted routes, - * which should be unset by the caller (when no longer needed) with - * g_value_unset(). - * - * Utility function to convert a #GSList of #NMIP6Route objects into a #GPtrArray of - * #GValueArrays of (#GArray of #guchars), #guint32, (#GArray of #guchars), and #guint32 - * representing a list of NetworkManager IPv6 routes (which is a tuple of destination, - * prefix, next hop, and metric). The specific format of this serialization is not - * guaranteed to be stable and may be extended in the future. + * nm_utils_ip6_routes_to_variant: + * @routes: (element-type NMIP6Route): an array of #NMIP6Route objects + * + * Utility function to convert a #GSList of #NMIP6Route objects into an + * "a(ayuayu)" variant representing a list of NetworkManager IPv6 + * routes (which is a tuple of destination, prefix, next hop, and metric). + * + * Return value: (transfer none): a new floating #GVariant containing the + * routes **/ -void -nm_utils_ip6_routes_to_gvalue (GSList *list, GValue *value) +GVariant * +nm_utils_ip6_routes_to_variant (GPtrArray *routes) { - GPtrArray *routes; - GSList *iter; - - routes = g_ptr_array_new (); - - for (iter = list; iter; iter = iter->next) { - NMIP6Route *route = (NMIP6Route *) iter->data; - GValueArray *array; - const struct in6_addr *addr; - GByteArray *ba; - GValue element = G_VALUE_INIT; - - array = g_value_array_new (4); - - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - addr = nm_ip6_route_get_dest (route); - ba = g_byte_array_new (); - g_byte_array_append (ba, (guchar *)addr, sizeof (*addr)); - g_value_take_boxed (&element, ba); - g_value_array_append (array, &element); - g_value_unset (&element); + GVariantBuilder builder; + int i; - g_value_init (&element, G_TYPE_UINT); - g_value_set_uint (&element, nm_ip6_route_get_prefix (route)); - g_value_array_append (array, &element); - g_value_unset (&element); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayuayu)")); - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - addr = nm_ip6_route_get_next_hop (route); - ba = g_byte_array_new (); - g_byte_array_append (ba, (guchar *)addr, sizeof (*addr)); - g_value_take_boxed (&element, ba); - g_value_array_append (array, &element); - g_value_unset (&element); + for (i = 0; i < routes->len; i++) { + NMIP6Route *route = (NMIP6Route *) routes->pdata[i]; + GVariant *dest, *next_hop; + guint32 prefix, metric; - g_value_init (&element, G_TYPE_UINT); - g_value_set_uint (&element, nm_ip6_route_get_metric (route)); - g_value_array_append (array, &element); - g_value_unset (&element); + dest = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + nm_ip6_route_get_dest (route), + 16, 1); + prefix = nm_ip6_route_get_prefix (route); + next_hop = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + nm_ip6_route_get_next_hop (route), + 16, 1); + metric = nm_ip6_route_get_metric (route); - g_ptr_array_add (routes, array); + g_variant_builder_add (&builder, "(@au@au)", dest, prefix, next_hop, metric); } - g_value_take_boxed (value, routes); + return g_variant_builder_end (&builder); } /** - * nm_utils_ip6_dns_from_gvalue: (skip) - * @value: a #GValue + * nm_utils_ip6_dns_from_variant: (skip) + * @variant: a #GVariant * - * Converts a #GValue containing a #GPtrArray of IP6 DNS, represented as - * #GByteArrays into a #GSList of IP address strings. + * Converts a #GVariant containing an "aay" of DNS server IPv6 + * addresses into an array of IPv6 address strings. * - * Returns: a #GSList of IP6 addresses. + * Returns: a %NULL-terminated array of IPv6 address strings. */ -GSList * -nm_utils_ip6_dns_from_gvalue (const GValue *value) +char ** +nm_utils_ip6_dns_from_variant (GVariant *variant) { + GVariantIter iter; + GVariant *ip_var; + const struct in6_addr *ip; + gsize ip_len; + const char *str; GPtrArray *dns; - int i; - GSList *list = NULL; - dns = (GPtrArray *) g_value_get_boxed (value); - for (i = 0; dns && (i < dns->len); i++) { - GByteArray *bytearray = (GByteArray *) g_ptr_array_index (dns, i); - const char *str; + dns = g_ptr_array_new (); - if (bytearray->len != 16) { + g_variant_iter_init (&iter, variant); + while (g_variant_iter_next (&iter, "@a", &ip_var)) { + if (!g_variant_is_of_type (ip_var, G_VARIANT_TYPE_BYTESTRING)) { + g_warning ("%s: ignoring invalid IP6 address structure", __func__); + goto next; + } + + ip = g_variant_get_fixed_array (ip_var, &ip_len, 1); + if (ip_len != 16) { g_warning ("%s: ignoring invalid IP6 address of length %d", - __func__, bytearray->len); - continue; + __func__, (int) ip_len); + goto next; } - str = nm_utils_inet6_ntop ((struct in6_addr *) bytearray->data, NULL); - list = g_slist_prepend (list, g_strdup (str)); + str = nm_utils_inet6_ntop (ip, NULL); + g_ptr_array_add (dns, g_strdup (str)); + + next: + g_variant_unref (ip_var); } - return g_slist_reverse (list); + g_ptr_array_add (dns, NULL); + return (char **) g_ptr_array_free (dns, FALSE); } /** - * nm_utils_ip6_dns_to_gvalue: (skip) - * @list: a list of #NMIP6Route objects - * @value: a pointer to a #GValue into which to place the converted DNS server - * addresses, which should be unset by the caller (when no longer needed) with - * g_value_unset(). - * - * Utility function to convert a #GSList of <literal><type>struct - * in6_addr</type></literal> structs into a #GPtrArray of #GByteArrays - * representing each server's IPv6 addresses in network byte order. - * The specific format of this serialization is not guaranteed to be - * stable and may be extended in the future. + * nm_utils_ip6_dns_to_variant: (skip) + * @dns: a %NULL-termianted array of IP address strings + * + * Utility function to convert an array of IPv6 address strings into an "aay" + * variant representing each server's IPv6 addresses in network byte order. */ -void -nm_utils_ip6_dns_to_gvalue (GSList *list, GValue *value) +GVariant * +nm_utils_ip6_dns_to_variant (char **dns) { - GPtrArray *dns; - GSList *iter; + GVariantBuilder builder; + int i; - dns = g_ptr_array_new (); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("aay")); - for (iter = list; iter; iter = iter->next) { - const char *str = iter->data; - GByteArray *bytearray; + if (dns) { + for (i = 0; dns[i]; i++) { + struct in6_addr ip = IN6ADDR_ANY_INIT; - bytearray = g_byte_array_new (); - g_byte_array_set_size (bytearray, 16); - inet_pton (AF_INET6, str, bytearray->data); - g_ptr_array_add (dns, bytearray); + inet_pton (AF_INET6, dns[i], &ip); + g_variant_builder_add (&builder, "@a", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, &ip, 16, 1)); + } } - g_value_take_boxed (value, dns); + return g_variant_builder_end (&builder); } /** @@ -2719,25 +2535,33 @@ nm_utils_hwaddr_equal (gconstpointer hwaddr1, return !memcmp (hwaddr1, hwaddr2, hwaddr1_len); } -void -_nm_utils_hwaddr_to_dbus (const GValue *prop_value, - GValue *dbus_value) +GVariant * +_nm_utils_hwaddr_to_dbus (const GValue *prop_value) { const char *str = g_value_get_string (prop_value); - GByteArray *array; + guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; + int len; + + if (str) { + len = hwaddr_binary_len (str); + g_return_val_if_fail (len <= NM_UTILS_HWADDR_LEN_MAX, NULL); + if (!nm_utils_hwaddr_aton (str, buf, len)) + len = 0; + } else + len = 0; - array = str ? nm_utils_hwaddr_atoba (str, hwaddr_binary_len (str)) : NULL; - g_value_take_boxed (dbus_value, array); + return g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, buf, len, 1); } void -_nm_utils_hwaddr_from_dbus (const GValue *dbus_value, +_nm_utils_hwaddr_from_dbus (GVariant *dbus_value, GValue *prop_value) { - GByteArray *array = g_value_get_boxed (dbus_value); + gsize length = 0; + const guint8 *array = g_variant_get_fixed_array (dbus_value, &length, 1); char *str; - str = array ? nm_utils_hwaddr_ntoa (array->data, array->len) : NULL; + str = length ? nm_utils_hwaddr_ntoa (array, length) : NULL; g_value_take_string (prop_value, str); } |