diff --git a/ChangeLog b/ChangeLog index cfdbfdf283..de63ab072d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2008-06-26 Dan Williams + + Patch from David Cantrell and me + + * include/nm-dbus-glib-types.h + - Add IP6 address types + + * libnm-util/Makefile.am + libnm-util/nm-setting-ip6-config.c + libnm-util/nm-setting-ip6-config.h + - Add IP6 settings object + + * libnm-util/nm-connection.c + - (register_default_settings): register ip6 settings object + + * libnm-util/nm-utils.c + libnm-util/nm-utils.h + - (nm_utils_ip6_addresses_from_gvalue, nm_utils_ip6_addresses_to_gvalue, + nm_utils_ip6_dns_from_gvalue, nm_utils_ip6_dns_to_gvalue): add + ip6 address conversion functions + 2008-06-26 Dan Williams Patch from David Cantrell diff --git a/include/nm-dbus-glib-types.h b/include/nm-dbus-glib-types.h index ee094e62d4..be52614cfd 100644 --- a/include/nm-dbus-glib-types.h +++ b/include/nm-dbus-glib-types.h @@ -24,14 +24,18 @@ #include -#define DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH)) -#define DBUS_TYPE_G_ARRAY_OF_STRING (dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING)) -#define DBUS_TYPE_G_ARRAY_OF_UINT (dbus_g_type_get_collection ("GArray", G_TYPE_UINT)) -#define DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_ARRAY_OF_UINT)) -#define DBUS_TYPE_G_MAP_OF_VARIANT (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)) -#define DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT)) -#define DBUS_TYPE_G_MAP_OF_STRING (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING)) -#define DBUS_TYPE_G_LIST_OF_STRING (dbus_g_type_get_collection ("GSList", G_TYPE_STRING)) +#define DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH)) +#define DBUS_TYPE_G_ARRAY_OF_STRING (dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING)) +#define DBUS_TYPE_G_ARRAY_OF_UINT (dbus_g_type_get_collection ("GArray", G_TYPE_UINT)) +#define DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_UCHAR_ARRAY)) +#define DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_ARRAY_OF_UINT)) +#define DBUS_TYPE_G_MAP_OF_VARIANT (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)) +#define DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT)) +#define DBUS_TYPE_G_MAP_OF_STRING (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING)) +#define DBUS_TYPE_G_LIST_OF_STRING (dbus_g_type_get_collection ("GSList", G_TYPE_STRING)) + +#define DBUS_TYPE_G_IP6_ADDRESS (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_INVALID)) +#define DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_IP6_ADDRESS)) #endif /* DBUS_GLIB_TYPES_H */ diff --git a/libnm-util/Makefile.am b/libnm-util/Makefile.am index 8f4255aee7..a7803c644d 100644 --- a/libnm-util/Makefile.am +++ b/libnm-util/Makefile.am @@ -14,6 +14,7 @@ libnm_util_include_HEADERS = \ nm-setting-8021x.h \ nm-setting-connection.h \ nm-setting-ip4-config.h \ + nm-setting-ip6-config.h \ nm-setting-ppp.h \ nm-setting-pppoe.h \ nm-setting-serial.h \ @@ -35,6 +36,7 @@ libnm_util_la_SOURCES= \ nm-setting-8021x.c \ nm-setting-connection.c \ nm-setting-ip4-config.c \ + nm-setting-ip6-config.c \ nm-setting-ppp.c \ nm-setting-pppoe.c \ nm-setting-serial.c \ diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c index ff3cf5254b..c2d4ccaf26 100644 --- a/libnm-util/nm-connection.c +++ b/libnm-util/nm-connection.c @@ -9,6 +9,7 @@ #include "nm-setting-8021x.h" #include "nm-setting-connection.h" #include "nm-setting-ip4-config.h" +#include "nm-setting-ip6-config.h" #include "nm-setting-ppp.h" #include "nm-setting-pppoe.h" #include "nm-setting-wired.h" @@ -151,6 +152,11 @@ register_default_settings (void) NM_TYPE_SETTING_IP4_CONFIG, NM_SETTING_IP4_CONFIG_ERROR, 6); + + register_one_setting (NM_SETTING_IP6_CONFIG_SETTING_NAME, + NM_TYPE_SETTING_IP6_CONFIG, + NM_SETTING_IP6_CONFIG_ERROR, + 7); } static guint32 diff --git a/libnm-util/nm-setting-ip6-config.c b/libnm-util/nm-setting-ip6-config.c new file mode 100644 index 0000000000..32d27459b1 --- /dev/null +++ b/libnm-util/nm-setting-ip6-config.c @@ -0,0 +1,318 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#include + +#include +#include "nm-setting-ip6-config.h" +#include "nm-param-spec-specialized.h" +#include "nm-utils.h" +#include "nm-dbus-glib-types.h" + +GQuark +nm_setting_ip6_config_error_quark (void) +{ + static GQuark quark; + + if (G_UNLIKELY (!quark)) + quark = g_quark_from_static_string ("nm-setting-ip6-config-error-quark"); + return quark; +} + +/* This should really be standard. */ +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +nm_setting_ip6_config_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + /* Unknown error. */ + ENUM_ENTRY (NM_SETTING_IP6_CONFIG_ERROR_UNKNOWN, "UnknownError"), + /* The specified property was invalid. */ + ENUM_ENTRY (NM_SETTING_IP6_CONFIG_ERROR_INVALID_PROPERTY, "InvalidProperty"), + /* The specified property was missing and is required. */ + ENUM_ENTRY (NM_SETTING_IP6_CONFIG_ERROR_MISSING_PROPERTY, "MissingProperty"), + /* The specified property was not allowed in combination with the current 'method' */ + ENUM_ENTRY (NM_SETTING_IP6_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD, "NotAllowedForMethod"), + { 0, 0, 0 } + }; + etype = g_enum_register_static ("NMSettingIP6ConfigError", values); + } + return etype; +} + + +G_DEFINE_TYPE (NMSettingIP6Config, nm_setting_ip6_config, NM_TYPE_SETTING) + +enum { + PROP_0, + PROP_METHOD, + PROP_DNS, + PROP_DNS_SEARCH, + PROP_ADDRESSES, + PROP_ROUTES, + PROP_IGNORE_DHCPV6_DNS, + PROP_DISABLE_RA, + PROP_DHCPV6_MODE, + + LAST_PROP +}; + +NMSetting * +nm_setting_ip6_config_new (void) +{ + return (NMSetting *) g_object_new (NM_TYPE_SETTING_IP6_CONFIG, NULL); +} + +static gboolean +verify (NMSetting *setting, GSList *all_settings, GError **error) +{ + NMSettingIP6Config *self = NM_SETTING_IP6_CONFIG (setting); + + if (!self->method) { + g_set_error (error, + NM_SETTING_IP6_CONFIG_ERROR, + NM_SETTING_IP6_CONFIG_ERROR_MISSING_PROPERTY, + NM_SETTING_IP6_CONFIG_METHOD); + return FALSE; + } + + if (!strcmp (self->method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { + if (!self->addresses) { + g_set_error (error, + NM_SETTING_IP6_CONFIG_ERROR, + NM_SETTING_IP6_CONFIG_ERROR_MISSING_PROPERTY, + NM_SETTING_IP6_CONFIG_ADDRESSES); + return FALSE; + } + } else if ( !strcmp (self->method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) + || !strcmp (self->method, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) { + if (!self->ignore_dhcpv6_dns) { + if (self->dns && g_slist_length (self->dns)) { + g_set_error (error, + NM_SETTING_IP6_CONFIG_ERROR, + NM_SETTING_IP6_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD, + NM_SETTING_IP6_CONFIG_DNS); + return FALSE; + } + + if (g_slist_length (self->dns_search)) { + g_set_error (error, + NM_SETTING_IP6_CONFIG_ERROR, + NM_SETTING_IP6_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD, + NM_SETTING_IP6_CONFIG_DNS_SEARCH); + return FALSE; + } + } + + if (g_slist_length (self->addresses)) { + g_set_error (error, + NM_SETTING_IP6_CONFIG_ERROR, + NM_SETTING_IP6_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD, + NM_SETTING_IP6_CONFIG_ADDRESSES); + return FALSE; + } + + /* if router advertisement autoconf is disabled, dhcpv6 mode must + * be SOMETHING as long as the user has selected the auto method + */ + if (self->disable_ra && (self->dhcpv6_mode == NULL)) { + g_set_error (error, + NM_SETTING_IP6_CONFIG_ERROR, + NM_SETTING_IP6_CONFIG_ERROR_INVALID_PROPERTY, + NM_SETTING_IP6_CONFIG_DHCPV6_MODE); + return FALSE; + } + } else { + g_set_error (error, + NM_SETTING_IP6_CONFIG_ERROR, + NM_SETTING_IP6_CONFIG_ERROR_INVALID_PROPERTY, + NM_SETTING_IP6_CONFIG_METHOD); + return FALSE; + } + + return TRUE; +} + + +static void +nm_setting_ip6_config_init (NMSettingIP6Config *setting) +{ + ((NMSetting *) setting)->name = g_strdup (NM_SETTING_IP6_CONFIG_SETTING_NAME); +} + +static void +finalize (GObject *object) +{ + NMSettingIP6Config *self = NM_SETTING_IP6_CONFIG (object); + + g_free (self->method); + + if (self->dns) + g_slist_free (self->dns); + + nm_utils_slist_free (self->dns_search, g_free); + nm_utils_slist_free (self->addresses, g_free); + nm_utils_slist_free (self->routes, g_free); + + G_OBJECT_CLASS (nm_setting_ip6_config_parent_class)->finalize (object); +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSettingIP6Config *setting = NM_SETTING_IP6_CONFIG (object); + + switch (prop_id) { + case PROP_METHOD: + g_free (setting->method); + setting->method = g_value_dup_string (value); + break; + case PROP_DNS: + nm_utils_slist_free (setting->dns, g_free); + setting->dns = nm_utils_ip6_dns_from_gvalue (value); + break; + case PROP_DNS_SEARCH: + nm_utils_slist_free (setting->dns_search, g_free); + setting->dns_search = g_value_dup_boxed (value); + break; + case PROP_ADDRESSES: + nm_utils_slist_free (setting->addresses, g_free); + setting->addresses = nm_utils_ip6_addresses_from_gvalue (value); + case PROP_ROUTES: + nm_utils_slist_free (setting->routes, g_free); + setting->routes = nm_utils_ip6_addresses_from_gvalue (value); + break; + case PROP_IGNORE_DHCPV6_DNS: + setting->ignore_dhcpv6_dns = g_value_get_boolean (value); + break; + case PROP_DISABLE_RA: + setting->disable_ra = g_value_get_boolean (value); + break; + case PROP_DHCPV6_MODE: + g_free (setting->dhcpv6_mode); + setting->dhcpv6_mode = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMSettingIP6Config *setting = NM_SETTING_IP6_CONFIG (object); + + switch (prop_id) { + case PROP_METHOD: + g_value_set_string (value, setting->method); + break; + case PROP_DNS: + nm_utils_ip6_dns_to_gvalue (setting->dns, value); + break; + case PROP_DNS_SEARCH: + g_value_set_boxed (value, setting->dns_search); + break; + case PROP_ADDRESSES: + nm_utils_ip6_addresses_to_gvalue (setting->addresses, value); + break; + case PROP_ROUTES: + nm_utils_ip6_addresses_to_gvalue (setting->routes, value); + break; + case PROP_IGNORE_DHCPV6_DNS: + g_value_set_boolean (value, setting->ignore_dhcpv6_dns); + break; + case PROP_DISABLE_RA: + g_value_set_boolean (value, setting->disable_ra); + break; + case PROP_DHCPV6_MODE: + g_value_set_string (value, setting->dhcpv6_mode); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (setting_class); + NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class); + + /* virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->finalize = finalize; + parent_class->verify = verify; + + /* Properties */ + g_object_class_install_property + (object_class, PROP_METHOD, + g_param_spec_string (NM_SETTING_IP6_CONFIG_METHOD, + "Method", + "IP configuration method", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_DNS, + nm_param_spec_specialized (NM_SETTING_IP6_CONFIG_DNS, + "DNS", + "List of DNS servers", + DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_DNS_SEARCH, + nm_param_spec_specialized (NM_SETTING_IP6_CONFIG_DNS_SEARCH, + "DNS search", + "List of DNS search domains", + DBUS_TYPE_G_LIST_OF_STRING, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_ADDRESSES, + nm_param_spec_specialized (NM_SETTING_IP6_CONFIG_ADDRESSES, + "Addresses", + "List of NMSettingIP6Addresses", + DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_ROUTES, + nm_param_spec_specialized (NM_SETTING_IP6_CONFIG_ROUTES, + "Routes", + "List of NMSettingIP6Addresses", + DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_IGNORE_DHCPV6_DNS, + g_param_spec_boolean (NM_SETTING_IP6_CONFIG_IGNORE_DHCPV6_DNS, + "Ignore DHCPv6 DNS", + "Ignore DHCPv6 DNS", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_DISABLE_RA, + g_param_spec_boolean (NM_SETTING_IP6_CONFIG_DISABLE_RA, + "Ignore Router Advertisements", + "Ignore Router Advertisements", + FALSE, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_DHCPV6_MODE, + g_param_spec_string (NM_SETTING_IP6_CONFIG_DHCPV6_MODE, + "DHCPv6 Client Mode", + "DHCPv6 Client Mode", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); +} diff --git a/libnm-util/nm-setting-ip6-config.h b/libnm-util/nm-setting-ip6-config.h new file mode 100644 index 0000000000..0ac2531228 --- /dev/null +++ b/libnm-util/nm-setting-ip6-config.h @@ -0,0 +1,80 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#ifndef NM_SETTING_IP6_CONFIG_H +#define NM_SETTING_IP6_CONFIG_H + +#include + +#include "nm-setting.h" + +G_BEGIN_DECLS + +#define NM_TYPE_SETTING_IP6_CONFIG (nm_setting_ip6_config_get_type ()) +#define NM_SETTING_IP6_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_IP6_CONFIG, NMSettingIP6Config)) +#define NM_SETTING_IP6_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_IP6CONFIG, NMSettingIP6ConfigClass)) +#define NM_IS_SETTING_IP6_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_IP6_CONFIG)) +#define NM_IS_SETTING_IP6_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTING_IP6_CONFIG)) +#define NM_SETTING_IP6_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_IP6_CONFIG, NMSettingIP6ConfigClass)) + +#define NM_SETTING_IP6_CONFIG_SETTING_NAME "ipv6" + +typedef enum +{ + NM_SETTING_IP6_CONFIG_ERROR_UNKNOWN = 0, + NM_SETTING_IP6_CONFIG_ERROR_INVALID_PROPERTY, + NM_SETTING_IP6_CONFIG_ERROR_MISSING_PROPERTY, + NM_SETTING_IP6_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD +} NMSettingIP6ConfigError; + +#define NM_TYPE_SETTING_IP6_CONFIG_ERROR (nm_setting_ip6_config_error_get_type ()) +GType nm_setting_ip6_config_error_get_type (void); + +#define NM_SETTING_IP6_CONFIG_ERROR nm_setting_ip6_config_error_quark () +GQuark nm_setting_ip6_config_error_quark (void); + +#define NM_SETTING_IP6_CONFIG_METHOD "method" +#define NM_SETTING_IP6_CONFIG_DNS "dns" +#define NM_SETTING_IP6_CONFIG_DNS_SEARCH "dns-search" +#define NM_SETTING_IP6_CONFIG_ADDRESSES "addresses" +#define NM_SETTING_IP6_CONFIG_ROUTES "routes" +#define NM_SETTING_IP6_CONFIG_IGNORE_DHCPV6_DNS "ignore-dhcpv6-dns" +#define NM_SETTING_IP6_CONFIG_DISABLE_RA "disable-ra" +#define NM_SETTING_IP6_CONFIG_DHCPV6_MODE "dhcpv6-mode" + +#define NM_SETTING_IP6_CONFIG_METHOD_AUTO "auto" +#define NM_SETTING_IP6_CONFIG_METHOD_MANUAL "manual" +#define NM_SETTING_IP6_CONFIG_METHOD_SHARED "shared" + +#define NM_SETTING_IP6_CONFIG_DHCPV6_MODE_INFO "info" +#define NM_SETTING_IP6_CONFIG_DHCPV6_MODE_REQUEST "request" + +typedef struct { + struct in6_addr address; + guint32 prefix; + struct in6_addr gateway; +} NMSettingIP6Address; + +typedef struct { + NMSetting parent; + + char *method; + GSList *dns; /* array of struct in6_addr */ + GSList *dns_search; /* list of strings */ + GSList *addresses; /* array of NMSettingIP6Address */ + GSList *routes; /* array of NMSettingIP6Address */ + gboolean ignore_dhcpv6_dns; + gboolean disable_ra; + char *dhcpv6_mode; +} NMSettingIP6Config; + +typedef struct { + NMSettingClass parent; +} NMSettingIP6ConfigClass; + +GType nm_setting_ip6_config_get_type (void); + +NMSetting *nm_setting_ip6_config_new (void); + +G_END_DECLS + +#endif /* NM_SETTING_IP6_CONFIG_H */ diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c index a66b08d837..e23ba361bc 100644 --- a/libnm-util/nm-utils.c +++ b/libnm-util/nm-utils.c @@ -36,6 +36,7 @@ #include "NetworkManager.h" #include "nm-dbus-glib-types.h" #include "nm-setting-ip4-config.h" +#include "nm-setting-ip6-config.h" struct EncodingTriplet { @@ -845,3 +846,141 @@ nm_utils_ip4_addresses_to_gvalue (GSList *list, GValue *value) g_value_take_boxed (value, addresses); } +GSList * +nm_utils_ip6_addresses_from_gvalue (const GValue *value) +{ + 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, *ba_gw; + NMSettingIP6Address *addr; + guint32 prefix; + + if ( (elements->n_values != 3) + || (G_VALUE_TYPE (g_value_array_get_nth (elements, 0)) != DBUS_TYPE_G_UCHAR_ARRAY) + || (G_VALUE_TYPE (g_value_array_get_nth (elements, 1)) != G_TYPE_UINT) + || (G_VALUE_TYPE (g_value_array_get_nth (elements, 2)) != DBUS_TYPE_G_UCHAR_ARRAY)) { + nm_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) { + nm_warning ("%s: ignoring invalid IP6 address of length %d", + __func__, ba_addr->len); + continue; + } + + tmp = g_value_array_get_nth (elements, 1); + prefix = g_value_get_uint (tmp); + if (prefix > 32) { + nm_warning ("%s: ignoring invalid IP6 prefix %d", + __func__, prefix); + continue; + } + + tmp = g_value_array_get_nth (elements, 2); + ba_gw = g_value_get_boxed (tmp); + if (ba_gw->len != 16) { + nm_warning ("%s: ignoring invalid IP6 gateway of length %d", + __func__, ba_gw->len); + continue; + } + + addr = g_malloc0 (sizeof (NMSettingIP6Address)); + addr->prefix = prefix; + memcpy (addr->address.s6_addr, ba_addr->data, 16); + memcpy (addr->gateway.s6_addr, ba_gw->data, 16); + list = g_slist_prepend (list, addr); + } + + return g_slist_reverse (list); +} + +void +nm_utils_ip6_addresses_to_gvalue (GSList *list, GValue *value) +{ + GPtrArray *addresses; + GSList *iter; + + addresses = g_ptr_array_new (); + + for (iter = list; iter; iter = iter->next) { + NMSettingIP6Address *addr = (NMSettingIP6Address *) iter->data; + GValue element = { 0, }; + GByteArray *ba_addr, *ba_gw; + + g_value_init (&element, DBUS_TYPE_G_IP6_ADDRESS); + g_value_take_boxed (&element, dbus_g_type_specialized_construct (DBUS_TYPE_G_IP6_ADDRESS)); + + ba_addr = g_byte_array_sized_new (16); + g_byte_array_append (ba_addr, (guint8 *) addr->address.s6_addr, 16); + + ba_gw = g_byte_array_sized_new (16); + g_byte_array_append (ba_gw, (guint8 *) addr->gateway.s6_addr, 16); + + dbus_g_type_struct_set (&element, + 0, ba_addr, + 1, addr->prefix, + 2, ba_gw, + G_MAXUINT); + + g_ptr_array_add (addresses, g_value_get_boxed (&element)); + g_value_unset (&element); + } + + g_value_take_boxed (value, addresses); +} + +GSList * +nm_utils_ip6_dns_from_gvalue (const GValue *value) +{ + 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); + struct in6_addr *addr; + + if (bytearray->len != 16) { + nm_warning ("%s: ignoring invalid IP6 address of length %d", + __func__, bytearray->len); + continue; + } + + addr = g_malloc0 (sizeof (struct in6_addr)); + memcpy (addr->s6_addr, bytearray->data, bytearray->len); + list = g_slist_prepend (list, addr); + } + + return g_slist_reverse (list); +} + +void +nm_utils_ip6_dns_to_gvalue (GSList *list, GValue *value) +{ + GPtrArray *dns; + GSList *iter; + + dns = g_ptr_array_new (); + + for (iter = list; iter; iter = iter->next) { + struct in6_addr *addr = (struct in6_addr *) iter->data; + GByteArray *bytearray; + + bytearray = g_byte_array_sized_new (16); + g_byte_array_append (bytearray, (guint8 *) addr->s6_addr, 16); + g_ptr_array_add (dns, bytearray); + } + + g_value_take_boxed (value, dns); +} diff --git a/libnm-util/nm-utils.h b/libnm-util/nm-utils.h index 46cf0ff9a0..f9694b4ec1 100644 --- a/libnm-util/nm-utils.h +++ b/libnm-util/nm-utils.h @@ -180,4 +180,10 @@ gboolean nm_utils_security_valid (NMUtilsSecurityType type, GSList *nm_utils_ip4_addresses_from_gvalue (const GValue *value); void nm_utils_ip4_addresses_to_gvalue (GSList *list, GValue *value); +GSList *nm_utils_ip6_addresses_from_gvalue (const GValue *value); +void nm_utils_ip6_addresses_to_gvalue (GSList *list, GValue *value); + +GSList *nm_utils_ip6_dns_from_gvalue (const GValue *value); +void nm_utils_ip6_dns_to_gvalue (GSList *list, GValue *value); + #endif /* NM_UTILS_H */