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.c202
1 files changed, 192 insertions, 10 deletions
diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c
index 9d4418e4..a8806206 100644
--- a/libnm-util/nm-utils.c
+++ b/libnm-util/nm-utils.c
@@ -25,13 +25,14 @@
  */
 
 #include "config.h"
+#include <ctype.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <arpa/inet.h>
-
-#include "wireless-helper.h"
+#include <netinet/ether.h>
+#include <linux/if_infiniband.h>
 
 #include <glib.h>
 #include <glib-object.h>
@@ -360,6 +361,8 @@ nm_utils_is_empty_ssid (const guint8 * ssid, int len)
         return TRUE;
 }
 
+#define ESSID_MAX_SIZE 32
+
 /**
  * nm_utils_escape_ssid:
  * @ssid: pointer to a buffer containing the SSID data
@@ -376,7 +379,7 @@ nm_utils_is_empty_ssid (const guint8 * ssid, int len)
 const char *
 nm_utils_escape_ssid (const guint8 * ssid, guint32 len)
 {
-	static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
+	static char escaped[ESSID_MAX_SIZE * 2 + 1];
 	const guint8 *s = ssid;
 	char *d = escaped;
 
@@ -385,7 +388,7 @@ nm_utils_escape_ssid (const guint8 * ssid, guint32 len)
 		return escaped;
 	}
 
-	len = MIN (len, (guint32) IW_ESSID_MAX_SIZE);
+	len = MIN (len, (guint32) ESSID_MAX_SIZE);
 	while (len--) {
 		if (*s == '\0') {
 			*d++ = '\\';
@@ -534,6 +537,14 @@ _nm_utils_string_slist_validate (GSList *list, const char **valid_values)
 }
 
 static void
+_nm_utils_convert_op_to_string (const GValue *src_value, GValue *dest_value)
+{
+	g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_OBJECT_PATH));
+
+	g_value_set_string (dest_value, (const char *) g_value_get_boxed (src_value));
+}
+
+static void
 _nm_utils_convert_strv_to_slist (const GValue *src_value, GValue *dest_value)
 {
 	char **str;
@@ -595,16 +606,11 @@ _nm_utils_convert_strv_to_string (const GValue *src_value, GValue *dest_value)
 }
 
 static void
-_nm_utils_convert_string_array_to_string (const GValue *src_value, GValue *dest_value)
+_string_array_to_string (const GPtrArray *strings, GValue *dest_value)
 {
-	GPtrArray *strings;
 	GString *printable;
 	int i;
 
-	g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_STRING));
-
-	strings = (GPtrArray *) g_value_get_boxed (src_value);
-
 	printable = g_string_new ("[");
 	for (i = 0; strings && i < strings->len; i++) {
 		if (i > 0)
@@ -621,6 +627,28 @@ _nm_utils_convert_string_array_to_string (const GValue *src_value, GValue *dest_
 }
 
 static void
+_nm_utils_convert_string_array_to_string (const GValue *src_value, GValue *dest_value)
+{
+	const GPtrArray *strings;
+
+	g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_STRING));
+
+	strings = (const GPtrArray *) g_value_get_boxed (src_value);
+	_string_array_to_string (strings, dest_value);
+}
+
+static void
+_nm_utils_convert_op_array_to_string (const GValue *src_value, GValue *dest_value)
+{
+	const GPtrArray *strings;
+
+	g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH));
+
+	strings = (const GPtrArray *) g_value_get_boxed (src_value);
+	_string_array_to_string (strings, dest_value);
+}
+
+static void
 _nm_utils_convert_uint_array_to_string (const GValue *src_value, GValue *dest_value)
 {
 	GArray *array;
@@ -1079,6 +1107,9 @@ _nm_utils_register_value_transformations (void)
 	static gboolean registered = FALSE;
 
 	if (G_UNLIKELY (!registered)) {
+		g_value_register_transform_func (DBUS_TYPE_G_OBJECT_PATH,
+		                                 G_TYPE_STRING,
+		                                 _nm_utils_convert_op_to_string);
 		g_value_register_transform_func (G_TYPE_STRV, 
 		                                 DBUS_TYPE_G_LIST_OF_STRING,
 		                                 _nm_utils_convert_strv_to_slist);
@@ -1091,6 +1122,9 @@ _nm_utils_register_value_transformations (void)
 		g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_STRING,
 		                                 G_TYPE_STRING,
 		                                 _nm_utils_convert_string_array_to_string);
+		g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH,
+		                                 G_TYPE_STRING,
+		                                 _nm_utils_convert_op_array_to_string);
 		g_value_register_transform_func (DBUS_TYPE_G_UINT_ARRAY,
 		                                 G_TYPE_STRING, 
 		                                 _nm_utils_convert_uint_array_to_string);
@@ -1209,6 +1243,8 @@ nm_utils_security_valid (NMUtilsSecurityType type,
 		    || ((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;
 		}
 	}
 
@@ -1249,6 +1285,8 @@ nm_utils_security_valid (NMUtilsSecurityType type,
 		}
 		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) {
@@ -1275,6 +1313,8 @@ nm_utils_security_valid (NMUtilsSecurityType type,
 		}
 		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) {
@@ -2386,3 +2426,145 @@ nm_utils_wifi_is_channel_valid (guint32 channel, const char *band)
 		return FALSE;
 }
 
+/**
+ * nm_utils_hwaddr_len:
+ * @type: the type of address; either %ARPHRD_ETHER or %ARPHRD_INFINIBAND
+ *
+ * Returns the length in octets of a hardware address of type @type.
+ *
+ * Return value: the length
+ */
+int
+nm_utils_hwaddr_len (int type)
+{
+	if (type == ARPHRD_ETHER)
+		return ETH_ALEN;
+	else if (type == ARPHRD_INFINIBAND)
+		return INFINIBAND_ALEN;
+	else
+		g_return_val_if_reached (-1);
+}
+
+/**
+ * nm_utils_hwaddr_type:
+ * @len: the length of hardware address in bytes
+ *
+ * Returns the type (either %ARPHRD_ETHER or %ARPHRD_INFINIBAND) of the raw
+ * address given its length.
+ *
+ * Return value: the type, either %ARPHRD_ETHER or %ARPHRD_INFINIBAND, or -1 if
+ * the address length was not recognized
+ */
+int
+nm_utils_hwaddr_type (int len)
+{
+	if (len == ETH_ALEN)
+		return ARPHRD_ETHER;
+	else if (len == INFINIBAND_ALEN)
+		return ARPHRD_INFINIBAND;
+	else
+		g_return_val_if_reached (-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 %ARPHRD_ETHER or %ARPHRD_INFINIBAND
+ * @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.
+ *
+ * Return value: @buffer, or %NULL if @asc couldn't be parsed
+ */
+guint8 *
+nm_utils_hwaddr_aton (const char *asc, int type, gpointer buffer)
+{
+	const char *in = asc;
+	guint8 *out = (guint8 *)buffer;
+	int left = nm_utils_hwaddr_len (type);
+
+	while (left && *in) {
+		guint8 d1 = in[0], d2 = in[1];
+
+		if (!isxdigit (d1))
+			return NULL;
+
+		/* If there's no leading zero (ie "aa:b:cc") then fake it */
+		if (d2 && isxdigit (d2)) {
+			*out++ = (HEXVAL (d1) << 4) + HEXVAL (d2);
+			in += 2;
+		} else {
+			/* Fake leading zero */
+			*out++ = (HEXVAL ('0') << 4) + HEXVAL (d1);
+			in += 1;
+		}
+
+		left--;
+		if (*in) {
+			if (*in != ':')
+				return NULL;
+			in++;
+		}
+	}
+
+	if (left == 0 && !*in)
+		return buffer;
+	else
+		return NULL;
+}
+
+/**
+ * nm_utils_hwaddr_atoba:
+ * @asc: the ASCII representation of a hardware address
+ * @type: the type of address; either %ARPHRD_ETHER or %ARPHRD_INFINIBAND
+ *
+ * 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);
+
+	ba = g_byte_array_sized_new (len);
+	ba->len = len;
+	if (!nm_utils_hwaddr_aton (asc, type, ba->data)) {
+		g_byte_array_unref (ba);
+		return NULL;
+	}
+
+	return ba;
+}
+
+/**
+ * nm_utils_hwaddr_ntoa:
+ * @addr: a binary hardware address
+ * @type: the type of address; either %ARPHRD_ETHER or %ARPHRD_INFINIBAND
+ *
+ * Converts @addr to textual form.
+ *
+ * Return value: (transfer full): the textual form of @addr
+ */
+char *
+nm_utils_hwaddr_ntoa (gconstpointer addr, int type)
+{
+	const guint8 *in = addr;
+	GString *out = g_string_new (NULL);
+	int left = nm_utils_hwaddr_len (type);
+
+	while (left--) {
+		if (out->len)
+			g_string_append_c (out, ':');
+		g_string_append_printf (out, "%02X", *in++);
+	}
+
+	return g_string_free (out, FALSE);
+}