libnm-glib: add *_connection_valid() utility functions

Like the *_filter_connections() functions, but for just one connection,
and now the *_filter_connections() functions call these new ones so
it's really just moving code around and not anything new.

These new functions more closely match the usage I've seen from
gnome-shell's network.js and elsewhere.
This commit is contained in:
Dan Williams 2011-04-25 17:07:38 -05:00
parent c790c95e75
commit 779215c742
12 changed files with 367 additions and 324 deletions

View file

@ -5,6 +5,7 @@ global:
libnm_glib_register_callback;
libnm_glib_shutdown;
libnm_glib_unregister_callback;
nm_access_point_connection_valid;
nm_access_point_filter_connections;
nm_access_point_get_bssid;
nm_access_point_get_flags;
@ -56,6 +57,7 @@ global:
nm_device_bt_get_name;
nm_device_bt_get_type;
nm_device_bt_new;
nm_device_connection_valid;
nm_device_disconnect;
nm_device_ethernet_get_carrier;
nm_device_ethernet_get_hw_address;
@ -161,6 +163,7 @@ global:
nm_vpn_connection_get_type;
nm_vpn_connection_get_vpn_state;
nm_vpn_connection_new;
nm_wimax_nsp_connection_valid;
nm_wimax_nsp_filter_connections;
nm_wimax_nsp_get_name;
nm_wimax_nsp_get_network_type;

View file

