From 528e0876082f563e6fbafc3f7c2c44c5ef184750 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 22 Nov 2010 08:22:50 -0600 Subject: [PATCH] wifi: handle new supplicant AP property formats --- src/nm-wifi-ap.c | 169 +++++++++++++++++++++++++++-------------------- src/nm-wifi-ap.h | 4 -- 2 files changed, 97 insertions(+), 76 deletions(-) diff --git a/src/nm-wifi-ap.c b/src/nm-wifi-ap.c index 7770b8bc42..642b6d978e 100644 --- a/src/nm-wifi-ap.c +++ b/src/nm-wifi-ap.c @@ -369,10 +369,69 @@ NMAccessPoint *nm_ap_new (void) return (NMAccessPoint *) object; } +static guint32 +pair_to_flags (const char *str) +{ + g_return_val_if_fail (str != NULL, NM_802_11_AP_SEC_NONE); -#define IEEE80211_CAP_ESS 0x0001 -#define IEEE80211_CAP_IBSS 0x0002 -#define IEEE80211_CAP_PRIVACY 0x0010 + if (strcmp (str, "wep40") == 0) + return NM_802_11_AP_SEC_PAIR_WEP40; + if (strcmp (str, "wep104") == 0) + return NM_802_11_AP_SEC_PAIR_WEP104; + if (strcmp (str, "tkip") == 0) + return NM_802_11_AP_SEC_PAIR_TKIP; + if (strcmp (str, "ccmp") == 0) + return NM_802_11_AP_SEC_PAIR_CCMP; + return NM_802_11_AP_SEC_NONE; +} + +static guint32 +group_to_flags (const char *str) +{ + g_return_val_if_fail (str != NULL, NM_802_11_AP_SEC_NONE); + + if (strcmp (str, "wep40") == 0) + return NM_802_11_AP_SEC_GROUP_WEP40; + if (strcmp (str, "wep104") == 0) + return NM_802_11_AP_SEC_GROUP_WEP104; + if (strcmp (str, "tkip") == 0) + return NM_802_11_AP_SEC_GROUP_TKIP; + if (strcmp (str, "ccmp") == 0) + return NM_802_11_AP_SEC_GROUP_CCMP; + return NM_802_11_AP_SEC_NONE; +} + +static guint32 +security_from_dict (GHashTable *security) +{ + GValue *value; + guint32 flags = NM_802_11_AP_SEC_NONE; + const char **items, **iter; + + value = g_hash_table_lookup (security, "KeyMgmt"); + if (value) { + items = g_value_get_boxed (value); + for (iter = items; iter && *iter; iter++) { + if (strcmp (*iter, "wpa-psk") == 0) + flags |= NM_802_11_AP_SEC_KEY_MGMT_PSK; + else if (strcmp (*iter, "wpa-eap") == 0) + flags |= NM_802_11_AP_SEC_KEY_MGMT_802_1X; + } + } + + value = g_hash_table_lookup (security, "Pairwise"); + if (value) { + items = g_value_get_boxed (value); + for (iter = items; iter && *iter; iter++) + flags |= pair_to_flags (*iter); + } + + value = g_hash_table_lookup (security, "Group"); + if (value) + flags |= group_to_flags (g_value_get_string (value)); + + return flags; +} static void foreach_property_cb (gpointer key, gpointer value, gpointer user_data) @@ -383,9 +442,9 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data) if (G_VALUE_HOLDS_BOXED (variant)) { GArray *array = g_value_get_boxed (variant); - if (!strcmp (key, "ssid")) { + if (!strcmp (key, "SSID")) { guint32 len = MIN (IW_ESSID_MAX_SIZE, array->len); - GByteArray * ssid; + GByteArray *ssid; /* Stupid ieee80211 layer uses */ if (((len == 8) || (len == 9)) @@ -399,7 +458,7 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data) g_byte_array_append (ssid, (const guint8 *) array->data, len); nm_ap_set_ssid (ap, ssid); g_byte_array_free (ssid, TRUE); - } else if (!strcmp (key, "bssid")) { + } else if (!strcmp (key, "BSSID")) { struct ether_addr addr; if (array->len != ETH_ALEN) @@ -407,43 +466,49 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data) memset (&addr, 0, sizeof (struct ether_addr)); memcpy (&addr, array->data, ETH_ALEN); nm_ap_set_address (ap, &addr); - } else if (!strcmp (key, "wpaie")) { - guint8 * ie = (guint8 *) array->data; + } else if (!strcmp (key, "Rates")) { + guint32 maxrate = 0; + int i; + + /* Find the max AP rate */ + for (i = 0; i < array->len; i++) { + guint32 r = g_array_index (array, guint32, i); + + if (r > maxrate) { + maxrate = r; + nm_ap_set_max_bitrate (ap, r / 1000); + } + } + } else if (!strcmp (key, "WPA")) { guint32 flags = nm_ap_get_wpa_flags (ap); - if (array->len <= 0 || array->len > WPA_MAX_IE_LEN) - return; - flags = nm_ap_add_security_from_ie (flags, ie, array->len); + flags |= security_from_dict (g_value_get_boxed (variant)); nm_ap_set_wpa_flags (ap, flags); - } else if (!strcmp (key, "rsnie")) { - guint8 * ie = (guint8 *) array->data; + } else if (!strcmp (key, "RSN")) { guint32 flags = nm_ap_get_rsn_flags (ap); - if (array->len <= 0 || array->len > WPA_MAX_IE_LEN) - return; - flags = nm_ap_add_security_from_ie (flags, ie, array->len); + flags |= security_from_dict (g_value_get_boxed (variant)); nm_ap_set_rsn_flags (ap, flags); } - } else if (G_VALUE_HOLDS_INT (variant)) { - gint32 int_val = g_value_get_int (variant); - - if (!strcmp (key, "frequency")) { - nm_ap_set_freq (ap, (guint32) int_val); - } else if (!strcmp (key, "maxrate")) { - /* Supplicant reports as b/s, we use Kb/s internally */ - nm_ap_set_max_bitrate (ap, int_val / 1000); - } } else if (G_VALUE_HOLDS_UINT (variant)) { guint32 val = g_value_get_uint (variant); - if (!strcmp (key, "capabilities")) { - if (val & IEEE80211_CAP_ESS) { - nm_ap_set_mode (ap, NM_802_11_MODE_INFRA); - } else if (val & IEEE80211_CAP_IBSS) { - nm_ap_set_mode (ap, NM_802_11_MODE_ADHOC); - } + if (!strcmp (key, "Frequency")) + nm_ap_set_freq (ap, val); + } else if (G_VALUE_HOLDS_STRING (variant)) { + const char *val = g_value_get_string (variant); - if (val & IEEE80211_CAP_PRIVACY) { + if (val && !strcmp (key, "Mode")) { + if (strcmp (val, "infrastructure") == 0) + nm_ap_set_mode (ap, NM_802_11_MODE_INFRA); + else if (strcmp (val, "ad-hoc") == 0) + nm_ap_set_mode (ap, NM_802_11_MODE_ADHOC); + } + } else if (G_VALUE_HOLDS_BOOLEAN (variant)) { + gboolean val = g_value_get_boolean (variant); + + if (strcmp (key, "Privacy") == 0) { + if (val) { guint32 flags = nm_ap_get_flags (ap); nm_ap_set_flags (ap, flags | NM_802_11_AP_FLAGS_PRIVACY); } @@ -451,7 +516,6 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data) } } - NMAccessPoint * nm_ap_new_from_properties (GHashTable *properties) { @@ -1170,45 +1234,6 @@ void nm_ap_set_user_addresses (NMAccessPoint *ap, GSList *list) } -guint32 -nm_ap_add_security_from_ie (guint32 flags, - const guint8 *wpa_ie, - guint32 length) -{ - wpa_ie_data * cap_data; - - if (!(cap_data = wpa_parse_wpa_ie (wpa_ie, length))) - return NM_802_11_AP_SEC_NONE; - - /* Pairwise cipher flags */ - if (cap_data->pairwise_cipher & IW_AUTH_CIPHER_WEP40) - flags |= NM_802_11_AP_SEC_PAIR_WEP40; - if (cap_data->pairwise_cipher & IW_AUTH_CIPHER_WEP104) - flags |= NM_802_11_AP_SEC_PAIR_WEP104; - if (cap_data->pairwise_cipher & IW_AUTH_CIPHER_TKIP) - flags |= NM_802_11_AP_SEC_PAIR_TKIP; - if (cap_data->pairwise_cipher & IW_AUTH_CIPHER_CCMP) - flags |= NM_802_11_AP_SEC_PAIR_CCMP; - - /* Group cipher flags */ - if (cap_data->group_cipher & IW_AUTH_CIPHER_WEP40) - flags |= NM_802_11_AP_SEC_GROUP_WEP40; - if (cap_data->group_cipher & IW_AUTH_CIPHER_WEP104) - flags |= NM_802_11_AP_SEC_GROUP_WEP104; - if (cap_data->group_cipher & IW_AUTH_CIPHER_TKIP) - flags |= NM_802_11_AP_SEC_GROUP_TKIP; - if (cap_data->group_cipher & IW_AUTH_CIPHER_CCMP) - flags |= NM_802_11_AP_SEC_GROUP_CCMP; - - if (cap_data->key_mgmt & IW_AUTH_KEY_MGMT_802_1X) - flags |= NM_802_11_AP_SEC_KEY_MGMT_802_1X; - if (cap_data->key_mgmt & IW_AUTH_KEY_MGMT_PSK) - flags |= NM_802_11_AP_SEC_KEY_MGMT_PSK; - - g_slice_free (wpa_ie_data, cap_data); - return flags; -} - gboolean nm_ap_check_compatible (NMAccessPoint *self, NMConnection *connection) diff --git a/src/nm-wifi-ap.h b/src/nm-wifi-ap.h index 86b785a316..09c87d970a 100644 --- a/src/nm-wifi-ap.h +++ b/src/nm-wifi-ap.h @@ -110,10 +110,6 @@ void nm_ap_set_user_created (NMAccessPoint *ap, gboolean user_created); GSList * nm_ap_get_user_addresses (const NMAccessPoint *ap); void nm_ap_set_user_addresses (NMAccessPoint *ap, GSList *list); -guint32 nm_ap_add_security_from_ie (guint32 flags, - const guint8 *wpa_ie, - guint32 length); - gboolean nm_ap_check_compatible (NMAccessPoint *self, NMConnection *connection);