summary refs log tree commit diff
path: root/libnm-util/nm-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm-util/nm-utils.c')
-rw-r--r--libnm-util/nm-utils.c2608
1 files changed, 0 insertions, 2608 deletions
diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c
deleted file mode 100644
index eae80a04..00000000
--- a/libnm-util/nm-utils.c
+++ /dev/null
@@ -1,2608 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-
-/*
- * 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 "nm-default.h"
-
-#include "nm-utils.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <netinet/ether.h>
-#include <linux/if_infiniband.h>
-#include <uuid/uuid.h>
-#include <libintl.h>
-#include <gmodule.h>
-
-#include "nm-gvaluearray-compat.h"
-#include "nm-utils-private.h"
-#include "nm-dbus-glib-types.h"
-#include "nm-setting-private.h"
-#include "crypto.h"
-
-/**
- * SECTION:nm-utils
- * @short_description: Utility functions
- * @include: nm-utils.h
- *
- * A collection of utility functions for working with SSIDs, IP addresses, Wi-Fi
- * access points and devices, among other things.
- */
-
-struct EncodingTriplet
-{
-	const char *encoding1;
-	const char *encoding2;
-	const char *encoding3;
-};
-
-struct IsoLangToEncodings
-{
-	const char *lang;
-	struct EncodingTriplet encodings;
-};
-
-/* 5-letter language codes */
-static const struct IsoLangToEncodings isoLangEntries5[] =
-{
-	/* Simplified Chinese */
-	{ "zh_cn",      {"euc-cn",      "gb2312",                       "gb18030"} },   /* PRC */
-	{ "zh_sg",      {"euc-cn",      "gb2312",                       "gb18030"} },   /* Singapore */
-
-	/* Traditional Chinese */
-	{ "zh_tw",      {"big5",                "euc-tw",                       NULL} },                /* Taiwan */
-	{ "zh_hk",      {"big5",                "euc-tw",                       "big5-hkcs"} },/* Hong Kong */
-	{ "zh_mo",      {"big5",                "euc-tw",                       NULL} },                /* Macau */
-
-	/* Table end */
-	{ NULL, {NULL, NULL, NULL} }
-};
-
-/* 2-letter language codes; we don't care about the other 3 in this table */
-static const struct IsoLangToEncodings isoLangEntries2[] =
-{
-	/* Japanese */
-	{ "ja",         {"euc-jp",      "shift_jis",            "iso-2022-jp"} },
-
-	/* Korean */
-	{ "ko",         {"euc-kr",      "iso-2022-kr",          "johab"} },
-
-	/* Thai */
-	{ "th",         {"iso-8859-11","windows-874",           NULL} },
-
-	/* Central European */
-	{ "hu",         {"iso-8859-2",  "windows-1250", NULL} },        /* Hungarian */
-	{ "cs",         {"iso-8859-2",  "windows-1250", NULL} },        /* Czech */
-	{ "hr",         {"iso-8859-2",  "windows-1250", NULL} },        /* Croatian */
-	{ "pl",         {"iso-8859-2",  "windows-1250", NULL} },        /* Polish */
-	{ "ro",         {"iso-8859-2",  "windows-1250", NULL} },        /* Romanian */
-	{ "sk",         {"iso-8859-2",  "windows-1250", NULL} },        /* Slovakian */
-	{ "sl",         {"iso-8859-2",  "windows-1250", NULL} },        /* Slovenian */
-	{ "sh",         {"iso-8859-2",  "windows-1250", NULL} },        /* Serbo-Croatian */
-
-	/* Cyrillic */
-	{ "ru",         {"koi8-r",      "windows-1251", "iso-8859-5"} },        /* Russian */
-	{ "be",         {"koi8-r",      "windows-1251", "iso-8859-5"} },        /* Belorussian */
-	{ "bg",         {"windows-1251","koi8-r",               "iso-8859-5"} },        /* Bulgarian */
-	{ "mk",         {"koi8-r",      "windows-1251", "iso-8859-5"} },        /* Macedonian */
-	{ "sr",         {"koi8-r",      "windows-1251", "iso-8859-5"} },        /* Serbian */
-	{ "uk",         {"koi8-u",      "koi8-r",                       "windows-1251"} },      /* Ukrainian */
-
-	/* Arabic */
-	{ "ar",         {"iso-8859-6",  "windows-1256", NULL} },
-
-	/* Baltic */
-	{ "et",         {"iso-8859-4",  "windows-1257", NULL} },        /* Estonian */
-	{ "lt",         {"iso-8859-4",  "windows-1257", NULL} },        /* Lithuanian */
-	{ "lv",         {"iso-8859-4",  "windows-1257", NULL} },        /* Latvian */
-
-	/* Greek */
-	{ "el",         {"iso-8859-7",  "windows-1253", NULL} },
-
-	/* Hebrew */
-	{ "he",         {"iso-8859-8",  "windows-1255", NULL} },
-	{ "iw",         {"iso-8859-8",  "windows-1255", NULL} },
-
-	/* Turkish */
-	{ "tr",         {"iso-8859-9",  "windows-1254", NULL} },
-
-	/* Table end */
-	{ NULL, {NULL, NULL, NULL} }
-};
-
-static GHashTable * langToEncodings5 = NULL;
-static GHashTable * langToEncodings2 = NULL;
-
-static void
-init_lang_to_encodings_hash (void)
-{
-	struct IsoLangToEncodings *enc;
-
-	if (G_UNLIKELY (langToEncodings5 == NULL)) {
-		/* Five-letter codes */
-		enc = (struct IsoLangToEncodings *) &isoLangEntries5[0];
-		langToEncodings5 = g_hash_table_new (g_str_hash, g_str_equal);
-		while (enc->lang) {
-			g_hash_table_insert (langToEncodings5, (gpointer) enc->lang,
-			                     (gpointer) &enc->encodings);
-			enc++;
-		}
-	}
-
-	if (G_UNLIKELY (langToEncodings2 == NULL)) {
-		/* Two-letter codes */
-		enc = (struct IsoLangToEncodings *) &isoLangEntries2[0];
-		langToEncodings2 = g_hash_table_new (g_str_hash, g_str_equal);
-		while (enc->lang) {
-			g_hash_table_insert (langToEncodings2, (gpointer) enc->lang,
-			                     (gpointer) &enc->encodings);
-			enc++;
-		}
-	}
-}
-
-static gboolean
-get_encodings_for_lang (const char *lang,
-                        char **encoding1,
-                        char **encoding2,
-                        char **encoding3)
-{
-	struct EncodingTriplet *encodings;
-	gboolean success = FALSE;
-	char *tmp_lang;
-
-	g_return_val_if_fail (lang != NULL, FALSE);
-	g_return_val_if_fail (encoding1 != NULL, FALSE);
-	g_return_val_if_fail (encoding2 != NULL, FALSE);
-	g_return_val_if_fail (encoding3 != NULL, FALSE);
-
-	*encoding1 = "iso-8859-1";
-	*encoding2 = "windows-1251";
-	*encoding3 = NULL;
-
-	init_lang_to_encodings_hash ();
-
-	tmp_lang = g_strdup (lang);
-	if ((encodings = g_hash_table_lookup (langToEncodings5, tmp_lang))) {
-		*encoding1 = (char *) encodings->encoding1;
-		*encoding2 = (char *) encodings->encoding2;
-		*encoding3 = (char *) encodings->encoding3;
-		success = TRUE;
-	}
-
-	/* Truncate tmp_lang to length of 2 */
-	if (strlen (tmp_lang) > 2)
-		tmp_lang[2] = '\0';
-	if (!success && (encodings = g_hash_table_lookup (langToEncodings2, tmp_lang))) {
-		*encoding1 = (char *) encodings->encoding1;
-		*encoding2 = (char *) encodings->encoding2;
-		*encoding3 = (char *) encodings->encoding3;
-		success = TRUE;
-	}
-
-	g_free (tmp_lang);
-	return success;
-}
-
-/* init, deinit for libnm_util */
-
-static void __attribute__((constructor))
-_check_symbols (void)
-{
-	GModule *self;
-	gpointer func;
-
-	self = g_module_open (NULL, 0);
-	if (g_module_symbol (self, "nm_device_state_get_type", &func))
-		g_error ("libnm symbols detected; Mixing libnm with libnm-util/libnm-glib is not supported");
-	g_module_close (self);
-}
-
-static gboolean initialized = FALSE;
-
-/**
- * nm_utils_init:
- * @error: location to store error, or %NULL
- *
- * Initializes libnm-util; should be called when starting any program that
- * uses libnm-util.  This function can be called more than once.
- *
- * Returns: %TRUE if the initialization was successful, %FALSE on failure.
- **/
-gboolean
-nm_utils_init (GError **error)
-{
-	if (!initialized) {
-		initialized = TRUE;
-
-		bindtextdomain (GETTEXT_PACKAGE, NMLOCALEDIR);
-		bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-
-		if (!crypto_init (error))
-			return FALSE;
-
-		_nm_value_transforms_register ();
-	}
-	return TRUE;
-}
-
-/**
- * nm_utils_deinit:
- *
- * No-op. Although this function still exists for ABI compatibility reasons, it
- * does not have any effect, and does not ever need to be called.
- **/
-void
-nm_utils_deinit (void)
-{
-}
-
-/* ssid helpers */
-
-/**
- * nm_utils_ssid_to_utf8:
- * @ssid: a byte array containing the SSID data
- *
- * Wi-Fi SSIDs are byte arrays, they are _not_ strings.  Thus, an SSID may
- * contain embedded NULLs and other unprintable characters.  Often it is
- * useful to print the SSID out for debugging purposes, but that should be the
- * _only_ use of this function.  Do not use this function for any persistent
- * storage of the SSID, since the printable SSID returned from this function
- * cannot be converted back into the real SSID of the access point.
- *
- * This function does almost everything humanly possible to convert the input
- * into a printable UTF-8 string, using roughly the following procedure:
- *
- * 1) if the input data is already UTF-8 safe, no conversion is performed
- * 2) attempts to get the current system language from the LANG environment
- *    variable, and depending on the language, uses a table of alternative
- *    encodings to try.  For example, if LANG=hu_HU, the table may first try
- *    the ISO-8859-2 encoding, and if that fails, try the Windows-1250 encoding.
- *    If all fallback encodings fail, replaces non-UTF-8 characters with '?'.
- * 3) If the system language was unable to be determined, falls back to the
- *    ISO-8859-1 encoding, then to the Windows-1251 encoding.
- * 4) If step 3 fails, replaces non-UTF-8 characters with '?'.
- *
- * Again, this function should be used for debugging and display purposes
- * _only_.
- *
- * Returns: (transfer full): an allocated string containing a UTF-8
- * representation of the SSID, which must be freed by the caller using g_free().
- * Returns %NULL on errors.
- **/
-char *
-nm_utils_ssid_to_utf8 (const GByteArray *ssid)
-{
-	char *converted = NULL;
-	char *lang, *e1 = NULL, *e2 = NULL, *e3 = NULL;
-
-	g_return_val_if_fail (ssid != NULL, NULL);
-
-	if (g_utf8_validate ((const char *) ssid->data, ssid->len, NULL))
-		return g_strndup ((const char *) ssid->data, ssid->len);
-
-	/* LANG may be a good encoding hint */
-	g_get_charset ((const char **)(&e1));
-	if ((lang = getenv ("LANG"))) {
-		char * dot;
-
-		lang = g_ascii_strdown (lang, -1);
-		if ((dot = strchr (lang, '.')))
-			*dot = '\0';
-
-		get_encodings_for_lang (lang, &e1, &e2, &e3);
-		g_free (lang);
-	}
-
-	converted = g_convert ((const char *) ssid->data, ssid->len, "UTF-8", e1, NULL, NULL, NULL);
-	if (!converted && e2)
-		converted = g_convert ((const char *) ssid->data, ssid->len, "UTF-8", e2, NULL, NULL, NULL);
-
-	if (!converted && e3)
-		converted = g_convert ((const char *) ssid->data, ssid->len, "UTF-8", e3, NULL, NULL, NULL);
-
-	if (!converted) {
-		converted = g_convert_with_fallback ((const char *) ssid->data, ssid->len,
-		                                     "UTF-8", e1, "?", NULL, NULL, NULL);
-	}
-
-	if (!converted) {
-		/* If there is still no converted string, the SSID probably
-		 * contains characters not valid in the current locale. Convert
-		 * the string to ASCII instead.
-		 */
-
-		/* Use the printable range of 0x20-0x7E */
-		char *valid_chars = " !\"#$%&'()*+,-./0123456789:;<=>?@"
-		                     "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`"
-		                     "abcdefghijklmnopqrstuvwxyz{|}~";
-
-		converted = g_strndup ((const char *)ssid->data, ssid->len);
-		g_strcanon (converted, valid_chars, '?');
-	}
-
-	return converted;
-}
-
-/* Shamelessly ripped from the Linux kernel ieee80211 stack */
-/**
- * nm_utils_is_empty_ssid:
- * @ssid: pointer to a buffer containing the SSID data
- * @len: length of the SSID data in @ssid
- *
- * Different manufacturers use different mechanisms for not broadcasting the
- * AP's SSID.  This function attempts to detect blank/empty SSIDs using a
- * number of known SSID-cloaking methods.
- *
- * Returns: %TRUE if the SSID is "empty", %FALSE if it is not
- **/
-gboolean
-nm_utils_is_empty_ssid (const guint8 * ssid, int len)
-{
-	/* Single white space is for Linksys APs */
-	if (len == 1 && ssid[0] == ' ')
-		return TRUE;
-
-	/* Otherwise, if the entire ssid is 0, we assume it is hidden */
-	while (len--) {
-		if (ssid[len] != '\0')
-			return FALSE;
-	}
-	return TRUE;
-}
-
-#define ESSID_MAX_SIZE 32
-
-/**
- * nm_utils_escape_ssid:
- * @ssid: pointer to a buffer containing the SSID data
- * @len: length of the SSID data in @ssid
- *
- * This function does a quick printable character conversion of the SSID, simply
- * replacing embedded NULLs and non-printable characters with the hexadecimal
- * representation of that character.  Intended for debugging only, should not
- * be used for display of SSIDs.
- *
- * Returns: pointer to the escaped SSID, which uses an internal static buffer
- * and will be overwritten by subsequent calls to this function
- **/
-const char *
-nm_utils_escape_ssid (const guint8 * ssid, guint32 len)
-{
-	static char escaped[ESSID_MAX_SIZE * 2 + 1];
-	const guint8 *s = ssid;
-	char *d = escaped;
-
-	if (nm_utils_is_empty_ssid (ssid, len)) {
-		memcpy (escaped, "<hidden>", sizeof ("<hidden>"));
-		return escaped;
-	}
-
-	len = MIN (len, (guint32) ESSID_MAX_SIZE);
-	while (len--) {
-		if (*s == '\0') {
-			*d++ = '\\';
-			*d++ = '0';
-			s++;
-		} else {
-			*d++ = *s++;
-		}
-	}
-	*d = '\0';
-	return escaped;
-}
-
-/**
- * nm_utils_same_ssid:
- * @ssid1: first SSID data to compare
- * @ssid2: second SSID data to compare
- * @ignore_trailing_null: %TRUE to ignore one trailing NULL byte
- *
- * Earlier versions of the Linux kernel added a NULL byte to the end of the
- * SSID to enable easy printing of the SSID on the console or in a terminal,
- * but this behavior was problematic (SSIDs are simply byte arrays, not strings)
- * and thus was changed.  This function compensates for that behavior at the
- * cost of some compatibility with odd SSIDs that may legitimately have trailing
- * NULLs, even though that is functionally pointless.
- *
- * Returns: %TRUE if the SSIDs are the same, %FALSE if they are not
- **/
-gboolean
-nm_utils_same_ssid (const GByteArray * ssid1,
-                    const GByteArray * ssid2,
-                    gboolean ignore_trailing_null)
-{
-	guint32 ssid1_len, ssid2_len;
-
-	if (ssid1 == ssid2)
-		return TRUE;
-	if (!ssid1 || !ssid2)
-		return FALSE;
-
-	ssid1_len = ssid1->len;
-	ssid2_len = ssid2->len;
-	if (ssid1_len && ssid2_len && ignore_trailing_null) {
-		if (ssid1->data[ssid1_len - 1] == '\0')
-			ssid1_len--;
-		if (ssid2->data[ssid2_len - 1] == '\0')
-			ssid2_len--;
-	}
-
-	if (ssid1_len != ssid2_len)
-		return FALSE;
-
-	return memcmp (ssid1->data, ssid2->data, ssid1_len) == 0 ? TRUE : FALSE;
-}
-
-static void
-value_destroy (gpointer data)
-{
-	GValue *value = (GValue *) data;
-
-	g_value_unset (value);
-	g_slice_free (GValue, value);
-}
-
-static void
-value_dup (gpointer key, gpointer val, gpointer user_data)
-{
-	GHashTable *table = (GHashTable *) user_data;
-	GValue *value = (GValue *) val;
-	GValue *dup_value;
-
-	dup_value = g_slice_new0 (GValue);
-	g_value_init (dup_value, G_VALUE_TYPE (value));
-	g_value_copy (value, dup_value);
-
-	g_hash_table_insert (table, g_strdup ((char *) key), dup_value);
-}
-
-/**
- * nm_utils_gvalue_hash_dup:
- * @hash: a #GHashTable mapping string:GValue
- *
- * Utility function to duplicate a hash table of #GValues.
- *
- * Returns: (transfer container) (element-type utf8 GObject.Value): a newly allocated duplicated #GHashTable, caller must free the
- * returned hash with g_hash_table_unref() or g_hash_table_destroy()
- **/
-GHashTable *
-nm_utils_gvalue_hash_dup (GHashTable *hash)
-{
-	GHashTable *table;
-
-	g_return_val_if_fail (hash != NULL, NULL);
-
-	table = g_hash_table_new_full (g_str_hash, g_str_equal,
-	                               g_free,
-	                               value_destroy);
-
-	g_hash_table_foreach (hash, value_dup, table);
-
-	return table;
-}
-
-/**
- * nm_utils_slist_free: (skip)
- * @list: a #GSList
- * @elem_destroy_fn: user function called for each element in @list
- *
- * Utility function to free a #GSList.
- *
- * Deprecated: use g_slist_free_full().
- **/
-void
-nm_utils_slist_free (GSList *list, GDestroyNotify elem_destroy_fn)
-{
-	g_slist_free_full (list, elem_destroy_fn);
-}
-
-gboolean
-_nm_utils_string_slist_validate (GSList *list, const char **valid_values)
-{
-	GSList *iter;
-
-	for (iter = list; iter; iter = iter->next) {
-		if (!g_strv_contains (valid_values, (char *) iter->data))
-			return FALSE;
-	}
-
-	return TRUE;
-}
-
-gboolean
-_nm_utils_gvalue_array_validate (GValueArray *elements, guint n_expected, ...)
-{
-	va_list args;
-	GValue *tmp;
-	int i;
-	gboolean valid = FALSE;
-
-	if (n_expected != elements->n_values)
-		return FALSE;
-
-	va_start (args, n_expected);
-	for (i = 0; i < n_expected; i++) {
-		tmp = g_value_array_get_nth (elements, i);
-		if (G_VALUE_TYPE (tmp) != va_arg (args, GType))
-			goto done;
-	}
-	valid = TRUE;
-
-done:
-	va_end (args);
-	return valid;
-}
-
-static gboolean
-device_supports_ap_ciphers (guint32 dev_caps,
-                            guint32 ap_flags,
-                            gboolean static_wep)
-{
-	gboolean have_pair = FALSE;
-	gboolean have_group = FALSE;
-	/* Device needs to support at least one pairwise and one group cipher */
-
-	/* Pairwise */
-	if (static_wep) {
-		/* Static WEP only uses group ciphers */
-		have_pair = TRUE;
-	} else {
-		if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_WEP40)
-			if (ap_flags & NM_802_11_AP_SEC_PAIR_WEP40)
-				have_pair = TRUE;
-		if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_WEP104)
-			if (ap_flags & NM_802_11_AP_SEC_PAIR_WEP104)
-				have_pair = TRUE;
-		if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP)
-			if (ap_flags & NM_802_11_AP_SEC_PAIR_TKIP)
-				have_pair = TRUE;
-		if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP)
-			if (ap_flags & NM_802_11_AP_SEC_PAIR_CCMP)
-				have_pair = TRUE;
-	}
-
-	/* Group */
-	if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_WEP40)
-		if (ap_flags & NM_802_11_AP_SEC_GROUP_WEP40)
-			have_group = TRUE;
-	if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_WEP104)
-		if (ap_flags & NM_802_11_AP_SEC_GROUP_WEP104)
-			have_group = TRUE;
-	if (!static_wep) {
-		if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP)
-			if (ap_flags & NM_802_11_AP_SEC_GROUP_TKIP)
-				have_group = TRUE;
-		if (dev_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP)
-			if (ap_flags & NM_802_11_AP_SEC_GROUP_CCMP)
-				have_group = TRUE;
-	}
-
-	return (have_pair && have_group);
-}
-
-/**
- * nm_utils_ap_mode_security_valid:
- * @type: the security type to check device capabilities against,
- * e.g. #NMU_SEC_STATIC_WEP
- * @wifi_caps: bitfield of the capabilities of the specific Wi-Fi device, e.g.
- * #NM_WIFI_DEVICE_CAP_CIPHER_WEP40
- *
- * Given a set of device capabilities, and a desired security type to check
- * against, determines whether the combination of device capabilities and
- * desired security type are valid for AP/Hotspot connections.
- *
- * Returns: %TRUE if the device capabilities are compatible with the desired
- * @type, %FALSE if they are not.
- *
- * Since: 0.9.8
- **/
-gboolean
-nm_utils_ap_mode_security_valid (NMUtilsSecurityType type,
-                                 NMDeviceWifiCapabilities wifi_caps)
-{
-	if (!(wifi_caps & NM_WIFI_DEVICE_CAP_AP))
-		return FALSE;
-
-	/* Return TRUE for any security that wpa_supplicant's lightweight AP
-	 * mode can handle: which is open, WEP, and WPA/WPA2 PSK.
-	 */
-	switch (type) {
-	case NMU_SEC_NONE:
-	case NMU_SEC_STATIC_WEP:
-	case NMU_SEC_WPA_PSK:
-	case NMU_SEC_WPA2_PSK:
-		return TRUE;
-	default:
-		break;
-	}
-	return FALSE;
-}
-
-/**
- * nm_utils_security_valid:
- * @type: the security type to check AP flags and device capabilities against,
- * e.g. #NMU_SEC_STATIC_WEP
- * @wifi_caps: bitfield of the capabilities of the specific Wi-Fi device, e.g.
- * #NM_WIFI_DEVICE_CAP_CIPHER_WEP40
- * @have_ap: whether the @ap_flags, @ap_wpa, and @ap_rsn arguments are valid
- * @adhoc: whether the capabilities being tested are from an Ad-Hoc AP (IBSS)
- * @ap_flags: bitfield of AP capabilities, e.g. #NM_802_11_AP_FLAGS_PRIVACY
- * @ap_wpa: bitfield of AP capabilities derived from the AP's WPA beacon,
- * e.g. (#NM_802_11_AP_SEC_PAIR_TKIP | #NM_802_11_AP_SEC_KEY_MGMT_PSK)
- * @ap_rsn: bitfield of AP capabilities derived from the AP's RSN/WPA2 beacon,
- * e.g. (#NM_802_11_AP_SEC_PAIR_CCMP | #NM_802_11_AP_SEC_PAIR_TKIP)
- *
- * Given a set of device capabilities, and a desired security type to check
- * against, determines whether the combination of device, desired security
- * type, and AP capabilities intersect.
- *
- * NOTE: this function cannot handle checking security for AP/Hotspot mode;
- * use nm_utils_ap_mode_security_valid() instead.
- *
- * Returns: %TRUE if the device capabilities and AP capabilities intersect and are
- * compatible with the desired @type, %FALSE if they are not
- **/
-gboolean
-nm_utils_security_valid (NMUtilsSecurityType type,
-                         NMDeviceWifiCapabilities wifi_caps,
-                         gboolean have_ap,
-                         gboolean adhoc,
-                         NM80211ApFlags ap_flags,
-                         NM80211ApSecurityFlags ap_wpa,
-                         NM80211ApSecurityFlags ap_rsn)
-{
-	gboolean good = TRUE;
-
-	if (!have_ap) {
-		if (type == NMU_SEC_NONE)
-			return TRUE;
-		if (   (type == NMU_SEC_STATIC_WEP)
-		    || ((type == NMU_SEC_DYNAMIC_WEP) && !adhoc)
-		    || ((type == NMU_SEC_LEAP) && !adhoc)) {
-			if (wifi_caps & (NM_WIFI_DEVICE_CAP_CIPHER_WEP40 | NM_WIFI_DEVICE_CAP_CIPHER_WEP104))
-				return TRUE;
-			else
-				return FALSE;
-		}
-	}
-
-	switch (type) {
-	case NMU_SEC_NONE:
-		g_assert (have_ap);
-		if (ap_flags & NM_802_11_AP_FLAGS_PRIVACY)
-			return FALSE;
-		if (ap_wpa || ap_rsn)
-			return FALSE;
-		break;
-	case NMU_SEC_LEAP: /* require PRIVACY bit for LEAP? */
-		if (adhoc)
-			return FALSE;
-		/* fall through */
-	case NMU_SEC_STATIC_WEP:
-		g_assert (have_ap);
-		if (!(ap_flags & NM_802_11_AP_FLAGS_PRIVACY))
-			return FALSE;
-		if (ap_wpa || ap_rsn) {
-			if (!device_supports_ap_ciphers (wifi_caps, ap_wpa, TRUE))
-				if (!device_supports_ap_ciphers (wifi_caps, ap_rsn, TRUE))
-					return FALSE;
-		}
-		break;
-	case NMU_SEC_DYNAMIC_WEP:
-		if (adhoc)
-			return FALSE;
-		g_assert (have_ap);
-		if (ap_rsn || !(ap_flags & NM_802_11_AP_FLAGS_PRIVACY))
-			return FALSE;
-		/* Some APs broadcast minimal WPA-enabled beacons that must be handled */
-		if (ap_wpa) {
-			if (!(ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_802_1X))
-				return FALSE;
-			if (!device_supports_ap_ciphers (wifi_caps, ap_wpa, FALSE))
-				return FALSE;
-		}
-		break;
-	case NMU_SEC_WPA_PSK:
-		if (adhoc)
-			return FALSE;  /* FIXME: Kernel WPA Ad-Hoc support is buggy */
-		if (!(wifi_caps & NM_WIFI_DEVICE_CAP_WPA))
-			return FALSE;
-		if (have_ap) {
-			/* Ad-Hoc WPA APs won't necessarily have the PSK flag set, and
-			 * they don't have any pairwise ciphers. */
-			if (adhoc) {
-				/* coverity[dead_error_line] */
-				if (   (ap_wpa & NM_802_11_AP_SEC_GROUP_TKIP)
-				    && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP))
-					return TRUE;
-				if (   (ap_wpa & NM_802_11_AP_SEC_GROUP_CCMP)
-				    && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP))
-					return TRUE;
-			} else {
-				if (ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_PSK) {
-					if (   (ap_wpa & NM_802_11_AP_SEC_PAIR_TKIP)
-					    && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP))
-						return TRUE;
-					if (   (ap_wpa & NM_802_11_AP_SEC_PAIR_CCMP)
-					    && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP))
-						return TRUE;
-				}
-			}
-			return FALSE;
-		}
-		break;
-	case NMU_SEC_WPA2_PSK:
-		if (adhoc)
-			return FALSE;  /* FIXME: Kernel WPA Ad-Hoc support is buggy */
-		if (!(wifi_caps & NM_WIFI_DEVICE_CAP_RSN))
-			return FALSE;
-		if (have_ap) {
-			/* Ad-Hoc WPA APs won't necessarily have the PSK flag set, and
-			 * they don't have any pairwise ciphers, nor any RSA flags yet. */
-			if (adhoc) {
-				/* coverity[dead_error_line] */
-				if (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP)
-					return TRUE;
-				if (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP)
-					return TRUE;
-			} else {
-				if (ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_PSK) {
-					if (   (ap_rsn & NM_802_11_AP_SEC_PAIR_TKIP)
-					    && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP))
-						return TRUE;
-					if (   (ap_rsn & NM_802_11_AP_SEC_PAIR_CCMP)
-					    && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP))
-						return TRUE;
-				}
-			}
-			return FALSE;
-		}
-		break;
-	case NMU_SEC_WPA_ENTERPRISE:
-		if (adhoc)
-			return FALSE;
-		if (!(wifi_caps & NM_WIFI_DEVICE_CAP_WPA))
-			return FALSE;
-		if (have_ap) {
-			if (!(ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_802_1X))
-				return FALSE;
-			/* Ensure at least one WPA cipher is supported */
-			if (!device_supports_ap_ciphers (wifi_caps, ap_wpa, FALSE))
-				return FALSE;
-		}
-		break;
-	case NMU_SEC_WPA2_ENTERPRISE:
-		if (adhoc)
-			return FALSE;
-		if (!(wifi_caps & NM_WIFI_DEVICE_CAP_RSN))
-			return FALSE;
-		if (have_ap) {
-			if (!(ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_802_1X))
-				return FALSE;
-			/* Ensure at least one WPA cipher is supported */
-			if (!device_supports_ap_ciphers (wifi_caps, ap_rsn, FALSE))
-				return FALSE;
-		}
-		break;
-	default:
-		good = FALSE;
-		break;
-	}
-
-	return good;
-}
-
-/**
- * nm_utils_wep_key_valid:
- * @key: a string that might be a WEP key
- * @wep_type: the #NMWepKeyType type of the WEP key
- *
- * Checks if @key is a valid WEP key
- *
- * Returns: %TRUE if @key is a WEP key, %FALSE if not
- *
- * Since: 0.9.8
- */
-gboolean
-nm_utils_wep_key_valid (const char *key, NMWepKeyType wep_type)
-{
-	int keylen, i;
-
-	if (!key)
-		return FALSE;
-
-	keylen = strlen (key);
-	if (   wep_type == NM_WEP_KEY_TYPE_KEY
-	    || wep_type == NM_WEP_KEY_TYPE_UNKNOWN) {
-		if (keylen == 10 || keylen == 26) {
-			/* Hex key */
-			for (i = 0; i < keylen; i++) {
-				if (!g_ascii_isxdigit (key[i]))
-					return FALSE;
-			}
-		} else if (keylen == 5 || keylen == 13) {
-			/* ASCII key */
-			for (i = 0; i < keylen; i++) {
-				if (!g_ascii_isprint (key[i]))
-					return FALSE;
-			}
-		} else
-			return FALSE;
-
-	} else if (wep_type == NM_WEP_KEY_TYPE_PASSPHRASE) {
-		if (!keylen || keylen > 64)
-			return FALSE;
-	}
-
-	return TRUE;
-}
-
-/**
- * nm_utils_wpa_psk_valid:
- * @psk: a string that might be a WPA PSK
- *
- * Checks if @psk is a valid WPA PSK
- *
- * Returns: %TRUE if @psk is a WPA PSK, %FALSE if not
- *
- * Since: 0.9.8
- */
-gboolean
-nm_utils_wpa_psk_valid (const char *psk)
-{
-	int psklen, i;
-
-	if (!psk)
-		return FALSE;
-
-	psklen = strlen (psk);
-	if (psklen < 8 || psklen > 64)
-		return FALSE;
-
-	if (psklen == 64) {
-		/* Hex PSK */
-		for (i = 0; i < psklen; i++) {
-			if (!g_ascii_isxdigit (psk[i]))
-				return FALSE;
-		}
-	}
-
-	return TRUE;
-}
-
-/**
- * nm_utils_ip4_addresses_from_gvalue:
- * @value: #GValue containing a #GPtrArray of #GArrays of #guint32s
- *
- * Utility function to convert a #GPtrArray of #GArrays of #guint32s representing
- * a list of NetworkManager IPv4 addresses (which is a tuple of address, gateway,
- * and prefix) into a #GSList of #NMIP4Address objects.  The specific format of
- * this serialization is not guaranteed to be stable and the #GArray may be
- * extended in the future.
- *
- * Returns: (transfer full) (element-type NMIP4Address): a newly allocated #GSList of #NMIP4Address objects
- **/
-GSList *
-nm_utils_ip4_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++) {
-		GArray *array = (GArray *) g_ptr_array_index (addresses, i);
-		NMIP4Address *addr;
-
-		if (array->len < 3) {
-			g_warning ("Ignoring invalid IP4 address");
-			continue;
-		}
-
-		addr = nm_ip4_address_new ();
-		nm_ip4_address_set_address (addr, g_array_index (array, guint32, 0));
-		nm_ip4_address_set_prefix (addr, g_array_index (array, guint32, 1));
-		nm_ip4_address_set_gateway (addr, g_array_index (array, guint32, 2));
-		list = g_slist_prepend (list, addr);
-	}
-
-	return g_slist_reverse (list);
-}
-
-/**
- * nm_utils_ip4_addresses_to_gvalue:
- * @list: (element-type NMIP4Address): a list of #NMIP4Address objects
- * @value: a pointer to a #GValue into which to place the converted addresses,
- * which should be unset by the caller (when no longer needed) with
- * g_value_unset().
- *
- * Utility function to convert a #GSList of #NMIP4Address objects into a
- * #GPtrArray of #GArrays of #guint32s representing a list of NetworkManager IPv4
- * addresses (which is a tuple of address, gateway, and prefix).   The specific
- * format of this serialization is not guaranteed to be stable and may be
- * extended in the future.
- **/
-void
-nm_utils_ip4_addresses_to_gvalue (GSList *list, GValue *value)
-{
-	GPtrArray *addresses;
-	GSList *iter;
-
-	addresses = g_ptr_array_new ();
-
-	for (iter = list; iter; iter = iter->next) {
-		NMIP4Address *addr = (NMIP4Address *) iter->data;
-		GArray *array;
-		guint32 tmp;
-
-		array = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3);
-
-		tmp = nm_ip4_address_get_address (addr);
-		g_array_append_val (array, tmp);
-
-		tmp = nm_ip4_address_get_prefix (addr);
-		g_array_append_val (array, tmp);
-
-		tmp = nm_ip4_address_get_gateway (addr);
-		g_array_append_val (array, tmp);
-
-		g_ptr_array_add (addresses, array);
-	}
-
-	g_value_take_boxed (value, addresses);
-}
-
-/**
- * nm_utils_ip4_routes_from_gvalue:
- * @value: #GValue containing a #GPtrArray of #GArrays of #guint32s
- *
- * Utility function to convert a #GPtrArray of #GArrays of #guint32s representing
- * a list of NetworkManager IPv4 routes (which is a tuple of route, next hop,
- * prefix, and metric) into a #GSList of #NMIP4Route objects.  The specific
- * format of this serialization is not guaranteed to be stable and may be
- * extended in the future.
- *
- * Returns: (transfer full) (element-type NMIP4Route): a newly allocated #GSList of #NMIP4Route objects
- **/
-GSList *
-nm_utils_ip4_routes_from_gvalue (const GValue *value)
-{
-	GPtrArray *routes;
-	int i;
-	GSList *list = NULL;
-
-	routes = (GPtrArray *) g_value_get_boxed (value);
-	for (i = 0; routes && (i < routes->len); i++) {
-		GArray *array = (GArray *) g_ptr_array_index (routes, i);
-		NMIP4Route *route;
-
-		if (array->len < 4) {
-			g_warning ("Ignoring invalid IP4 route");
-			continue;
-		}
-
-		route = nm_ip4_route_new ();
-		nm_ip4_route_set_dest (route, g_array_index (array, guint32, 0));
-		nm_ip4_route_set_prefix (route, g_array_index (array, guint32, 1));
-		nm_ip4_route_set_next_hop (route, g_array_index (array, guint32, 2));
-		nm_ip4_route_set_metric (route, g_array_index (array, guint32, 3));
-		list = g_slist_prepend (list, route);
-	}
-
-	return g_slist_reverse (list);
-}
-
-/**
- * nm_utils_ip4_routes_to_gvalue:
- * @list: (element-type NMIP4Route): a list of #NMIP4Route objects
- * @value: a pointer to a #GValue into which to place the converted routes,
- * which should be unset by the caller (when no longer needed) with
- * g_value_unset().
- *
- * Utility function to convert a #GSList of #NMIP4Route objects into a
- * #GPtrArray of #GArrays of #guint32s representing a list of NetworkManager IPv4
- * routes (which is a tuple of route, next hop, prefix, and metric).   The
- * specific format of this serialization is not guaranteed to be stable and may
- * be extended in the future.
- **/
-void
-nm_utils_ip4_routes_to_gvalue (GSList *list, GValue *value)
-{
-	GPtrArray *routes;
-	GSList *iter;
-
-	routes = g_ptr_array_new ();
-
-	for (iter = list; iter; iter = iter->next) {
-		NMIP4Route *route = (NMIP4Route *) iter->data;
-		GArray *array;
-		guint32 tmp;
-
-		array = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3);
-
-		tmp = nm_ip4_route_get_dest (route);
-		g_array_append_val (array, tmp);
-
-		tmp = nm_ip4_route_get_prefix (route);
-		g_array_append_val (array, tmp);
-
-		tmp = nm_ip4_route_get_next_hop (route);
-		g_array_append_val (array, tmp);
-
-		tmp = nm_ip4_route_get_metric (route);
-		g_array_append_val (array, tmp);
-
-		g_ptr_array_add (routes, array);
-	}
-
-	g_value_take_boxed (value, routes);
-}
-
-/**
- * nm_utils_ip4_netmask_to_prefix:
- * @netmask: an IPv4 netmask in network byte order
- *
- * Returns: the CIDR prefix represented by the netmask
- **/
-guint32
-nm_utils_ip4_netmask_to_prefix (guint32 netmask)
-{
-	guint32 prefix;
-	guint8 v;
-	const guint8 *p = (guint8 *) &netmask;
-
-	if (p[3]) {
-		prefix = 24;
-		v = p[3];
-	} else if (p[2]) {
-		prefix = 16;
-		v = p[2];
-	} else if (p[1]) {
-		prefix = 8;
-		v = p[1];
-	} else {
-		prefix = 0;
-		v = p[0];
-	}
-
-	while (v) {
-		prefix++;
-		v <<= 1;
-	}
-
-	return prefix;
-}
-
-/**
- * nm_utils_ip4_prefix_to_netmask:
- * @prefix: a CIDR prefix
- *
- * Returns: the netmask represented by the prefix, in network byte order
- **/
-guint32
-nm_utils_ip4_prefix_to_netmask (guint32 prefix)
-{
-	return _nm_utils_ip4_prefix_to_netmask (prefix);
-}
-
-/**
- * nm_utils_ip4_get_default_prefix:
- * @ip: an IPv4 address (in network byte order)
- *
- * When the Internet was originally set up, various ranges of IP addresses were
- * segmented into three network classes: A, B, and C.  This function will return
- * a prefix that is associated with the IP address specified defining where it
- * falls in the predefined classes.
- *
- * Returns: the default class prefix for the given IP
- **/
-/* The function is originally from ipcalc.c of Red Hat's initscripts. */
-guint32
-nm_utils_ip4_get_default_prefix (guint32 ip)
-{
-	return _nm_utils_ip4_get_default_prefix (ip);
-}
-
-/**
- * nm_utils_ip6_addresses_from_gvalue:
- * @value: gvalue containing a GPtrArray of GValueArrays of (GArray of guchars) and #guint32
- *
- * Utility function to convert a #GPtrArray of #GValueArrays of (#GArray of guchars) and #guint32
- * representing a list of NetworkManager IPv6 addresses (which is a tuple of address,
- * prefix, and gateway), into a #GSList of #NMIP6Address objects.  The specific format of
- * this serialization is not guaranteed to be stable and the #GValueArray may be
- * extended in the future.
- *
- * Returns: (transfer full) (element-type NMIP6Address): a newly allocated #GSList of #NMIP6Address objects
- **/
-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;
-		GByteArray *ba_gw = NULL;
-		NMIP6Address *addr;
-		guint32 prefix;
-
-		if (elements->n_values < 2 || elements->n_values > 3) {
-			g_warning ("%s: ignoring invalid IP6 address structure", __func__);
-			continue;
-		}
-
-		/* Third element (gateway) is optional */
-		if (   !_nm_utils_gvalue_array_validate (elements, 2, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT)
-		    && !_nm_utils_gvalue_array_validate (elements, 3, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, DBUS_TYPE_G_UCHAR_ARRAY)) {
-			g_warning ("%s: ignoring invalid IP6 address structure", __func__);
-			continue;
-		}
-
-		tmp = g_value_array_get_nth (elements, 0);
-		ba_addr = g_value_get_boxed (tmp);
-		if (ba_addr->len != 16) {
-			g_warning ("%s: ignoring invalid IP6 address of length %d",
-			           __func__, ba_addr->len);
-			continue;
-		}
-
-		tmp = g_value_array_get_nth (elements, 1);
-		prefix = g_value_get_uint (tmp);
-		if (prefix > 128) {
-			g_warning ("%s: ignoring invalid IP6 prefix %d",
-			           __func__, prefix);
-			continue;
-		}
-
-		if (elements->n_values == 3) {
-			tmp = g_value_array_get_nth (elements, 2);
-			ba_gw = g_value_get_boxed (tmp);
-			if (ba_gw->len != 16) {
-				g_warning ("%s: ignoring invalid IP6 gateway address of length %d",
-				           __func__, ba_gw->len);
-				continue;
-			}
-		}
-
-		addr = nm_ip6_address_new ();
-		nm_ip6_address_set_prefix (addr, prefix);
-		nm_ip6_address_set_address (addr, (const struct in6_addr *) ba_addr->data);
-		if (ba_gw)
-			nm_ip6_address_set_gateway (addr, (const struct in6_addr *) ba_gw->data);
-
-		list = g_slist_prepend (list, addr);
-	}
-
-	return g_slist_reverse (list);
-}
-
-/**
- * nm_utils_ip6_addresses_to_gvalue:
- * @list: (element-type NMIP6Address): a list of #NMIP6Address objects
- * @value: a pointer to a #GValue into which to place the converted addresses,
- * which should be unset by the caller (when no longer needed) with
- * g_value_unset().
- *
- * Utility function to convert a #GSList of #NMIP6Address objects into a
- * #GPtrArray of #GValueArrays representing a list of NetworkManager IPv6 addresses
- * (which is a tuple of address, prefix, and gateway). The specific format of
- * this serialization is not guaranteed to be stable and may be extended in the
- * future.
- **/
-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) {
-		NMIP6Address *addr = (NMIP6Address *) iter->data;
-		GValueArray *array;
-		GValue element = G_VALUE_INIT;
-		GByteArray *ba;
-
-		array = g_value_array_new (3);
-
-		/* IP address */
-		g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY);
-		ba = g_byte_array_new ();
-		g_byte_array_append (ba, (guint8 *) nm_ip6_address_get_address (addr), 16);
-		g_value_take_boxed (&element, ba);
-		g_value_array_append (array, &element);
-		g_value_unset (&element);
-
-		/* Prefix */
-		g_value_init (&element, G_TYPE_UINT);
-		g_value_set_uint (&element, nm_ip6_address_get_prefix (addr));
-		g_value_array_append (array, &element);
-		g_value_unset (&element);
-
-		/* Gateway */
-		g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY);
-		ba = g_byte_array_new ();
-		g_byte_array_append (ba, (guint8 *) nm_ip6_address_get_gateway (addr), 16);
-		g_value_take_boxed (&element, ba);
-		g_value_array_append (array, &element);
-		g_value_unset (&element);
-
-		g_ptr_array_add (addresses, array);
-	}
-
-	g_value_take_boxed (value, addresses);
-}
-
-/**
- * nm_utils_ip6_routes_from_gvalue:
- * @value: #GValue containing a #GPtrArray of #GValueArrays of (#GArray of #guchars), #guint32,
- * (#GArray of #guchars), and #guint32
- *
- * Utility function #GPtrArray of #GValueArrays of (#GArray of #guchars), #guint32,
- * (#GArray of #guchars), and #guint32 representing a list of NetworkManager IPv6
- * routes (which is a tuple of destination, prefix, next hop, and metric)
- * into a #GSList of #NMIP6Route objects.  The specific format of this serialization
- * is not guaranteed to be stable and may be extended in the future.
- *
- * Returns: (transfer full) (element-type NMIP6Route): a newly allocated #GSList of #NMIP6Route objects
- **/
-GSList *
-nm_utils_ip6_routes_from_gvalue (const GValue *value)
-{
-	GPtrArray *routes;
-	int i;
-	GSList *list = NULL;
-
-	routes = (GPtrArray *) g_value_get_boxed (value);
-	for (i = 0; routes && (i < routes->len); i++) {
-		GValueArray *route_values = (GValueArray *) g_ptr_array_index (routes, i);
-		GByteArray *dest, *next_hop;
-		guint prefix, metric;
-		NMIP6Route *route;
-
-		if (!_nm_utils_gvalue_array_validate (route_values, 4,
-		                                      DBUS_TYPE_G_UCHAR_ARRAY,
-		                                      G_TYPE_UINT,
-		                                      DBUS_TYPE_G_UCHAR_ARRAY,
-		                                      G_TYPE_UINT)) {
-			g_warning ("Ignoring invalid IP6 route");
-			continue;
-		}
-
-		dest = g_value_get_boxed (g_value_array_get_nth (route_values, 0));
-		if (dest->len != 16) {
-			g_warning ("%s: ignoring invalid IP6 dest address of length %d",
-			           __func__, dest->len);
-			continue;
-		}
-
-		prefix = g_value_get_uint (g_value_array_get_nth (route_values, 1));
-
-		next_hop = g_value_get_boxed (g_value_array_get_nth (route_values, 2));
-		if (next_hop->len != 16) {
-			g_warning ("%s: ignoring invalid IP6 next_hop address of length %d",
-			           __func__, next_hop->len);
-			continue;
-		}
-
-		metric = g_value_get_uint (g_value_array_get_nth (route_values, 3));
-
-		route = nm_ip6_route_new ();
-		nm_ip6_route_set_dest (route, (struct in6_addr *)dest->data);
-		nm_ip6_route_set_prefix (route, prefix);
-		nm_ip6_route_set_next_hop (route, (struct in6_addr *)next_hop->data);
-		nm_ip6_route_set_metric (route, metric);
-		list = g_slist_prepend (list, route);
-	}
-
-	return g_slist_reverse (list);
-}
-
-/**
- * nm_utils_ip6_routes_to_gvalue:
- * @list: (element-type NMIP6Route): a list of #NMIP6Route objects
- * @value: a pointer to a #GValue into which to place the converted routes,
- * which should be unset by the caller (when no longer needed) with
- * g_value_unset().
- *
- * Utility function to convert a #GSList of #NMIP6Route objects into a #GPtrArray of
- * #GValueArrays of (#GArray of #guchars), #guint32, (#GArray of #guchars), and #guint32
- * representing a list of NetworkManager IPv6 routes (which is a tuple of destination,
- * prefix, next hop, and metric).  The specific format of this serialization is not
- * guaranteed to be stable and may be extended in the future.
- **/
-void
-nm_utils_ip6_routes_to_gvalue (GSList *list, GValue *value)
-{
-	GPtrArray *routes;
-	GSList *iter;
-
-	routes = g_ptr_array_new ();
-
-	for (iter = list; iter; iter = iter->next) {
-		NMIP6Route *route = (NMIP6Route *) iter->data;
-		GValueArray *array;
-		const struct in6_addr *addr;
-		GByteArray *ba;
-		GValue element = G_VALUE_INIT;
-
-		array = g_value_array_new (4);
-
-		g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY);
-		addr = nm_ip6_route_get_dest (route);
-		ba = g_byte_array_new ();
-		g_byte_array_append (ba, (guchar *)addr, sizeof (*addr));
-		g_value_take_boxed (&element, ba);
-		g_value_array_append (array, &element);
-		g_value_unset (&element);
-
-		g_value_init (&element, G_TYPE_UINT);
-		g_value_set_uint (&element, nm_ip6_route_get_prefix (route));
-		g_value_array_append (array, &element);
-		g_value_unset (&element);
-
-		g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY);
-		addr = nm_ip6_route_get_next_hop (route);
-		ba = g_byte_array_new ();
-		g_byte_array_append (ba, (guchar *)addr, sizeof (*addr));
-		g_value_take_boxed (&element, ba);
-		g_value_array_append (array, &element);
-		g_value_unset (&element);
-
-		g_value_init (&element, G_TYPE_UINT);
-		g_value_set_uint (&element, nm_ip6_route_get_metric (route));
-		g_value_array_append (array, &element);
-		g_value_unset (&element);
-
-		g_ptr_array_add (routes, array);
-	}
-
-	g_value_take_boxed (value, routes);
-}
-
-/**
- * nm_utils_ip6_dns_from_gvalue: (skip)
- * @value: a #GValue
- *
- * Converts a #GValue containing a #GPtrArray of IP6 DNS, represented as
- * #GByteArrays into a #GSList of <literal><type>struct in6_addr</type></literal>s.
- *
- * Returns: a #GSList of IP6 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) {
-			g_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);
-}
-
-/**
- * nm_utils_ip6_dns_to_gvalue: (skip)
- * @list: a list of #NMIP6Route objects
- * @value: a pointer to a #GValue into which to place the converted DNS server
- * addresses, which should be unset by the caller (when no longer needed) with
- * g_value_unset().
- *
- * Utility function to convert a #GSList of <literal><type>struct
- * in6_addr</type></literal> structs into a #GPtrArray of #GByteArrays
- * representing each server's IPv6 addresses in network byte order.
- * The specific format of this serialization is not guaranteed to be
- * stable and may be extended in the future.
- */
-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);
-}
-
-/**
- * nm_utils_uuid_generate:
- *
- * Returns: a newly allocated UUID suitable for use as the #NMSettingConnection
- * object's #NMSettingConnection:id: property.  Should be freed with g_free()
- **/
-char *
-nm_utils_uuid_generate (void)
-{
-	uuid_t uuid;
-	char *buf;
-
-	buf = g_malloc0 (37);
-	uuid_generate_random (uuid);
-	uuid_unparse_lower (uuid, &buf[0]);
-	return buf;
-}
-
-/**
- * nm_utils_uuid_generate_from_string:
- * @s: a string to use as the seed for the UUID
- *
- * For a given @s, this function will always return the same UUID.
- *
- * Returns: a newly allocated UUID suitable for use as the #NMSettingConnection
- * object's #NMSettingConnection:id: property
- **/
-char *
-nm_utils_uuid_generate_from_string (const char *s)
-{
-	GError *error = NULL;
-	uuid_t uuid;
-	char *buf = NULL;
-
-	g_return_val_if_fail (s && *s, NULL);
-
-	if (!nm_utils_init (&error)) {
-		g_warning ("error initializing crypto: %s", error->message);
-		g_error_free (error);
-		return NULL;
-	}
-
-	if (!crypto_md5_hash (NULL, 0, s, strlen (s), (char *) uuid, sizeof (uuid), &error)) {
-		g_warning ("error generating UUID: %s", error->message);
-		g_error_free (error);
-		return NULL;
-	}
-
-	buf = g_malloc0 (37);
-	uuid_unparse_lower (uuid, &buf[0]);
-
-	return buf;
-}
-
-static char *
-make_key (const char *cipher,
-          const char *salt,
-          const gsize salt_len,
-          const char *password,
-          gsize *out_len,
-          GError **error)
-{
-	char *key;
-	guint32 digest_len = 24; /* DES-EDE3-CBC */
-
-	g_return_val_if_fail (salt != NULL, NULL);
-	g_return_val_if_fail (salt_len >= 8, NULL);
-	g_return_val_if_fail (password != NULL, NULL);
-	g_return_val_if_fail (out_len != NULL, NULL);
-
-	if (!strcmp (cipher, "DES-EDE3-CBC"))
-		digest_len = 24;
-	else if (!strcmp (cipher, "AES-128-CBC"))
-		digest_len = 16;
-
-	key = g_malloc0 (digest_len + 1);
-
-	if (!crypto_md5_hash (salt, salt_len, password, strlen (password), key, digest_len, error)) {
-		*out_len = 0;
-		memset (key, 0, digest_len);
-		g_free (key);
-		key = NULL;
-	} else
-		*out_len = digest_len;
-
-	return key;
-}
-
-/**
- * nm_utils_rsa_key_encrypt_helper:
- * @cipher: cipher to use for encryption ("DES-EDE3-CBC" or "AES-128-CBC")
- * @data: RSA private key data to be encrypted
- * @in_password: (allow-none): existing password to use, if any
- * @out_password: (out) (allow-none): if @in_password was %NULL, a random password will be generated
- *  and returned in this argument
- * @error: detailed error information on return, if an error occurred
- *
- * Encrypts the given RSA private key data with the given password (or generates
- * a password if no password was given) and converts the data to PEM format
- * suitable for writing to a file.
- *
- * Returns: (transfer full): on success, PEM-formatted data suitable for writing to a PEM-formatted
- * certificate/private key file.
- **/
-static GByteArray *
-nm_utils_rsa_key_encrypt_helper (const char *cipher,
-                                 const GByteArray *data,
-                                 const char *in_password,
-                                 char **out_password,
-                                 GError **error)
-{
-	char salt[16];
-	int salt_len;
-	char *key = NULL, *enc = NULL, *pw_buf[32];
-	gsize key_len = 0, enc_len = 0;
-	GString *pem = NULL;
-	char *tmp, *tmp_password = NULL;
-	int left;
-	const char *p;
-	GByteArray *ret = NULL;
-
-	g_return_val_if_fail (!g_strcmp0 (cipher, CIPHER_DES_EDE3_CBC) || !g_strcmp0 (cipher, CIPHER_AES_CBC), NULL);
-	g_return_val_if_fail (data != NULL, NULL);
-	g_return_val_if_fail (data->len > 0, NULL);
-	if (out_password)
-		g_return_val_if_fail (*out_password == NULL, NULL);
-
-	/* Make the password if needed */
-	if (!in_password) {
-		if (!crypto_randomize (pw_buf, sizeof (pw_buf), error))
-			return NULL;
-		in_password = tmp_password = nm_utils_bin2hexstr ((const char *) pw_buf, sizeof (pw_buf), -1);
-	}
-
-	if (g_strcmp0 (cipher, CIPHER_AES_CBC) == 0)
-		salt_len = 16;
-	else
-		salt_len = 8;
-
-	if (!crypto_randomize (salt, salt_len, error))
-		goto out;
-
-	key = make_key (cipher, &salt[0], salt_len, in_password, &key_len, error);
-	if (!key)
-		goto out;
-
-	enc = crypto_encrypt (cipher, data, salt, salt_len, key, key_len, &enc_len, error);
-	if (!enc)
-		goto out;
-
-	pem = g_string_sized_new (enc_len * 2 + 100);
-	g_string_append (pem, "-----BEGIN RSA PRIVATE KEY-----\n");
-	g_string_append (pem, "Proc-Type: 4,ENCRYPTED\n");
-
-	/* Convert the salt to a hex string */
-	tmp = nm_utils_bin2hexstr ((const char *) salt, salt_len, salt_len * 2);
-	g_string_append_printf (pem, "DEK-Info: %s,%s\n\n", cipher, tmp);
-	g_free (tmp);
-
-	/* Convert the encrypted key to a base64 string */
-	p = tmp = g_base64_encode ((const guchar *) enc, enc_len);
-	left = strlen (tmp);
-	while (left > 0) {
-		g_string_append_len (pem, p, (left < 64) ? left : 64);
-		g_string_append_c (pem, '\n');
-		left -= 64;
-		p += 64;
-	}
-	g_free (tmp);
-
-	g_string_append (pem, "-----END RSA PRIVATE KEY-----\n");
-
-	ret = g_byte_array_sized_new (pem->len);
-	g_byte_array_append (ret, (const unsigned char *) pem->str, pem->len);
-	if (tmp_password && out_password)
-		*out_password = g_strdup (tmp_password);
-
-out:
-	if (key) {
-		memset (key, 0, key_len);
-		g_free (key);
-	}
-	if (enc) {
-		memset (enc, 0, enc_len);
-		g_free (enc);
-	}
-	if (pem)
-		g_string_free (pem, TRUE);
-
-	if (tmp_password) {
-		memset (tmp_password, 0, strlen (tmp_password));
-		g_free (tmp_password);
-	}
-
-	return ret;
-}
-
-/**
- * nm_utils_rsa_key_encrypt:
- * @data: RSA private key data to be encrypted
- * @in_password: (allow-none): existing password to use, if any
- * @out_password: (out) (allow-none): if @in_password was %NULL, a random password will be generated
- *  and returned in this argument
- * @error: detailed error information on return, if an error occurred
- *
- * Encrypts the given RSA private key data with the given password (or generates
- * a password if no password was given) and converts the data to PEM format
- * suitable for writing to a file. It uses Triple DES cipher for the encryption.
- *
- * Returns: (transfer full): on success, PEM-formatted data suitable for writing to a PEM-formatted
- * certificate/private key file.
- **/
-GByteArray *
-nm_utils_rsa_key_encrypt (const GByteArray *data,
-                          const char *in_password,
-                          char **out_password,
-                          GError **error)
-{
-
-	return nm_utils_rsa_key_encrypt_helper (CIPHER_DES_EDE3_CBC,
-	                                        data,
-	                                        in_password,
-	                                        out_password,
-	                                        error);
-}
-
-/**
- * nm_utils_rsa_key_encrypt_aes:
- * @data: RSA private key data to be encrypted
- * @in_password: (allow-none): existing password to use, if any
- * @out_password: (out) (allow-none): if @in_password was %NULL, a random password will be generated
- *  and returned in this argument
- * @error: detailed error information on return, if an error occurred
- *
- * Encrypts the given RSA private key data with the given password (or generates
- * a password if no password was given) and converts the data to PEM format
- * suitable for writing to a file.  It uses AES cipher for the encryption.
- *
- * Returns: (transfer full): on success, PEM-formatted data suitable for writing to a PEM-formatted
- * certificate/private key file.
- **/
-GByteArray *
-nm_utils_rsa_key_encrypt_aes (const GByteArray *data,
-                              const char *in_password,
-                              char **out_password,
-                              GError **error)
-{
-
-	return nm_utils_rsa_key_encrypt_helper (CIPHER_AES_CBC,
-	                                        data,
-	                                        in_password,
-	                                        out_password,
-	                                        error);
-}
-
-/**
- * nm_utils_file_is_pkcs12:
- * @filename: name of the file to test
- *
- * Utility function to find out if the @filename is in PKCS#<!-- -->12 format.
- *
- * Returns: %TRUE if the file is PKCS#<!-- -->12, %FALSE if it is not
- **/
-gboolean
-nm_utils_file_is_pkcs12 (const char *filename)
-{
-	return crypto_is_pkcs12_file (filename, NULL);
-}
-
-/*****************************************************************************/
-
-/**
- * nm_utils_file_search_in_paths:
- * @progname: the helper program name, like "iptables"
- *   Must be a non-empty string, without path separator (/).
- * @try_first: (allow-none): a custom path to try first before searching.
- *   It is silently ignored if it is empty or not an absolute path.
- * @paths: (allow-none): a %NULL terminated list of search paths.
- *   Can be empty or %NULL, in which case only @try_first is checked.
- * @file_test_flags: the flags passed to g_file_test() when searching
- *   for @progname. Set it to 0 to skip the g_file_test().
- * @predicate: (scope call): if given, pass the file name to this function
- *   for additional checks. This check is performed after the check for
- *   @file_test_flags. You cannot omit both @file_test_flags and @predicate.
- * @user_data: (closure) (allow-none): user data for @predicate function.
- * @error: (allow-none): on failure, set a "not found" error %G_IO_ERROR %G_IO_ERROR_NOT_FOUND.
- *
- * Searches for a @progname file in a list of search @paths.
- *
- * Returns: (transfer none): the full path to the helper, if found, or %NULL if not found.
- *   The returned string is not owned by the caller, but later
- *   invocations of the function might overwrite it.
- */
-const char *
-nm_utils_file_search_in_paths (const char *progname,
-                               const char *try_first,
-                               const char *const *paths,
-                               GFileTest file_test_flags,
-                               NMUtilsFileSearchInPathsPredicate predicate,
-                               gpointer user_data,
-                               GError **error)
-{
-	GString *tmp;
-	const char *ret;
-
-	g_return_val_if_fail (!error || !*error, NULL);
-	g_return_val_if_fail (progname && progname[0] && !strchr (progname, '/'), NULL);
-	g_return_val_if_fail (file_test_flags || predicate, NULL);
-
-	/* Only consider @try_first if it is a valid, absolute path. This makes
-	 * it simpler to pass in a path from configure checks. */
-	if (   try_first
-	    && try_first[0] == '/'
-	    && (file_test_flags == 0 || g_file_test (try_first, file_test_flags))
-	    && (!predicate || predicate (try_first, user_data)))
-		return g_intern_string (try_first);
-
-	if (!paths || !*paths)
-		goto NOT_FOUND;
-
-	tmp = g_string_sized_new (50);
-	for (; *paths; paths++) {
-		if (!*paths)
-			continue;
-		g_string_append (tmp, *paths);
-		if (tmp->str[tmp->len - 1] != '/')
-			g_string_append_c (tmp, '/');
-		g_string_append (tmp, progname);
-		if (   (file_test_flags == 0 || g_file_test (tmp->str, file_test_flags))
-		    && (!predicate || predicate (tmp->str, user_data))) {
-			ret = g_intern_string (tmp->str);
-			g_string_free (tmp, TRUE);
-			return ret;
-		}
-		g_string_set_size (tmp, 0);
-	}
-	g_string_free (tmp, TRUE);
-
-NOT_FOUND:
-	g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("Could not find \"%s\" binary"), progname);
-	return NULL;
-}
-
-/*****************************************************************************/
-
-/* Band, channel/frequency stuff for wireless */
-struct cf_pair {
-	guint32 chan;
-	guint32 freq;
-};
-
-static struct cf_pair a_table[] = {
-	/* A band */
-	{  7, 5035 },
-	{  8, 5040 },
-	{  9, 5045 },
-	{ 11, 5055 },
-	{ 12, 5060 },
-	{ 16, 5080 },
-	{ 34, 5170 },
-	{ 36, 5180 },
-	{ 38, 5190 },
-	{ 40, 5200 },
-	{ 42, 5210 },
-	{ 44, 5220 },
-	{ 46, 5230 },
-	{ 48, 5240 },
-	{ 50, 5250 },
-	{ 52, 5260 },
-	{ 56, 5280 },
-	{ 58, 5290 },
-	{ 60, 5300 },
-	{ 64, 5320 },
-	{ 100, 5500 },
-	{ 104, 5520 },
-	{ 108, 5540 },
-	{ 112, 5560 },
-	{ 116, 5580 },
-	{ 120, 5600 },
-	{ 124, 5620 },
-	{ 128, 5640 },
-	{ 132, 5660 },
-	{ 136, 5680 },
-	{ 140, 5700 },
-	{ 149, 5745 },
-	{ 152, 5760 },
-	{ 153, 5765 },
-	{ 157, 5785 },
-	{ 160, 5800 },
-	{ 161, 5805 },
-	{ 165, 5825 },
-	{ 183, 4915 },
-	{ 184, 4920 },
-	{ 185, 4925 },
-	{ 187, 4935 },
-	{ 188, 4945 },
-	{ 192, 4960 },
-	{ 196, 4980 },
-	{ 0, -1 }
-};
-
-static struct cf_pair bg_table[] = {
-	/* B/G band */
-	{ 1, 2412 },
-	{ 2, 2417 },
-	{ 3, 2422 },
-	{ 4, 2427 },
-	{ 5, 2432 },
-	{ 6, 2437 },
-	{ 7, 2442 },
-	{ 8, 2447 },
-	{ 9, 2452 },
-	{ 10, 2457 },
-	{ 11, 2462 },
-	{ 12, 2467 },
-	{ 13, 2472 },
-	{ 14, 2484 },
-	{ 0, -1 }
-};
-
-/**
- * nm_utils_wifi_freq_to_channel:
- * @freq: frequency
- *
- * Utility function to translate a Wi-Fi frequency to its corresponding channel.
- *
- * Returns: the channel represented by the frequency or 0
- **/
-guint32
-nm_utils_wifi_freq_to_channel (guint32 freq)
-{
-	int i = 0;
-
-	if (freq > 4900) {
-		while (a_table[i].chan && (a_table[i].freq != freq))
-			i++;
-		return a_table[i].chan;
-	} else {
-		while (bg_table[i].chan && (bg_table[i].freq != freq))
-			i++;
-		return bg_table[i].chan;
-	}
-
-	return 0;
-}
-
-/**
- * nm_utils_wifi_channel_to_freq:
- * @channel: channel
- * @band: frequency band for wireless ("a" or "bg")
- *
- * Utility function to translate a Wi-Fi channel to its corresponding frequency.
- *
- * Returns: the frequency represented by the channel of the band,
- *          or -1 when the freq is invalid, or 0 when the band
- *          is invalid
- **/
-guint32
-nm_utils_wifi_channel_to_freq (guint32 channel, const char *band)
-{
-	int i = 0;
-
-	if (!strcmp (band, "a")) {
-		while (a_table[i].chan && (a_table[i].chan != channel))
-			i++;
-		return a_table[i].freq;
-	} else if (!strcmp (band, "bg")) {
-		while (bg_table[i].chan && (bg_table[i].chan != channel))
-			i++;
-		return bg_table[i].freq;
-	}
-
-	return 0;
-}
-
-/**
- * nm_utils_wifi_find_next_channel:
- * @channel: current channel
- * @direction: whether going downward (0 or less) or upward (1 or more)
- * @band: frequency band for wireless ("a" or "bg")
- *
- * Utility function to find out next/previous Wi-Fi channel for a channel.
- *
- * Returns: the next channel in the specified direction or 0
- **/
-guint32
-nm_utils_wifi_find_next_channel (guint32 channel, int direction, char *band)
-{
-	size_t a_size = sizeof (a_table) / sizeof (struct cf_pair);
-	size_t bg_size = sizeof (bg_table) / sizeof (struct cf_pair);
-	struct cf_pair *pair = NULL;
-
-	if (!strcmp (band, "a")) {
-		if (channel < a_table[0].chan)
-			return a_table[0].chan;
-		if (channel > a_table[a_size - 2].chan)
-			return a_table[a_size - 2].chan;
-		pair = &a_table[0];
-	} else if (!strcmp (band, "bg")) {
-		if (channel < bg_table[0].chan)
-			return bg_table[0].chan;
-		if (channel > bg_table[bg_size - 2].chan)
-			return bg_table[bg_size - 2].chan;
-		pair = &bg_table[0];
-	} else {
-		g_assert_not_reached ();
-		return 0;
-	}
-
-	while (pair->chan) {
-		if (channel == pair->chan)
-			return channel;
-		if ((channel < (pair+1)->chan) && (channel > pair->chan)) {
-			if (direction > 0)
-				return (pair+1)->chan;
-			else
-				return pair->chan;
-		}
-		pair++;
-	}
-	return 0;
-}
-
-/**
- * nm_utils_wifi_is_channel_valid:
- * @channel: channel
- * @band: frequency band for wireless ("a" or "bg")
- *
- * Utility function to verify Wi-Fi channel validity.
- *
- * Returns: %TRUE or %FALSE
- **/
-gboolean
-nm_utils_wifi_is_channel_valid (guint32 channel, const char *band)
-{
-	struct cf_pair *table = NULL;
-	int i = 0;
-
-	if (!strcmp (band, "a"))
-		table = a_table;
-	else if (!strcmp (band, "bg"))
-		table = bg_table;
-	else
-		return FALSE;
-
-	while (table[i].chan && (table[i].chan != channel))
-		i++;
-
-	if (table[i].chan != 0)
-		return TRUE;
-	else
-		return FALSE;
-}
-
-/**
- * nm_utils_hwaddr_len:
- * @type: the type of address; either <literal>ARPHRD_ETHER</literal> or
- *   <literal>ARPHRD_INFINIBAND</literal>
- *
- * Returns the length in octets of a hardware address of type @type.
- *
- * Return value: the positive length, or -1 if the type is unknown/unsupported.
- */
-int
-nm_utils_hwaddr_len (int type)
-{
-	if (type == ARPHRD_ETHER)
-		return ETH_ALEN;
-	else if (type == ARPHRD_INFINIBAND)
-		return INFINIBAND_ALEN;
-	else
-		return -1;
-}
-
-/**
- * nm_utils_hwaddr_type:
- * @len: the length of hardware address in bytes
- *
- * Returns the type (either <literal>ARPHRD_ETHER</literal> or
- * <literal>ARPHRD_INFINIBAND</literal>) of the raw address given its length.
- *
- * Return value: the type, either <literal>ARPHRD_ETHER</literal> or
- * <literal>ARPHRD_INFINIBAND</literal>.  If the length is unexpected, return -1
- * (unsupported type/length).
- *
- * Deprecated: This could not be extended to cover other types, since
- * there is not a one-to-one mapping between types and lengths. This
- * was mostly only used to get a type to pass to
- * nm_utils_hwaddr_ntoa() or nm_utils_hwaddr_aton() when you only had
- * a length; but you can just use nm_utils_hwaddr_ntoa_len() or
- * nm_utils_hwaddr_aton_len() now instead.
- */
-int
-nm_utils_hwaddr_type (int len)
-{
-	if (len == ETH_ALEN)
-		return ARPHRD_ETHER;
-	else if (len == INFINIBAND_ALEN)
-		return ARPHRD_INFINIBAND;
-	else
-		return -1;
-}
-
-#define HEXVAL(c) ((c) <= '9' ? (c) - '0' : ((c) & 0x4F) - 'A' + 10)
-
-/**
- * nm_utils_hwaddr_aton:
- * @asc: the ASCII representation of a hardware address
- * @type: the type of address; either <literal>ARPHRD_ETHER</literal> or
- *   <literal>ARPHRD_INFINIBAND</literal>
- * @buffer: buffer to store the result into
- *
- * Parses @asc and converts it to binary form in @buffer. See
- * nm_utils_hwaddr_atoba() if you'd rather have the result in a
- * #GByteArray.
- *
- * See also nm_utils_hwaddr_aton_len(), which takes an output length
- * instead of a type.
- *
- * Return value: @buffer, or %NULL if @asc couldn't be parsed
- */
-guint8 *
-nm_utils_hwaddr_aton (const char *asc, int type, gpointer buffer)
-{
-	int len = nm_utils_hwaddr_len (type);
-
-	if (len <= 0) {
-		g_return_val_if_reached (NULL);
-		return NULL;
-	}
-	return nm_utils_hwaddr_aton_len (asc, buffer, len);
-}
-
-/**
- * nm_utils_hwaddr_atoba:
- * @asc: the ASCII representation of a hardware address
- * @type: the type of address; either <literal>ARPHRD_ETHER</literal> or
- *   <literal>ARPHRD_INFINIBAND</literal>
- *
- * Parses @asc and converts it to binary form in a #GByteArray. See
- * nm_utils_hwaddr_aton() if you don't want a #GByteArray.
- *
- * Return value: (transfer full): a new #GByteArray, or %NULL if @asc couldn't
- * be parsed
- */
-GByteArray *
-nm_utils_hwaddr_atoba (const char *asc, int type)
-{
-	GByteArray *ba;
-	int len = nm_utils_hwaddr_len (type);
-
-	if (len <= 0) {
-		g_return_val_if_reached (NULL);
-		return NULL;
-	}
-
-	ba = g_byte_array_sized_new (len);
-	g_byte_array_set_size (ba, len);
-	if (!nm_utils_hwaddr_aton_len (asc, ba->data, len)) {
-		g_byte_array_unref (ba);
-		return NULL;
-	}
-
-	return ba;
-}
-
-/**
- * nm_utils_hwaddr_ntoa:
- * @addr: a binary hardware address
- * @type: the type of address; either <literal>ARPHRD_ETHER</literal> or
- *   <literal>ARPHRD_INFINIBAND</literal>
- *
- * Converts @addr to textual form.
- *
- * See also nm_utils_hwaddr_ntoa_len(), which takes a length instead of
- * a type.
- *
- * Return value: (transfer full): the textual form of @addr
- */
-char *
-nm_utils_hwaddr_ntoa (gconstpointer addr, int type)
-{
-	int len = nm_utils_hwaddr_len (type);
-
-	if (len <= 0) {
-		g_return_val_if_reached (NULL);
-		return NULL;
-	}
-
-	return nm_utils_hwaddr_ntoa_len (addr, len);
-}
-
-/**
- * nm_utils_hwaddr_aton_len:
- * @asc: the ASCII representation of a hardware address
- * @buffer: buffer to store the result into
- * @length: the expected length in bytes of the result and
- * the size of the buffer in bytes.
- *
- * Parses @asc and converts it to binary form in @buffer.
- * Bytes in @asc can be sepatared by colons (:), or hyphens (-), but not mixed.
- *
- * Return value: @buffer, or %NULL if @asc couldn't be parsed
- *   or would be shorter or longer than @length.
- *
- * Since: 0.9.10
- */
-guint8 *
-nm_utils_hwaddr_aton_len (const char *asc, gpointer buffer, gsize length)
-{
-	const char *in = asc;
-	guint8 *out = (guint8 *)buffer;
-	char delimiter = '\0';
-
-	if (!asc) {
-		g_return_val_if_reached (NULL);
-		return NULL;
-	}
-	g_return_val_if_fail (buffer, NULL);
-	g_return_val_if_fail (length, NULL);
-
-	while (length && *in) {
-		guint8 d1 = in[0], d2 = in[1];
-
-		if (!g_ascii_isxdigit (d1))
-			return NULL;
-
-		/* If there's no leading zero (ie "aa:b:cc") then fake it */
-		if (d2 && g_ascii_isxdigit (d2)) {
-			*out++ = (HEXVAL (d1) << 4) + HEXVAL (d2);
-			in += 2;
-		} else {
-			/* Fake leading zero */
-			*out++ = (HEXVAL ('0') << 4) + HEXVAL (d1);
-			in += 1;
-		}
-
-		length--;
-		if (*in) {
-			if (delimiter == '\0') {
-				if (*in == ':' || *in == '-')
-					delimiter = *in;
-				else
-					return NULL;
-			} else {
-				if (*in != delimiter)
-					return NULL;
-			}
-			in++;
-		}
-	}
-
-	if (length == 0 && !*in)
-		return buffer;
-	else
-		return NULL;
-}
-
-/**
- * nm_utils_hwaddr_ntoa_len:
- * @addr: a binary hardware address
- * @length: the length of @addr
- *
- * Converts @addr to textual form.
- *
- * Return value: (transfer full): the textual form of @addr
- *
- * Since: 0.9.10
- */
-char *
-nm_utils_hwaddr_ntoa_len (gconstpointer addr, gsize length)
-{
-	const guint8 *in = addr;
-	char *out, *result;
-	const char *LOOKUP = "0123456789ABCDEF";
-
-	g_return_val_if_fail (addr != NULL, g_strdup (""));
-	g_return_val_if_fail (length != 0, g_strdup (""));
-
-	result = out = g_malloc (length * 3);
-	for (;;) {
-		guint8 v = *in++;
-
-		*out++ = LOOKUP[v >> 4];
-		*out++ = LOOKUP[v & 0x0F];
-		if (--length == 0) {
-			*out = 0;
-			return result;
-		}
-		*out++ = ':';
-	}
-}
-
-/**
- * nm_utils_hwaddr_valid:
- * @asc: the ASCII representation of a hardware address
- *
- * Parses @asc to see if it is a valid hardware address of some type.
- *
- * Return value: %TRUE if @asc appears to be a valid hardware address
- *   of some type, %FALSE if not.
- *
- * Since: 0.9.10
- */
-gboolean
-nm_utils_hwaddr_valid (const char *asc)
-{
-	guint8 buf[NM_UTILS_HWADDR_LEN_MAX];
-	gsize in_len, out_len;
-
-	if (!asc || !*asc)
-		return FALSE;
-	in_len = strlen (asc);
-	if ((in_len + 1) % 3 != 0)
-		return FALSE;
-	out_len = (in_len + 1) / 3;
-	if (out_len > NM_UTILS_HWADDR_LEN_MAX)
-		return FALSE;
-	return nm_utils_hwaddr_aton_len (asc, buf, out_len) != NULL;
-}
-
-/**
- * nm_utils_bin2hexstr:
- * @bytes: an array of bytes
- * @len: the length of the @bytes array
- * @final_len: an index where to cut off the returned string, or -1
- *
- * Converts a byte-array @bytes into a hexadecimal string.
- * If @final_len is greater than -1, the returned string is terminated at
- * that index (returned_string[final_len] == '\0'),
- *
- * Return value: (transfer full): the textual form of @bytes
- *
- * Since: 0.9.10
- */
-/*
- * Code originally by Alex Larsson <alexl@redhat.com> and
- *  copyright Red Hat, Inc. under terms of the LGPL.
- */
-char *
-nm_utils_bin2hexstr (const char *bytes, int len, int final_len)
-{
-	static char hex_digits[] = "0123456789abcdef";
-	char *result;
-	int i;
-	gsize buflen = (len * 2) + 1;
-
-	g_return_val_if_fail (bytes != NULL, NULL);
-	g_return_val_if_fail (len > 0, NULL);
-	g_return_val_if_fail (len < 4096, NULL);   /* Arbitrary limit */
-	if (final_len > -1)
-		g_return_val_if_fail (final_len < buflen, NULL);
-
-	result = g_malloc0 (buflen);
-	for (i = 0; i < len; i++) {
-		result[2*i] = hex_digits[(bytes[i] >> 4) & 0xf];
-		result[2*i+1] = hex_digits[bytes[i] & 0xf];
-	}
-	/* Cut converted key off at the correct length for this cipher type */
-	if (final_len > -1)
-		result[final_len] = '\0';
-	else
-		result[buflen - 1] = '\0';
-
-	return result;
-}
-
-/* From hostap, Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi> */
-/**
- * nm_utils_hex2byte:
- * @hex: a string representing a hex byte
- *
- * Converts a hex string (2 characters) into its byte representation.
- *
- * Return value: a byte, or -1 if @hex doesn't represent a hex byte
- *
- * Since: 0.9.10
- */
-int
-nm_utils_hex2byte (const char *hex)
-{
-	int a, b;
-	a = g_ascii_xdigit_value (*hex++);
-	if (a < 0)
-		return -1;
-	b = g_ascii_xdigit_value (*hex++);
-	if (b < 0)
-		return -1;
-	return (a << 4) | b;
-}
-
-/**
- * nm_utils_hexstr2bin:
- * @hex: an hex string
- * @len: the length of the @hex string (it has to be even)
- *
- * Converts a hexadecimal string @hex into a byte-array. The returned array
- * length is @len/2.
- *
- * Return value: (transfer full): a array of bytes, or %NULL on error
- *
- * Since: 0.9.10
- */
-char *
-nm_utils_hexstr2bin (const char *hex, size_t len)
-{
-	size_t       i;
-	int          a;
-	const char * ipos = hex;
-	char *       buf = NULL;
-	char *       opos;
-
-	/* Length must be a multiple of 2 */
-	if ((len % 2) != 0)
-		return NULL;
-
-	opos = buf = g_malloc0 ((len / 2) + 1);
-	for (i = 0; i < len; i += 2) {
-		a = nm_utils_hex2byte (ipos);
-		if (a < 0) {
-			g_free (buf);
-			return NULL;
-		}
-		*opos++ = a;
-		ipos += 2;
-	}
-	return buf;
-}
-/* End from hostap */
-
-/**
- * nm_utils_iface_valid_name:
- * @name: Name of interface
- *
- * This function is a 1:1 copy of the kernel's interface validation
- * function in net/core/dev.c.
- *
- * Returns: %TRUE if interface name is valid, otherwise %FALSE is returned.
- *
- * Since: 0.9.8
- */
-gboolean
-nm_utils_iface_valid_name (const char *name)
-{
-	g_return_val_if_fail (name != NULL, FALSE);
-
-	if (*name == '\0')
-		return FALSE;
-
-	if (strlen (name) >= 16)
-		return FALSE;
-
-	if (!strcmp (name, ".") || !strcmp (name, ".."))
-		return FALSE;
-
-	while (*name) {
-		if (*name == '/' || g_ascii_isspace (*name))
-			return FALSE;
-		name++;
-	}
-
-	return TRUE;
-}
-
-/**
- * nm_utils_is_uuid:
- * @str: a string that might be a UUID
- *
- * Checks if @str is a UUID
- *
- * Returns: %TRUE if @str is a UUID, %FALSE if not
- *
- * Since: 0.9.8
- */
-gboolean
-nm_utils_is_uuid (const char *str)
-{
-	const char *p = str;
-	int num_dashes = 0;
-
-	while (*p) {
-		if (*p == '-')
-			num_dashes++;
-		else if (!g_ascii_isxdigit (*p))
-			return FALSE;
-		p++;
-	}
-
-	if ((num_dashes == 4) && (p - str == 36))
-		return TRUE;
-
-	/* Backwards compat for older configurations */
-	if ((num_dashes == 0) && (p - str == 40))
-		return TRUE;
-
-	return FALSE;
-}
-
-static char _nm_utils_inet_ntop_buffer[NM_UTILS_INET_ADDRSTRLEN];
-
-/**
- * nm_utils_inet4_ntop: (skip)
- * @inaddr: the address that should be converted to string.
- * @dst: the destination buffer, it must contain at least
- *  <literal>INET_ADDRSTRLEN</literal> or %NM_UTILS_INET_ADDRSTRLEN
- *  characters. If set to %NULL, it will return a pointer to an internal, static
- *  buffer (shared with nm_utils_inet6_ntop()).  Beware, that the internal
- *  buffer will be overwritten with ever new call of nm_utils_inet4_ntop() or
- *  nm_utils_inet6_ntop() that does not provied it's own @dst buffer. Also,
- *  using the internal buffer is not thread safe. When in doubt, pass your own
- *  @dst buffer to avoid these issues.
- *
- * Wrapper for inet_ntop.
- *
- * Returns: the input buffer @dst, or a pointer to an
- *  internal, static buffer. This function cannot fail.
- *
- * Since: 0.9.10
- **/
-const char *
-nm_utils_inet4_ntop (in_addr_t inaddr, char *dst)
-{
-	return inet_ntop (AF_INET, &inaddr, dst ?: _nm_utils_inet_ntop_buffer,
-	                  INET_ADDRSTRLEN);
-}
-
-/**
- * nm_utils_inet6_ntop: (skip)
- * @in6addr: the address that should be converted to string.
- * @dst: the destination buffer, it must contain at least
- *  <literal>INET6_ADDRSTRLEN</literal> or %NM_UTILS_INET_ADDRSTRLEN
- *  characters. If set to %NULL, it will return a pointer to an internal, static
- *  buffer (shared with nm_utils_inet4_ntop()).  Beware, that the internal
- *  buffer will be overwritten with ever new call of nm_utils_inet4_ntop() or
- *  nm_utils_inet6_ntop() that does not provied it's own @dst buffer. Also,
- *  using the internal buffer is not thread safe. When in doubt, pass your own
- *  @dst buffer to avoid these issues.
- *
- * Wrapper for inet_ntop.
- *
- * Returns: the input buffer @dst, or a pointer to an
- *  internal, static buffer. %NULL is not allowed as @in6addr,
- *  otherwise, this function cannot fail.
- *
- * Since: 0.9.10
- **/
-const char *
-nm_utils_inet6_ntop (const struct in6_addr *in6addr, char *dst)
-{
-	g_return_val_if_fail (in6addr, NULL);
-	return inet_ntop (AF_INET6, in6addr, dst ?: _nm_utils_inet_ntop_buffer,
-	                  INET6_ADDRSTRLEN);
-}
-
-/**
- * nm_utils_check_virtual_device_compatibility:
- * @virtual_type: a virtual connection type
- * @other_type: a connection type to test against @virtual_type
- *
- * Determines if a connection of type @virtual_type can (in the
- * general case) work with connections of type @other_type.
- *
- * If @virtual_type is %NM_TYPE_SETTING_VLAN, then this checks if
- * @other_type is a valid type for the parent of a VLAN.
- *
- * If @virtual_type is a "master" type (eg, %NM_TYPE_SETTING_BRIDGE),
- * then this checks if @other_type is a valid type for a slave of that
- * master.
- *
- * Note that even if this returns %TRUE it is not guaranteed that
- * <emphasis>every</emphasis> connection of type @other_type is
- * compatible with @virtual_type; it may depend on the exact
- * configuration of the two connections, or on the capabilities of an
- * underlying device driver.
- *
- * Returns: %TRUE or %FALSE
- *
- * Since: 0.9.10
- */
-gboolean
-nm_utils_check_virtual_device_compatibility (GType virtual_type, GType other_type)
-{
-	g_return_val_if_fail (_nm_setting_type_is_base_type (virtual_type), FALSE);
-	g_return_val_if_fail (_nm_setting_type_is_base_type (other_type), FALSE);
-
-	if (virtual_type == NM_TYPE_SETTING_BOND) {
-		return (   other_type == NM_TYPE_SETTING_INFINIBAND
-		        || other_type == NM_TYPE_SETTING_WIRED
-		        || other_type == NM_TYPE_SETTING_BRIDGE
-		        || other_type == NM_TYPE_SETTING_BOND
-		        || other_type == NM_TYPE_SETTING_TEAM
-		        || other_type == NM_TYPE_SETTING_VLAN);
-	} else if (virtual_type == NM_TYPE_SETTING_BRIDGE) {
-		return (   other_type == NM_TYPE_SETTING_WIRED
-		        || other_type == NM_TYPE_SETTING_BOND
-		        || other_type == NM_TYPE_SETTING_TEAM
-		        || other_type == NM_TYPE_SETTING_VLAN);
-	} else if (virtual_type == NM_TYPE_SETTING_TEAM) {
-		return (   other_type == NM_TYPE_SETTING_WIRED
-		        || other_type == NM_TYPE_SETTING_BRIDGE
-		        || other_type == NM_TYPE_SETTING_BOND
-		        || other_type == NM_TYPE_SETTING_TEAM
-		        || other_type == NM_TYPE_SETTING_VLAN);
-	} else if (virtual_type == NM_TYPE_SETTING_VLAN) {
-		return (   other_type == NM_TYPE_SETTING_WIRED
-		        || other_type == NM_TYPE_SETTING_WIRELESS
-		        || other_type == NM_TYPE_SETTING_BRIDGE
-		        || other_type == NM_TYPE_SETTING_BOND
-		        || other_type == NM_TYPE_SETTING_TEAM
-		        || other_type == NM_TYPE_SETTING_VLAN);
-	} else {
-		g_warn_if_reached ();
-		return FALSE;
-	}
-}
-
-/*****************************************************************************/
-
-/* Unused prototypes to make the compiler happy */
-gconstpointer nm_utils_get_private (void);
-gconstpointer nm_util_get_private (void);
-
-/**
- * nm_utils_get_private:
- *
- * Entry point for NetworkManager-internal API.  You should not use this
- * function for any reason.
- *
- * Returns: Who knows? It's a mystery.
- *
- * Since: 0.9.10
- */
-gconstpointer
-nm_utils_get_private (void)
-{
-	/* We told you not to use it! */
-	g_assert_not_reached ();
-}
-
-/**
- * nm_util_get_private:
- *
- * You should not use this function for any reason.
- *
- * Returns: Who knows? It's a mystery.
- *
- * Since: 0.9.10
- */
-gconstpointer
-nm_util_get_private (void)
-{
-	/* We told you not to use it! */
-	g_assert_not_reached ();
-}