@ -358,10 +358,117 @@ nm_access_point_get_strength (NMAccessPoint *ap)
return priv->strength;
}
/**
* nm_access_point_filter_connections:
* @ap: an #NMAccessPoint to validate @connection against
* @connections: an #NMConnection to validate against @ap
*
* Validates a given connection against a given WiFi access point to ensure that
* the connection may be activated with that AP. The connection must match the
* @ap's SSID, (if given) BSSID, and other attributes like security settings,
* channel, band, etc.
*
* Returns: %TRUE if the connection may be activated with this WiFi AP,
* %FALSE if it cannot be.
**/
gboolean
nm_access_point_connection_valid (NMAccessPoint *ap, NMConnection *connection)
{
NMSettingConnection *s_con;
NMSettingWireless *s_wifi;
NMSettingWirelessSecurity *s_wsec;
const char *ctype, *ap_bssid_str;
const GByteArray *setting_ssid;
const GByteArray *ap_ssid;
const GByteArray *setting_bssid;
struct ether_addr *ap_bssid;
const char *setting_mode;
NM80211Mode ap_mode;
const char *setting_band;
guint32 ap_freq, setting_chan, ap_chan;
s_con = nm_connection_get_setting_connection (connection);
g_assert (s_con);
ctype = nm_setting_connection_get_connection_type (s_con);
if (strcmp (ctype, NM_SETTING_WIRELESS_SETTING_NAME) != 0)
return FALSE;
s_wifi = nm_connection_get_setting_wireless (connection);
if (!s_wifi)
return FALSE;
/* SSID checks */
ap_ssid = nm_access_point_get_ssid (ap);
g_warn_if_fail (ap_ssid != NULL);
setting_ssid = nm_setting_wireless_get_ssid (s_wifi);
if (!setting_ssid || !ap_ssid || (setting_ssid->len != ap_ssid->len))
return FALSE;
if (memcmp (setting_ssid->data, ap_ssid->data, ap_ssid->len) != 0)
return FALSE;
/* BSSID checks */
ap_bssid_str = nm_access_point_get_bssid (ap);
g_warn_if_fail (ap_bssid_str);
setting_bssid = nm_setting_wireless_get_bssid (s_wifi);
if (setting_bssid && ap_bssid_str) {
g_assert (setting_bssid->len == ETH_ALEN);
ap_bssid = ether_aton (ap_bssid_str);
g_warn_if_fail (ap_bssid);
if (ap_bssid) {
if (memcmp (ap_bssid->ether_addr_octet, setting_bssid->data, ETH_ALEN) != 0)
return FALSE;
}
}
/* Mode */
ap_mode = nm_access_point_get_mode (ap);
g_warn_if_fail (ap_mode != NM_802_11_MODE_UNKNOWN);
setting_mode = nm_setting_wireless_get_mode (s_wifi);
if (setting_mode && ap_mode) {
if (!strcmp (setting_mode, "infrastructure") && (ap_mode != NM_802_11_MODE_INFRA))
return FALSE;
if (!strcmp (setting_mode, "adhoc") && (ap_mode != NM_802_11_MODE_ADHOC))
return FALSE;
}
/* Band and Channel/Frequency */
ap_freq = nm_access_point_get_frequency (ap);
g_warn_if_fail (ap_freq > 0);
if (ap_freq) {
setting_band = nm_setting_wireless_get_band (s_wifi);
if (g_strcmp0 (setting_band, "a") == 0) {
if (ap_freq < 4915 || ap_freq > 5825)
return FALSE;
} else if (g_strcmp0 (setting_band, "bg") == 0) {
if (ap_freq < 2412 || ap_freq > 2484)
return FALSE;
}
setting_chan = nm_setting_wireless_get_channel (s_wifi);
if (setting_chan) {
ap_chan = nm_utils_wifi_freq_to_channel (ap_freq);
if (setting_chan != ap_chan)
return FALSE;
}
}
s_wsec = nm_connection_get_setting_wireless_security (connection);
if (!nm_setting_wireless_ap_security_compatible (s_wifi,
s_wsec,
nm_access_point_get_flags (ap),
nm_access_point_get_wpa_flags (ap),
nm_access_point_get_rsn_flags (ap),
ap_mode))
return FALSE;
return TRUE;
}
/**
* nm_access_point_filter_connections:
* @ap: an #NMAccessPoint to filter connections for
* @connections: a list of #NMConnection objects to filter
* @connections: (element-type NetworkManager.Connection): a list of
* #NMConnection objects to filter
*
* Filters a given list of connections for a given #NMAccessPoint object and
* return connections which may be activated with the access point. Any
@ -382,95 +489,9 @@ nm_access_point_filter_connections (NMAccessPoint *ap, const GSList *connections
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, *ap_bssid_str;
const GByteArray *setting_ssid;
const GByteArray *ap_ssid;
const GByteArray *setting_bssid;
struct ether_addr *ap_bssid;
const char *setting_mode;
NM80211Mode ap_mode;
const char *setting_band;
guint32 ap_freq, setting_chan, ap_chan;
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;
/* SSID checks */
ap_ssid = nm_access_point_get_ssid (ap);
g_warn_if_fail (ap_ssid != NULL);
setting_ssid = nm_setting_wireless_get_ssid (s_wifi);
if (!setting_ssid || !ap_ssid || (setting_ssid->len != ap_ssid->len))
continue;
if (memcmp (setting_ssid->data, ap_ssid->data, ap_ssid->len) != 0)
continue;
/* BSSID checks */
ap_bssid_str = nm_access_point_get_bssid (ap);
g_warn_if_fail (ap_bssid_str);
setting_bssid = nm_setting_wireless_get_bssid (s_wifi);
if (setting_bssid && ap_bssid_str) {
g_assert (setting_bssid->len == ETH_ALEN);
ap_bssid = ether_aton (ap_bssid_str);
g_warn_if_fail (ap_bssid);
if (ap_bssid) {
if (memcmp (ap_bssid->ether_addr_octet, setting_bssid->data, ETH_ALEN) != 0)
continue;
}
}
/* Mode */
ap_mode = nm_access_point_get_mode (ap);
g_warn_if_fail (ap_mode != NM_802_11_MODE_UNKNOWN);
setting_mode = nm_setting_wireless_get_mode (s_wifi);
if (setting_mode && ap_mode) {
if (!strcmp (setting_mode, "infrastructure") && (ap_mode != NM_802_11_MODE_INFRA))
return NULL;
if (!strcmp (setting_mode, "adhoc") && (ap_mode != NM_802_11_MODE_ADHOC))
return NULL;
}
/* Band and Channel/Frequency */
ap_freq = nm_access_point_get_frequency (ap);
g_warn_if_fail (ap_freq > 0);
if (ap_freq) {
setting_band = nm_setting_wireless_get_band (s_wifi);
if (g_strcmp0 (setting_band, "a") == 0) {
if (ap_freq < 4915 || ap_freq > 5825)
continue;
} else if (g_strcmp0 (setting_band, "bg") == 0) {
if (ap_freq < 2412 || ap_freq > 2484)
continue;
}
setting_chan = nm_setting_wireless_get_channel (s_wifi);
if (setting_chan) {
ap_chan = nm_utils_wifi_freq_to_channel (ap_freq);
if (setting_chan != ap_chan)
continue;
}
}
s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (candidate, NM_TYPE_SETTING_WIRELESS_SECURITY);
if (!nm_setting_wireless_ap_security_compatible (s_wifi,
s_wsec,
nm_access_point_get_flags (ap),
nm_access_point_get_wpa_flags (ap),
nm_access_point_get_rsn_flags (ap),
ap_mode))
continue;
/* Connection applies to this device */
filtered = g_slist_prepend (filtered, candidate);
if (nm_access_point_connection_valid (ap, candidate))
filtered = g_slist_prepend (filtered, candidate);
}
return g_slist_reverse (filtered);

