summary refs log tree commit diff
path: root/libnm-util/nm-setting-wireless.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnm-util/nm-setting-wireless.c')
-rw-r--r--libnm-util/nm-setting-wireless.c103
1 files changed, 64 insertions, 39 deletions
diff --git a/libnm-util/nm-setting-wireless.c b/libnm-util/nm-setting-wireless.c
index 9213429c..ec7d53ad 100644
--- a/libnm-util/nm-setting-wireless.c
+++ b/libnm-util/nm-setting-wireless.c
@@ -19,11 +19,12 @@
  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  * Boston, MA 02110-1301 USA.
  *
- * (C) Copyright 2007 - 2008 Red Hat, Inc.
+ * (C) Copyright 2007 - 2010 Red Hat, Inc.
  * (C) Copyright 2007 - 2008 Novell, Inc.
  */
 
 #include <string.h>
+#include <net/ethernet.h>
 #include <netinet/ether.h>
 #include <dbus/dbus-glib.h>
 
@@ -86,7 +87,8 @@ typedef struct {
 	GByteArray *bssid;
 	guint32 rate;
 	guint32 tx_power;
-	GByteArray *mac_address;
+	GByteArray *device_mac_address;
+	GByteArray *cloned_mac_address;
 	guint32 mtu;
 	GSList *seen_bssids;
 	char *security;
@@ -102,6 +104,7 @@ enum {
 	PROP_RATE,
 	PROP_TX_POWER,
 	PROP_MAC_ADDRESS,
+	PROP_CLONED_MAC_ADDRESS,
 	PROP_MTU,
 	PROP_SEEN_BSSIDS,
 	PROP_SEC,
@@ -353,7 +356,15 @@ nm_setting_wireless_get_mac_address (NMSettingWireless *setting)
 {
 	g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL);
 
-	return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->mac_address;
+	return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->device_mac_address;
+}
+
+const GByteArray *
+nm_setting_wireless_get_cloned_mac_address (NMSettingWireless *setting)
+{
+	g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL);
+
+	return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->cloned_mac_address;
 }
 
 guint32
@@ -480,31 +491,11 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
 	}
 
 	if (priv->channel) {
-		if (!strcmp (priv->band, "a")) {
-			int i;
-			int valid_channels[] = { 7, 8, 9, 11, 12, 16, 34, 36, 40, 44, 48,
-			                         52, 56, 60, 64, 100, 104, 108, 112, 116,
-			                         120, 124, 128, 132, 136, 140, 149, 153,
-			                         157, 161, 165, 183, 184, 185, 187, 188,
-			                         192, 196, 0 };
-
-			for (i = 0; valid_channels[i]; i++) {
-				if (priv->channel == valid_channels[i])
-					break;
-			}
-
-			if (valid_channels[i] == 0) {
-				g_set_error (error,
-				             NM_SETTING_WIRELESS_ERROR,
-				             NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
-				             NM_SETTING_WIRELESS_CHANNEL);
-				return FALSE;
-			}
-		} else if (!strcmp (priv->band, "bg") && priv->channel > 14) {
-				g_set_error (error,
-				             NM_SETTING_WIRELESS_ERROR,
-				             NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
-				             NM_SETTING_WIRELESS_CHANNEL);
+		if (!nm_utils_wifi_is_channel_valid (priv->channel, priv->band)) {
+			g_set_error (error,
+			             NM_SETTING_WIRELESS_ERROR,
+			             NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
+			             NM_SETTING_WIRELESS_CHANNEL);
 			return FALSE;
 		}
 	}
@@ -517,7 +508,7 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
 		return FALSE;
 	}
 
