diff options
Diffstat (limited to 'libnm-util/nm-utils.c')
| -rw-r--r-- | libnm-util/nm-utils.c | 202 |
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); +} |