View file

@ -85,6 +85,9 @@ guint8 nm_access_point_get_strength (NMAccessPoint *ap);
GSList * nm_access_point_filter_connections (NMAccessPoint *ap,
const GSList *connections);
gboolean nm_access_point_connection_valid (NMAccessPoint *ap,
NMConnection *connection);
/* DEPRECATED */
const char * nm_access_point_get_hw_address (NMAccessPoint *ap);

View file

@ -184,53 +184,44 @@ get_connection_bt_type (NMConnection *connection)
return NM_BT_CAPABILITY_NONE;
}
static GSList *
filter_connections (NMDevice *device, const GSList *connections)
static gboolean
connection_valid (NMDevice *device, NMConnection *connection)
{
GSList *filtered = NULL;
const GSList *iter;
NMSettingConnection *s_con;
NMSettingBluetooth *s_bt;
const char *ctype;
const GByteArray *mac;
const char *hw_str;
struct ether_addr *hw_mac;
NMBluetoothCapabilities dev_caps;
NMBluetoothCapabilities bt_type;
for (iter = connections; iter; iter = g_slist_next (iter)) {
NMConnection *candidate = NM_CONNECTION (iter->data);
NMSettingConnection *s_con;
NMSettingBluetooth *s_bt;
const char *ctype;
const GByteArray *mac;
const char *hw_str;
struct ether_addr *hw_mac;
NMBluetoothCapabilities dev_caps;
NMBluetoothCapabilities bt_type;
s_con = nm_connection_get_setting_connection (connection);
g_assert (s_con);
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_BLUETOOTH_SETTING_NAME) != 0)
return FALSE;
ctype = nm_setting_connection_get_connection_type (s_con);
if (strcmp (ctype, NM_SETTING_BLUETOOTH_SETTING_NAME) != 0)
continue;
s_bt = nm_connection_get_setting_bluetooth (connection);
if (!s_bt)
return FALSE;
s_bt = (NMSettingBluetooth *) nm_connection_get_setting (candidate, NM_TYPE_SETTING_BLUETOOTH);
if (!s_bt)
continue;
/* Check BT address */
hw_str = nm_device_bt_get_hw_address (NM_DEVICE_BT (device));
if (hw_str) {
hw_mac = ether_aton (hw_str);
mac = nm_setting_bluetooth_get_bdaddr (s_bt);
if (mac && hw_mac && memcmp (mac->data, hw_mac->ether_addr_octet, ETH_ALEN))
continue;
}
dev_caps = nm_device_bt_get_capabilities (NM_DEVICE_BT (device));
bt_type = get_connection_bt_type (candidate);
if (!(bt_type & dev_caps))
continue;
/* Connection applies to this device */
filtered = g_slist_prepend (filtered, candidate);
/* Check BT address */
hw_str = nm_device_bt_get_hw_address (NM_DEVICE_BT (device));
if (hw_str) {
hw_mac = ether_aton (hw_str);
mac = nm_setting_bluetooth_get_bdaddr (s_bt);
if (mac && hw_mac && memcmp (mac->data, hw_mac->ether_addr_octet, ETH_ALEN))
return FALSE;
}
return g_slist_reverse (filtered);
dev_caps = nm_device_bt_get_capabilities (NM_DEVICE_BT (device));
bt_type = get_connection_bt_type (connection);
if (!(bt_type & dev_caps))
return FALSE;
return TRUE;
}
/************************************************************/
@ -344,7 +335,7 @@ nm_device_bt_class_init (NMDeviceBtClass *bt_class)
object_class->dispose = dispose;
object_class->finalize = finalize;
object_class->get_property = get_property;
device_class->filter_connections = filter_connections;
device_class->connection_valid = connection_valid;
/* properties */