-	if (priv->mac_address && priv->mac_address->len != ETH_ALEN) {
+	if (priv->device_mac_address && priv->device_mac_address->len != ETH_ALEN) {
 		g_set_error (error,
 		             NM_SETTING_WIRELESS_ERROR,
 		             NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
@@ -525,6 +516,14 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
 		return FALSE;
 	}
 
+	if (priv->cloned_mac_address && priv->cloned_mac_address->len != ETH_ALEN) {
+		g_set_error (error,
+		             NM_SETTING_WIRELESS_ERROR,
+		             NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
+		             NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS);
+		return FALSE;
+	}
+
 	for (iter = priv->seen_bssids; iter; iter = iter->next) {
 		struct ether_addr addr;
 
@@ -568,8 +567,10 @@ finalize (GObject *object)
 		g_byte_array_free (priv->ssid, TRUE);
 	if (priv->bssid)
 		g_byte_array_free (priv->bssid, TRUE);
-	if (priv->mac_address)
-		g_byte_array_free (priv->mac_address, TRUE);
+	if (priv->device_mac_address)
+		g_byte_array_free (priv->device_mac_address, TRUE);
+	if (priv->cloned_mac_address)
+		g_byte_array_free (priv->cloned_mac_address, TRUE);
 
 	nm_utils_slist_free (priv->seen_bssids, g_free);
 
@@ -611,9 +612,14 @@ set_property (GObject *object, guint prop_id,
 		priv->tx_power = g_value_get_uint (value);
 		break;
 	case PROP_MAC_ADDRESS:
-		if (priv->mac_address)
-			g_byte_array_free (priv->mac_address, TRUE);
-		priv->mac_address = g_value_dup_boxed (value);
+		if (priv->device_mac_address)
+			g_byte_array_free (priv->device_mac_address, TRUE);
+		priv->device_mac_address = g_value_dup_boxed (value);
+		break;
+	case PROP_CLONED_MAC_ADDRESS:
+		if (priv->cloned_mac_address)
+			g_byte_array_free (priv->cloned_mac_address, TRUE);
+		priv->cloned_mac_address = g_value_dup_boxed (value);
 		break;
 	case PROP_MTU:
 		priv->mtu = g_value_get_uint (value);
@@ -663,6 +669,9 @@ get_property (GObject *object, guint prop_id,
 	case PROP_MAC_ADDRESS:
 		g_value_set_boxed (value, nm_setting_wireless_get_mac_address (setting));
 		break;
+	case PROP_CLONED_MAC_ADDRESS:
+		g_value_set_boxed (value, nm_setting_wireless_get_cloned_mac_address (setting));
+		break;
 	case PROP_MTU:
 		g_value_set_uint (value, nm_setting_wireless_get_mtu (setting));
 		break;
@@ -829,21 +838,37 @@ nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class)
 	 * NMSettingWireless:mac-address:
 	 *
 	 * If specified, this connection will only apply to the WiFi device
-	 * whose MAC address matches. This property does not change the MAC address
-	 * of the device (known as MAC spoofing).
+	 * whose permanent MAC address matches. This property does not change the MAC address
+	 * of the device (i.e. MAC spoofing).
 	 **/
 	g_object_class_install_property
 		(object_class, PROP_MAC_ADDRESS,
 		 _nm_param_spec_specialized (NM_SETTING_WIRELESS_MAC_ADDRESS,
-							   "MAC Address",
+							   "Device MAC Address",
 							   "If specified, this connection will only apply to "
-							   "the WiFi device whose MAC address matches.  "
+							   "the WiFi device whose permanent MAC address matches.  "
 							   "This property does not change the MAC address "
-							   "of the device (known as MAC spoofing).",
+							   "of the device (i.e. MAC spoofing).",
 							   DBUS_TYPE_G_UCHAR_ARRAY,
 							   G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
 
 	/**
+	 * NMSettingWireless:cloned-mac-address:
+	 *
+	 * If specified, request that the Wifi device use this MAC address instead of its
+	 * permanent MAC address.  This is known as MAC cloning or spoofing.
+	 **/
+	g_object_class_install_property
+		(object_class, PROP_CLONED_MAC_ADDRESS,
+		 _nm_param_spec_specialized (NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS,
+	                                     "Spoof MAC Address",
+	                                     "If specified, request that the WiFi device use "
+	                                     "this MAC address instead of its permanent MAC address.  "
+	                                     "This is known as MAC cloning or spoofing.",
+	                                     DBUS_TYPE_G_UCHAR_ARRAY,
+	                                     G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
+	/**
 	 * NMSettingWireless:seen-bssids:
 	 *
 	 * A list of BSSIDs (each BSSID formatted as a MAC address like