summaryrefslogtreecommitdiff
path: root/libnm-glib/nm-device-wifi.c
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2011-03-10 22:27:10 -0600
committerDan Williams <dcbw@redhat.com>2011-03-10 22:27:10 -0600
commit3320764e1e3eb6e7ffa845c1181aecec301623a8 (patch)
treef2e4310db7ac1df29d906041501c64f9de6b2383 /libnm-glib/nm-device-wifi.c
parentfbf118e58e47c41d63910dbe979325eb6d31e49f (diff)
downloadNetworkManager-3320764e1e3eb6e7ffa845c1181aecec301623a8.tar.gz
libnm-glib: add nm_device_filter_connections()
Diffstat (limited to 'libnm-glib/nm-device-wifi.c')
-rw-r--r--libnm-glib/nm-device-wifi.c98
1 files changed, 95 insertions, 3 deletions
diff --git a/libnm-glib/nm-device-wifi.c b/libnm-glib/nm-device-wifi.c
index f8a891c1e7..c0a366dd93 100644
--- a/libnm-glib/nm-device-wifi.c
+++ b/libnm-glib/nm-device-wifi.c
@@ -21,7 +21,13 @@
* Copyright (C) 2007 - 2011 Red Hat, Inc.
*/
+#include <config.h>
#include <string.h>
+#include <netinet/ether.h>
+
+#include <nm-setting-connection.h>
+#include <nm-setting-wireless.h>
+#include <nm-setting-wireless-security.h>
#include "nm-device-wifi.h"
#include "nm-device-private.h"
@@ -477,6 +483,90 @@ _nm_device_wifi_set_wireless_enabled (NMDeviceWifi *device,
clean_up_aps (device, TRUE);
}
+#define WPA_CAPS (NM_WIFI_DEVICE_CAP_CIPHER_TKIP | \
+ NM_WIFI_DEVICE_CAP_CIPHER_CCMP | \
+ NM_WIFI_DEVICE_CAP_WPA | \
+ NM_WIFI_DEVICE_CAP_RSN)
+
+#define RSN_CAPS (NM_WIFI_DEVICE_CAP_CIPHER_CCMP | NM_WIFI_DEVICE_CAP_RSN)
+
+static gboolean
+has_proto (NMSettingWirelessSecurity *s_wsec, const char *proto)
+{
+ int i;
+
+ for (i = 0; i < nm_setting_wireless_security_get_num_protos (s_wsec); i++) {
+ if (g_strcmp0 (proto, nm_setting_wireless_security_get_proto (s_wsec, i)) == 0)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static GSList *
+filter_connections (NMDevice *device, const GSList *connections)
+{
+ GSList *filtered = NULL;
+ const GSList *iter;
+
+ for (iter = connections; iter; iter = g_slist_next (iter)) {
+ NMConnection *candidate = NM_CONNECTION (iter->data);
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wifi;
+ NMSettingWirelessSecurity *s_wsec;
+ const char *ctype;
+ const GByteArray *mac;
+ const char *hw_str;
+ struct ether_addr *hw_mac;
+ NMDeviceWifiCapabilities wifi_caps;
+ const char *key_mgmt;
+
+ s_con = (NMSettingConnection *) nm_connection_get_setting (candidate, NM_TYPE_SETTING_CONNECTION);
+ g_assert (s_con);
+
+ ctype = nm_setting_connection_get_connection_type (s_con);
+ if (strcmp (ctype, NM_SETTING_WIRELESS_SETTING_NAME) != 0)
+ continue;
+
+ s_wifi = (NMSettingWireless *) nm_connection_get_setting (candidate, NM_TYPE_SETTING_WIRELESS);
+ if (!s_wifi)
+ continue;
+
+ /* Check MAC address */
+ hw_str = nm_device_wifi_get_permanent_hw_address (NM_DEVICE_WIFI (device));
+ if (hw_str) {
+ hw_mac = ether_aton (hw_str);
+ mac = nm_setting_wireless_get_mac_address (s_wifi);
+ if (mac && hw_mac && memcmp (mac->data, hw_mac->ether_addr_octet, ETH_ALEN))
+ continue;
+ }
+
+ /* Check device capabilities; we assume all devices can do WEP at least */
+ wifi_caps = nm_device_wifi_get_capabilities (NM_DEVICE_WIFI (device));
+
+ s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (candidate, NM_TYPE_SETTING_WIRELESS_SECURITY);
+ if (s_wsec) {
+ /* Connection has security, verify it against the device's capabilities */
+ key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec);
+ if ( !g_strcmp0 (key_mgmt, "wpa-none")
+ || !g_strcmp0 (key_mgmt, "wpa-psk")
+ || !g_strcmp0 (key_mgmt, "wpa-eap")) {
+
+ /* Is device only WEP capable? */
+ if (!(wifi_caps & WPA_CAPS))
+ continue;
+
+ /* Make sure WPA2/RSN-only connections don't get chosen for WPA-only cards */
+ if (has_proto (s_wsec, "rsn") && !has_proto (s_wsec, "wpa") && !(wifi_caps & RSN_CAPS))
+ continue;
+ }
+ }
+
+ /* Connection applies to this device */
+ filtered = g_slist_prepend (filtered, candidate);
+ }
+
+ return g_slist_reverse (filtered);
+}
/**************************************************************/
@@ -683,17 +773,19 @@ finalize (GObject *object)
}
static void
-nm_device_wifi_class_init (NMDeviceWifiClass *device_class)
+nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class)
{
- GObjectClass *object_class = G_OBJECT_CLASS (device_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (wifi_class);
+ NMDeviceClass *device_class = NM_DEVICE_CLASS (wifi_class);
- g_type_class_add_private (device_class, sizeof (NMDeviceWifiPrivate));
+ g_type_class_add_private (wifi_class, sizeof (NMDeviceWifiPrivate));
/* virtual methods */
object_class->constructor = constructor;
object_class->get_property = get_property;
object_class->dispose = dispose;
object_class->finalize = finalize;
+ device_class->filter_connections = filter_connections;
/* properties */