View file

@ -194,55 +194,46 @@ nm_device_ethernet_get_carrier (NMDeviceEthernet *device)
return priv->carrier;
}
static GSList *
filter_connections (NMDevice *device, const GSList *connections)
static gboolean
connection_valid (NMDevice *device, NMConnection *connection)
{
GSList *filtered = NULL;
const GSList *iter;
NMSettingConnection *s_con;
NMSettingWired *s_wired;
const char *ctype;
gboolean is_pppoe = FALSE;
for (iter = connections; iter; iter = g_slist_next (iter)) {
NMConnection *candidate = NM_CONNECTION (iter->data);
NMSettingConnection *s_con;
NMSettingWired *s_wired;
const char *ctype;
gboolean is_pppoe = FALSE;
s_con = nm_connection_get_setting_connection (connection);
g_assert (s_con);
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_PPPOE_SETTING_NAME))
is_pppoe = TRUE;
else if (strcmp (ctype, NM_SETTING_WIRED_SETTING_NAME) != 0)
return FALSE;
ctype = nm_setting_connection_get_connection_type (s_con);
if (!strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME))
is_pppoe = TRUE;
else if (strcmp (ctype, NM_SETTING_WIRED_SETTING_NAME) != 0)
continue;
s_wired = nm_connection_get_setting_wired (connection);
/* Wired setting optional for PPPoE */
if (!is_pppoe && !s_wired)
return FALSE;
s_wired = (NMSettingWired *) nm_connection_get_setting (candidate, NM_TYPE_SETTING_WIRED);
/* Wired setting optional for PPPoE */
if (!is_pppoe && !s_wired)
continue;
if (s_wired) {
const GByteArray *mac;
const char *perm_str;
struct ether_addr *perm_mac;
if (s_wired) {
const GByteArray *mac;
const char *perm_str;
struct ether_addr *perm_mac;
/* FIXME: filter using s390 subchannels when they are exported over the bus */
/* FIXME: filter using s390 subchannels when they are exported over the bus */
/* Check MAC address */
perm_str = nm_device_ethernet_get_permanent_hw_address (NM_DEVICE_ETHERNET (device));
if (perm_str) {
perm_mac = ether_aton (perm_str);
mac = nm_setting_wired_get_mac_address (s_wired);
if (mac && perm_mac && memcmp (mac->data, perm_mac->ether_addr_octet, ETH_ALEN))
continue;
}
/* Check MAC address */
perm_str = nm_device_ethernet_get_permanent_hw_address (NM_DEVICE_ETHERNET (device));
if (perm_str) {
perm_mac = ether_aton (perm_str);
mac = nm_setting_wired_get_mac_address (s_wired);
if (mac && perm_mac && memcmp (mac->data, perm_mac->ether_addr_octet, ETH_ALEN))
return FALSE;
}
/* Connection applies to this device */
filtered = g_slist_prepend (filtered, candidate);
}
return g_slist_reverse (filtered);
return TRUE;
}
/***********************************************************/
@ -368,7 +359,7 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *eth_class)
object_class->dispose = dispose;
object_class->finalize = finalize;
object_class->get_property = get_property;
device_class->filter_connections = filter_connections;
device_class->connection_valid = connection_valid;
/* properties */

View file

