mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-01 15:20:11 +01:00
core: consolidate and clean up MAC cloning code
- Just use a byte array to old MAC addresses so we don't need to use .ether_addr_octet everywhere - Consolidate setting the current MAC address into one location - Make sure that if the GPERMADDR call fails we use the current MAC (this wasn't done for wired devices) - Make log messages consistent
This commit is contained in:
parent
3beea85a0b
commit
88eb6ced3f
4 changed files with 181 additions and 186 deletions
|
|
@ -104,8 +104,8 @@ typedef struct Supplicant {
|
|||
typedef struct {
|
||||
gboolean disposed;
|
||||
|
||||
struct ether_addr hw_addr; /* Currently set MAC address */
|
||||
struct ether_addr perm_hw_addr; /* Permanent MAC address */
|
||||
guint8 hw_addr[ETH_ALEN]; /* Currently set MAC address */
|
||||
guint8 perm_hw_addr[ETH_ALEN]; /* Currently set MAC address */
|
||||
gboolean carrier;
|
||||
|
||||
NMNetlinkMonitor * monitor;
|
||||
|
|
@ -451,25 +451,13 @@ nm_device_ethernet_new (const char *udi,
|
|||
void
|
||||
nm_device_ethernet_get_address (NMDeviceEthernet *self, struct ether_addr *addr)
|
||||
{
|
||||
NMDeviceEthernetPrivate *priv;
|
||||
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (addr != NULL);
|
||||
|
||||
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));
|
||||
priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
memcpy (addr, &priv->hw_addr, sizeof (priv->hw_addr));
|
||||
}
|
||||
|
||||
/* Returns speed in Mb/s */
|
||||
|
|
@ -512,11 +500,66 @@ out:
|
|||
return speed;
|
||||
}
|
||||
|
||||
static void
|
||||
_update_hw_addr (NMDeviceEthernet *self, const guint8 *addr)
|
||||
{
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
|
||||
g_return_if_fail (addr != NULL);
|
||||
|
||||
if (memcmp (&priv->hw_addr, addr, ETH_ALEN)) {
|
||||
memcpy (&priv->hw_addr, addr, ETH_ALEN);
|
||||
g_object_notify (G_OBJECT (self), NM_DEVICE_ETHERNET_HW_ADDRESS);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_set_hw_addr (NMDeviceEthernet *self, const guint8 *addr, const char *detail)
|
||||
{
|
||||
NMDevice *dev = NM_DEVICE (self);
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
const char *iface;
|
||||
char *mac_str = NULL;
|
||||
gboolean success = FALSE;
|
||||
|
||||
g_return_val_if_fail (addr != NULL, FALSE);
|
||||
|
||||
iface = nm_device_get_iface (dev);
|
||||
|
||||
mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
|
||||
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
|
||||
|
||||
/* Do nothing if current MAC is same */
|
||||
if (!memcmp (&priv->hw_addr, addr, ETH_ALEN)) {
|
||||
nm_log_dbg (LOGD_DEVICE | LOGD_ETHER, "(%s): no MAC address change needed",
|
||||
iface, detail, mac_str);
|
||||
g_free (mac_str);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Can't change MAC address while device is up */
|
||||
real_hw_take_down (dev);
|
||||
|
||||
success = nm_system_device_set_mac (iface, (struct ether_addr *) addr);
|
||||
if (success) {
|
||||
/* MAC address succesfully changed; update the current MAC to match */
|
||||
_update_hw_addr (self, addr);
|
||||
nm_log_info (LOGD_DEVICE | LOGD_ETHER, "(%s): %s MAC address to %s",
|
||||
iface, detail, mac_str);
|
||||
} else {
|
||||
nm_log_warn (LOGD_DEVICE | LOGD_ETHER, "(%s): failed to %s MAC address to %s",
|
||||
iface, detail, mac_str);
|
||||
}
|
||||
real_hw_bring_up (dev, NULL);
|
||||
g_free (mac_str);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static void
|
||||
real_update_hw_address (NMDevice *dev)
|
||||
{
|
||||
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (dev);
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
struct ifreq req;
|
||||
int fd;
|
||||
|
||||
|
|
@ -528,19 +571,15 @@ real_update_hw_address (NMDevice *dev)
|
|||
|
||||
memset (&req, 0, sizeof (struct ifreq));
|
||||
strncpy (req.ifr_name, nm_device_get_iface (dev), IFNAMSIZ);
|
||||
|
||||
errno = 0;
|
||||
if (ioctl (fd, SIOCGIFHWADDR, &req) < 0) {
|
||||
nm_log_err (LOGD_HW | LOGD_ETHER,
|
||||
"(%s) error getting hardware address: %d",
|
||||
"(%s) failed to read hardware address (error %d)",
|
||||
nm_device_get_iface (dev), errno);
|
||||
goto out;
|
||||
}
|
||||
} else
|
||||
_update_hw_addr (self, (const guint8 *) &req.ifr_hwaddr.sa_data);
|
||||
|
||||
if (memcmp (&priv->hw_addr, &req.ifr_hwaddr.sa_data, sizeof (struct ether_addr))) {
|
||||
memcpy (&priv->hw_addr, &req.ifr_hwaddr.sa_data, sizeof (struct ether_addr));
|
||||
g_object_notify (G_OBJECT (dev), NM_DEVICE_ETHERNET_HW_ADDRESS);
|
||||
}
|
||||
|
||||
out:
|
||||
close (fd);
|
||||
}
|
||||
|
||||
|
|
@ -551,7 +590,7 @@ real_update_permanent_hw_address (NMDevice *dev)
|
|||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
struct ifreq req;
|
||||
struct ethtool_perm_addr *epaddr = NULL;
|
||||
int fd;
|
||||
int fd, ret;
|
||||
|
||||
fd = socket (PF_INET, SOCK_DGRAM, 0);
|
||||
if (fd < 0) {
|
||||
|
|
@ -562,24 +601,26 @@ real_update_permanent_hw_address (NMDevice *dev)
|
|||
/* 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 = g_malloc0 (sizeof (struct ethtool_perm_addr) + ETH_ALEN);
|
||||
epaddr->cmd = ETHTOOL_GPERMADDR;
|
||||
epaddr->size = ETH_ALEN;
|
||||
req.ifr_data = epaddr;
|
||||
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));
|
||||
goto out;
|
||||
ret = ioctl (fd, SIOCETHTOOL, &req);
|
||||
if (ret < 0) {
|
||||
nm_log_err (LOGD_HW | LOGD_ETHER, "(%s): unable to read permanent MAC address (error %d)",
|
||||
nm_device_get_iface (dev), errno);
|
||||
/* Fall back to current address */
|
||||
memcpy (epaddr->data, &priv->hw_addr, ETH_ALEN);
|
||||
}
|
||||
|
||||
if (memcmp (&priv->perm_hw_addr, epaddr->data, sizeof (struct ether_addr))) {
|
||||
memcpy (&priv->perm_hw_addr, epaddr->data, sizeof (struct ether_addr));
|
||||
if (memcmp (&priv->perm_hw_addr, epaddr->data, ETH_ALEN)) {
|
||||
memcpy (&priv->perm_hw_addr, epaddr->data, ETH_ALEN);
|
||||
g_object_notify (G_OBJECT (dev), NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS);
|
||||
}
|
||||
|
||||
out:
|
||||
g_free (epaddr);
|
||||
close (fd);
|
||||
}
|
||||
|
||||
|
|
@ -666,7 +707,7 @@ real_get_best_auto_connection (NMDevice *dev,
|
|||
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, ETH_ALEN))
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1278,7 +1319,6 @@ 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;
|
||||
|
|
@ -1292,23 +1332,10 @@ real_act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
|
|||
s_wired = NM_SETTING_WIRED (device_get_setting (dev, NM_TYPE_SETTING_WIRED));
|
||||
g_assert (s_wired);
|
||||
|
||||
/* Set device MAC address if the connection wants to change it */
|
||||
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);
|
||||
}
|
||||
if (cloned_mac && (cloned_mac->len == ETH_ALEN))
|
||||
_set_hw_addr (self, (const guint8 *) cloned_mac->data, "set");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1541,8 +1568,8 @@ real_act_stage4_get_ip4_config (NMDevice *device,
|
|||
static void
|
||||
real_deactivate_quickly (NMDevice *device)
|
||||
{
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device);
|
||||
char *mac_str = NULL;
|
||||
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device);
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
|
||||
if (priv->pending_ip4_config) {
|
||||
g_object_unref (priv->pending_ip4_config);
|
||||
|
|
@ -1554,23 +1581,10 @@ real_deactivate_quickly (NMDevice *device)
|
|||
priv->ppp_manager = NULL;
|
||||
}
|
||||
|
||||
supplicant_interface_release (NM_DEVICE_ETHERNET (device));
|
||||
supplicant_interface_release (self);
|
||||
|
||||
/* 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);
|
||||
/* Reset MAC address back to permanent address */
|
||||
_set_hw_addr (self, priv->perm_hw_addr, "reset");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -1613,7 +1627,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->perm_hw_addr.ether_addr_octet), ETH_ALEN)) {
|
||||
if (mac && memcmp (mac->data, &priv->perm_hw_addr, ETH_ALEN)) {
|
||||
g_set_error (error,
|
||||
NM_ETHERNET_ERROR, NM_ETHERNET_ERROR_CONNECTION_INCOMPATIBLE,
|
||||
"The connection's MAC address did not match this device.");
|
||||
|
|
@ -1629,12 +1643,11 @@ real_check_connection_compatible (NMDevice *device,
|
|||
static gboolean
|
||||
spec_match_list (NMDevice *device, const GSList *specs)
|
||||
{
|
||||
struct ether_addr ether;
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device);
|
||||
char *hwaddr;
|
||||
gboolean matched;
|
||||
|
||||
nm_device_ethernet_get_permanent_address (NM_DEVICE_ETHERNET (device), ðer);
|
||||
hwaddr = nm_ether_ntop (ðer);
|
||||
hwaddr = nm_ether_ntop ((struct ether_addr *) &priv->perm_hw_addr);
|
||||
matched = nm_match_spec_hwaddr (specs, hwaddr);
|
||||
g_free (hwaddr);
|
||||
|
||||
|
|
@ -1644,8 +1657,8 @@ spec_match_list (NMDevice *device, const GSList *specs)
|
|||
static gboolean
|
||||
wired_match_config (NMDevice *self, NMConnection *connection)
|
||||
{
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
NMSettingWired *s_wired;
|
||||
struct ether_addr ether;
|
||||
const GByteArray *s_ether;
|
||||
|
||||
s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
|
||||
|
|
@ -1654,12 +1667,8 @@ 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_permanent_address (NM_DEVICE_ETHERNET (self), ðer);
|
||||
|
||||
if (memcmp (s_ether->data, ether.ether_addr_octet, ETH_ALEN))
|
||||
return FALSE;
|
||||
}
|
||||
if (s_ether && memcmp (s_ether->data, priv->perm_hw_addr, ETH_ALEN))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -1875,16 +1884,13 @@ get_property (GObject *object, guint prop_id,
|
|||
{
|
||||
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (object);
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
struct ether_addr hw_addr;
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_HW_ADDRESS:
|
||||
nm_device_ethernet_get_address (self, &hw_addr);
|
||||
g_value_take_string (value, nm_ether_ntop (&hw_addr));
|
||||
g_value_take_string (value, nm_ether_ntop ((struct ether_addr *) &priv->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));
|
||||
g_value_take_string (value, nm_ether_ntop ((struct ether_addr *) &priv->perm_hw_addr));
|
||||
break;
|
||||
case PROP_SPEED:
|
||||
g_value_set_uint (value, nm_device_ethernet_get_speed (self));
|
||||
|
|
|
|||
|
|
@ -63,9 +63,6 @@ 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 */
|
||||
|
|
|
|||
|
|
@ -146,9 +146,8 @@ typedef struct Supplicant {
|
|||
struct _NMDeviceWifiPrivate {
|
||||
gboolean disposed;
|
||||
|
||||
struct ether_addr hw_addr; /* Currently set MAC address */
|
||||
struct ether_addr perm_hw_addr; /* Permanent MAC address */
|
||||
gboolean perm_hw_addr_is_set;
|
||||
guint8 hw_addr[ETH_ALEN]; /* Currently set MAC address */
|
||||
guint8 perm_hw_addr[ETH_ALEN]; /* Permanent MAC address */
|
||||
|
||||
/* Legacy rfkill for ipw2x00; will be fixed with 2.6.33 kernel */
|
||||
char * ipw_rfkill_path;
|
||||
|
|
@ -1090,6 +1089,62 @@ real_bring_up (NMDevice *dev)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_update_hw_addr (NMDeviceWifi *self, const guint8 *addr)
|
||||
{
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
|
||||
g_return_if_fail (addr != NULL);
|
||||
|
||||
if (memcmp (&priv->hw_addr, addr, ETH_ALEN)) {
|
||||
memcpy (&priv->hw_addr, addr, ETH_ALEN);
|
||||
g_object_notify (G_OBJECT (self), NM_DEVICE_WIFI_HW_ADDRESS);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_set_hw_addr (NMDeviceWifi *self, const guint8 *addr, const char *detail)
|
||||
{
|
||||
NMDevice *dev = NM_DEVICE (self);
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
const char *iface;
|
||||
char *mac_str = NULL;
|
||||
gboolean success = FALSE;
|
||||
|
||||
g_return_val_if_fail (addr != NULL, FALSE);
|
||||
|
||||
iface = nm_device_get_iface (dev);
|
||||
|
||||
mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
|
||||
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
|
||||
|
||||
/* Do nothing if current MAC is same */
|
||||
if (!memcmp (&priv->hw_addr, addr, ETH_ALEN)) {
|
||||
nm_log_dbg (LOGD_DEVICE | LOGD_ETHER, "(%s): no MAC address change needed",
|
||||
iface, detail, mac_str);
|
||||
g_free (mac_str);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Can't change MAC address while device is up */
|
||||
real_hw_take_down (dev);
|
||||
|
||||
success = nm_system_device_set_mac (iface, (struct ether_addr *) addr);
|
||||
if (success) {
|
||||
/* MAC address succesfully changed; update the current MAC to match */
|
||||
_update_hw_addr (self, addr);
|
||||
nm_log_info (LOGD_DEVICE | LOGD_ETHER, "(%s): %s MAC address to %s",
|
||||
iface, detail, mac_str);
|
||||
} else {
|
||||
nm_log_warn (LOGD_DEVICE | LOGD_ETHER, "(%s): failed to %s MAC address to %s",
|
||||
iface, detail, mac_str);
|
||||
}
|
||||
real_hw_bring_up (dev, NULL);
|
||||
g_free (mac_str);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static void
|
||||
access_point_removed (NMDeviceWifi *device, NMAccessPoint *ap)
|
||||
{
|
||||
|
|
@ -1135,7 +1190,6 @@ 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);
|
||||
|
||||
|
|
@ -1156,21 +1210,7 @@ real_deactivate_quickly (NMDevice *dev)
|
|||
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);
|
||||
_set_hw_addr (self, priv->perm_hw_addr, "reset");
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1213,7 +1253,7 @@ real_check_connection_compatible (NMDevice *device,
|
|||
}
|
||||
|
||||
mac = nm_setting_wireless_get_mac_address (s_wireless);
|
||||
if (mac && memcmp (mac->data, &(priv->perm_hw_addr.ether_addr_octet), ETH_ALEN)) {
|
||||
if (mac && memcmp (mac->data, &priv->perm_hw_addr, ETH_ALEN)) {
|
||||
g_set_error (error,
|
||||
NM_WIFI_ERROR, NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE,
|
||||
"The connection's MAC address did not match this device.");
|
||||
|
|
@ -1288,7 +1328,7 @@ real_get_best_auto_connection (NMDevice *dev,
|
|||
continue;
|
||||
|
||||
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, ETH_ALEN))
|
||||
continue;
|
||||
|
||||
/* Use the connection if it's a shared connection */
|
||||
|
|
@ -1328,26 +1368,7 @@ nm_device_wifi_get_address (NMDeviceWifi *self,
|
|||
g_return_if_fail (addr != NULL);
|
||||
|
||||
priv = NM_DEVICE_WIFI_GET_PRIVATE (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));
|
||||
memcpy (addr, &priv->hw_addr, sizeof (struct ether_addr));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -2964,7 +2985,6 @@ static void
|
|||
real_update_hw_address (NMDevice *dev)
|
||||
{
|
||||
NMDeviceWifi *self = NM_DEVICE_WIFI (dev);
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
struct ifreq req;
|
||||
int fd;
|
||||
|
||||
|
|
@ -2976,18 +2996,13 @@ real_update_hw_address (NMDevice *dev)
|
|||
|
||||
memset (&req, 0, sizeof (struct ifreq));
|
||||
strncpy (req.ifr_name, nm_device_get_iface (dev), IFNAMSIZ);
|
||||
errno = 0;
|
||||
if (ioctl (fd, SIOCGIFHWADDR, &req) < 0) {
|
||||
nm_log_err (LOGD_HW | LOGD_WIFI, "(%s) error getting hardware address: %d",
|
||||
nm_log_err (LOGD_HW | LOGD_WIFI, "(%s): unable to read hardware address (error %d)",
|
||||
nm_device_get_iface (dev), errno);
|
||||
goto out;
|
||||
}
|
||||
} else
|
||||
_update_hw_addr (self, (const guint8 *) &req.ifr_hwaddr.sa_data);
|
||||
|
||||
if (memcmp (&priv->hw_addr, &req.ifr_hwaddr.sa_data, sizeof (struct ether_addr))) {
|
||||
memcpy (&priv->hw_addr, &req.ifr_hwaddr.sa_data, sizeof (struct ether_addr));
|
||||
g_object_notify (G_OBJECT (dev), NM_DEVICE_WIFI_HW_ADDRESS);
|
||||
}
|
||||
|
||||
out:
|
||||
close (fd);
|
||||
}
|
||||
|
||||
|
|
@ -2998,7 +3013,7 @@ real_update_permanent_hw_address (NMDevice *dev)
|
|||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
struct ifreq req;
|
||||
struct ethtool_perm_addr *epaddr = NULL;
|
||||
int fd;
|
||||
int fd, ret;
|
||||
|
||||
fd = socket (PF_INET, SOCK_DGRAM, 0);
|
||||
if (fd < 0) {
|
||||
|
|
@ -3009,29 +3024,26 @@ real_update_permanent_hw_address (NMDevice *dev)
|
|||
/* 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 = 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;
|
||||
ret = ioctl (fd, SIOCETHTOOL, &req);
|
||||
if (ret < 0) {
|
||||
nm_log_err (LOGD_HW | LOGD_ETHER, "(%s): unable to read permanent MAC address (error %d)",
|
||||
nm_device_get_iface (dev), errno);
|
||||
/* Fall back to current address */
|
||||
memcpy (epaddr->data, &priv->hw_addr, ETH_ALEN);
|
||||
}
|
||||
|
||||
if (memcmp (&priv->perm_hw_addr, epaddr->data, sizeof (struct ether_addr))) {
|
||||
memcpy (&priv->perm_hw_addr, epaddr->data, sizeof (struct ether_addr));
|
||||
if (memcmp (&priv->perm_hw_addr, epaddr->data, ETH_ALEN)) {
|
||||
memcpy (&priv->perm_hw_addr, epaddr->data, ETH_ALEN);
|
||||
g_object_notify (G_OBJECT (dev), NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS);
|
||||
}
|
||||
|
||||
out:
|
||||
g_free (epaddr);
|
||||
close (fd);
|
||||
}
|
||||
|
|
@ -3060,22 +3072,8 @@ real_act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
|
|||
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 (cloned_mac && (cloned_mac->len == ETH_ALEN))
|
||||
_set_hw_addr (self, (const guint8 *) cloned_mac->data, "set");
|
||||
|
||||
/* 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
|
||||
|
|
@ -3537,12 +3535,11 @@ real_get_type_capabilities (NMDevice *dev)
|
|||
static gboolean
|
||||
spec_match_list (NMDevice *device, const GSList *specs)
|
||||
{
|
||||
struct ether_addr ether;
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device);
|
||||
char *hwaddr;
|
||||
gboolean matched;
|
||||
|
||||
nm_device_wifi_get_permanent_address (NM_DEVICE_WIFI (device), ðer);
|
||||
hwaddr = nm_ether_ntop (ðer);
|
||||
hwaddr = nm_ether_ntop ((struct ether_addr *) &priv->perm_hw_addr);
|
||||
matched = nm_match_spec_hwaddr (specs, hwaddr);
|
||||
g_free (hwaddr);
|
||||
|
||||
|
|
@ -3800,16 +3797,13 @@ get_property (GObject *object, guint prop_id,
|
|||
{
|
||||
NMDeviceWifi *device = NM_DEVICE_WIFI (object);
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device);
|
||||
struct ether_addr hw_addr;
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_HW_ADDRESS:
|
||||
nm_device_wifi_get_address (device, &hw_addr);
|
||||
g_value_take_string (value, nm_ether_ntop (&hw_addr));
|
||||
g_value_take_string (value, nm_ether_ntop ((struct ether_addr *) &priv->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));
|
||||
g_value_take_string (value, nm_ether_ntop ((struct ether_addr *) &priv->perm_hw_addr));
|
||||
break;
|
||||
case PROP_MODE:
|
||||
g_value_set_uint (value, nm_device_wifi_get_mode (device));
|
||||
|
|
|
|||
|
|
@ -88,8 +88,6 @@ NMDevice *nm_device_wifi_new (const char *udi,
|
|||
|
||||
void nm_device_wifi_get_address (NMDeviceWifi *dev, struct ether_addr *addr);
|
||||
|
||||
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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue