summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2014-09-06 17:57:39 -0400
committerDan Winship <danw@gnome.org>2014-09-18 11:04:25 -0400
commitab4199c785c7a26c5f0835a88b45eefe7c9fee92 (patch)
tree17ecd96300eab814318bb2e7838d27957bb44d18
parent4fab71b4666a49f6f3efa5b5855d8b07174b703e (diff)
downloadNetworkManager-ab4199c785c7a26c5f0835a88b45eefe7c9fee92.tar.gz
libnm-core: add GVariant-based versions of IP structure-manipulating utilities
-rw-r--r--libnm-core/nm-utils.c508
-rw-r--r--libnm-core/nm-utils.h14
-rw-r--r--libnm/libnm.ver12
3 files changed, 534 insertions, 0 deletions
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c
index d386440606..2a0497c342 100644
--- a/libnm-core/nm-utils.c
+++ b/libnm-core/nm-utils.c
@@ -1432,6 +1432,232 @@ nm_utils_ip4_routes_to_gvalue (GSList *list, GValue *value)
}
/**
+ * nm_utils_ip4_dns_to_variant:
+ * @dns: (type utf8): an array of IP address strings
+ *
+ * Utility function to convert an array of IP address strings int a #GVariant of
+ * type 'au' representing an array of IPv4 addresses.
+ *
+ * Returns: (transfer none): a new floating #GVariant representing @dns.
+ **/
+GVariant *
+nm_utils_ip4_dns_to_variant (char **dns)
+{
+ GVariantBuilder builder;
+ int i;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("au"));
+
+ if (dns) {
+ for (i = 0; dns[i]; i++) {
+ guint32 ip = 0;
+
+ inet_pton (AF_INET, dns[i], &ip);
+ g_variant_builder_add (&builder, "u", ip);
+ }
+ }
+
+ return g_variant_builder_end (&builder);
+}
+
+/**
+ * nm_utils_ip4_dns_from_variant:
+ * @value: a #GVariant of type 'au'
+ *
+ * Utility function to convert a #GVariant of type 'au' representing a list of
+ * IPv4 addresses into an array of IP address strings.
+ *
+ * Returns: (transfer full) (type utf8): a %NULL-terminated array of IP address strings.
+ **/
+char **
+nm_utils_ip4_dns_from_variant (GVariant *value)
+{
+ const guint32 *array;
+ gsize length;
+ char **dns;
+ int i;
+
+ g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("au")), NULL);
+
+ array = g_variant_get_fixed_array (value, &length, sizeof (guint32));
+ dns = g_new (char *, length + 1);
+
+ for (i = 0; i < length; i++)
+ dns[i] = g_strdup (nm_utils_inet4_ntop (array[i], NULL));
+ dns[i] = NULL;
+
+ return dns;
+}
+
+/**
+ * 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 a
+ * #GVariant of type 'aau' representing an array of NetworkManager IPv4
+ * addresses (which are tuples of address, prefix, and gateway).
+ *
+ * Returns: (transfer none): a new floating #GVariant representing @addresses.
+ **/
+GVariant *
+nm_utils_ip4_addresses_to_variant (GPtrArray *addresses)
+{
+ GVariantBuilder builder;
+ int i;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("aau"));
+
+ if (addresses) {
+ for (i = 0; i < addresses->len; i++) {
+ NMIP4Address *addr = addresses->pdata[i];
+ guint32 array[3];
+
+ 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_variant_builder_add (&builder, "@au",
+ g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32,
+ array, 3, sizeof (guint32)));
+ }
+ }
+
+ return g_variant_builder_end (&builder);
+}
+
+/**
+ * nm_utils_ip4_addresses_from_variant:
+ * @value: a #GVariant of type 'aau'
+ *
+ * Utility function to convert a #GVariant of type 'aau' representing a list of
+ * NetworkManager IPv4 addresses (which are tuples of address, prefix, and
+ * gateway) into a #GPtrArray of #NMIP4Address objects.
+ *
+ * Returns: (transfer full) (element-type NMIP4Address): a newly allocated
+ * #GPtrArray of #NMIP4Address objects
+ **/
+GPtrArray *
+nm_utils_ip4_addresses_from_variant (GVariant *value)
+{
+ GPtrArray *addresses;
+ GVariantIter iter;
+ GVariant *addr_var;
+
+ g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aau")), NULL);
+
+ g_variant_iter_init (&iter, value);
+ 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;
+ gsize length;
+ NMIP4Address *addr;
+
+ addr_array = g_variant_get_fixed_array (addr_var, &length, sizeof (guint32));
+ if (length < 3) {
+ g_warning ("Ignoring invalid IP4 address");
+ g_variant_unref (addr_var);
+ continue;
+ }
+
+ addr = nm_ip4_address_new ();
+ 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 addresses;
+}
+
+/**
+ * nm_utils_ip4_routes_to_variant:
+ * @routes: (element-type NMIP4Route): an array of #NMIP4Route objects
+ *
+ * Utility function to convert a #GPtrArray of #NMIP4Route objects into a
+ * #GVariant of type 'aau' representing an array of NetworkManager IPv4 routes
+ * (which are tuples of route, prefix, next hop, and metric).
+ *
+ * Returns: (transfer none): a new floating #GVariant representing @routes.
+ **/
+GVariant *
+nm_utils_ip4_routes_to_variant (GPtrArray *routes)
+{
+ GVariantBuilder builder;
+ int i;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("aau"));
+
+ if (routes) {
+ for (i = 0; i < routes->len; i++) {
+ NMIP4Route *route = routes->pdata[i];
+ guint32 array[4];
+
+ 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);
+
+ g_variant_builder_add (&builder, "@au",
+ g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32,
+ array, 4, sizeof (guint32)));
+ }
+ }
+
+ return g_variant_builder_end (&builder);
+}
+
+/**
+ * nm_utils_ip4_routes_from_variant:
+ * @value: #GVariant of type 'aau'
+ *
+ * Utility function to convert a #GVariant of type 'aau' representing an array
+ * of NetworkManager IPv4 routes (which are tuples of route, prefix, next hop,
+ * and metric) into a #GPtrArray of #NMIP4Route objects.
+ *
+ * Returns: (transfer full) (element-type NMIP4Route): a newly allocated
+ * #GPtrArray of #NMIP4Route objects
+ **/
+GPtrArray *
+nm_utils_ip4_routes_from_variant (GVariant *value)
+{
+ GVariantIter iter;
+ GVariant *route_var;
+ GPtrArray *routes;
+
+ g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aau")), NULL);
+
+ g_variant_iter_init (&iter, value);
+ 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;
+ gsize length;
+ NMIP4Route *route;
+
+ route_array = g_variant_get_fixed_array (route_var, &length, sizeof (guint32));
+ if (length < 4) {
+ g_warning ("Ignoring invalid IP4 route");
+ g_variant_unref (route_var);
+ continue;
+ }
+
+ route = nm_ip4_route_new ();
+ 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 routes;
+}
+
+/**
* nm_utils_ip4_netmask_to_prefix:
* @netmask: an IPv4 netmask in network byte order
*
@@ -2117,6 +2343,288 @@ nm_utils_ip6_dns_to_gvalue (GSList *list, GValue *value)
}
/**
+ * nm_utils_ip6_dns_to_variant:
+ * @dns: (type utf8): an array of IP address strings
+ *
+ * Utility function to convert an array of IP address strings int a #GVariant of
+ * type 'aay' representing an array of IPv6 addresses.
+ *
+ * Returns: (transfer none): a new floating #GVariant representing @dns.
+ **/
+GVariant *
+nm_utils_ip6_dns_to_variant (char **dns)
+{
+ GVariantBuilder builder;
+ int i;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("aay"));
+
+ if (dns) {
+ for (i = 0; dns[i]; i++) {
+ struct in6_addr ip;
+
+ 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));
+ }
+ }
+
+ return g_variant_builder_end (&builder);
+}
+
+/**
+ * nm_utils_ip6_dns_from_variant:
+ * @value: a #GVariant of type 'aay'
+ *
+ * Utility function to convert a #GVariant of type 'aay' representing a list of
+ * IPv6 addresses into an array of IP address strings.
+ *
+ * Returns: (transfer full) (type utf8): a %NULL-terminated array of IP address strings.
+ **/
+char **
+nm_utils_ip6_dns_from_variant (GVariant *value)
+{
+ GVariantIter iter;
+ GVariant *ip_var;
+ char **dns;
+ int i;
+
+ g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aay")), NULL);
+
+ dns = g_new (char *, g_variant_n_children (value) + 1);
+
+ g_variant_iter_init (&iter, value);
+ i = 0;
+ 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);
+
+ 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;
+ }
+
+ dns[i++] = g_strdup (nm_utils_inet6_ntop (ip, NULL));
+ g_variant_unref (ip_var);
+ }
+ dns[i] = NULL;
+
+ return dns;
+}
+
+/**
+ * nm_utils_ip6_addresses_to_variant:
+ * @addresses: (element-type NMIP6Address): an array of #NMIP6Address objects
+ *
+ * Utility function to convert a #GPtrArray of #NMIP6Address objects into a
+ * #GVariant of type 'a(ayuay)' representing an array of NetworkManager IPv6
+ * addresses (which are tuples of address, prefix, and gateway).
+ *
+ * Returns: (transfer none): a new floating #GVariant representing @addresses.
+ **/
+GVariant *
+nm_utils_ip6_addresses_to_variant (GPtrArray *addresses)
+{
+ GVariantBuilder builder;
+ int i;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayuay)"));
+
+ if (addresses) {
+ for (i = 0; i < addresses->len; i++) {
+ NMIP6Address *addr = addresses->pdata[i];
+ 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, "(@ayu@ay)", ip, prefix, gateway);
+ }
+ }
+
+ return g_variant_builder_end (&builder);
+}
+
+/**
+ * nm_utils_ip6_addresses_from_variant:
+ * @value: a #GVariant of type 'a(ayuay)'
+ *
+ * Utility function to convert a #GVariant of type 'a(ayuay)' representing a
+ * list of NetworkManager IPv6 addresses (which are tuples of address, prefix,
+ * and gateway) into a #GPtrArray of #NMIP6Address objects.
+ *
+ * Returns: (transfer full) (element-type NMIP6Address): a newly allocated
+ * #GPtrArray of #NMIP6Address objects
+ **/
+GPtrArray *
+nm_utils_ip6_addresses_from_variant (GVariant *value)
+{
+ GVariantIter iter;
+ GVariant *addr_var, *gateway_var;
+ guint32 prefix;
+ GPtrArray *addresses;
+
+ g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("a(ayuay)")), NULL);
+
+ g_variant_iter_init (&iter, value);
+ addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip6_address_unref);
+
+ while (g_variant_iter_next (&iter, "(@ayu@ay)", &addr_var, &prefix, &gateway_var)) {
+ NMIP6Address *addr;
+ const struct in6_addr *addr_bytes, *gateway_bytes;
+ gsize addr_len, gateway_len;
+
+ if ( !g_variant_is_of_type (addr_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;
+ }
+
+ addr_bytes = g_variant_get_fixed_array (addr_var, &addr_len, 1);
+ if (addr_len != 16) {
+ g_warning ("%s: ignoring invalid IP6 address of length %d",
+ __func__, (int) addr_len);
+ goto next;
+ }
+ if (prefix > 128) {
+ g_warning ("%s: ignoring invalid IP6 prefix %d",
+ __func__, prefix);
+ goto next;
+ }
+ gateway_bytes = 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, addr_bytes);
+ nm_ip6_address_set_prefix (addr, prefix);
+ nm_ip6_address_set_gateway (addr, gateway_bytes);
+ g_ptr_array_add (addresses, addr);
+
+ next:
+ g_variant_unref (addr_var);
+ g_variant_unref (gateway_var);
+ }
+
+ return addresses;
+}
+
+/**
+ * nm_utils_ip6_routes_to_variant:
+ * @routes: (element-type NMIP6Route): an array of #NMIP6Route objects
+ *
+ * Utility function to convert a #GPtrArray of #NMIP6Route objects into a
+ * #GVariant of type 'a(ayuayu)' representing an array of NetworkManager IPv6
+ * routes (which are tuples of route, prefix, next hop, and metric).
+ *
+ * Returns: (transfer none): a new floating #GVariant representing @routes.
+ **/
+GVariant *
+nm_utils_ip6_routes_to_variant (GPtrArray *routes)
+{
+ GVariantBuilder builder;
+ int i;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayuayu)"));
+
+ if (routes) {
+ for (i = 0; i < routes->len; i++) {
+ NMIP6Route *route = routes->pdata[i];
+ 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, "(@ayu@ayu)", dest, prefix, next_hop, metric);
+ }
+ }
+
+ return g_variant_builder_end (&builder);
+}
+
+/**
+ * nm_utils_ip6_routes_from_variant:
+ * @value: #GVariant of type 'a(ayuayu)'
+ *
+ * Utility function to convert a #GVariant of type 'a(ayuayu)' representing an
+ * array of NetworkManager IPv6 routes (which are tuples of route, prefix, next
+ * hop, and metric) into a #GPtrArray of #NMIP6Route objects.
+ *
+ * Returns: (transfer full) (element-type NMIP6Route): a newly allocated
+ * #GPtrArray of #NMIP6Route objects
+ **/
+GPtrArray *
+nm_utils_ip6_routes_from_variant (GVariant *value)
+{
+ 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;
+
+ g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("a(ayuayu)")), NULL);
+
+ routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip6_route_unref);
+
+ g_variant_iter_init (&iter, value);
+ while (g_variant_iter_next (&iter, "(@ayu@ayu)", &dest_var, &prefix, &next_hop_var, &metric)) {
+ NMIP6Route *route;
+
+ 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_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, 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);
+
+ next:
+ g_variant_unref (dest_var);
+ g_variant_unref (next_hop_var);
+ }
+
+ return routes;
+}
+
+/**
* nm_utils_uuid_generate:
*
* Returns: a newly allocated UUID suitable for use as the #NMSettingConnection
diff --git a/libnm-core/nm-utils.h b/libnm-core/nm-utils.h
index b6b9db583b..5c11112357 100644
--- a/libnm-core/nm-utils.h
+++ b/libnm-core/nm-utils.h
@@ -101,6 +101,13 @@ void nm_utils_ip4_addresses_to_gvalue (GSList *list, GValue *value);
GSList *nm_utils_ip4_routes_from_gvalue (const GValue *value);
void nm_utils_ip4_routes_to_gvalue (GSList *list, GValue *value);
+GVariant *nm_utils_ip4_dns_to_variant (char **dns);
+char **nm_utils_ip4_dns_from_variant (GVariant *value);
+GVariant *nm_utils_ip4_addresses_to_variant (GPtrArray *addresses);
+GPtrArray *nm_utils_ip4_addresses_from_variant (GVariant *value);
+GVariant *nm_utils_ip4_routes_to_variant (GPtrArray *routes);
+GPtrArray *nm_utils_ip4_routes_from_variant (GVariant *value);
+
guint32 nm_utils_ip4_netmask_to_prefix (guint32 netmask);
guint32 nm_utils_ip4_prefix_to_netmask (guint32 prefix);
guint32 nm_utils_ip4_get_default_prefix (guint32 ip);
@@ -114,6 +121,13 @@ void nm_utils_ip6_routes_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);
+GVariant *nm_utils_ip6_dns_to_variant (char **dns);
+char **nm_utils_ip6_dns_from_variant (GVariant *value);
+GVariant *nm_utils_ip6_addresses_to_variant (GPtrArray *addresses);
+GPtrArray *nm_utils_ip6_addresses_from_variant (GVariant *value);
+GVariant *nm_utils_ip6_routes_to_variant (GPtrArray *routes);
+GPtrArray *nm_utils_ip6_routes_from_variant (GVariant *value);
+
char *nm_utils_uuid_generate (void);
char *nm_utils_uuid_generate_from_string (const char *s);
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index e0592f548f..d48731c474 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -880,18 +880,30 @@ global:
nm_utils_inet6_ntop;
nm_utils_init;
nm_utils_ip4_addresses_from_gvalue;
+ nm_utils_ip4_addresses_from_variant;
nm_utils_ip4_addresses_to_gvalue;
+ nm_utils_ip4_addresses_to_variant;
+ nm_utils_ip4_dns_from_variant;
+ nm_utils_ip4_dns_to_variant;
nm_utils_ip4_get_default_prefix;
nm_utils_ip4_netmask_to_prefix;
nm_utils_ip4_prefix_to_netmask;
nm_utils_ip4_routes_from_gvalue;
+ nm_utils_ip4_routes_from_variant;
nm_utils_ip4_routes_to_gvalue;
+ nm_utils_ip4_routes_to_variant;
nm_utils_ip6_addresses_from_gvalue;
+ nm_utils_ip6_addresses_from_variant;
nm_utils_ip6_addresses_to_gvalue;
+ nm_utils_ip6_addresses_to_variant;
nm_utils_ip6_dns_from_gvalue;
+ nm_utils_ip6_dns_from_variant;
nm_utils_ip6_dns_to_gvalue;
+ nm_utils_ip6_dns_to_variant;
nm_utils_ip6_routes_from_gvalue;
+ nm_utils_ip6_routes_from_variant;
nm_utils_ip6_routes_to_gvalue;
+ nm_utils_ip6_routes_to_variant;
nm_utils_is_empty_ssid;
nm_utils_is_uuid;
nm_utils_rsa_key_encrypt;