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.
This commit is contained in:
Jiří Klimeš
2010-06-22 14:21:25 +02:00
parent a8e0c2637b
commit 1b49f941a6
28 changed files with 705 additions and 128 deletions

View File

@@ -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.");

View File

@@ -56,7 +56,8 @@ static NmcOutputField nmc_fields_setting_wired[] = {
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 (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);

View File

@@ -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>

View File

@@ -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.

View File

@@ -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

View File

@@ -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;

View File

@@ -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
@@ -169,6 +198,7 @@ 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_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));

View File

@@ -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);

View File

@@ -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;
@@ -555,6 +587,7 @@ 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_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 },
@@ -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));

View File

@@ -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);

View File

@@ -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

View File

@@ -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;

View File

@@ -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,17 +380,33 @@ 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));

View File

@@ -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

View File

@@ -86,7 +86,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 +103,7 @@ enum {
PROP_RATE,
PROP_TX_POWER,
PROP_MAC_ADDRESS,
PROP_CLONED_MAC_ADDRESS,
PROP_MTU,
PROP_SEEN_BSSIDS,
PROP_SEC,
@@ -353,7 +355,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
@@ -497,7 +507,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,
@@ -505,6 +515,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;
@@ -548,8 +566,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);
@@ -591,9 +611,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);
@@ -643,6 +668,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;
@@ -809,17 +837,33 @@ 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));

View File

