diff --git a/libnm-util/Makefile.am b/libnm-util/Makefile.am index 2222ec2b2f..0f46f4b32b 100644 --- a/libnm-util/Makefile.am +++ b/libnm-util/Makefile.am @@ -42,7 +42,7 @@ libnm_util_include_HEADERS = \ libnm_util_la_private_headers = \ crypto.h \ nm-param-spec-specialized.h \ - nm-utils-private.h \ + nm-utils-private.h \ nm-setting-private.h libnm_util_la_csources = \ @@ -73,7 +73,8 @@ libnm_util_la_csources = \ nm-setting-wireless-security.c \ nm-setting-vpn.c \ nm-utils-enum-types.c \ - nm-utils.c + nm-utils.c \ + nm-value-transforms.c libnm_util_la_SOURCES = \ $(libnm_util_la_csources) \ diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c index b075bfe601..3a38ec4d0d 100644 --- a/libnm-util/nm-connection.c +++ b/libnm-util/nm-connection.c @@ -127,7 +127,7 @@ static void __attribute__((constructor)) _ensure_registered (void) { g_type_init (); - _nm_utils_register_value_transformations (); + _nm_value_transforms_register (); if (G_UNLIKELY (registered_settings == NULL)) registered_settings = g_hash_table_new (g_str_hash, g_str_equal); } diff --git a/libnm-util/nm-utils-private.h b/libnm-util/nm-utils-private.h index bbafbbbfe9..28fdfcb2de 100644 --- a/libnm-util/nm-utils-private.h +++ b/libnm-util/nm-utils-private.h @@ -32,9 +32,11 @@ gboolean _nm_utils_string_in_list (const char *str, gboolean _nm_utils_string_slist_validate (GSList *list, const char **valid_values); -void _nm_utils_register_value_transformations (void); +gboolean _nm_utils_gvalue_array_validate (GValueArray *elements, + guint n_expected, ...); gboolean _nm_utils_carrier_detect_mode_valid (const char *carrier_detect); +void _nm_value_transforms_register (void); #endif diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c index aa47788544..da17b2a676 100644 --- a/libnm-util/nm-utils.c +++ b/libnm-util/nm-utils.c @@ -25,27 +25,17 @@ */ #include "config.h" + #include -#include #include -#include -#include #include #include - -#include -#include -#include -#include #include #include "nm-utils.h" #include "nm-utils-private.h" -#include "NetworkManager.h" #include "nm-glib-compat.h" #include "nm-dbus-glib-types.h" -#include "nm-setting-ip4-config.h" -#include "nm-setting-ip6-config.h" #include "crypto.h" /** @@ -240,7 +230,7 @@ nm_utils_init (GError **error) if (!crypto_init (error)) return FALSE; - _nm_utils_register_value_transformations (); + _nm_value_transforms_register (); } return TRUE; } @@ -536,363 +526,8 @@ _nm_utils_string_slist_validate (GSList *list, const char **valid_values) return TRUE; } -static void -_nm_utils_convert_op_to_string (const GValue *src_value, GValue *dest_value) -{ - g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_OBJECT_PATH)); - - g_value_set_string (dest_value, (const char *) g_value_get_boxed (src_value)); -} - -static void -_nm_utils_convert_strv_to_slist (const GValue *src_value, GValue *dest_value) -{ - char **str; - GSList *list = NULL; - guint i = 0; - - g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), G_TYPE_STRV)); - - str = (char **) g_value_get_boxed (src_value); - - while (str && str[i]) - list = g_slist_prepend (list, g_strdup (str[i++])); - - g_value_take_boxed (dest_value, g_slist_reverse (list)); -} - -static void -_nm_utils_convert_strv_to_ptrarray (const GValue *src_value, GValue *dest_value) -{ - char **str; - GPtrArray *array = NULL; - guint i = 0; - - g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), G_TYPE_STRV)); - - str = (char **) g_value_get_boxed (src_value); - - array = g_ptr_array_sized_new (3); - while (str && str[i]) - g_ptr_array_add (array, g_strdup (str[i++])); - - g_value_take_boxed (dest_value, array); -} - -static void -_nm_utils_convert_strv_to_string (const GValue *src_value, GValue *dest_value) -{ - GSList *strings; - GString *printable; - GSList *iter; - - g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_LIST_OF_STRING)); - - strings = (GSList *) g_value_get_boxed (src_value); - - printable = g_string_new ("["); - for (iter = strings; iter; iter = g_slist_next (iter)) { - if (iter != strings) - g_string_append (printable, ", '"); - else - g_string_append_c (printable, '\''); - g_string_append (printable, iter->data); - g_string_append_c (printable, '\''); - } - g_string_append_c (printable, ']'); - - g_value_take_string (dest_value, printable->str); - g_string_free (printable, FALSE); -} - -static void -_string_array_to_string (const GPtrArray *strings, GValue *dest_value) -{ - GString *printable; - int i; - - printable = g_string_new ("["); - for (i = 0; strings && i < strings->len; i++) { - if (i > 0) - g_string_append (printable, ", '"); - else - g_string_append_c (printable, '\''); - g_string_append (printable, g_ptr_array_index (strings, i)); - g_string_append_c (printable, '\''); - } - g_string_append_c (printable, ']'); - - g_value_take_string (dest_value, printable->str); - g_string_free (printable, FALSE); -} - -static void -_nm_utils_convert_string_array_to_string (const GValue *src_value, GValue *dest_value) -{ - const GPtrArray *strings; - - g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_STRING)); - - strings = (const GPtrArray *) g_value_get_boxed (src_value); - _string_array_to_string (strings, dest_value); -} - -static void -_nm_utils_convert_op_array_to_string (const GValue *src_value, GValue *dest_value) -{ - const GPtrArray *strings; - - g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH)); - - strings = (const GPtrArray *) g_value_get_boxed (src_value); - _string_array_to_string (strings, dest_value); -} - -static void -_nm_utils_convert_uint_array_to_string (const GValue *src_value, GValue *dest_value) -{ - GArray *array; - GString *printable; - guint i = 0; - - g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_UINT_ARRAY)); - - array = (GArray *) g_value_get_boxed (src_value); - - printable = g_string_new ("["); - while (array && (i < array->len)) { - char buf[INET_ADDRSTRLEN + 1]; - struct in_addr addr; - - if (i > 0) - g_string_append (printable, ", "); - - memset (buf, 0, sizeof (buf)); - addr.s_addr = g_array_index (array, guint32, i++); - if (!inet_ntop (AF_INET, &addr, buf, INET_ADDRSTRLEN)) - g_warning ("%s: error converting IP4 address 0x%X", - __func__, ntohl (addr.s_addr)); - g_string_append_printf (printable, "%u (%s)", addr.s_addr, buf); - } - g_string_append_c (printable, ']'); - - g_value_take_string (dest_value, printable->str); - g_string_free (printable, FALSE); -} - -static void -_nm_utils_convert_ip4_addr_route_struct_array_to_string (const GValue *src_value, GValue *dest_value) -{ - GPtrArray *ptr_array; - GString *printable; - guint i = 0; - - g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT)); - - ptr_array = (GPtrArray *) g_value_get_boxed (src_value); - - printable = g_string_new ("["); - while (ptr_array && (i < ptr_array->len)) { - GArray *array; - char buf[INET_ADDRSTRLEN + 1]; - struct in_addr addr; - gboolean is_addr; /* array contains address x route */ - - if (i > 0) - g_string_append (printable, ", "); - - g_string_append (printable, "{ "); - array = (GArray *) g_ptr_array_index (ptr_array, i++); - if (array->len < 2) { - g_string_append (printable, "invalid"); - continue; - } - is_addr = (array->len < 4); - - memset (buf, 0, sizeof (buf)); - addr.s_addr = g_array_index (array, guint32, 0); - if (!inet_ntop (AF_INET, &addr, buf, INET_ADDRSTRLEN)) - g_warning ("%s: error converting IP4 address 0x%X", - __func__, ntohl (addr.s_addr)); - if (is_addr) - g_string_append_printf (printable, "ip = %s", buf); - else - g_string_append_printf (printable, "dst = %s", buf); - g_string_append (printable, ", "); - - memset (buf, 0, sizeof (buf)); - g_string_append_printf (printable, "px = %u", - g_array_index (array, guint32, 1)); - - if (array->len > 2) { - g_string_append (printable, ", "); - - memset (buf, 0, sizeof (buf)); - addr.s_addr = g_array_index (array, guint32, 2); - if (!inet_ntop (AF_INET, &addr, buf, INET_ADDRSTRLEN)) - g_warning ("%s: error converting IP4 address 0x%X", - __func__, ntohl (addr.s_addr)); - if (is_addr) - g_string_append_printf (printable, "gw = %s", buf); - else - g_string_append_printf (printable, "nh = %s", buf); - } - - if (array->len > 3) { - g_string_append (printable, ", "); - - memset (buf, 0, sizeof (buf)); - g_string_append_printf (printable, "mt = %u", - g_array_index (array, guint32, 3)); - } - - g_string_append (printable, " }"); - } - g_string_append_c (printable, ']'); - - g_value_take_string (dest_value, printable->str); - g_string_free (printable, FALSE); -} - -static void -convert_one_gvalue_hash_entry (gpointer key, gpointer value, gpointer user_data) -{ - GString *printable = (GString *) user_data; - char *value_as_string; - - value_as_string = g_strdup_value_contents ((GValue *) value); - g_string_append_printf (printable, " { '%s': %s },", (const char *) key, value_as_string); - g_free (value_as_string); -} - -static void -_nm_utils_convert_gvalue_hash_to_string (const GValue *src_value, GValue *dest_value) -{ - GHashTable *hash; - GString *printable; - - g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_MAP_OF_VARIANT)); - - hash = (GHashTable *) g_value_get_boxed (src_value); - - printable = g_string_new ("["); - g_hash_table_foreach (hash, convert_one_gvalue_hash_entry, printable); - g_string_append (printable, " ]"); - - g_value_take_string (dest_value, printable->str); - g_string_free (printable, FALSE); -} - -static void -convert_one_string_hash_entry (gpointer key, gpointer value, gpointer user_data) -{ - GString *printable = (GString *) user_data; - - g_string_append_printf (printable, " { '%s': %s },", (const char *) key, (const char *) value); -} - -static void -_nm_utils_convert_string_hash_to_string (const GValue *src_value, GValue *dest_value) -{ - GHashTable *hash; - GString *printable; - - g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_MAP_OF_STRING)); - - hash = (GHashTable *) g_value_get_boxed (src_value); - - printable = g_string_new ("["); - if (hash) - g_hash_table_foreach (hash, convert_one_string_hash_entry, printable); - g_string_append (printable, " ]"); - - g_value_take_string (dest_value, printable->str); - g_string_free (printable, FALSE); -} - -static void -_nm_utils_convert_byte_array_to_string (const GValue *src_value, GValue *dest_value) -{ - GArray *array; - GString *printable; - guint i = 0; - - g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_UCHAR_ARRAY)); - - array = (GArray *) g_value_get_boxed (src_value); - - printable = g_string_new ("["); - if (array) { - while (i < MIN (array->len, 35)) { - if (i > 0) - g_string_append_c (printable, ' '); - g_string_append_printf (printable, "0x%02X", - g_array_index (array, unsigned char, i++)); - } - if (i < array->len) - g_string_append (printable, " ... "); - } - g_string_append_c (printable, ']'); - - g_value_take_string (dest_value, printable->str); - g_string_free (printable, FALSE); -} - -static gboolean -_nm_utils_inet6_ntop (struct in6_addr *addr, char *buf) -{ - if (!inet_ntop (AF_INET6, addr, buf, INET6_ADDRSTRLEN)) { - int i; - GString *ip6_str = g_string_new (NULL); - g_string_append_printf (ip6_str, "%02X", addr->s6_addr[0]); - for (i = 1; i < 16; i++) - g_string_append_printf (ip6_str, " %02X", addr->s6_addr[i]); - g_warning ("%s: error converting IP6 address %s", - __func__, ip6_str->str); - g_string_free (ip6_str, TRUE); - return FALSE; - } - return TRUE; -} - -static void -_nm_utils_convert_ip6_dns_array_to_string (const GValue *src_value, GValue *dest_value) -{ - GPtrArray *ptr_array; - GString *printable; - guint i = 0; - - g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR)); - - ptr_array = (GPtrArray *) g_value_get_boxed (src_value); - - printable = g_string_new ("["); - while (ptr_array && (i < ptr_array->len)) { - GByteArray *bytearray; - char buf[INET6_ADDRSTRLEN]; - struct in6_addr *addr; - - if (i > 0) - g_string_append (printable, ", "); - - bytearray = (GByteArray *) g_ptr_array_index (ptr_array, i++); - if (bytearray->len != 16) { - g_string_append (printable, "invalid"); - continue; - } - addr = (struct in6_addr *) bytearray->data; - memset (buf, 0, sizeof (buf)); - _nm_utils_inet6_ntop (addr, buf); - g_string_append_printf (printable, "%s", buf); - } - g_string_append_c (printable, ']'); - - g_value_take_string (dest_value, printable->str); - g_string_free (printable, FALSE); -} - -static gboolean -validate_gvalue_array (GValueArray *elements, guint n_expected, ...) +gboolean +_nm_utils_gvalue_array_validate (GValueArray *elements, guint n_expected, ...) { va_list args; GValue *tmp; @@ -915,268 +550,6 @@ done: return valid; } -static void -_nm_utils_convert_ip6_addr_struct_array_to_string (const GValue *src_value, GValue *dest_value) -{ - GPtrArray *ptr_array; - GString *printable; - guint i = 0; - - g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS)); - - ptr_array = (GPtrArray *) g_value_get_boxed (src_value); - - printable = g_string_new ("["); - while (ptr_array && (i < ptr_array->len)) { - GValueArray *elements; - GValue *tmp; - GByteArray *ba_addr; - char buf[INET6_ADDRSTRLEN]; - struct in6_addr *addr; - guint32 prefix; - - if (i > 0) - g_string_append (printable, ", "); - - g_string_append (printable, "{ "); - elements = (GValueArray *) g_ptr_array_index (ptr_array, i++); - if (!validate_gvalue_array (elements, 3, - DBUS_TYPE_G_UCHAR_ARRAY, - G_TYPE_UINT, - DBUS_TYPE_G_UCHAR_ARRAY)) { - g_string_append (printable, "invalid }"); - continue; - } - - /* IPv6 address */ - tmp = g_value_array_get_nth (elements, 0); - ba_addr = g_value_get_boxed (tmp); - if (ba_addr->len != 16) { - g_string_append (printable, "invalid }"); - continue; - } - addr = (struct in6_addr *) ba_addr->data; - memset (buf, 0, sizeof (buf)); - _nm_utils_inet6_ntop (addr, buf); - g_string_append_printf (printable, "ip = %s", buf); - g_string_append (printable, ", "); - - /* Prefix */ - tmp = g_value_array_get_nth (elements, 1); - prefix = g_value_get_uint (tmp); - if (prefix > 128) { - g_string_append (printable, "invalid }"); - continue; - } - g_string_append_printf (printable, "px = %u", prefix); - g_string_append (printable, ", "); - - /* IPv6 Gateway */ - tmp = g_value_array_get_nth (elements, 2); - ba_addr = g_value_get_boxed (tmp); - if (ba_addr->len != 16) { - g_string_append (printable, "invalid }"); - continue; - } - addr = (struct in6_addr *) ba_addr->data; - memset (buf, 0, sizeof (buf)); - _nm_utils_inet6_ntop (addr, buf); - g_string_append_printf (printable, "gw = %s", buf); - g_string_append (printable, " }"); - } - g_string_append_c (printable, ']'); - - g_value_take_string (dest_value, printable->str); - g_string_free (printable, FALSE); -} - -static void -_nm_utils_convert_ip6_route_struct_array_to_string (const GValue *src_value, GValue *dest_value) -{ - GPtrArray *ptr_array; - GString *printable; - guint i = 0; - - g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE)); - - ptr_array = (GPtrArray *) g_value_get_boxed (src_value); - - printable = g_string_new ("["); - while (ptr_array && (i < ptr_array->len)) { - GValueArray *elements; - GValue *tmp; - GByteArray *ba_addr; - char buf[INET6_ADDRSTRLEN]; - struct in6_addr *addr; - guint32 prefix, metric; - - if (i > 0) - g_string_append (printable, ", "); - - g_string_append (printable, "{ "); - elements = (GValueArray *) g_ptr_array_index (ptr_array, i++); - if (!validate_gvalue_array (elements, 4, - DBUS_TYPE_G_UCHAR_ARRAY, - G_TYPE_UINT, - DBUS_TYPE_G_UCHAR_ARRAY, - G_TYPE_UINT)) { - g_string_append (printable, "invalid"); - continue; - } - - /* Destination address */ - tmp = g_value_array_get_nth (elements, 0); - ba_addr = g_value_get_boxed (tmp); - if (ba_addr->len != 16) { - g_string_append (printable, "invalid"); - continue; - } - addr = (struct in6_addr *) ba_addr->data; - memset (buf, 0, sizeof (buf)); - _nm_utils_inet6_ntop (addr, buf); - g_string_append_printf (printable, "dst = %s", buf); - g_string_append (printable, ", "); - - /* Prefix */ - tmp = g_value_array_get_nth (elements, 1); - prefix = g_value_get_uint (tmp); - if (prefix > 128) { - g_string_append (printable, "invalid"); - continue; - } - g_string_append_printf (printable, "px = %u", prefix); - g_string_append (printable, ", "); - - /* Next hop addresses */ - tmp = g_value_array_get_nth (elements, 2); - ba_addr = g_value_get_boxed (tmp); - if (ba_addr->len != 16) { - g_string_append (printable, "invalid"); - continue; - } - addr = (struct in6_addr *) ba_addr->data; - memset (buf, 0, sizeof (buf)); - _nm_utils_inet6_ntop (addr, buf); - g_string_append_printf (printable, "nh = %s", buf); - g_string_append (printable, ", "); - - /* Metric */ - tmp = g_value_array_get_nth (elements, 3); - metric = g_value_get_uint (tmp); - g_string_append_printf (printable, "mt = %u", metric); - - g_string_append (printable, " }"); - } - g_string_append_c (printable, ']'); - - g_value_take_string (dest_value, printable->str); - g_string_free (printable, FALSE); -} - -#define OLD_DBUS_TYPE_G_IP6_ADDRESS (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, G_TYPE_INVALID)) -#define OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS (dbus_g_type_get_collection ("GPtrArray", OLD_DBUS_TYPE_G_IP6_ADDRESS)) - -static void -_nm_utils_convert_old_ip6_addr_array (const GValue *src_value, GValue *dst_value) -{ - GPtrArray *src_outer_array; - GPtrArray *dst_outer_array; - guint i; - - g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS)); - - src_outer_array = (GPtrArray *) g_value_get_boxed (src_value); - dst_outer_array = g_ptr_array_new (); - - for (i = 0; src_outer_array && (i < src_outer_array->len); i++) { - GValueArray *src_addr_array; - GValueArray *dst_addr_array; - GValue element = G_VALUE_INIT; - GValue *src_addr, *src_prefix; - GByteArray *ba; - - src_addr_array = (GValueArray *) g_ptr_array_index (src_outer_array, i); - if (!validate_gvalue_array (src_addr_array, 2, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT)) { - g_warning ("%s: invalid old IPv6 address type", __func__); - return; - } - - dst_addr_array = g_value_array_new (3); - - src_addr = g_value_array_get_nth (src_addr_array, 0); - g_value_array_append (dst_addr_array, src_addr); - src_prefix = g_value_array_get_nth (src_addr_array, 1); - g_value_array_append (dst_addr_array, src_prefix); - - /* Blank Gateway */ - g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); - ba = g_byte_array_new (); - g_byte_array_append (ba, (guint8 *) "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16); - g_value_take_boxed (&element, ba); - g_value_array_append (dst_addr_array, &element); - g_value_unset (&element); - - g_ptr_array_add (dst_outer_array, dst_addr_array); - } - - g_value_take_boxed (dst_value, dst_outer_array); -} - -void -_nm_utils_register_value_transformations (void) -{ - static gboolean registered = FALSE; - - if (G_UNLIKELY (!registered)) { - g_value_register_transform_func (DBUS_TYPE_G_OBJECT_PATH, - G_TYPE_STRING, - _nm_utils_convert_op_to_string); - g_value_register_transform_func (G_TYPE_STRV, - DBUS_TYPE_G_LIST_OF_STRING, - _nm_utils_convert_strv_to_slist); - g_value_register_transform_func (G_TYPE_STRV, - DBUS_TYPE_G_ARRAY_OF_STRING, - _nm_utils_convert_strv_to_ptrarray); - g_value_register_transform_func (DBUS_TYPE_G_LIST_OF_STRING, - G_TYPE_STRING, - _nm_utils_convert_strv_to_string); - g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_STRING, - G_TYPE_STRING, - _nm_utils_convert_string_array_to_string); - g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, - G_TYPE_STRING, - _nm_utils_convert_op_array_to_string); - g_value_register_transform_func (DBUS_TYPE_G_UINT_ARRAY, - G_TYPE_STRING, - _nm_utils_convert_uint_array_to_string); - g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT, - G_TYPE_STRING, - _nm_utils_convert_ip4_addr_route_struct_array_to_string); - g_value_register_transform_func (DBUS_TYPE_G_MAP_OF_VARIANT, - G_TYPE_STRING, - _nm_utils_convert_gvalue_hash_to_string); - g_value_register_transform_func (DBUS_TYPE_G_MAP_OF_STRING, - G_TYPE_STRING, - _nm_utils_convert_string_hash_to_string); - g_value_register_transform_func (DBUS_TYPE_G_UCHAR_ARRAY, - G_TYPE_STRING, - _nm_utils_convert_byte_array_to_string); - g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR, - G_TYPE_STRING, - _nm_utils_convert_ip6_dns_array_to_string); - g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS, - G_TYPE_STRING, - _nm_utils_convert_ip6_addr_struct_array_to_string); - g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE, - G_TYPE_STRING, - _nm_utils_convert_ip6_route_struct_array_to_string); - g_value_register_transform_func (OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS, - DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS, - _nm_utils_convert_old_ip6_addr_array); - registered = TRUE; - } -} - static gboolean device_supports_ap_ciphers (guint32 dev_caps, guint32 ap_flags, @@ -1799,8 +1172,8 @@ nm_utils_ip6_addresses_from_gvalue (const GValue *value) } /* Third element (gateway) is optional */ - if ( !validate_gvalue_array (elements, 2, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT) - && !validate_gvalue_array (elements, 3, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, DBUS_TYPE_G_UCHAR_ARRAY)) { + 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; } @@ -1927,11 +1300,11 @@ nm_utils_ip6_routes_from_gvalue (const GValue *value) guint prefix, metric; NMIP6Route *route; - if (!validate_gvalue_array (route_values, 4, - DBUS_TYPE_G_UCHAR_ARRAY, - G_TYPE_UINT, - DBUS_TYPE_G_UCHAR_ARRAY, - G_TYPE_UINT)) { + 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; } diff --git a/libnm-util/nm-value-transforms.c b/libnm-util/nm-value-transforms.c new file mode 100644 index 0000000000..dde0be4a95 --- /dev/null +++ b/libnm-util/nm-value-transforms.c @@ -0,0 +1,647 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ + +/* NetworkManager -- Network link manager + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2005 - 2013 Red Hat, Inc. + */ + +#include "config.h" + +#include + +#include "nm-utils.h" +#include "nm-utils-private.h" +#include "nm-dbus-glib-types.h" +#include "nm-glib-compat.h" + +static void +_nm_utils_convert_op_to_string (const GValue *src_value, GValue *dest_value) +{ + g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_OBJECT_PATH)); + + g_value_set_string (dest_value, (const char *) g_value_get_boxed (src_value)); +} + +static void +_nm_utils_convert_strv_to_slist (const GValue *src_value, GValue *dest_value) +{ + char **str; + GSList *list = NULL; + guint i = 0; + + g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), G_TYPE_STRV)); + + str = (char **) g_value_get_boxed (src_value); + + while (str && str[i]) + list = g_slist_prepend (list, g_strdup (str[i++])); + + g_value_take_boxed (dest_value, g_slist_reverse (list)); +} + +static void +_nm_utils_convert_strv_to_ptrarray (const GValue *src_value, GValue *dest_value) +{ + char **str; + GPtrArray *array = NULL; + guint i = 0; + + g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), G_TYPE_STRV)); + + str = (char **) g_value_get_boxed (src_value); + + array = g_ptr_array_sized_new (3); + while (str && str[i]) + g_ptr_array_add (array, g_strdup (str[i++])); + + g_value_take_boxed (dest_value, array); +} + +static void +_nm_utils_convert_strv_to_string (const GValue *src_value, GValue *dest_value) +{ + GSList *strings; + GString *printable; + GSList *iter; + + g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_LIST_OF_STRING)); + + strings = (GSList *) g_value_get_boxed (src_value); + + printable = g_string_new ("["); + for (iter = strings; iter; iter = g_slist_next (iter)) { + if (iter != strings) + g_string_append (printable, ", '"); + else + g_string_append_c (printable, '\''); + g_string_append (printable, iter->data); + g_string_append_c (printable, '\''); + } + g_string_append_c (printable, ']'); + + g_value_take_string (dest_value, printable->str); + g_string_free (printable, FALSE); +} + +static void +_string_array_to_string (const GPtrArray *strings, GValue *dest_value) +{ + GString *printable; + int i; + + printable = g_string_new ("["); + for (i = 0; strings && i < strings->len; i++) { + if (i > 0) + g_string_append (printable, ", '"); + else + g_string_append_c (printable, '\''); + g_string_append (printable, g_ptr_array_index (strings, i)); + g_string_append_c (printable, '\''); + } + g_string_append_c (printable, ']'); + + g_value_take_string (dest_value, printable->str); + g_string_free (printable, FALSE); +} + +static void +_nm_utils_convert_string_array_to_string (const GValue *src_value, GValue *dest_value) +{ + const GPtrArray *strings; + + g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_STRING)); + + strings = (const GPtrArray *) g_value_get_boxed (src_value); + _string_array_to_string (strings, dest_value); +} + +static void +_nm_utils_convert_op_array_to_string (const GValue *src_value, GValue *dest_value) +{ + const GPtrArray *strings; + + g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH)); + + strings = (const GPtrArray *) g_value_get_boxed (src_value); + _string_array_to_string (strings, dest_value); +} + +static void +_nm_utils_convert_uint_array_to_string (const GValue *src_value, GValue *dest_value) +{ + GArray *array; + GString *printable; + guint i = 0; + + g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_UINT_ARRAY)); + + array = (GArray *) g_value_get_boxed (src_value); + + printable = g_string_new ("["); + while (array && (i < array->len)) { + char buf[INET_ADDRSTRLEN + 1]; + struct in_addr addr; + + if (i > 0) + g_string_append (printable, ", "); + + memset (buf, 0, sizeof (buf)); + addr.s_addr = g_array_index (array, guint32, i++); + if (!inet_ntop (AF_INET, &addr, buf, INET_ADDRSTRLEN)) + g_warning ("%s: error converting IP4 address 0x%X", + __func__, ntohl (addr.s_addr)); + g_string_append_printf (printable, "%u (%s)", addr.s_addr, buf); + } + g_string_append_c (printable, ']'); + + g_value_take_string (dest_value, printable->str); + g_string_free (printable, FALSE); +} + +static void +_nm_utils_convert_ip4_addr_route_struct_array_to_string (const GValue *src_value, GValue *dest_value) +{ + GPtrArray *ptr_array; + GString *printable; + guint i = 0; + + g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT)); + + ptr_array = (GPtrArray *) g_value_get_boxed (src_value); + + printable = g_string_new ("["); + while (ptr_array && (i < ptr_array->len)) { + GArray *array; + char buf[INET_ADDRSTRLEN + 1]; + struct in_addr addr; + gboolean is_addr; /* array contains address x route */ + + if (i > 0) + g_string_append (printable, ", "); + + g_string_append (printable, "{ "); + array = (GArray *) g_ptr_array_index (ptr_array, i++); + if (array->len < 2) { + g_string_append (printable, "invalid"); + continue; + } + is_addr = (array->len < 4); + + memset (buf, 0, sizeof (buf)); + addr.s_addr = g_array_index (array, guint32, 0); + if (!inet_ntop (AF_INET, &addr, buf, INET_ADDRSTRLEN)) + g_warning ("%s: error converting IP4 address 0x%X", + __func__, ntohl (addr.s_addr)); + if (is_addr) + g_string_append_printf (printable, "ip = %s", buf); + else + g_string_append_printf (printable, "dst = %s", buf); + g_string_append (printable, ", "); + + memset (buf, 0, sizeof (buf)); + g_string_append_printf (printable, "px = %u", + g_array_index (array, guint32, 1)); + + if (array->len > 2) { + g_string_append (printable, ", "); + + memset (buf, 0, sizeof (buf)); + addr.s_addr = g_array_index (array, guint32, 2); + if (!inet_ntop (AF_INET, &addr, buf, INET_ADDRSTRLEN)) + g_warning ("%s: error converting IP4 address 0x%X", + __func__, ntohl (addr.s_addr)); + if (is_addr) + g_string_append_printf (printable, "gw = %s", buf); + else + g_string_append_printf (printable, "nh = %s", buf); + } + + if (array->len > 3) { + g_string_append (printable, ", "); + + memset (buf, 0, sizeof (buf)); + g_string_append_printf (printable, "mt = %u", + g_array_index (array, guint32, 3)); + } + + g_string_append (printable, " }"); + } + g_string_append_c (printable, ']'); + + g_value_take_string (dest_value, printable->str); + g_string_free (printable, FALSE); +} + +static void +convert_one_gvalue_hash_entry (gpointer key, gpointer value, gpointer user_data) +{ + GString *printable = (GString *) user_data; + char *value_as_string; + + value_as_string = g_strdup_value_contents ((GValue *) value); + g_string_append_printf (printable, " { '%s': %s },", (const char *) key, value_as_string); + g_free (value_as_string); +} + +static void +_nm_utils_convert_gvalue_hash_to_string (const GValue *src_value, GValue *dest_value) +{ + GHashTable *hash; + GString *printable; + + g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_MAP_OF_VARIANT)); + + hash = (GHashTable *) g_value_get_boxed (src_value); + + printable = g_string_new ("["); + g_hash_table_foreach (hash, convert_one_gvalue_hash_entry, printable); + g_string_append (printable, " ]"); + + g_value_take_string (dest_value, printable->str); + g_string_free (printable, FALSE); +} + +static void +convert_one_string_hash_entry (gpointer key, gpointer value, gpointer user_data) +{ + GString *printable = (GString *) user_data; + + g_string_append_printf (printable, " { '%s': %s },", (const char *) key, (const char *) value); +} + +static void +_nm_utils_convert_string_hash_to_string (const GValue *src_value, GValue *dest_value) +{ + GHashTable *hash; + GString *printable; + + g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_MAP_OF_STRING)); + + hash = (GHashTable *) g_value_get_boxed (src_value); + + printable = g_string_new ("["); + if (hash) + g_hash_table_foreach (hash, convert_one_string_hash_entry, printable); + g_string_append (printable, " ]"); + + g_value_take_string (dest_value, printable->str); + g_string_free (printable, FALSE); +} + +static void +_nm_utils_convert_byte_array_to_string (const GValue *src_value, GValue *dest_value) +{ + GArray *array; + GString *printable; + guint i = 0; + + g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_UCHAR_ARRAY)); + + array = (GArray *) g_value_get_boxed (src_value); + + printable = g_string_new ("["); + if (array) { + while (i < MIN (array->len, 35)) { + if (i > 0) + g_string_append_c (printable, ' '); + g_string_append_printf (printable, "0x%02X", + g_array_index (array, unsigned char, i++)); + } + if (i < array->len) + g_string_append (printable, " ... "); + } + g_string_append_c (printable, ']'); + + g_value_take_string (dest_value, printable->str); + g_string_free (printable, FALSE); +} + +static gboolean +_nm_utils_inet6_ntop (struct in6_addr *addr, char *buf) +{ + if (!inet_ntop (AF_INET6, addr, buf, INET6_ADDRSTRLEN)) { + int i; + GString *ip6_str = g_string_new (NULL); + g_string_append_printf (ip6_str, "%02X", addr->s6_addr[0]); + for (i = 1; i < 16; i++) + g_string_append_printf (ip6_str, " %02X", addr->s6_addr[i]); + g_warning ("%s: error converting IP6 address %s", + __func__, ip6_str->str); + g_string_free (ip6_str, TRUE); + return FALSE; + } + return TRUE; +} + +static void +_nm_utils_convert_ip6_dns_array_to_string (const GValue *src_value, GValue *dest_value) +{ + GPtrArray *ptr_array; + GString *printable; + guint i = 0; + + g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR)); + + ptr_array = (GPtrArray *) g_value_get_boxed (src_value); + + printable = g_string_new ("["); + while (ptr_array && (i < ptr_array->len)) { + GByteArray *bytearray; + char buf[INET6_ADDRSTRLEN]; + struct in6_addr *addr; + + if (i > 0) + g_string_append (printable, ", "); + + bytearray = (GByteArray *) g_ptr_array_index (ptr_array, i++); + if (bytearray->len != 16) { + g_string_append (printable, "invalid"); + continue; + } + addr = (struct in6_addr *) bytearray->data; + memset (buf, 0, sizeof (buf)); + _nm_utils_inet6_ntop (addr, buf); + g_string_append_printf (printable, "%s", buf); + } + g_string_append_c (printable, ']'); + + g_value_take_string (dest_value, printable->str); + g_string_free (printable, FALSE); +} + +static void +_nm_utils_convert_ip6_addr_struct_array_to_string (const GValue *src_value, GValue *dest_value) +{ + GPtrArray *ptr_array; + GString *printable; + guint i = 0; + + g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS)); + + ptr_array = (GPtrArray *) g_value_get_boxed (src_value); + + printable = g_string_new ("["); + while (ptr_array && (i < ptr_array->len)) { + GValueArray *elements; + GValue *tmp; + GByteArray *ba_addr; + char buf[INET6_ADDRSTRLEN]; + struct in6_addr *addr; + guint32 prefix; + + if (i > 0) + g_string_append (printable, ", "); + + g_string_append (printable, "{ "); + elements = (GValueArray *) g_ptr_array_index (ptr_array, i++); + if (!_nm_utils_gvalue_array_validate (elements, 3, + DBUS_TYPE_G_UCHAR_ARRAY, + G_TYPE_UINT, + DBUS_TYPE_G_UCHAR_ARRAY)) { + g_string_append (printable, "invalid }"); + continue; + } + + /* IPv6 address */ + tmp = g_value_array_get_nth (elements, 0); + ba_addr = g_value_get_boxed (tmp); + if (ba_addr->len != 16) { + g_string_append (printable, "invalid }"); + continue; + } + addr = (struct in6_addr *) ba_addr->data; + memset (buf, 0, sizeof (buf)); + _nm_utils_inet6_ntop (addr, buf); + g_string_append_printf (printable, "ip = %s", buf); + g_string_append (printable, ", "); + + /* Prefix */ + tmp = g_value_array_get_nth (elements, 1); + prefix = g_value_get_uint (tmp); + if (prefix > 128) { + g_string_append (printable, "invalid }"); + continue; + } + g_string_append_printf (printable, "px = %u", prefix); + g_string_append (printable, ", "); + + /* IPv6 Gateway */ + tmp = g_value_array_get_nth (elements, 2); + ba_addr = g_value_get_boxed (tmp); + if (ba_addr->len != 16) { + g_string_append (printable, "invalid }"); + continue; + } + addr = (struct in6_addr *) ba_addr->data; + memset (buf, 0, sizeof (buf)); + _nm_utils_inet6_ntop (addr, buf); + g_string_append_printf (printable, "gw = %s", buf); + g_string_append (printable, " }"); + } + g_string_append_c (printable, ']'); + + g_value_take_string (dest_value, printable->str); + g_string_free (printable, FALSE); +} + +static void +_nm_utils_convert_ip6_route_struct_array_to_string (const GValue *src_value, GValue *dest_value) +{ + GPtrArray *ptr_array; + GString *printable; + guint i = 0; + + g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE)); + + ptr_array = (GPtrArray *) g_value_get_boxed (src_value); + + printable = g_string_new ("["); + while (ptr_array && (i < ptr_array->len)) { + GValueArray *elements; + GValue *tmp; + GByteArray *ba_addr; + char buf[INET6_ADDRSTRLEN]; + struct in6_addr *addr; + guint32 prefix, metric; + + if (i > 0) + g_string_append (printable, ", "); + + g_string_append (printable, "{ "); + elements = (GValueArray *) g_ptr_array_index (ptr_array, i++); + if (!_nm_utils_gvalue_array_validate (elements, 4, + DBUS_TYPE_G_UCHAR_ARRAY, + G_TYPE_UINT, + DBUS_TYPE_G_UCHAR_ARRAY, + G_TYPE_UINT)) { + g_string_append (printable, "invalid"); + continue; + } + + /* Destination address */ + tmp = g_value_array_get_nth (elements, 0); + ba_addr = g_value_get_boxed (tmp); + if (ba_addr->len != 16) { + g_string_append (printable, "invalid"); + continue; + } + addr = (struct in6_addr *) ba_addr->data; + memset (buf, 0, sizeof (buf)); + _nm_utils_inet6_ntop (addr, buf); + g_string_append_printf (printable, "dst = %s", buf); + g_string_append (printable, ", "); + + /* Prefix */ + tmp = g_value_array_get_nth (elements, 1); + prefix = g_value_get_uint (tmp); + if (prefix > 128) { + g_string_append (printable, "invalid"); + continue; + } + g_string_append_printf (printable, "px = %u", prefix); + g_string_append (printable, ", "); + + /* Next hop addresses */ + tmp = g_value_array_get_nth (elements, 2); + ba_addr = g_value_get_boxed (tmp); + if (ba_addr->len != 16) { + g_string_append (printable, "invalid"); + continue; + } + addr = (struct in6_addr *) ba_addr->data; + memset (buf, 0, sizeof (buf)); + _nm_utils_inet6_ntop (addr, buf); + g_string_append_printf (printable, "nh = %s", buf); + g_string_append (printable, ", "); + + /* Metric */ + tmp = g_value_array_get_nth (elements, 3); + metric = g_value_get_uint (tmp); + g_string_append_printf (printable, "mt = %u", metric); + + g_string_append (printable, " }"); + } + g_string_append_c (printable, ']'); + + g_value_take_string (dest_value, printable->str); + g_string_free (printable, FALSE); +} + +#define OLD_DBUS_TYPE_G_IP6_ADDRESS (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, G_TYPE_INVALID)) +#define OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS (dbus_g_type_get_collection ("GPtrArray", OLD_DBUS_TYPE_G_IP6_ADDRESS)) + +static void +_nm_utils_convert_old_ip6_addr_array (const GValue *src_value, GValue *dst_value) +{ + GPtrArray *src_outer_array; + GPtrArray *dst_outer_array; + guint i; + + g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS)); + + src_outer_array = (GPtrArray *) g_value_get_boxed (src_value); + dst_outer_array = g_ptr_array_new (); + + for (i = 0; src_outer_array && (i < src_outer_array->len); i++) { + GValueArray *src_addr_array; + GValueArray *dst_addr_array; + GValue element = G_VALUE_INIT; + GValue *src_addr, *src_prefix; + GByteArray *ba; + + src_addr_array = (GValueArray *) g_ptr_array_index (src_outer_array, i); + if (!_nm_utils_gvalue_array_validate (src_addr_array, 2, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT)) { + g_warning ("%s: invalid old IPv6 address type", __func__); + return; + } + + dst_addr_array = g_value_array_new (3); + + src_addr = g_value_array_get_nth (src_addr_array, 0); + g_value_array_append (dst_addr_array, src_addr); + src_prefix = g_value_array_get_nth (src_addr_array, 1); + g_value_array_append (dst_addr_array, src_prefix); + + /* Blank Gateway */ + g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); + ba = g_byte_array_new (); + g_byte_array_append (ba, (guint8 *) "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16); + g_value_take_boxed (&element, ba); + g_value_array_append (dst_addr_array, &element); + g_value_unset (&element); + + g_ptr_array_add (dst_outer_array, dst_addr_array); + } + + g_value_take_boxed (dst_value, dst_outer_array); +} + +void +_nm_value_transforms_register (void) +{ + static gboolean registered = FALSE; + + if (G_UNLIKELY (!registered)) { + g_value_register_transform_func (DBUS_TYPE_G_OBJECT_PATH, + G_TYPE_STRING, + _nm_utils_convert_op_to_string); + g_value_register_transform_func (G_TYPE_STRV, + DBUS_TYPE_G_LIST_OF_STRING, + _nm_utils_convert_strv_to_slist); + g_value_register_transform_func (G_TYPE_STRV, + DBUS_TYPE_G_ARRAY_OF_STRING, + _nm_utils_convert_strv_to_ptrarray); + g_value_register_transform_func (DBUS_TYPE_G_LIST_OF_STRING, + G_TYPE_STRING, + _nm_utils_convert_strv_to_string); + g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_STRING, + G_TYPE_STRING, + _nm_utils_convert_string_array_to_string); + g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, + G_TYPE_STRING, + _nm_utils_convert_op_array_to_string); + g_value_register_transform_func (DBUS_TYPE_G_UINT_ARRAY, + G_TYPE_STRING, + _nm_utils_convert_uint_array_to_string); + g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT, + G_TYPE_STRING, + _nm_utils_convert_ip4_addr_route_struct_array_to_string); + g_value_register_transform_func (DBUS_TYPE_G_MAP_OF_VARIANT, + G_TYPE_STRING, + _nm_utils_convert_gvalue_hash_to_string); + g_value_register_transform_func (DBUS_TYPE_G_MAP_OF_STRING, + G_TYPE_STRING, + _nm_utils_convert_string_hash_to_string); + g_value_register_transform_func (DBUS_TYPE_G_UCHAR_ARRAY, + G_TYPE_STRING, + _nm_utils_convert_byte_array_to_string); + g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR, + G_TYPE_STRING, + _nm_utils_convert_ip6_dns_array_to_string); + g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS, + G_TYPE_STRING, + _nm_utils_convert_ip6_addr_struct_array_to_string); + g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE, + G_TYPE_STRING, + _nm_utils_convert_ip6_route_struct_array_to_string); + g_value_register_transform_func (OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS, + DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS, + _nm_utils_convert_old_ip6_addr_array); + registered = TRUE; + } +}