@ -117,42 +117,35 @@ nm_device_modem_get_current_capabilities (NMDeviceModem *self)
return priv->current_caps;
}
static GSList *
filter_connections (NMDevice *device, const GSList *connections)
static gboolean
connection_valid (NMDevice *device, NMConnection *connection)
{
GSList *filtered = NULL;
const GSList *iter;
NMSettingConnection *s_con;
NMSettingGsm *s_gsm;
NMSettingCdma *s_cdma;
const char *ctype;
NMDeviceModemCapabilities current_caps;
for (iter = connections; iter; iter = g_slist_next (iter)) {
NMConnection *candidate = NM_CONNECTION (iter->data);
NMSettingConnection *s_con;
NMSettingGsm *s_gsm;
NMSettingCdma *s_cdma;
const char *ctype;
NMDeviceModemCapabilities current_caps;
s_con = nm_connection_get_setting_connection (connection);
g_assert (s_con);
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_GSM_SETTING_NAME) != 0
&& strcmp (ctype, NM_SETTING_CDMA_SETTING_NAME) != 0)
return FALSE;
ctype = nm_setting_connection_get_connection_type (s_con);
if ( strcmp (ctype, NM_SETTING_GSM_SETTING_NAME) != 0
&& strcmp (ctype, NM_SETTING_CDMA_SETTING_NAME) != 0)
continue;
s_gsm = nm_connection_get_setting_gsm (connection);
s_cdma = nm_connection_get_setting_cdma (connection);
if (!s_cdma && !s_gsm)
return FALSE;
s_gsm = (NMSettingGsm *) nm_connection_get_setting (candidate, NM_TYPE_SETTING_GSM);
s_cdma = (NMSettingCdma *) nm_connection_get_setting (candidate, NM_TYPE_SETTING_CDMA);
if (!s_cdma && !s_gsm)
continue;
current_caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device));
if ( (s_gsm && (current_caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS))
|| (s_cdma && (current_caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO))) {
/* Connection applies to this device */
filtered = g_slist_prepend (filtered, candidate);
}
current_caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device));
if ( !(s_gsm && (current_caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS))
&& !(s_cdma && (current_caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO))) {
return FALSE;
}
return g_slist_reverse (filtered);
return TRUE;
}
/*******************************************************************/
@ -252,7 +245,7 @@ nm_device_modem_class_init (NMDeviceModemClass *modem_class)
object_class->constructor = constructor;
object_class->get_property = get_property;
object_class->dispose = dispose;
device_class->filter_connections = filter_connections;
device_class->connection_valid = connection_valid;
/**
* NMDeviceModem:modem-capabilities:

View file

@ -504,70 +504,61 @@ has_proto (NMSettingWirelessSecurity *s_wsec, const char *proto)
return FALSE;
}
static GSList *
filter_connections (NMDevice *device, const GSList *connections)
static gboolean
connection_valid (NMDevice *device, NMConnection *connection)
{
GSList *filtered = NULL;
const GSList *iter;
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;
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 = nm_connection_get_setting_connection (connection);
g_assert (s_con);
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)
return FALSE;
ctype = nm_setting_connection_get_connection_type (s_con);
if (strcmp (ctype, NM_SETTING_WIRELESS_SETTING_NAME) != 0)
continue;
s_wifi = nm_connection_get_setting_wireless (connection);
if (!s_wifi)
return FALSE;
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);
/* 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))
return FALSE;
}
return g_slist_reverse (filtered);
/* 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 = nm_connection_get_setting_wireless_security (connection);
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))
return FALSE;
/* 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))
return FALSE;
}
}
return TRUE;
}
/**************************************************************/
@ -784,7 +775,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class)
object_class->get_property = get_property;
object_class->dispose = dispose;
object_class->finalize = finalize;
device_class->filter_connections = filter_connections;
device_class->connection_valid = connection_valid;
/* properties */

View file

