Commit 1b49f941 authored by Jiří Klimeš's avatar Jiří Klimeš

core: MAC address spoofing/cloning (rh #447827) (bgo #553771)

This commit implements MAC cloning feature in NetworkManager. To support that,
'PermHwAddress' property is added into *.Device.Wired and *.Device.Wireless
interfaces. The permanent MAC address is obtained when creating the device, and
is used for 'locking' connections to the device. If a cloned MAC is specified
in connection to be activated, the MAC is set to the interface in stage1. While
disconecting, the permanent MAC is set back to the interface.
parent a8e0c263
......@@ -713,7 +713,7 @@ check_ethernet_compatible (NMDeviceEthernet *device, NMConnection *connection, G
const char *device_mac_str;
struct ether_addr *device_mac;
device_mac_str = nm_device_ethernet_get_hw_address (device);
device_mac_str = nm_device_ethernet_get_permanent_hw_address (device);
device_mac = ether_aton (device_mac_str);
if (!device_mac) {
g_set_error (error, 0, 0, "Invalid device MAC address.");
......@@ -762,7 +762,7 @@ check_wifi_compatible (NMDeviceWifi *device, NMConnection *connection, GError **
const char *device_mac_str;
struct ether_addr *device_mac;
device_mac_str = nm_device_wifi_get_hw_address (device);
device_mac_str = nm_device_wifi_get_permanent_hw_address (device);
device_mac = ether_aton (device_mac_str);
if (!device_mac) {
g_set_error (error, 0, 0, "Invalid device MAC address.");
......
......@@ -50,13 +50,14 @@ static NmcOutputField nmc_fields_setting_connection[] = {
/* Available fields for NM_SETTING_WIRED_SETTING_NAME */
static NmcOutputField nmc_fields_setting_wired[] = {
SETTING_FIELD ("name", 17), /* 0 */
SETTING_FIELD (NM_SETTING_WIRED_PORT, 8), /* 1 */
SETTING_FIELD (NM_SETTING_WIRED_SPEED, 10), /* 2 */
SETTING_FIELD (NM_SETTING_WIRED_DUPLEX, 10), /* 3 */
SETTING_FIELD (NM_SETTING_WIRED_AUTO_NEGOTIATE, 15), /* 4 */
SETTING_FIELD (NM_SETTING_WIRED_MAC_ADDRESS, 19), /* 5 */
SETTING_FIELD (NM_SETTING_WIRED_MTU, 6), /* 6 */
SETTING_FIELD ("name", 17), /* 0 */
SETTING_FIELD (NM_SETTING_WIRED_PORT, 8), /* 1 */
SETTING_FIELD (NM_SETTING_WIRED_SPEED, 10), /* 2 */
SETTING_FIELD (NM_SETTING_WIRED_DUPLEX, 10), /* 3 */
SETTING_FIELD (NM_SETTING_WIRED_AUTO_NEGOTIATE, 15), /* 4 */
SETTING_FIELD (NM_SETTING_WIRED_MAC_ADDRESS, 19), /* 5 */
SETTING_FIELD (NM_SETTING_WIRED_CLONED_MAC_ADDRESS, 19), /* 6 */
SETTING_FIELD (NM_SETTING_WIRED_MTU, 6), /* 7 */
{NULL, NULL, 0, NULL, 0}
};
#define NMC_FIELDS_SETTING_WIRED_ALL "name"","\
......@@ -65,6 +66,7 @@ static NmcOutputField nmc_fields_setting_wired[] = {
NM_SETTING_WIRED_DUPLEX","\
NM_SETTING_WIRED_AUTO_NEGOTIATE","\
NM_SETTING_WIRED_MAC_ADDRESS","\
NM_SETTING_WIRED_CLONED_MAC_ADDRESS","\
NM_SETTING_WIRED_MTU
#define NMC_FIELDS_SETTING_WIRED_COMMON NMC_FIELDS_SETTING_WIRED_ALL
......@@ -131,9 +133,10 @@ static NmcOutputField nmc_fields_setting_wireless[] = {
SETTING_FIELD (NM_SETTING_WIRELESS_RATE, 10), /* 6 */
SETTING_FIELD (NM_SETTING_WIRELESS_TX_POWER, 10), /* 7 */
SETTING_FIELD (NM_SETTING_WIRELESS_MAC_ADDRESS, 19), /* 8 */
SETTING_FIELD (NM_SETTING_WIRELESS_MTU, 6), /* 9 */
SETTING_FIELD (NM_SETTING_WIRELESS_SEEN_BSSIDS, 35), /* 10 */
SETTING_FIELD (NM_SETTING_WIRELESS_SEC, 10), /* 11 */
SETTING_FIELD (NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, 19), /* 9 */
SETTING_FIELD (NM_SETTING_WIRELESS_MTU, 6), /* 10 */
SETTING_FIELD (NM_SETTING_WIRELESS_SEEN_BSSIDS, 35), /* 11 */
SETTING_FIELD (NM_SETTING_WIRELESS_SEC, 10), /* 12 */
{NULL, NULL, 0, NULL, 0}
};
#define NMC_FIELDS_SETTING_WIRELESS_ALL "name"","\
......@@ -145,6 +148,7 @@ static NmcOutputField nmc_fields_setting_wireless[] = {
NM_SETTING_WIRELESS_RATE","\
NM_SETTING_WIRELESS_TX_POWER","\
NM_SETTING_WIRELESS_MAC_ADDRESS","\
NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS","\
NM_SETTING_WIRELESS_MTU","\
NM_SETTING_WIRELESS_SEEN_BSSIDS","\
NM_SETTING_WIRELESS_SEC
......@@ -518,7 +522,7 @@ setting_wired_details (NMSetting *setting, NmCli *nmc)
{
NMSettingWired *s_wired;
const GByteArray *mac;
char *speed_str, *mtu_str, *mac_str = NULL;
char *speed_str, *mtu_str, *device_mac_str = NULL, *cloned_mac_str = NULL;
guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0;
......@@ -535,21 +539,26 @@ setting_wired_details (NMSetting *setting, NmCli *nmc)
mtu_str = g_strdup_printf ("%d", nm_setting_wired_get_mtu (s_wired));
mac = nm_setting_wired_get_mac_address (s_wired);
if (mac)
mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]);
device_mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]);
mac = nm_setting_wired_get_cloned_mac_address (s_wired);
if (mac)
cloned_mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]);
nmc->allowed_fields[0].value = NM_SETTING_WIRED_SETTING_NAME;
nmc->allowed_fields[1].value = nm_setting_wired_get_port (s_wired);
nmc->allowed_fields[2].value = speed_str;
nmc->allowed_fields[3].value = nm_setting_wired_get_duplex (s_wired);
nmc->allowed_fields[4].value = nm_setting_wired_get_auto_negotiate (s_wired) ? _("yes") : _("no");
nmc->allowed_fields[5].value = mac_str;
nmc->allowed_fields[6].value = strcmp (mtu_str, "0") ? mtu_str : _("auto");
nmc->allowed_fields[5].value = device_mac_str;
nmc->allowed_fields[6].value = cloned_mac_str;
nmc->allowed_fields[7].value = strcmp (mtu_str, "0") ? mtu_str : _("auto");
nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
g_free (speed_str);
g_free (mac_str);
g_free (device_mac_str);
g_free (cloned_mac_str);
g_free (mtu_str);
return TRUE;
......@@ -663,7 +672,7 @@ setting_wireless_details (NMSetting *setting, NmCli *nmc)
int i;
const GByteArray *ssid, *bssid, *mac;
char *ssid_str, *channel_str, *rate_str, *tx_power_str, *mtu_str;
char *mac_str = NULL, *bssid_str = NULL;
char *device_mac_str = NULL, *cloned_mac_str = NULL, *bssid_str = NULL;
GString *seen_bssids;
guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0;
guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0;
......@@ -688,7 +697,10 @@ setting_wireless_details (NMSetting *setting, NmCli *nmc)
mtu_str = g_strdup_printf ("%d", nm_setting_wireless_get_mtu (s_wireless));
mac = nm_setting_wireless_get_mac_address (s_wireless);
if (mac)
mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]);
device_mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]);
mac = nm_setting_wireless_get_cloned_mac_address (s_wireless);
if (mac)
cloned_mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]);
seen_bssids = g_string_new (NULL);
for (i = 0; i < nm_setting_wireless_get_num_seen_bssids (s_wireless); i++) {
if (i > 0)
......@@ -704,10 +716,11 @@ setting_wireless_details (NMSetting *setting, NmCli *nmc)
nmc->allowed_fields[5].value = bssid_str ? bssid_str : _("not set");
nmc->allowed_fields[6].value = rate_str;
nmc->allowed_fields[7].value = tx_power_str;
nmc->allowed_fields[8].value = mac_str ? mac_str : _("not set");
nmc->allowed_fields[9].value = strcmp (mtu_str, "0") ? mtu_str : _("auto");
nmc->allowed_fields[10].value = seen_bssids->str;
nmc->allowed_fields[11].value = nm_setting_wireless_get_security (s_wireless);
nmc->allowed_fields[8].value = device_mac_str ? device_mac_str : _("not set");
nmc->allowed_fields[9].value = cloned_mac_str ? cloned_mac_str : _("not set");
nmc->allowed_fields[10].value = strcmp (mtu_str, "0") ? mtu_str : _("auto");
nmc->allowed_fields[11].value = seen_bssids->str;
nmc->allowed_fields[12].value = nm_setting_wireless_get_security (s_wireless);
nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX;
print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */
......@@ -717,7 +730,8 @@ setting_wireless_details (NMSetting *setting, NmCli *nmc)
g_free (bssid_str);
g_free (rate_str);
g_free (tx_power_str);
g_free (mac_str);
g_free (device_mac_str);
g_free (cloned_mac_str);
g_free (mtu_str);
g_string_free (seen_bssids, TRUE);
......
......@@ -5,7 +5,13 @@
<property name="HwAddress" type="s" access="read">
<tp:docstring>
Hardware address of the device.
Active hardware address of the device.
</tp:docstring>
</property>
<property name="PermHwAddress" type="s" access="read">
<tp:docstring>
Permanent hardware address of the device.
</tp:docstring>
</property>
......
......@@ -16,9 +16,16 @@
<property name="HwAddress" type="s" access="read">
<tp:docstring>
The hardware address of the device.
The active hardware address of the device.
</tp:docstring>
</property>
<property name="PermHwAddress" type="s" access="read">
<tp:docstring>
The permanent hardware address of the device.
</tp:docstring>
</property>
<property name="Mode" type="u" access="read" tp:type="NM_802_11_MODE">
<tp:docstring>
The operating mode of the wireless device.
......
......@@ -132,7 +132,7 @@ libnm_glib_la_LIBADD = \
$(GUDEV_LIBS)
libnm_glib_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-glib.ver \
-version-info "5:0:3"
-version-info "6:0:4"
noinst_PROGRAMS = libnm-glib-test
......
......@@ -63,6 +63,7 @@ global:
nm_device_bt_get_type;
nm_device_ethernet_get_carrier;
nm_device_ethernet_get_hw_address;
nm_device_ethernet_get_permanent_hw_address;
nm_device_ethernet_get_speed;
nm_device_ethernet_get_type;
nm_device_ethernet_new;
......@@ -86,6 +87,7 @@ global:
nm_device_wifi_get_bitrate;
nm_device_wifi_get_capabilities;
nm_device_wifi_get_hw_address;
nm_device_wifi_get_permanent_hw_address;
nm_device_wifi_get_mode;
nm_device_wifi_get_type;
nm_device_wifi_new;
......
......@@ -18,7 +18,7 @@
* Boston, MA 02110-1301 USA.
*
* Copyright (C) 2007 - 2008 Novell, Inc.
* Copyright (C) 2007 - 2008 Red Hat, Inc.
* Copyright (C) 2007 - 2010 Red Hat, Inc.
*/
#include "nm-device-ethernet.h"
......@@ -34,7 +34,8 @@ G_DEFINE_TYPE (NMDeviceEthernet, nm_device_ethernet, NM_TYPE_DEVICE)
typedef struct {
DBusGProxy *proxy;
char * hw_address;
char *hw_address;
char *perm_hw_address;
guint32 speed;
gboolean carrier;
gboolean carrier_valid;
......@@ -45,6 +46,7 @@ typedef struct {
enum {
PROP_0,
PROP_HW_ADDRESS,
PROP_PERM_HW_ADDRESS,
PROP_SPEED,
PROP_CARRIER,
......@@ -52,6 +54,7 @@ enum {
};
#define DBUS_PROP_HW_ADDRESS "HwAddress"
#define DBUS_PROP_PERM_HW_ADDRESS "PermHwAddress"
#define DBUS_PROP_SPEED "Speed"
#define DBUS_PROP_CARRIER "Carrier"
......@@ -80,9 +83,9 @@ nm_device_ethernet_new (DBusGConnection *connection, const char *path)
* nm_device_ethernet_get_hw_address:
* @device: a #NMDeviceEthernet
*
* Gets the hardware (MAC) address of the #NMDeviceEthernet
* Gets the active hardware (MAC) address of the #NMDeviceEthernet
*
* Returns: the hardware address. This is the internal string used by the
* Returns: the active hardware address. This is the internal string used by the
* device, and must not be modified.
**/
const char *
......@@ -102,6 +105,32 @@ nm_device_ethernet_get_hw_address (NMDeviceEthernet *device)
return priv->hw_address;
}
/**
* nm_device_ethernet_get_permanent_hw_address:
* @device: a #NMDeviceEthernet
*
* Gets the permanent hardware (MAC) address of the #NMDeviceEthernet
*
* Returns: the permanent hardware address. This is the internal string used by the
* device, and must not be modified.
**/
const char *
nm_device_ethernet_get_permanent_hw_address (NMDeviceEthernet *device)
{
NMDeviceEthernetPrivate *priv;
g_return_val_if_fail (NM_IS_DEVICE_ETHERNET (device), NULL);
priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device);
if (!priv->perm_hw_address) {
priv->perm_hw_address = _nm_object_get_string_property (NM_OBJECT (device),
NM_DBUS_INTERFACE_DEVICE_WIRED,
DBUS_PROP_PERM_HW_ADDRESS);
}
return priv->perm_hw_address;
}
/**
* nm_device_ethernet_get_speed:
* @device: a #NMDeviceEthernet
......@@ -168,9 +197,10 @@ register_for_property_changed (NMDeviceEthernet *device)
{
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device);
const NMPropertiesChangedInfo property_changed_info[] = {
{ NM_DEVICE_ETHERNET_HW_ADDRESS, _nm_object_demarshal_generic, &priv->hw_address },
{ NM_DEVICE_ETHERNET_SPEED, _nm_object_demarshal_generic, &priv->speed },
{ NM_DEVICE_ETHERNET_CARRIER, _nm_object_demarshal_generic, &priv->carrier },
{ NM_DEVICE_ETHERNET_HW_ADDRESS, _nm_object_demarshal_generic, &priv->hw_address },
{ NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS, _nm_object_demarshal_generic, &priv->perm_hw_address },
{ NM_DEVICE_ETHERNET_SPEED, _nm_object_demarshal_generic, &priv->speed },
{ NM_DEVICE_ETHERNET_CARRIER, _nm_object_demarshal_generic, &priv->carrier },
{ NULL },
};
......@@ -230,6 +260,9 @@ finalize (GObject *object)
if (priv->hw_address)
g_free (priv->hw_address);
if (priv->perm_hw_address)
g_free (priv->perm_hw_address);
G_OBJECT_CLASS (nm_device_ethernet_parent_class)->finalize (object);
}
......@@ -245,6 +278,9 @@ get_property (GObject *object,
case PROP_HW_ADDRESS:
g_value_set_string (value, nm_device_ethernet_get_hw_address (device));
break;
case PROP_PERM_HW_ADDRESS:
g_value_set_string (value, nm_device_ethernet_get_permanent_hw_address (device));
break;
case PROP_SPEED:
g_value_set_uint (value, nm_device_ethernet_get_speed (device));
break;
......@@ -275,13 +311,26 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *device_class)
/**
* NMDeviceEthernet:hw-address:
*
* The hardware (MAC) address of the device.
* The active hardware (MAC) address of the device.
**/
g_object_class_install_property
(object_class, PROP_HW_ADDRESS,
g_param_spec_string (NM_DEVICE_ETHERNET_HW_ADDRESS,
"MAC Address",
"Hardware MAC address",
"Active MAC Address",
"Currently set hardware MAC address",
NULL,
G_PARAM_READABLE));
/**
* NMDeviceEthernet:perm-hw-address:
*
* The permanent hardware (MAC) address of the device.
**/
g_object_class_install_property
(object_class, PROP_PERM_HW_ADDRESS,
g_param_spec_string (NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS,
"Permanent MAC Address",
"Permanent hardware MAC address",
NULL,
G_PARAM_READABLE));
......
......@@ -18,7 +18,7 @@
* Boston, MA 02110-1301 USA.
*
* Copyright (C) 2007 - 2008 Novell, Inc.
* Copyright (C) 2007 - 2008 Red Hat, Inc.
* Copyright (C) 2007 - 2010 Red Hat, Inc.
*/
#ifndef NM_DEVICE_ETHERNET_H
......@@ -36,6 +36,7 @@ G_BEGIN_DECLS
#define NM_DEVICE_ETHERNET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_ETHERNET, NMDeviceEthernetClass))
#define NM_DEVICE_ETHERNET_HW_ADDRESS "hw-address"
#define NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS "perm-hw-address"
#define NM_DEVICE_ETHERNET_SPEED "speed"
#define NM_DEVICE_ETHERNET_CARRIER "carrier"
......@@ -60,6 +61,7 @@ GType nm_device_ethernet_get_type (void);
GObject *nm_device_ethernet_new (DBusGConnection *connection, const char *path);
const char * nm_device_ethernet_get_hw_address (NMDeviceEthernet *device);
const char * nm_device_ethernet_get_permanent_hw_address (NMDeviceEthernet *device);
guint32 nm_device_ethernet_get_speed (NMDeviceEthernet *device);
gboolean nm_device_ethernet_get_carrier (NMDeviceEthernet *device);
......
......@@ -18,7 +18,7 @@
* Boston, MA 02110-1301 USA.
*
* Copyright (C) 2007 - 2008 Novell, Inc.
* Copyright (C) 2007 - 2008 Red Hat, Inc.
* Copyright (C) 2007 - 2010 Red Hat, Inc.
*/
#include <string.h>
......@@ -45,6 +45,7 @@ typedef struct {
DBusGProxy *proxy;
char *hw_address;
char *perm_hw_address;
NM80211Mode mode;
guint32 rate;
NMAccessPoint *active_ap;
......@@ -58,6 +59,7 @@ typedef struct {
enum {
PROP_0,
PROP_HW_ADDRESS,
PROP_PERM_HW_ADDRESS,
PROP_MODE,
PROP_BITRATE,
PROP_ACTIVE_ACCESS_POINT,
......@@ -67,6 +69,7 @@ enum {
};
#define DBUS_PROP_HW_ADDRESS "HwAddress"
#define DBUS_PROP_PERM_HW_ADDRESS "PermHwAddress"
#define DBUS_PROP_MODE "Mode"
#define DBUS_PROP_BITRATE "Bitrate"
#define DBUS_PROP_ACTIVE_ACCESS_POINT "ActiveAccessPoint"
......@@ -106,9 +109,9 @@ nm_device_wifi_new (DBusGConnection *connection, const char *path)
* nm_device_wifi_get_hw_address:
* @device: a #NMDeviceWifi
*
* Gets the hardware (MAC) address of the #NMDeviceWifi
* Gets the actual hardware (MAC) address of the #NMDeviceWifi
*
* Returns: the hardware address. This is the internal string used by the
* Returns: the actual hardware address. This is the internal string used by the
* device, and must not be modified.
**/
const char *
......@@ -128,6 +131,32 @@ nm_device_wifi_get_hw_address (NMDeviceWifi *device)
return priv->hw_address;
}
/**
* nm_device_wifi_get_permanent_hw_address:
* @device: a #NMDeviceWifi
*
* Gets the permanent hardware (MAC) address of the #NMDeviceWifi
*
* Returns: the permanent hardware address. This is the internal string used by the
* device, and must not be modified.
**/
const char *
nm_device_wifi_get_permanent_hw_address (NMDeviceWifi *device)
{
NMDeviceWifiPrivate *priv;
g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), NULL);
priv = NM_DEVICE_WIFI_GET_PRIVATE (device);
if (!priv->perm_hw_address) {
priv->perm_hw_address = _nm_object_get_string_property (NM_OBJECT (device),
NM_DBUS_INTERFACE_DEVICE_WIRELESS,
DBUS_PROP_PERM_HW_ADDRESS);
}
return priv->perm_hw_address;
}
/**
* nm_device_wifi_get_mode:
* @device: a #NMDeviceWifi
......@@ -464,6 +493,9 @@ get_property (GObject *object,
case PROP_HW_ADDRESS:
g_value_set_string (value, nm_device_wifi_get_hw_address (self));
break;
case PROP_PERM_HW_ADDRESS:
g_value_set_string (value, nm_device_wifi_get_permanent_hw_address (self));
break;
case PROP_MODE:
g_value_set_uint (value, nm_device_wifi_get_mode (self));
break;
......@@ -554,11 +586,12 @@ register_for_property_changed (NMDeviceWifi *device)
{
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device);
const NMPropertiesChangedInfo property_changed_info[] = {
{ NM_DEVICE_WIFI_HW_ADDRESS, _nm_object_demarshal_generic, &priv->hw_address },
{ NM_DEVICE_WIFI_MODE, _nm_object_demarshal_generic, &priv->mode },
{ NM_DEVICE_WIFI_BITRATE, _nm_object_demarshal_generic, &priv->rate },
{ NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT, demarshal_active_ap, &priv->active_ap },
{ NM_DEVICE_WIFI_CAPABILITIES, _nm_object_demarshal_generic, &priv->wireless_caps },
{ NM_DEVICE_WIFI_HW_ADDRESS, _nm_object_demarshal_generic, &priv->hw_address },
{ NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS, _nm_object_demarshal_generic, &priv->perm_hw_address },
{ NM_DEVICE_WIFI_MODE, _nm_object_demarshal_generic, &priv->mode },
{ NM_DEVICE_WIFI_BITRATE, _nm_object_demarshal_generic, &priv->rate },
{ NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT, demarshal_active_ap, &priv->active_ap },
{ NM_DEVICE_WIFI_CAPABILITIES, _nm_object_demarshal_generic, &priv->wireless_caps },
{ NULL },
};
......@@ -638,6 +671,9 @@ finalize (GObject *object)
if (priv->hw_address)
g_free (priv->hw_address);
if (priv->perm_hw_address)
g_free (priv->perm_hw_address);
G_OBJECT_CLASS (nm_device_wifi_parent_class)->finalize (object);
}
......@@ -664,8 +700,21 @@ nm_device_wifi_class_init (NMDeviceWifiClass *device_class)
g_object_class_install_property
(object_class, PROP_HW_ADDRESS,
g_param_spec_string (NM_DEVICE_WIFI_HW_ADDRESS,
"MAC Address",
"Hardware MAC address",
"Active MAC Address",
"Currently set hardware MAC address",
NULL,
G_PARAM_READABLE));
/**
* NMDeviceWifi:perm-hw-address:
*
* The hardware (MAC) address of the device.
**/
g_object_class_install_property
(object_class, PROP_PERM_HW_ADDRESS,
g_param_spec_string (NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS,
"Permanent MAC Address",
"Permanent hardware MAC address",
NULL,
G_PARAM_READABLE));
......
......@@ -18,7 +18,7 @@
* Boston, MA 02110-1301 USA.
*
* Copyright (C) 2007 - 2008 Novell, Inc.
* Copyright (C) 2007 - 2008 Red Hat, Inc.
* Copyright (C) 2007 - 2010 Red Hat, Inc.
*/
#ifndef NM_DEVICE_WIFI_H
......@@ -37,6 +37,7 @@ G_BEGIN_DECLS
#define NM_DEVICE_WIFI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIFI, NMDeviceWifiClass))
#define NM_DEVICE_WIFI_HW_ADDRESS "hw-address"
#define NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS "perm-hw-address"
#define NM_DEVICE_WIFI_MODE "mode"
#define NM_DEVICE_WIFI_BITRATE "bitrate"
#define NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT "active-access-point"
......@@ -67,6 +68,7 @@ GType nm_device_wifi_get_type (void);
GObject *nm_device_wifi_new (DBusGConnection *connection, const char *path);
const char * nm_device_wifi_get_hw_address (NMDeviceWifi *device);
const char * nm_device_wifi_get_permanent_hw_address (NMDeviceWifi *device);
NM80211Mode nm_device_wifi_get_mode (NMDeviceWifi *device);
guint32 nm_device_wifi_get_bitrate (NMDeviceWifi *device);
guint32 nm_device_wifi_get_capabilities (NMDeviceWifi *device);
......
......@@ -59,7 +59,7 @@ libnm_util_la_SOURCES= \
libnm_util_la_LIBADD = $(GLIB_LIBS) $(DBUS_LIBS) $(UUID_LIBS)
libnm_util_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-util.ver \
-version-info "5:0:4"
-version-info "6:0:5"
if WITH_GNUTLS
libnm_util_la_SOURCES += crypto_gnutls.c
......
......@@ -288,6 +288,7 @@ global:
nm_setting_wired_get_duplex;
nm_setting_wired_get_auto_negotiate;
nm_setting_wired_get_mac_address;
nm_setting_wired_get_cloned_mac_address;
nm_setting_wired_get_mtu;
nm_setting_wireless_ap_security_compatible;
nm_setting_wireless_error_get_type;
......@@ -302,6 +303,7 @@ global:
nm_setting_wireless_get_rate;
nm_setting_wireless_get_tx_power;
nm_setting_wireless_get_mac_address;
nm_setting_wireless_get_cloned_mac_address;
nm_setting_wireless_get_mtu;
nm_setting_wireless_get_security;
nm_setting_wireless_add_seen_bssid;
......
......@@ -19,7 +19,7 @@
* 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.
*/
......@@ -73,7 +73,8 @@ typedef struct {
guint32 speed;
char *duplex;
gboolean auto_negotiate;
GByteArray *mac_address;
GByteArray *device_mac_address;
GByteArray *cloned_mac_address;
guint32 mtu;
} NMSettingWiredPrivate;
......@@ -84,6 +85,7 @@ enum {
PROP_DUPLEX,
PROP_AUTO_NEGOTIATE,
PROP_MAC_ADDRESS,
PROP_CLONED_MAC_ADDRESS,
PROP_MTU,
LAST_PROP
......@@ -132,7 +134,15 @@ nm_setting_wired_get_mac_address (NMSettingWired *setting)
{
g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL);
return NM_SETTING_WIRED_GET_PRIVATE (setting)->mac_address;
return NM_SETTING_WIRED_GET_PRIVATE (setting)->device_mac_address;
}
const GByteArray *
nm_setting_wired_get_cloned_mac_address (NMSettingWired *setting)
{
g_return_val_if_fail (NM_IS_SETTING_WIRED (setting), NULL);
return NM_SETTING_WIRED_GET_PRIVATE (setting)->cloned_mac_address;
}
guint32
......@@ -166,7 +176,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_WIRED_ERROR,
NM_SETTING_WIRED_ERROR_INVALID_PROPERTY,
......@@ -174,6 +184,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_WIRED_ERROR,
NM_SETTING_WIRED_ERROR_INVALID_PROPERTY,
NM_SETTING_WIRED_CLONED_MAC_ADDRESS);
return FALSE;
}
return TRUE;
}
......@@ -191,8 +209,11 @@ finalize (GObject *object)
g_free (priv->port);
g_free (priv->duplex);
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);
G_OBJECT_CLASS (nm_setting_wired_parent_class)->finalize (object);
}
......@@ -219,9 +240,14 @@ set_property (GObject *object, guint prop_id,
priv->auto_negotiate = g_value_get_boolean (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);
......@@ -254,6 +280,9 @@ get_property (GObject *object, guint prop_id,
case PROP_MAC_ADDRESS:
g_value_set_boxed (value, nm_setting_wired_get_mac_address (setting));
break;
case PROP_CLONED_MAC_ADDRESS:
g_value_set_boxed (value, nm_setting_wired_get_cloned_mac_address (setting));
break;
case PROP_MTU:
g_value_set_uint (value, nm_setting_wired_get_mtu (setting));
break;
......@@ -351,20 +380,36 @@ nm_setting_wired_class_init (NMSettingWiredClass *setting_class)
* NMSettingWired:mac-address:
*
* If specified, this connection will only apply to the ethernet 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_WIRED_MAC_ADDRESS,
"MAC Address",
"Device MAC Address",
"If specified, this connection will only apply to "
"the ethernet device whose MAC address matches. "
"the ethernet 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));
/**
* NMSettingWired:cloned-mac-address:
*
* If specified, request that the 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_WIRED_CLONED_MAC_ADDRESS,
"Cloned MAC Address",
"If specified, request that the 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));
/**
* NMSettingWired:mtu:
*
......
......@@ -19,7 +19,7 @@
* 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.
*/
......@@ -57,6 +57,7 @@ GQuark nm_setting_wired_error_quark (void);
#define NM_SETTING_WIRED_DUPLEX "duplex"
#define NM_SETTING_WIRED_AUTO_NEGOTIATE "auto-negotiate"
#define NM_SETTING_WIRED_MAC_ADDRESS "mac-address"
#define NM_SETTING_WIRED_CLONED_MAC_ADDRESS "cloned-mac-address"
#define NM_SETTING_WIRED_MTU "mtu"
typedef struct {
......@@ -81,6 +82,7 @@ guint32 nm_setting_wired_get_speed (NMSettingWired *setting);
const char *nm_setting_wired_get_duplex (NMSettingWired *setting);
gboolean nm_setting_wired_get_auto_negotiate (NMSettingWired *setting);
const GByteArray *nm_setting_wired_get_mac_address (NMSettingWired *setting);
const GByteArray *nm_setting_wired_get_cloned_mac_address (NMSettingWired *setting);
guint32 nm_setting_wired_get_mtu (NMSettingWired *setting);
G_END_DECLS
......