1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA.
19 * Copyright 2005 - 2014 Red Hat, Inc.
22 #include "nm-default.h"
26 #include "nm-gvaluearray-compat.h"
28 #include "nm-utils-private.h"
29 #include "nm-dbus-glib-types.h"
32 _nm_utils_convert_op_to_string (const GValue *src_value, GValue *dest_value)
34 g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_OBJECT_PATH));
36 g_value_set_string (dest_value, (const char *) g_value_get_boxed (src_value));
40 _nm_utils_convert_strv_to_slist (const GValue *src_value, GValue *dest_value)
46 g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), G_TYPE_STRV));
48 str = (char **) g_value_get_boxed (src_value);
51 list = g_slist_prepend (list, g_strdup (str[i++]));
53 g_value_take_boxed (dest_value, g_slist_reverse (list));
57 _nm_utils_convert_slist_to_strv (const GValue *src_value, GValue *dest_value)
63 slist = g_value_get_boxed (src_value);
64 len = g_slist_length (slist);
66 strv = g_new (char *, len + 1);
67 for (i = 0; slist; slist = slist->next, i++)
68 strv[i] = g_strdup (slist->data);
71 g_value_take_boxed (dest_value, strv);
75 _nm_utils_convert_strv_to_ptrarray (const GValue *src_value, GValue *dest_value)
78 GPtrArray *array = NULL;
81 g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), G_TYPE_STRV));
83 str = (char **) g_value_get_boxed (src_value);
85 array = g_ptr_array_sized_new (3);
87 g_ptr_array_add (array, g_strdup (str[i++]));
89 g_value_take_boxed (dest_value, array);
93 _nm_utils_convert_string_list_to_string (const GValue *src_value, GValue *dest_value)
99 g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_LIST_OF_STRING));
101 strings = (GSList *) g_value_get_boxed (src_value);
103 printable = g_string_new (NULL);
104 for (iter = strings; iter; iter = iter->next) {
106 g_string_append_c (printable, ',');
107 g_string_append (printable, iter->data ? iter->data : "(null)");
110 g_value_take_string (dest_value, g_string_free (printable, FALSE));
114 _string_array_to_string (const GPtrArray *strings, GValue *dest_value)
119 printable = g_string_new (NULL);
120 for (i = 0; strings && i < strings->len; i++) {
122 g_string_append_c (printable, ',');
123 g_string_append (printable, strings->pdata[i]);
126 g_value_take_string (dest_value, g_string_free (printable, FALSE));
130 _nm_utils_convert_string_array_to_string (const GValue *src_value, GValue *dest_value)
132 const GPtrArray *strings;
134 g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_STRING));
136 strings = (const GPtrArray *) g_value_get_boxed (src_value);
137 _string_array_to_string (strings, dest_value);
141 _nm_utils_convert_op_array_to_string (const GValue *src_value, GValue *dest_value)
143 const GPtrArray *strings;
145 g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH));
147 strings = (const GPtrArray *) g_value_get_boxed (src_value);
148 _string_array_to_string (strings, dest_value);
152 _nm_utils_convert_uint_array_to_string (const GValue *src_value, GValue *dest_value)
158 g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_UINT_ARRAY));
160 array = (GArray *) g_value_get_boxed (src_value);
162 printable = g_string_new (NULL);
163 while (array && (i < array->len)) {
167 g_string_append (printable, ", ");
169 addr = g_array_index (array, guint32, i++);
170 g_string_append (printable, nm_utils_inet4_ntop (addr, NULL));
173 g_value_take_string (dest_value, g_string_free (printable, FALSE));
177 _nm_utils_convert_ip4_addr_route_struct_array_to_string (const GValue *src_value, GValue *dest_value)
179 GPtrArray *ptr_array;
182 char buf[INET_ADDRSTRLEN];
184 g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT));
186 ptr_array = (GPtrArray *) g_value_get_boxed (src_value);
188 printable = g_string_new (NULL);
189 while (ptr_array && (i < ptr_array->len)) {
191 gboolean is_addr; /* array contains address x route */
194 g_string_append (printable, "; ");
196 g_string_append (printable, "{ ");
197 array = (GArray *) g_ptr_array_index (ptr_array, i++);
198 if (array->len < 2) {
199 g_string_append (printable, "invalid");
202 is_addr = (array->len < 4);
204 nm_utils_inet4_ntop (g_array_index (array, guint32, 0), buf);
206 g_string_append_printf (printable, "ip = %s", buf);
208 g_string_append_printf (printable, "dst = %s", buf);
210 g_string_append_printf (printable, "/%u",
211 g_array_index (array, guint32, 1));
213 if (array->len > 2) {
214 nm_utils_inet4_ntop (g_array_index (array, guint32, 2), buf);
216 g_string_append_printf (printable, ", gw = %s", buf);
218 g_string_append_printf (printable, ", nh = %s", buf);
221 if (array->len > 3) {
222 g_string_append_printf (printable, ", mt = %u",
223 g_array_index (array, guint32, 3));
226 g_string_append (printable, " }");
229 g_value_take_string (dest_value, g_string_free (printable, FALSE));
233 convert_one_gvalue_hash_entry (gpointer key, gpointer value, gpointer user_data)
235 GString *printable = (GString *) user_data;
236 char *value_as_string;
238 value_as_string = g_strdup_value_contents ((GValue *) value);
239 g_string_append_printf (printable, " { '%s': %s },", (const char *) key, value_as_string);
240 g_free (value_as_string);
244 _nm_utils_convert_gvalue_hash_to_string (const GValue *src_value, GValue *dest_value)
249 g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_MAP_OF_VARIANT));
251 hash = (GHashTable *) g_value_get_boxed (src_value);
253 printable = g_string_new ("[");
254 g_hash_table_foreach (hash, convert_one_gvalue_hash_entry, printable);
255 g_string_append (printable, " ]");
257 g_value_take_string (dest_value, printable->str);
258 g_string_free (printable, FALSE);
262 convert_one_string_hash_entry (gpointer key, gpointer value, gpointer user_data)
264 GString *printable = (GString *) user_data;
267 g_string_append_c (printable, ',');
268 g_string_append_printf (printable, "%s=%s", (const char *) key, (const char *) value);
272 _nm_utils_convert_string_hash_to_string (const GValue *src_value, GValue *dest_value)
277 g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_MAP_OF_STRING));
279 hash = (GHashTable *) g_value_get_boxed (src_value);
281 printable = g_string_new (NULL);
283 g_hash_table_foreach (hash, convert_one_string_hash_entry, printable);
285 g_value_take_string (dest_value, g_string_free (printable, FALSE));
289 _nm_utils_convert_byte_array_to_string (const GValue *src_value, GValue *dest_value)
295 g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_UCHAR_ARRAY));
297 array = (GArray *) g_value_get_boxed (src_value);
299 printable = g_string_new ("[");
301 while (i < MIN (array->len, 35)) {
303 g_string_append_c (printable, ' ');
304 g_string_append_printf (printable, "0x%02X",
305 g_array_index (array, unsigned char, i++));
308 g_string_append (printable, " ... ");
310 g_string_append_c (printable, ']');
312 g_value_take_string (dest_value, g_string_free (printable, FALSE));
316 _nm_utils_convert_ip6_dns_array_to_string (const GValue *src_value, GValue *dest_value)
318 GPtrArray *ptr_array;
322 g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR));
324 ptr_array = (GPtrArray *) g_value_get_boxed (src_value);
326 printable = g_string_new (NULL);
327 while (ptr_array && (i < ptr_array->len)) {
328 GByteArray *bytearray;
329 struct in6_addr *addr;
332 g_string_append (printable, ", ");
334 bytearray = (GByteArray *) g_ptr_array_index (ptr_array, i++);
335 if (bytearray->len != 16) {
336 g_string_append (printable, "invalid");
339 addr = (struct in6_addr *) bytearray->data;
340 g_string_append (printable, nm_utils_inet6_ntop (addr, NULL));
343 g_value_take_string (dest_value, g_string_free (printable, FALSE));
347 _nm_utils_convert_ip6_addr_struct_array_to_string (const GValue *src_value, GValue *dest_value)
349 GPtrArray *ptr_array;
353 g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS));
355 ptr_array = (GPtrArray *) g_value_get_boxed (src_value);
357 printable = g_string_new (NULL);
358 while (ptr_array && (i < ptr_array->len)) {
359 GValueArray *elements;
362 struct in6_addr *addr;
366 g_string_append (printable, "; ");
368 g_string_append (printable, "{ ");
369 elements = (GValueArray *) g_ptr_array_index (ptr_array, i++);
370 if (!_nm_utils_gvalue_array_validate (elements, 3,
371 DBUS_TYPE_G_UCHAR_ARRAY,
373 DBUS_TYPE_G_UCHAR_ARRAY)) {
374 g_string_append (printable, "invalid }");
379 tmp = g_value_array_get_nth (elements, 0);
380 ba_addr = g_value_get_boxed (tmp);
381 if (ba_addr->len != 16) {
382 g_string_append (printable, "invalid }");
385 addr = (struct in6_addr *) ba_addr->data;
386 g_string_append_printf (printable, "ip = %s", nm_utils_inet6_ntop (addr, NULL));
389 tmp = g_value_array_get_nth (elements, 1);
390 prefix = g_value_get_uint (tmp);
392 g_string_append (printable, "/invalid }");
395 g_string_append_printf (printable, "/%u", prefix);
396 g_string_append (printable, ", ");
399 tmp = g_value_array_get_nth (elements, 2);
400 ba_addr = g_value_get_boxed (tmp);
401 if (ba_addr->len != 16) {
402 g_string_append (printable, "invalid }");
405 addr = (struct in6_addr *) ba_addr->data;
406 g_string_append_printf (printable, "gw = %s", nm_utils_inet6_ntop (addr, NULL));
407 g_string_append (printable, " }");
410 g_value_take_string (dest_value, g_string_free (printable, FALSE));
414 _nm_utils_convert_ip6_route_struct_array_to_string (const GValue *src_value, GValue *dest_value)
416 GPtrArray *ptr_array;
420 g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE));
422 ptr_array = (GPtrArray *) g_value_get_boxed (src_value);
424 printable = g_string_new (NULL);
425 while (ptr_array && (i < ptr_array->len)) {
426 GValueArray *elements;
429 struct in6_addr *addr;
430 guint32 prefix, metric;
433 g_string_append (printable, "; ");
435 g_string_append (printable, "{ ");
436 elements = (GValueArray *) g_ptr_array_index (ptr_array, i++);
437 if (!_nm_utils_gvalue_array_validate (elements, 4,
438 DBUS_TYPE_G_UCHAR_ARRAY,
440 DBUS_TYPE_G_UCHAR_ARRAY,
442 g_string_append (printable, "invalid");
446 /* Destination address */
447 tmp = g_value_array_get_nth (elements, 0);
448 ba_addr = g_value_get_boxed (tmp);
449 if (ba_addr->len != 16) {
450 g_string_append (printable, "invalid");
453 addr = (struct in6_addr *) ba_addr->data;
454 g_string_append_printf (printable, "dst = %s", nm_utils_inet6_ntop (addr, NULL));
457 tmp = g_value_array_get_nth (elements, 1);
458 prefix = g_value_get_uint (tmp);
460 g_string_append (printable, "/invalid");
463 g_string_append_printf (printable, "/%u", prefix);
464 g_string_append (printable, ", ");
466 /* Next hop addresses */
467 tmp = g_value_array_get_nth (elements, 2);
468 ba_addr = g_value_get_boxed (tmp);
469 if (ba_addr->len != 16) {
470 g_string_append (printable, "invalid");
473 addr = (struct in6_addr *) ba_addr->data;
474 g_string_append_printf (printable, "nh = %s", nm_utils_inet6_ntop (addr, NULL));
475 g_string_append (printable, ", ");
478 tmp = g_value_array_get_nth (elements, 3);
479 metric = g_value_get_uint (tmp);
480 g_string_append_printf (printable, "mt = %u", metric);
482 g_string_append (printable, " }");
485 g_value_take_string (dest_value, g_string_free (printable, FALSE));
488 #define OLD_DBUS_TYPE_G_IP6_ADDRESS (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, G_TYPE_INVALID))
489 #define OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS (dbus_g_type_get_collection ("GPtrArray", OLD_DBUS_TYPE_G_IP6_ADDRESS))
492 _nm_utils_convert_old_ip6_addr_array (const GValue *src_value, GValue *dst_value)
494 GPtrArray *src_outer_array;
495 GPtrArray *dst_outer_array;
498 g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS));
500 src_outer_array = (GPtrArray *) g_value_get_boxed (src_value);
501 dst_outer_array = g_ptr_array_new ();
503 for (i = 0; src_outer_array && (i < src_outer_array->len); i++) {
504 GValueArray *src_addr_array;
505 GValueArray *dst_addr_array;
506 GValue element = G_VALUE_INIT;
507 GValue *src_addr, *src_prefix;
510 src_addr_array = (GValueArray *) g_ptr_array_index (src_outer_array, i);
511 if (!_nm_utils_gvalue_array_validate (src_addr_array, 2, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT)) {
512 g_warning ("%s: invalid old IPv6 address type", __func__);
516 dst_addr_array = g_value_array_new (3);
518 src_addr = g_value_array_get_nth (src_addr_array, 0);
519 g_value_array_append (dst_addr_array, src_addr);
520 src_prefix = g_value_array_get_nth (src_addr_array, 1);
521 g_value_array_append (dst_addr_array, src_prefix);
524 g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY);
525 ba = g_byte_array_new ();
526 g_byte_array_append (ba, (guint8 *) "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16);
527 g_value_take_boxed (&element, ba);
528 g_value_array_append (dst_addr_array, &element);
529 g_value_unset (&element);
531 g_ptr_array_add (dst_outer_array, dst_addr_array);
534 g_value_take_boxed (dst_value, dst_outer_array);
538 _nm_value_transforms_register (void)
540 static gboolean registered = FALSE;
542 if (G_UNLIKELY (!registered)) {
543 g_value_register_transform_func (DBUS_TYPE_G_OBJECT_PATH,
545 _nm_utils_convert_op_to_string);
546 g_value_register_transform_func (G_TYPE_STRV,
547 DBUS_TYPE_G_LIST_OF_STRING,
548 _nm_utils_convert_strv_to_slist);
549 g_value_register_transform_func (DBUS_TYPE_G_LIST_OF_STRING,
551 _nm_utils_convert_slist_to_strv);
552 g_value_register_transform_func (G_TYPE_STRV,
553 DBUS_TYPE_G_ARRAY_OF_STRING,
554 _nm_utils_convert_strv_to_ptrarray);
555 g_value_register_transform_func (DBUS_TYPE_G_LIST_OF_STRING,
557 _nm_utils_convert_string_list_to_string);
558 g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_STRING,
560 _nm_utils_convert_string_array_to_string);
561 g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH,
563 _nm_utils_convert_op_array_to_string);
564 g_value_register_transform_func (DBUS_TYPE_G_UINT_ARRAY,
566 _nm_utils_convert_uint_array_to_string);
567 g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT,
569 _nm_utils_convert_ip4_addr_route_struct_array_to_string);
570 g_value_register_transform_func (DBUS_TYPE_G_MAP_OF_VARIANT,
572 _nm_utils_convert_gvalue_hash_to_string);
573 g_value_register_transform_func (DBUS_TYPE_G_MAP_OF_STRING,
575 _nm_utils_convert_string_hash_to_string);
576 g_value_register_transform_func (DBUS_TYPE_G_UCHAR_ARRAY,
578 _nm_utils_convert_byte_array_to_string);
579 g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR,
581 _nm_utils_convert_ip6_dns_array_to_string);
582 g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS,
584 _nm_utils_convert_ip6_addr_struct_array_to_string);
585 g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE,
587 _nm_utils_convert_ip6_route_struct_array_to_string);
588 g_value_register_transform_func (OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS,
589 DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS,
590 _nm_utils_convert_old_ip6_addr_array);