@ -482,46 +482,37 @@ nm_device_wimax_get_bsid (NMDeviceWimax *self)
return priv->bsid;
}
static GSList *
filter_connections (NMDevice *device, const GSList *connections)
static gboolean
connection_valid (NMDevice *device, NMConnection *connection)
{
GSList *filtered = NULL;
const GSList *iter;
NMSettingConnection *s_con;
NMSettingWimax *s_wimax;
const char *ctype;
const GByteArray *mac;
const char *hw_str;
struct ether_addr *hw_mac;
for (iter = connections; iter; iter = g_slist_next (iter)) {
NMConnection *candidate = NM_CONNECTION (iter->data);
NMSettingConnection *s_con;
NMSettingWimax *s_wimax;
const char *ctype;
const GByteArray *mac;
const char *hw_str;
struct ether_addr *hw_mac;
s_con = nm_connection_get_setting_connection (connection);
g_assert (s_con);
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_WIMAX_SETTING_NAME) != 0)
return FALSE;
ctype = nm_setting_connection_get_connection_type (s_con);
if (strcmp (ctype, NM_SETTING_WIMAX_SETTING_NAME) != 0)
continue;
s_wimax = nm_connection_get_setting_wimax (connection);
if (!s_wimax)
return FALSE;
s_wimax = (NMSettingWimax *) nm_connection_get_setting (candidate, NM_TYPE_SETTING_WIMAX);
if (!s_wimax)
continue;
/* Check MAC address */
hw_str = nm_device_wimax_get_hw_address (NM_DEVICE_WIMAX (device));
if (hw_str) {
hw_mac = ether_aton (hw_str);
mac = nm_setting_wimax_get_mac_address (s_wimax);
if (mac && hw_mac && memcmp (mac->data, hw_mac->ether_addr_octet, ETH_ALEN))
continue;
}
/* Connection applies to this device */
filtered = g_slist_prepend (filtered, candidate);
/* Check MAC address */
hw_str = nm_device_wimax_get_hw_address (NM_DEVICE_WIMAX (device));
if (hw_str) {
hw_mac = ether_aton (hw_str);
mac = nm_setting_wimax_get_mac_address (s_wimax);
if (mac && hw_mac && memcmp (mac->data, hw_mac->ether_addr_octet, ETH_ALEN))
return FALSE;
}
return g_slist_reverse (filtered);
return TRUE;
}
/**************************************************************/
@ -768,7 +759,7 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class)
object_class->constructor = constructor;
object_class->get_property = get_property;
object_class->dispose = dispose;
device_class->filter_connections = filter_connections;
device_class->connection_valid = connection_valid;
/* properties */

View file

@ -1400,6 +1400,30 @@ nm_device_disconnect (NMDevice *device,
info);
}
/**
* nm_device_connection_valid:
* @device: an #NMDevice to validate @connection against
* @connection: an #NMConnection to validate against @device
*
* Validates a given connection for a given #NMDevice object and returns
* whether the connection may be activated with the device. For example if
* @device is a WiFi device that supports only WEP encryption, the connection
* will only be valid if it is a WiFi connection which describes a WEP or open
* network, and will not be valid if it describes a WPA network, or if it is
* an Ethernet, Bluetooth, WWAN, etc connection that is incompatible with the
* device.
*
* Returns: %TRUE if the connection may be activated with this device, %FALSE
* if is incompatible with the device's capabilities and characteristics.
**/
gboolean
nm_device_connection_valid (NMDevice *device, NMConnection *connection)
{
if (NM_DEVICE_GET_CLASS (device)->connection_valid)
return NM_DEVICE_GET_CLASS (device)->connection_valid (device, connection);
return FALSE;
}
/**
* nm_device_filter_connections:
* @device: an #NMDevice to filter connections for
@ -1422,8 +1446,17 @@ nm_device_disconnect (NMDevice *device,
GSList *
nm_device_filter_connections (NMDevice *device, const GSList *connections)
{
if (NM_DEVICE_GET_CLASS (device)->filter_connections)
return NM_DEVICE_GET_CLASS (device)->filter_connections (device, connections);
return NULL;
GSList *filtered = NULL;
const GSList *iter;
for (iter = connections; iter; iter = g_slist_next (iter)) {
NMConnection *candidate = NM_CONNECTION (iter->data);
/* Connection applies to this device */
if (nm_device_connection_valid (device, candidate))
filtered = g_slist_prepend (filtered, candidate);
}
return g_slist_reverse (filtered);
}

View file