@@ -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.
*/
@@ -63,6 +63,7 @@ GQuark nm_setting_wireless_error_quark (void);
#define NM_SETTING_WIRELESS_RATE "rate"
#define NM_SETTING_WIRELESS_TX_POWER "tx-power"
#define NM_SETTING_WIRELESS_MAC_ADDRESS "mac-address"
#define NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS "cloned-mac-address"
#define NM_SETTING_WIRELESS_MTU "mtu"
#define NM_SETTING_WIRELESS_SEEN_BSSIDS "seen-bssids"
#define NM_SETTING_WIRELESS_SEC "security"
@@ -93,6 +94,7 @@ const GByteArray *nm_setting_wireless_get_bssid (NMSettingWireless
guint32 nm_setting_wireless_get_rate (NMSettingWireless *setting);
guint32 nm_setting_wireless_get_tx_power (NMSettingWireless *setting);
const GByteArray *nm_setting_wireless_get_mac_address (NMSettingWireless *setting);
const GByteArray *nm_setting_wireless_get_cloned_mac_address (NMSettingWireless *setting);
guint32 nm_setting_wireless_get_mtu (NMSettingWireless *setting);
const char *nm_setting_wireless_get_security (NMSettingWireless *setting);

View File

@@ -104,7 +104,8 @@ typedef struct Supplicant {
typedef struct {
gboolean disposed;
struct ether_addr hw_addr;
struct ether_addr hw_addr; /* Currently set MAC address */
struct ether_addr perm_hw_addr; /* Permanent MAC address */
gboolean carrier;
NMNetlinkMonitor * monitor;
@@ -131,6 +132,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
enum {
PROP_0,
PROP_HW_ADDRESS,
PROP_PERM_HW_ADDRESS,
PROP_SPEED,
PROP_CARRIER,
@@ -455,6 +457,21 @@ nm_device_ethernet_get_address (NMDeviceEthernet *self, struct ether_addr *addr)
memcpy (addr, &(NM_DEVICE_ETHERNET_GET_PRIVATE (self)->hw_addr), sizeof (struct ether_addr));
}
/*
* nm_device_ethernet_get_permanent_address
*
* Get a device's permanent hardware address
*
*/
void
nm_device_ethernet_get_permanent_address (NMDeviceEthernet *self, struct ether_addr *addr)
{
g_return_if_fail (self != NULL);
g_return_if_fail (addr != NULL);
memcpy (addr, &(NM_DEVICE_ETHERNET_GET_PRIVATE (self)->perm_hw_addr), sizeof (struct ether_addr));
}
/* Returns speed in Mb/s */
static guint32
nm_device_ethernet_get_speed (NMDeviceEthernet *self)
@@ -527,10 +544,49 @@ out:
close (fd);
}
static void
real_obtain_permanent_hw_address (NMDevice *dev)
{
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (dev);
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
struct ifreq req;
struct ethtool_perm_addr *epaddr = NULL;
int fd;
fd = socket (PF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
nm_log_warn (LOGD_HW, "couldn't open control socket.");
return;
}
/* Get permanent MAC address */
memset (&req, 0, sizeof (struct ifreq));
strncpy (req.ifr_name, nm_device_get_iface (dev), IFNAMSIZ);
epaddr = (struct ethtool_perm_addr *) g_malloc0 (sizeof(struct ethtool_perm_addr) + ETH_ALEN);
epaddr->cmd = ETHTOOL_GPERMADDR;
epaddr->size = ETH_ALEN;
req.ifr_data = epaddr;
errno = 0;
if (ioctl (fd, SIOCETHTOOL, &req) < 0) {
nm_log_err (LOGD_HW | LOGD_ETHER, "SIOCETHTOOL failed: %d; unable to get permanent MAC address for %s",
errno, nm_device_get_iface (dev));
goto out;
}
if (memcmp (&priv->perm_hw_addr, epaddr->data, sizeof (struct ether_addr))) {
memcpy (&priv->perm_hw_addr, epaddr->data, sizeof (struct ether_addr));
g_object_notify (G_OBJECT (dev), NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS);
}
out:
g_free (epaddr);
close (fd);
}
static guint32
real_get_generic_capabilities (NMDevice *dev)
{
NMDeviceEthernet * self = NM_DEVICE_ETHERNET (dev);
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (dev);
guint32 caps = NM_DEVICE_CAP_NONE;
/* cipsec devices are also explicitly unsupported at this time */
@@ -1218,6 +1274,45 @@ supplicant_interface_init (NMDeviceEthernet *self)
return TRUE;
}
static NMActStageReturn
real_act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
{
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (dev);
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
NMActRequest *req;
NMSettingWired *s_wired;
const GByteArray *cloned_mac;
NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
req = nm_device_get_act_request (NM_DEVICE (self));
g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE);
s_wired = NM_SETTING_WIRED (device_get_setting (dev, NM_TYPE_SETTING_WIRED));
g_assert (s_wired);
cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired);
if (cloned_mac) {
char *mac_str = NULL;
mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", cloned_mac->data[0], cloned_mac->data[1], cloned_mac->data[2],
cloned_mac->data[3], cloned_mac->data[4], cloned_mac->data[5]);
real_hw_take_down (dev);
if (nm_system_device_set_mac (nm_device_get_iface (dev), (struct ether_addr *) cloned_mac->data)) {
/* MAC address succesfully spoofed on interface, set it to hw_addr too */
memcpy (priv->hw_addr.ether_addr_octet, cloned_mac->data, ETH_ALEN);
nm_log_info (LOGD_DEVICE | LOGD_ETHER, "cloned MAC %s set to %s", mac_str, nm_device_get_iface (dev));
} else {
nm_log_warn (LOGD_DEVICE | LOGD_ETHER, "failed to set cloned MAC %s to %s", mac_str, nm_device_get_iface (dev));
}
real_hw_bring_up (dev, NULL);
g_free (mac_str);
}
return ret;
}
static NMActStageReturn
nm_8021x_stage2_config (NMDeviceEthernet *self, NMDeviceStateReason *reason)
{
@@ -1447,6 +1542,7 @@ static void
real_deactivate_quickly (NMDevice *device)
{
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device);
char *mac_str = NULL;
if (priv->pending_ip4_config) {
g_object_unref (priv->pending_ip4_config);
@@ -1459,6 +1555,22 @@ real_deactivate_quickly (NMDevice *device)
}
supplicant_interface_release (NM_DEVICE_ETHERNET (device));
/* Set permanent MAC address back to the interface */
mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
priv->perm_hw_addr.ether_addr_octet[0], priv->perm_hw_addr.ether_addr_octet[1], priv->perm_hw_addr.ether_addr_octet[2],
priv->perm_hw_addr.ether_addr_octet[3], priv->perm_hw_addr.ether_addr_octet[4], priv->perm_hw_addr.ether_addr_octet[5]);
real_hw_take_down (device);
if (nm_system_device_set_mac (nm_device_get_iface (device), &priv->perm_hw_addr)) {
/* MAC address succesfully spoofed on interface, set it to hw_addr too */
memcpy (priv->hw_addr.ether_addr_octet, &priv->perm_hw_addr, ETH_ALEN);
nm_log_info (LOGD_DEVICE | LOGD_ETHER, "permanent MAC address %s set back to %s", mac_str, nm_device_get_iface (device));
} else {
nm_log_warn (LOGD_DEVICE | LOGD_ETHER, "failed to set permanent MAC address %s back to %s", mac_str, nm_device_get_iface (device));
}
real_hw_bring_up (device, NULL);
g_free (mac_str);
}
static gboolean
@@ -1501,7 +1613,7 @@ real_check_connection_compatible (NMDevice *device,
const GByteArray *mac;
mac = nm_setting_wired_get_mac_address (s_wired);
if (mac && memcmp (mac->data, &(priv->hw_addr.ether_addr_octet), ETH_ALEN)) {
if (mac && memcmp (mac->data, &(priv->perm_hw_addr.ether_addr_octet), ETH_ALEN)) {
g_set_error (error,
NM_ETHERNET_ERROR, NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE,
"The connection's MAC address did not match this device.");
@@ -1521,7 +1633,7 @@ spec_match_list (NMDevice *device, const GSList *specs)
char *hwaddr;
gboolean matched;
nm_device_ethernet_get_address (NM_DEVICE_ETHERNET (device), &ether);
nm_device_ethernet_get_permanent_address (NM_DEVICE_ETHERNET (device), &ether);
hwaddr = nm_ether_ntop (&ether);
matched = nm_match_spec_hwaddr (specs, hwaddr);
g_free (hwaddr);
@@ -1543,7 +1655,7 @@ wired_match_config (NMDevice *self, NMConnection *connection)
/* MAC address check */
s_ether = nm_setting_wired_get_mac_address (s_wired);
if (s_ether) {
nm_device_ethernet_get_address (NM_DEVICE_ETHERNET (self), &ether);
nm_device_ethernet_get_permanent_address (NM_DEVICE_ETHERNET (self), &ether);
if (memcmp (s_ether->data, ether.ether_addr_octet, ETH_ALEN))
return FALSE;
@@ -1770,6 +1882,10 @@ get_property (GObject *object, guint prop_id,
nm_device_ethernet_get_address (self, &hw_addr);
g_value_take_string (value, nm_ether_ntop (&hw_addr));
break;
case PROP_PERM_HW_ADDRESS:
nm_device_ethernet_get_permanent_address (self, &hw_addr);
g_value_take_string (value, nm_ether_ntop (&hw_addr));
break;
case PROP_SPEED:
g_value_set_uint (value, nm_device_ethernet_get_speed (self));
break;
@@ -1816,11 +1932,13 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
parent_class->take_down = real_take_down;
parent_class->can_interrupt_activation = real_can_interrupt_activation;
parent_class->update_hw_address = real_update_hw_address;
parent_class->obtain_permanent_hw_address = real_obtain_permanent_hw_address;
parent_class->get_best_auto_connection = real_get_best_auto_connection;
parent_class->is_available = real_is_available;
parent_class->connection_secrets_updated = real_connection_secrets_updated;
parent_class->check_connection_compatible = real_check_connection_compatible;
parent_class->act_stage1_prepare = real_act_stage1_prepare;
parent_class->act_stage2_config = real_act_stage2_config;
parent_class->act_stage3_ip4_config_start = real_act_stage3_ip4_config_start;
parent_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config;
@@ -1832,8 +1950,16 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
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));
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));

View File

@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2005 - 2008 Red Hat, Inc.
* Copyright (C) 2005 - 2010 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
@@ -37,6 +37,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"
@@ -62,6 +63,9 @@ NMDevice *nm_device_ethernet_new (const char *udi,
void nm_device_ethernet_get_address (NMDeviceEthernet *dev,
struct ether_addr *addr);
void nm_device_ethernet_get_permanent_address (NMDeviceEthernet *dev,
struct ether_addr *addr);
G_END_DECLS
#endif /* NM_DEVICE_ETHERNET_H */

View File

@@ -30,6 +30,9 @@
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include <linux/sockios.h>
#include <linux/ethtool.h>
#include <sys/ioctl.h>
#include "nm-glib-compat.h"
#include "nm-device.h"
@@ -78,6 +81,7 @@ G_DEFINE_TYPE_EXTENDED (NMDeviceWifi, nm_device_wifi, NM_TYPE_DEVICE, 0,
enum {
PROP_0,
PROP_HW_ADDRESS,
PROP_PERM_HW_ADDRESS,
PROP_MODE,
PROP_BITRATE,
PROP_ACTIVE_ACCESS_POINT,
@@ -142,7 +146,9 @@ typedef struct Supplicant {
struct _NMDeviceWifiPrivate {
gboolean disposed;
struct ether_addr hw_addr;
struct ether_addr hw_addr; /* Currently set MAC address */
struct ether_addr perm_hw_addr; /* Permanent MAC address */
gboolean perm_hw_addr_is_set;
/* Legacy rfkill for ipw2x00; will be fixed with 2.6.33 kernel */
char * ipw_rfkill_path;
@@ -1129,6 +1135,7 @@ real_deactivate_quickly (NMDevice *dev)
NMDeviceWifi *self = NM_DEVICE_WIFI (dev);
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
NMAccessPoint *orig_ap = nm_device_wifi_get_activation_ap (self);
char *mac_str = NULL;
cleanup_association_attempt (self, TRUE);
@@ -1148,6 +1155,22 @@ real_deactivate_quickly (NMDevice *dev)
priv->ap_list = g_slist_remove (priv->ap_list, orig_ap);
g_object_unref (orig_ap);
}
/* Set permanent MAC address back to the interface */
mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
priv->perm_hw_addr.ether_addr_octet[0], priv->perm_hw_addr.ether_addr_octet[1], priv->perm_hw_addr.ether_addr_octet[2],
priv->perm_hw_addr.ether_addr_octet[3], priv->perm_hw_addr.ether_addr_octet[4], priv->perm_hw_addr.ether_addr_octet[5]);
real_hw_take_down (dev);
if (nm_system_device_set_mac (nm_device_get_iface (dev), &priv->perm_hw_addr)) {
/* MAC address succesfully spoofed on interface, set it to hw_addr too */
memcpy (priv->hw_addr.ether_addr_octet, &priv->perm_hw_addr, ETH_ALEN);
nm_log_info (LOGD_DEVICE | LOGD_ETHER, "permanent MAC address %s set back to %s", mac_str, nm_device_get_iface (dev));
} else {
nm_log_warn (LOGD_DEVICE | LOGD_ETHER, "failed to set permanent MAC address %s back to %s", mac_str, nm_device_get_iface (dev));
}
real_hw_bring_up (dev, NULL);
g_free (mac_str);
}
static void
@@ -1190,7 +1213,7 @@ real_check_connection_compatible (NMDevice *device,
}
mac = nm_setting_wireless_get_mac_address (s_wireless);
if (mac && memcmp (mac->data, &(priv->hw_addr.ether_addr_octet), ETH_ALEN)) {
if (mac && memcmp (mac->data, &(priv->perm_hw_addr.ether_addr_octet), ETH_ALEN)) {
g_set_error (error,
NM_WIFI_ERROR, NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE,
"The connection's MAC address did not match this device.");
@@ -1308,6 +1331,25 @@ nm_device_wifi_get_address (NMDeviceWifi *self,
memcpy (addr, &(priv->hw_addr), sizeof (struct ether_addr));
}
/*
* nm_device_wifi_get_permanent_address
*
* Get a device's permanent hardware address
*
*/
void
nm_device_wifi_get_permanent_address (NMDeviceWifi *self,
struct ether_addr *addr)
{
NMDeviceWifiPrivate *priv;
g_return_if_fail (self != NULL);
g_return_if_fail (addr != NULL);
priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
memcpy (addr, &(priv->perm_hw_addr), sizeof (struct ether_addr));
}
static void
nm_device_wifi_ap_list_print (NMDeviceWifi *self)
{
@@ -2949,6 +2991,51 @@ out:
close (fd);
}
static void
real_obtain_permanent_hw_address (NMDevice *dev)
{
NMDeviceWifi *self = NM_DEVICE_WIFI (dev);
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
struct ifreq req;
struct ethtool_perm_addr *epaddr = NULL;
int fd;
fd = socket (PF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
nm_log_err (LOGD_HW, "could not open control socket.");
return;
}
/* Get permanent MAC address */
memset (&req, 0, sizeof (struct ifreq));
strncpy (req.ifr_name, nm_device_get_iface (dev), IFNAMSIZ);
epaddr = (struct ethtool_perm_addr *) g_malloc0 (sizeof(struct ethtool_perm_addr) + ETH_ALEN);
epaddr->cmd = ETHTOOL_GPERMADDR;
epaddr->size = ETH_ALEN;
req.ifr_data = (void *) epaddr;
errno = 0;
if (ioctl (fd, SIOCETHTOOL, &req) < 0) {
nm_log_err (LOGD_HW | LOGD_ETHER, "SIOCETHTOOL failed: %d; unable to get permanent MAC address for %s",
errno, nm_device_get_iface (dev));
nm_log_warn (LOGD_HW | LOGD_ETHER, "Using current address as permanent address for %s",
nm_device_get_iface (dev));
memcpy (&priv->perm_hw_addr, &priv->hw_addr, sizeof (struct ether_addr));
g_object_notify (G_OBJECT (dev), NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS);
goto out;
}
if (memcmp (&priv->perm_hw_addr, epaddr->data, sizeof (struct ether_addr))) {
memcpy (&priv->perm_hw_addr, epaddr->data, sizeof (struct ether_addr));
g_object_notify (G_OBJECT (dev), NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS);
}
out:
g_free (epaddr);
close (fd);
}
static NMActStageReturn
real_act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
@@ -2958,8 +3045,38 @@ real_act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
NMAccessPoint *ap = NULL;
NMActRequest *req;
NMConnection *connection;
NMSettingWireless *s_wireless;
const GByteArray *cloned_mac;
GSList *iter;
req = nm_device_get_act_request (NM_DEVICE (self));
g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE);
connection = nm_act_request_get_connection (req);
g_return_val_if_fail (connection != NULL, NM_ACT_STAGE_RETURN_FAILURE);
/* Set spoof MAC to the interface */
s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
g_assert (s_wireless);
cloned_mac = nm_setting_wireless_get_cloned_mac_address (s_wireless);
if (cloned_mac) {
char *mac_str = NULL;
mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", cloned_mac->data[0], cloned_mac->data[1], cloned_mac->data[2],
cloned_mac->data[3], cloned_mac->data[4], cloned_mac->data[5]);
real_hw_take_down (dev);
if (nm_system_device_set_mac (nm_device_get_iface (dev), (struct ether_addr *) cloned_mac->data)) {
/* MAC address succesfully spoofed on interface, set it to hw_addr too */
memcpy (priv->hw_addr.ether_addr_octet, cloned_mac->data, ETH_ALEN);
nm_log_info (LOGD_DEVICE | LOGD_ETHER, "cloned MAC %s set to %s", mac_str, nm_device_get_iface (dev));
} else {
nm_log_warn (LOGD_DEVICE | LOGD_ETHER, "failed to set cloned MAC %s to %s", mac_str, nm_device_get_iface (dev));
}
real_hw_bring_up (dev, NULL);
g_free (mac_str);
}
/* If the user is trying to connect to an AP that NM doesn't yet know about
* (hidden network or something), create an fake AP from the security
* settings in the connection to use until the AP is recognized from the
@@ -2969,12 +3086,6 @@ real_act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
if (ap)
goto done;
req = nm_device_get_act_request (NM_DEVICE (self));
g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE);
connection = nm_act_request_get_connection (req);
g_return_val_if_fail (connection != NULL, NM_ACT_STAGE_RETURN_FAILURE);
/* Find a compatible AP in the scan list */
for (iter = priv->ap_list; iter; iter = g_slist_next (iter)) {
NMAccessPoint *candidate = NM_AP (iter->data);
@@ -3430,7 +3541,7 @@ spec_match_list (NMDevice *device, const GSList *specs)
char *hwaddr;
gboolean matched;
nm_device_wifi_get_address (NM_DEVICE_WIFI (device), &ether);
nm_device_wifi_get_permanent_address (NM_DEVICE_WIFI (device), &ether);
hwaddr = nm_ether_ntop (&ether);
matched = nm_match_spec_hwaddr (specs, hwaddr);
g_free (hwaddr);
@@ -3696,6 +3807,10 @@ get_property (GObject *object, guint prop_id,
nm_device_wifi_get_address (device, &hw_addr);
g_value_take_string (value, nm_ether_ntop (&hw_addr));
break;
case PROP_PERM_HW_ADDRESS:
nm_device_wifi_get_permanent_address (device, &hw_addr);
g_value_take_string (value, nm_ether_ntop (&hw_addr));
break;
case PROP_MODE:
g_value_set_uint (value, nm_device_wifi_get_mode (device));
break;
@@ -3763,6 +3878,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
parent_class->bring_up = real_bring_up;
parent_class->take_down = real_take_down;
parent_class->update_hw_address = real_update_hw_address;
parent_class->obtain_permanent_hw_address = real_obtain_permanent_hw_address;
parent_class->get_best_auto_connection = real_get_best_auto_connection;
parent_class->is_available = real_is_available;
parent_class->connection_secrets_updated = real_connection_secrets_updated;
@@ -3783,8 +3899,15 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
/* Properties */
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));
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));

View File

@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2005 - 2008 Red Hat, Inc.
* Copyright (C) 2005 - 2010 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
@@ -43,6 +43,7 @@ G_BEGIN_DECLS
#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"
@@ -85,16 +86,15 @@ NMDevice *nm_device_wifi_new (const char *udi,
const char *iface,
const char *driver);
void nm_device_wifi_get_address (NMDeviceWifi *dev,
struct ether_addr *addr);
void nm_device_wifi_get_address (NMDeviceWifi *dev, struct ether_addr *addr);
void nm_device_wifi_get_bssid (NMDeviceWifi *dev,
struct ether_addr *bssid);
void nm_device_wifi_get_permanent_address (NMDeviceWifi *dev, struct ether_addr *addr);
void nm_device_wifi_get_bssid (NMDeviceWifi *dev, struct ether_addr *bssid);
const GByteArray * nm_device_wifi_get_ssid (NMDeviceWifi *self);
gboolean nm_device_wifi_set_mode (NMDeviceWifi *self,
const NM80211Mode mode);
gboolean nm_device_wifi_set_mode (NMDeviceWifi *self, const NM80211Mode mode);
NM80211Mode nm_device_wifi_get_mode (NMDeviceWifi *self);

View File

@@ -283,6 +283,9 @@ constructor (GType type,
if (NM_DEVICE_GET_CLASS (dev)->update_hw_address)
NM_DEVICE_GET_CLASS (dev)->update_hw_address (dev);
if (NM_DEVICE_GET_CLASS (dev)->obtain_permanent_hw_address)
NM_DEVICE_GET_CLASS (dev)->obtain_permanent_hw_address (dev);
priv->dhcp_manager = nm_dhcp_manager_get ();
update_accept_ra_save (dev);

View File

@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2005 - 2008 Red Hat, Inc.
* Copyright (C) 2005 - 2010 Red Hat, Inc.
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
@@ -72,6 +72,7 @@ typedef struct {
void (*take_down) (NMDevice *self);
void (* update_hw_address) (NMDevice *self);
void (* obtain_permanent_hw_address) (NMDevice *self);
guint32 (* get_type_capabilities) (NMDevice *self);
guint32 (* get_generic_capabilities) (NMDevice *self);

View File

@@ -772,6 +772,48 @@ nm_system_device_set_mtu (const char *iface, guint32 mtu)
return success;
}
gboolean
nm_system_device_set_mac (const char *iface, const struct ether_addr *mac)
{
struct rtnl_link *old;
struct rtnl_link *new;
gboolean success = FALSE;
struct nl_handle *nlh;
int iface_idx;
struct nl_addr *addr = NULL;
g_return_val_if_fail (iface != NULL, FALSE);
g_return_val_if_fail (mac != NULL, FALSE);
new = rtnl_link_alloc ();
if (!new)
return FALSE;
iface_idx = nm_netlink_iface_to_index (iface);
old = nm_netlink_index_to_rtnl_link (iface_idx);
if (old) {
addr = nl_addr_build (AF_LLC, (void *) mac, ETH_ALEN);
if (!addr) {
char *mac_str;
mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", mac->ether_addr_octet[0], mac->ether_addr_octet[1], mac->ether_addr_octet[2],
mac->ether_addr_octet[3], mac->ether_addr_octet[4], mac->ether_addr_octet[5]);
nm_log_err (LOGD_DEVICE, "(%s): could not allocate memory for MAC address (%s)", iface, mac_str);
g_free (mac_str);
return FALSE;
}
rtnl_link_set_addr (new, addr);
nlh = nm_netlink_get_default_handle ();
if (nlh) {
rtnl_link_change (nlh, old, new, 0);
success = TRUE;
}
rtnl_link_put (old);
}
rtnl_link_put (new);
return success;
}
static struct rtnl_route *
add_ip4_route_to_gateway (const char *iface, guint32 gw, guint32 mss)
{

View File

@@ -15,7 +15,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2004 - 2008 Red Hat, Inc.
* Copyright (C) 2004 - 2010 Red Hat, Inc.
* Copyright (C) 2005 - 2008 Novell, Inc.
*/
@@ -25,6 +25,8 @@
#include <netlink/route/rtnl.h>
#include <netlink/route/route.h>
#include <net/ethernet.h>
#include <glib.h>
#include "nm-device.h"
#include "nm-ip4-config.h"
@@ -80,5 +82,6 @@ gboolean nm_system_device_is_up (NMDevice *device);
gboolean nm_system_device_is_up_with_iface (const char *iface);
gboolean nm_system_device_set_mtu (const char *iface, guint32 mtu);
gboolean nm_system_device_set_mac (const char *iface, const struct ether_addr *mac);
#endif

View File

@@ -185,7 +185,7 @@ make_connection_setting (const char *file,
}
static gboolean
read_mac_address (shvarFile *ifcfg, GByteArray **array, GError **error)
read_mac_address (shvarFile *ifcfg, const char *key, GByteArray **array, GError **error)
{
char *value = NULL;
struct ether_addr *mac;
@@ -196,7 +196,7 @@ read_mac_address (shvarFile *ifcfg, GByteArray **array, GError **error)
g_return_val_if_fail (error != NULL, FALSE);
g_return_val_if_fail (*error == NULL, FALSE);
value = svGetValue (ifcfg, "HWADDR", FALSE);
value = svGetValue (ifcfg, key, FALSE);
if (!value || !strlen (value)) {
g_free (value);
return TRUE;
@@ -206,7 +206,7 @@ read_mac_address (shvarFile *ifcfg, GByteArray **array, GError **error)
if (!mac) {
g_free (value);
g_set_error (error, ifcfg_plugin_error_quark (), 0,
"The MAC address '%s' was invalid.", value);
"%s: the MAC address '%s' was invalid.", key, value);
return FALSE;
}
@@ -294,7 +294,7 @@ fill_ip4_setting_from_ibft (shvarFile *ifcfg,
goto done;
}
if (!read_mac_address (ifcfg, &ifcfg_mac, error))
if (!read_mac_address (ifcfg, "HWADDR", &ifcfg_mac, error))
goto done;
/* Ensure we got a MAC */
if (!ifcfg_mac) {
@@ -2655,7 +2655,7 @@ make_wireless_setting (shvarFile *ifcfg,
s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ());
if (read_mac_address (ifcfg, &array, error)) {
if (read_mac_address (ifcfg, "HWADDR", &array, error)) {
if (array) {
g_object_set (s_wireless, NM_SETTING_WIRELESS_MAC_ADDRESS, array, NULL);
@@ -2678,6 +2678,14 @@ make_wireless_setting (shvarFile *ifcfg,
return NULL;
}
array = NULL;
if (read_mac_address (ifcfg, "MACADDR", &array, error)) {
if (array) {
g_object_set (s_wireless, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, array, NULL);
g_byte_array_free (array, TRUE);
}
}
value = svGetValue (ifcfg, "ESSID", TRUE);
if (value) {
gsize ssid_len = 0, value_len = strlen (value);
@@ -2945,7 +2953,7 @@ make_wired_setting (shvarFile *ifcfg,
g_free (value);
}
if (read_mac_address (ifcfg, &mac, error)) {
if (read_mac_address (ifcfg, "HWADDR", &mac, error)) {
if (mac) {
g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL);
@@ -2968,6 +2976,14 @@ make_wired_setting (shvarFile *ifcfg,
s_wired = NULL;
}
mac = NULL;
if (read_mac_address (ifcfg, "MACADDR", &mac, error)) {
if (mac) {
g_object_set (s_wired, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, mac, NULL);
g_byte_array_free (mac, TRUE);
}
}
value = svGetValue (ifcfg, "KEY_MGMT", FALSE);
if (value) {
if (!strcmp (value, "IEEE8021X")) {

View File

@@ -704,7 +704,7 @@ write_wireless_setting (NMConnection *connection,
{
NMSettingWireless *s_wireless;
char *tmp, *tmp2;
const GByteArray *ssid, *mac, *bssid;
const GByteArray *ssid, *device_mac, *cloned_mac, *bssid;
const char *mode;
char buf[33];
guint32 mtu, chan, i;
@@ -718,15 +718,25 @@ write_wireless_setting (NMConnection *connection,
}
svSetValue (ifcfg, "HWADDR", NULL, FALSE);
mac = nm_setting_wireless_get_mac_address (s_wireless);
if (mac) {
device_mac = nm_setting_wireless_get_mac_address (s_wireless);
if (device_mac) {
tmp = 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->data[0], device_mac->data[1], device_mac->data[2],
device_mac->data[3], device_mac->data[4], device_mac->data[5]);
svSetValue (ifcfg, "HWADDR", tmp, FALSE);
g_free (tmp);
}
svSetValue (ifcfg, "MACADDR", NULL, FALSE);
cloned_mac = nm_setting_wireless_get_cloned_mac_address (s_wireless);
if (cloned_mac) {
tmp = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
cloned_mac->data[0], cloned_mac->data[1], cloned_mac->data[2],
cloned_mac->data[3], cloned_mac->data[4], cloned_mac->data[5]);
svSetValue (ifcfg, "MACADDR", tmp, FALSE);
g_free (tmp);
}
svSetValue (ifcfg, "MTU", NULL, FALSE);
mtu = nm_setting_wireless_get_mtu (s_wireless);
if (mtu) {
@@ -823,7 +833,7 @@ static gboolean
write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
{
NMSettingWired *s_wired;
const GByteArray *mac;
const GByteArray *device_mac, *cloned_mac;
char *tmp;
guint32 mtu;
@@ -834,15 +844,24 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
return FALSE;
}
mac = nm_setting_wired_get_mac_address (s_wired);
if (mac) {
device_mac = nm_setting_wired_get_mac_address (s_wired);
if (device_mac) {
tmp = 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->data[0], device_mac->data[1], device_mac->data[2],
device_mac->data[3], device_mac->data[4], device_mac->data[5]);
svSetValue (ifcfg, "HWADDR", tmp, FALSE);
g_free (tmp);
}
cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired);
if (cloned_mac) {
tmp = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
cloned_mac->data[0], cloned_mac->data[1], cloned_mac->data[2],
cloned_mac->data[3], cloned_mac->data[4], cloned_mac->data[5]);
svSetValue (ifcfg, "MACADDR", tmp, FALSE);
g_free (tmp);
}
svSetValue (ifcfg, "MTU", NULL, FALSE);
mtu = nm_setting_wired_get_mtu (s_wired);
if (mtu) {

View File

@@ -773,10 +773,18 @@ static KeyParser key_parsers[] = {
NM_SETTING_WIRED_MAC_ADDRESS,
TRUE,
mac_address_parser },
{ NM_SETTING_WIRED_SETTING_NAME,
NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
TRUE,
mac_address_parser },
{ NM_SETTING_WIRELESS_SETTING_NAME,
NM_SETTING_WIRELESS_MAC_ADDRESS,
TRUE,
mac_address_parser },
{ NM_SETTING_WIRELESS_SETTING_NAME,
NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS,
TRUE,
mac_address_parser },
{ NM_SETTING_WIRELESS_SETTING_NAME,
NM_SETTING_WIRELESS_BSSID,
TRUE,

View File

@@ -488,9 +488,15 @@ static KeyWriter key_writers[] = {
{ NM_SETTING_WIRED_SETTING_NAME,
NM_SETTING_WIRED_MAC_ADDRESS,
mac_address_writer },
{ NM_SETTING_WIRED_SETTING_NAME,
NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
mac_address_writer },
{ NM_SETTING_WIRELESS_SETTING_NAME,
NM_SETTING_WIRELESS_MAC_ADDRESS,
mac_address_writer },
{ NM_SETTING_WIRELESS_SETTING_NAME,
NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS,
mac_address_writer },
{ NM_SETTING_WIRELESS_SETTING_NAME,
NM_SETTING_WIRELESS_BSSID,
mac_address_writer },