@ -73,8 +73,8 @@ typedef struct {
NMDeviceState old_state,
NMDeviceStateReason reason);
GSList * (*filter_connections) (NMDevice *device,
const GSList *connections);
gboolean (*connection_valid) (NMDevice *device,
NMConnection *connection);
/* Padding for future expansion */
void (*_reserved1) (void);
@ -114,6 +114,9 @@ void nm_device_disconnect (NMDevice *device,
GSList * nm_device_filter_connections (NMDevice *device,
const GSList *connections);
gboolean nm_device_connection_valid (NMDevice *device,
NMConnection *connection);
G_END_DECLS
#endif /* NM_DEVICE_H */

View file

@ -156,10 +156,54 @@ nm_wimax_nsp_get_network_type (NMWimaxNsp *nsp)
return priv->network_type;
}
/**
* nm_wimax_nsp_filter_connections:
* @nsp: an #NMWimaxNsp to validate @connection against
* @connection: an #NMConnection to validate against @nsp
*
* Validates a given connection against a given WiMAX NSP to ensure that the
* connection may be activated with that NSP. The connection must match the
* @nsp's network name and other attributes.
*
* Returns: %TRUE if the connection may be activated with this WiMAX NSP,
* %FALSE if it cannot be.
**/
gboolean
nm_wimax_nsp_connection_valid (NMWimaxNsp *nsp, NMConnection *connection)
{
NMSettingConnection *s_con;
NMSettingWimax *s_wimax;
const char *ctype;
const char *nsp_name;
const char *setting_name;
s_con = nm_connection_get_setting_connection (connection);
g_assert (s_con);
ctype = nm_setting_connection_get_connection_type (s_con);
if (strcmp (ctype, NM_SETTING_WIMAX_SETTING_NAME) != 0)
return FALSE;
s_wimax = nm_connection_get_setting_wimax (connection);
if (!s_wimax)
return FALSE;
setting_name = nm_setting_wimax_get_network_name (s_wimax);
if (!setting_name)
return FALSE;
nsp_name = nm_wimax_nsp_get_name (nsp);
g_warn_if_fail (nsp_name != NULL);
if (g_strcmp0 (nsp_name, setting_name) != 0)
return FALSE;
return TRUE;
}
/**
* nm_wimax_nsp_filter_connections:
* @nsp: an #NMWimaxNsp to filter connections for
* @connections: a list of #NMConnection objects to filter
* @connections: (element-type NetworkManager.Connection): a list of
* #NMConnection objects to filter
*
* Filters a given list of connections for a given #NMWimaxNsp object and
* return connections which may be activated with the access point. Any
@ -179,33 +223,9 @@ nm_wimax_nsp_filter_connections (NMWimaxNsp *nsp, const GSList *connections)
for (iter = connections; iter; iter = g_slist_next (iter)) {
NMConnection *candidate = NM_CONNECTION (iter->data);
NMSettingConnection *s_con;
NMSettingWimax *s_wimax;
const char *ctype;
const char *nsp_name;
const char *setting_name;
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_WIMAX_SETTING_NAME) != 0)
continue;
s_wimax = (NMSettingWimax *) nm_connection_get_setting (candidate, NM_TYPE_SETTING_WIMAX);
if (!s_wimax)
continue;
setting_name = nm_setting_wimax_get_network_name (s_wimax);
if (!setting_name)
continue;
nsp_name = nm_wimax_nsp_get_name (nsp);
g_warn_if_fail (nsp_name != NULL);
if (g_strcmp0 (nsp_name, setting_name) != 0)
continue;
/* Connection applies to this device */
filtered = g_slist_prepend (filtered, candidate);
if (nm_wimax_nsp_connection_valid (nsp, candidate))
filtered = g_slist_prepend (filtered, candidate);
}
return g_slist_reverse (filtered);

View file

@ -76,6 +76,9 @@ NMWimaxNspNetworkType nm_wimax_nsp_get_network_type (NMWimaxNsp *nsp);
GSList * nm_wimax_nsp_filter_connections (NMWimaxNsp *nsp,
const GSList *connections);
gboolean nm_wimax_nsp_connection_valid (NMWimaxNsp *nsp,
NMConnection *connection);
G_END_DECLS
#endif /* NM_WIMAX_NSP_H */